Skip to content

Commit

Permalink
implements relative position feature based on coordinates
Browse files Browse the repository at this point in the history
  • Loading branch information
Moritz Kobitzsch authored and TheMarex committed Mar 18, 2016
1 parent f08b88c commit f11ec73
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 70 deletions.
19 changes: 9 additions & 10 deletions include/engine/api/base_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "engine/hint.hpp"

#include <boost/assert.hpp>
#include <boost/range/algorithm/transform.hpp>

#include <vector>

Expand All @@ -33,24 +34,22 @@ class BaseAPI

util::json::Array waypoints;
waypoints.values.resize(parameters.coordinates.size());
waypoints.values[0] = MakeWaypoint(parameters.coordinates.front(),
segment_end_coordinates.front().source_phantom);
waypoints.values[0] = MakeWaypoint(segment_end_coordinates.front().source_phantom);

auto coord_iter = std::next(parameters.coordinates.begin());
auto out_iter = std::next(waypoints.values.begin());
for (const auto &phantoms : segment_end_coordinates)
{
*out_iter++ = MakeWaypoint(*coord_iter++, phantoms.target_phantom);
}
boost::range::transform(segment_end_coordinates, out_iter,
[this](const PhantomNodes &phantom_pair)
{
return MakeWaypoint(phantom_pair.target_phantom);
});
return waypoints;
}

protected:
util::json::Object MakeWaypoint(const util::Coordinate input_coordinate,
const PhantomNode &phantom) const
util::json::Object MakeWaypoint(const PhantomNode &phantom) const
{
return json::makeWaypoint(phantom.location, facade.get_name_for_id(phantom.name_id),
Hint{input_coordinate, phantom, facade.GetCheckSum()});
Hint{phantom, facade.GetCheckSum()});
}

const datafacade::BaseDataFacade &facade;
Expand Down
2 changes: 1 addition & 1 deletion include/engine/api/match_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ class MatchAPI final : public RouteAPI
}
const auto &phantom =
sub_matchings[matching_index.sub_matching_index].nodes[matching_index.point_index];
auto waypoint = BaseAPI::MakeWaypoint(parameters.coordinates[trace_index], phantom);
auto waypoint = BaseAPI::MakeWaypoint(phantom);
waypoint.values["matchings_index"] = matching_index.sub_matching_index;
waypoint.values["waypoint_index"] = matching_index.point_index;
waypoints.values.push_back(std::move(waypoint));
Expand Down
3 changes: 1 addition & 2 deletions include/engine/api/nearest_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ class NearestAPI final : public BaseAPI
waypoints.values.begin(),
[this](const PhantomNodeWithDistance &phantom_with_distance)
{
auto waypoint = MakeWaypoint(parameters.coordinates.front(),
phantom_with_distance.phantom_node);
auto waypoint = MakeWaypoint(phantom_with_distance.phantom_node);
waypoint.values["distance"] = phantom_with_distance.distance;
return waypoint;
});
Expand Down
27 changes: 14 additions & 13 deletions include/engine/api/table_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#include "util/integer_range.hpp"

#include <boost/range/algorithm/transform.hpp>

namespace osrm
{
namespace engine
Expand Down Expand Up @@ -72,13 +74,12 @@ class TableAPI final : public BaseAPI
util::json::Array json_waypoints;
json_waypoints.values.reserve(phantoms.size());
BOOST_ASSERT(phantoms.size() == parameters.coordinates.size());
auto phantom_iter = phantoms.begin();
auto coordinate_iter = parameters.coordinates.begin();
for (; phantom_iter != phantoms.end() && coordinate_iter != parameters.coordinates.end();
++phantom_iter, ++coordinate_iter)
{
json_waypoints.values.push_back(BaseAPI::MakeWaypoint(*coordinate_iter, *phantom_iter));
}

boost::range::transform(phantoms, std::back_inserter(json_waypoints.values),
[this](const PhantomNode &phantom)
{
return BaseAPI::MakeWaypoint(phantom);
});
return json_waypoints;
}

