implements relative position feature based on coordinates
This commit is contained in:
		
							parent
							
								
									64ace032f6
								
							
						
					
					
						commit
						4f1503c4a1
					
				| @ -8,6 +8,7 @@ | ||||
| #include "engine/hint.hpp" | ||||
| 
 | ||||
| #include <boost/assert.hpp> | ||||
| #include <boost/range/algorithm/transform.hpp> | ||||
| 
 | ||||
| #include <vector> | ||||
| 
 | ||||
| @ -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) | ||||
|         boost::range::transform(segment_end_coordinates, out_iter, | ||||
|                                 [this](const PhantomNodes &phantom_pair) | ||||
|                                 { | ||||
|             *out_iter++ = MakeWaypoint(*coord_iter++, phantoms.target_phantom); | ||||
|         } | ||||
|                                     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; | ||||
|  | ||||
| @ -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)); | ||||
|  | ||||
| @ -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; | ||||
|                        }); | ||||
|  | ||||
| @ -17,6 +17,8 @@ | ||||
| 
 | ||||
| #include "util/integer_range.hpp" | ||||
| 
 | ||||
| #include <boost/range/algorithm/transform.hpp> | ||||
| 
 | ||||
| namespace osrm | ||||
| { | ||||
| namespace engine | ||||
| @ -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) | ||||
| 
 | ||||
|         boost::range::transform(phantoms, std::back_inserter(json_waypoints.values), | ||||
|                                 [this](const PhantomNode &phantom) | ||||
|                                 { | ||||
|             json_waypoints.values.push_back(BaseAPI::MakeWaypoint(*coordinate_iter, *phantom_iter)); | ||||
|         } | ||||
|                                     return BaseAPI::MakeWaypoint(phantom); | ||||
|                                 }); | ||||
|         return json_waypoints; | ||||
|     } | ||||
| 
 | ||||
| @ -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::range::transform(indices, std::back_inserter(json_waypoints.values), | ||||
|                                 [this, phantoms](const std::size_t idx) | ||||
|                                 { | ||||
|             BOOST_ASSERT(idx < phantoms.size() && idx < parameters.coordinates.size()); | ||||
|             json_waypoints.values.push_back( | ||||
|                 BaseAPI::MakeWaypoint(parameters.coordinates[idx], phantoms[idx])); | ||||
|         } | ||||
|                                     BOOST_ASSERT(idx < phantoms.size()); | ||||
|                                     return BaseAPI::MakeWaypoint(phantoms[idx]); | ||||
|                                 }); | ||||
|         return json_waypoints; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -36,8 +36,8 @@ 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, | ||||
|             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)); | ||||
| @ -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)); | ||||
|  | ||||
| @ -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)); | ||||
| @ -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)); | ||||
| @ -393,9 +393,13 @@ 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}, | ||||
|         auto transformed = PhantomNodeWithDistance{PhantomNode{data, | ||||
|                                                                forward_weight, | ||||
|                                                                forward_offset, | ||||
|                                                                reverse_weight, | ||||
|                                                                reverse_offset, | ||||
|                                                                point_on_segment, | ||||
|                                                                input_coordinate}, | ||||
|                                                    current_perpendicular_distance}; | ||||
| 
 | ||||
|         return transformed; | ||||
|  | ||||
| @ -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 | ||||
| @ -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) | ||||
| @ -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, | ||||
| @ -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}); | ||||
|     } | ||||
| @ -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; | ||||
| } | ||||
|  | ||||
| @ -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; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -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) | ||||
| @ -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) | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
| @ -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; } | ||||
| @ -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; | ||||
| @ -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; | ||||
| @ -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
 | ||||
| @ -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>; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user