Expand All @@ -87,12 +88,12 @@ class TableAPI final : public BaseAPI
{
util::json::Array json_waypoints;
json_waypoints.values.reserve(indices.size());
for (auto idx : indices)
{
BOOST_ASSERT(idx < phantoms.size() && idx < parameters.coordinates.size());
json_waypoints.values.push_back(
BaseAPI::MakeWaypoint(parameters.coordinates[idx], phantoms[idx]));
}
boost::range::transform(indices, std::back_inserter(json_waypoints.values),
[this, phantoms](const std::size_t idx)
{
BOOST_ASSERT(idx < phantoms.size());
return BaseAPI::MakeWaypoint(phantoms[idx]);
});
return json_waypoints;
}

Expand Down
11 changes: 5 additions & 6 deletions include/engine/api/trip_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ class TripAPI final : public RouteAPI
BOOST_ASSERT(sub_trips.size() == sub_routes.size());
for (auto index : util::irange<std::size_t>(0UL, sub_trips.size()))
{
auto route = MakeRoute(
sub_routes[index].segment_end_coordinates, sub_routes[index].unpacked_path_segments,
sub_routes[index].source_traversed_in_reverse,
sub_routes[index].target_traversed_in_reverse);
auto route = MakeRoute(sub_routes[index].segment_end_coordinates,
sub_routes[index].unpacked_path_segments,
sub_routes[index].source_traversed_in_reverse,
sub_routes[index].target_traversed_in_reverse);
routes.values.push_back(std::move(route));
}
response.values["waypoints"] = MakeWaypoints(sub_trips, phantoms);
Expand Down Expand Up @@ -90,8 +90,7 @@ class TripAPI final : public RouteAPI
auto trip_index = input_idx_to_trip_idx[input_index];
BOOST_ASSERT(!trip_index.NotUsed());

auto waypoint =
BaseAPI::MakeWaypoint(parameters.coordinates[input_index], phantoms[input_index]);
auto waypoint = BaseAPI::MakeWaypoint(phantoms[input_index]);
waypoint.values["trips_index"] = trip_index.sub_trip_index;
waypoint.values["waypoint_index"] = trip_index.point_index;
waypoints.values.push_back(std::move(waypoint));
Expand Down
20 changes: 12 additions & 8 deletions include/engine/geospatial_query.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
bool has_big_component = false;
auto results = rtree.Nearest(
input_coordinate,
[this, bearing, bearing_range, &has_big_component,
&has_small_component](const EdgeData &data)
[this, bearing, bearing_range, &has_big_component, &has_small_component](
const EdgeData &data)
{
auto use_segment =
(!has_small_component || (!has_big_component && !data.component.is_tiny));
Expand Down Expand Up @@ -290,8 +290,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
bool has_big_component = false;
auto results = rtree.Nearest(
input_coordinate,
[this, bearing, bearing_range, &has_big_component,
&has_small_component](const EdgeData &data)
[this, bearing, bearing_range, &has_big_component, &has_small_component](
const EdgeData &data)
{
auto use_segment =
(!has_small_component || (!has_big_component && !data.component.is_tiny));
Expand Down Expand Up @@ -393,10 +393,14 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
reverse_weight *= 1.0 - ratio;
}

auto transformed =
PhantomNodeWithDistance{PhantomNode{data, forward_weight, forward_offset,
reverse_weight, reverse_offset, point_on_segment},
current_perpendicular_distance};
auto transformed = PhantomNodeWithDistance{PhantomNode{data,
forward_weight,
forward_offset,
reverse_weight,
reverse_offset,
point_on_segment,
input_coordinate},
current_perpendicular_distance};

return transformed;
}
Expand Down
78 changes: 57 additions & 21 deletions include/engine/guidance/assemble_steps.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
const bool source_traversed_in_reverse,
const bool target_traversed_in_reverse)
{
const double constexpr ZERO_DURACTION = 0., ZERO_DISTANCE = 0., NO_BEARING = 0.;
const EdgeWeight source_duration =
source_traversed_in_reverse ? source_node.reverse_weight : source_node.forward_weight;
const auto source_mode = source_traversed_in_reverse ? source_node.backward_travel_mode
Expand All @@ -56,10 +57,19 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
steps.reserve(number_of_segments);

std::size_t segment_index = 0;
BOOST_ASSERT(leg_geometry.locations.size() >= 2);

// We report the relative position of source/target to the road only within a range that is
// sufficiently different but not full of the path
const constexpr double MINIMAL_RELATIVE_DISTANCE = 5., MAXIMAL_RELATIVE_DISTANCE = 300.;
const auto distance_to_start = util::coordinate_calculation::haversineDistance(
source_node.input_location, leg_geometry.locations[0]);
const auto initial_modifier =
leg_geometry.locations.size() >= 3
distance_to_start >= MINIMAL_RELATIVE_DISTANCE &&
distance_to_start <= MAXIMAL_RELATIVE_DISTANCE
? angleToDirectionModifier(util::coordinate_calculation::computeAngle(
leg_geometry.locations[0], leg_geometry.locations[1], leg_geometry.locations[2]))
source_node.input_location, leg_geometry.locations[0],
leg_geometry.locations[1]))
: extractor::guidance::DirectionModifier::UTurn;

if (leg_data.size() > 0)
Expand All @@ -84,8 +94,12 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
BOOST_ASSERT(segment_duration >= 0);
const auto name = facade.get_name_for_id(path_point.name_id);
const auto distance = leg_geometry.segment_distances[segment_index];
steps.push_back(RouteStep{path_point.name_id, name, segment_duration / 10.0,
distance, path_point.travel_mode, maneuver,
steps.push_back(RouteStep{path_point.name_id,
name,
segment_duration / 10.0,
distance,
path_point.travel_mode,
maneuver,
leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1});
maneuver = detail::stepManeuverFromGeometry(path_point.turn_instruction,
Expand All @@ -98,8 +112,12 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
const auto distance = leg_geometry.segment_distances[segment_index];
const int duration = segment_duration + target_duration;
BOOST_ASSERT(duration >= 0);
steps.push_back(RouteStep{target_node.name_id, facade.get_name_for_id(target_node.name_id),
duration / 10., distance, target_mode, maneuver,
steps.push_back(RouteStep{target_node.name_id,
facade.get_name_for_id(target_node.name_id),
duration / 10.,
distance,
target_mode,
maneuver,
leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1});
}
Expand All @@ -112,35 +130,53 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
// |---| source_duration
// |---------| target_duration

StepManeuver maneuver = {source_node.location, 0., 0.,
StepManeuver maneuver = {source_node.location,
NO_BEARING,
NO_BEARING,
extractor::guidance::TurnInstruction{
extractor::guidance::TurnType::NoTurn, initial_modifier},
WaypointType::Depart, INVALID_EXIT_NR};
WaypointType::Depart,
INVALID_EXIT_NR};
int duration = target_duration - source_duration;
BOOST_ASSERT(duration >= 0);

steps.push_back(RouteStep{source_node.name_id, facade.get_name_for_id(source_node.name_id),
duration / 10., leg_geometry.segment_distances[segment_index], source_mode,
std::move(maneuver), leg_geometry.FrontIndex(segment_index),
steps.push_back(RouteStep{source_node.name_id,
facade.get_name_for_id(source_node.name_id),
duration / 10.,
leg_geometry.segment_distances[segment_index],
source_mode,
std::move(maneuver),
leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1});
}

BOOST_ASSERT(segment_index == number_of_segments - 1);
const auto distance_from_end = util::coordinate_calculation::haversineDistance(
target_node.input_location, leg_geometry.locations.back());
const auto final_modifier =
leg_geometry.locations.size() >= 3
distance_from_end >= MINIMAL_RELATIVE_DISTANCE &&
distance_from_end <= MAXIMAL_RELATIVE_DISTANCE
? angleToDirectionModifier(util::coordinate_calculation::computeAngle(
leg_geometry.locations[leg_geometry.locations.size() - 3],
leg_geometry.locations[leg_geometry.locations.size() - 2],
leg_geometry.locations[leg_geometry.locations.size() - 1]))
leg_geometry.locations[leg_geometry.locations.size() - 1],
target_node.input_location))
: extractor::guidance::DirectionModifier::UTurn;
// This step has length zero, the only reason we need it is the target location
steps.push_back(RouteStep{
target_node.name_id, facade.get_name_for_id(target_node.name_id), 0., 0., target_mode,
StepManeuver{target_node.location, 0., 0.,
extractor::guidance::TurnInstruction{extractor::guidance::TurnType::NoTurn,
final_modifier},
WaypointType::Arrive, INVALID_EXIT_NR},
leg_geometry.locations.size(), leg_geometry.locations.size()});
steps.push_back(
RouteStep{target_node.name_id,
facade.get_name_for_id(target_node.name_id),
ZERO_DURACTION,
ZERO_DISTANCE,
target_mode,
StepManeuver{target_node.location,
NO_BEARING,
NO_BEARING,
extractor::guidance::TurnInstruction{
extractor::guidance::TurnType::NoTurn, final_modifier},
WaypointType::Arrive,
INVALID_EXIT_NR},
leg_geometry.locations.size(),
leg_geometry.locations.size()});

return steps;
}
Expand Down
5 changes: 1 addition & 4 deletions include/engine/hint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,13 @@ namespace engine
// Is returned as a temporary identifier for snapped coodinates
struct Hint
{
util::Coordinate input_coordinate;
PhantomNode phantom;
std::uint32_t data_checksum;

template <typename DataFacadeT>
bool IsValid(const util::Coordinate new_input_coordinates, DataFacadeT &facade) const
{
auto is_same_input_coordinate = new_input_coordinates.lon == input_coordinate.lon &&
new_input_coordinates.lat == input_coordinate.lat;
return is_same_input_coordinate && phantom.IsValid(facade.GetNumberOfNodes()) &&
return phantom.IsValid(facade.GetNumberOfNodes(), new_input_coordinates) &&
facade.GetCheckSum() == data_checksum;
}

Expand Down
19 changes: 14 additions & 5 deletions include/engine/phantom_node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ struct PhantomNode
bool is_tiny_component,
unsigned component_id,
util::Coordinate location,
util::Coordinate input_location,
unsigned short fwd_segment_position,
extractor::TravelMode forward_travel_mode,
extractor::TravelMode backward_travel_mode)
Expand All @@ -65,8 +66,8 @@ struct PhantomNode
forward_packed_geometry_id(forward_packed_geometry_id_),
reverse_packed_geometry_id(reverse_packed_geometry_id_),
component{component_id, is_tiny_component}, location(std::move(location)),
fwd_segment_position(fwd_segment_position), forward_travel_mode(forward_travel_mode),
backward_travel_mode(backward_travel_mode)
input_location(std::move(input_location)), fwd_segment_position(fwd_segment_position),
forward_travel_mode(forward_travel_mode), backward_travel_mode(backward_travel_mode)
{
}

Expand Down Expand Up @@ -115,6 +116,11 @@ struct PhantomNode
(component.id != INVALID_COMPONENTID) && (name_id != INVALID_NAMEID);
}

bool IsValid(const unsigned number_of_nodes, const util::Coordinate queried_coordinate) const
{
return queried_coordinate == input_location && IsValid(number_of_nodes);
}

bool IsValid() const { return location.IsValid() && (name_id != INVALID_NAMEID); }

bool operator==(const PhantomNode &other) const { return location == other.location; }
Expand All @@ -125,7 +131,8 @@ struct PhantomNode
int forward_offset_,
int reverse_weight_,
int reverse_offset_,
const util::Coordinate foot_point)
const util::Coordinate location_,
const util::Coordinate input_location_)
{
forward_node_id = other.forward_edge_based_node_id;
reverse_node_id = other.reverse_edge_based_node_id;
Expand All @@ -143,7 +150,8 @@ struct PhantomNode
component.id = other.component.id;
component.is_tiny = other.component.is_tiny;

location = foot_point;
location = location_;
input_location = input_location_;
fwd_segment_position = other.fwd_segment_position;

forward_travel_mode = other.forward_travel_mode;
Expand All @@ -169,6 +177,7 @@ struct PhantomNode
static_assert(sizeof(ComponentType) == 4, "ComponentType needs to 4 bytes big");
#endif
util::Coordinate location;
util::Coordinate input_location;
unsigned short fwd_segment_position;
// note 4 bits would suffice for each,
// but the saved byte would be padding anyway
Expand All @@ -177,7 +186,7 @@ struct PhantomNode
};

#ifndef _MSC_VER
static_assert(sizeof(PhantomNode) == 52, "PhantomNode has more padding then expected");
static_assert(sizeof(PhantomNode) == 60, "PhantomNode has more padding then expected");
#endif

using PhantomNodePair = std::pair<PhantomNode, PhantomNode>;
Expand Down

0 comments on commit f11ec73

Please sign in to comment.