void MakeResponse(const InternalRouteResult &raw_route, util::json::Object &response) const { auto number_of_routes = raw_route.has_alternative() ? 2UL : 1UL; util::json::Array routes; routes.values.resize(number_of_routes); routes.values[0] = MakeRoute(raw_route.segment_end_coordinates, raw_route.unpacked_path_segments, raw_route.source_traversed_in_reverse, raw_route.target_traversed_in_reverse); if (raw_route.has_alternative()) { std::vector<std::vector<PathData>> wrapped_leg(1); wrapped_leg.front() = std::move(raw_route.unpacked_alternative); routes.values[1] = MakeRoute(raw_route.segment_end_coordinates, wrapped_leg, raw_route.alt_source_traversed_in_reverse, raw_route.alt_target_traversed_in_reverse); } response.values["waypoints"] = BaseAPI::MakeWaypoints(raw_route.segment_end_coordinates); response.values["routes"] = std::move(routes); response.values["code"] = "Ok"; }
void ApiResponseGenerator<DataFacadeT>::DescribeRoute(const RouteParameters &config, const InternalRouteResult &raw_route, util::json::Object &json_result) { if (!raw_route.is_valid()) { return; } const constexpr bool ALLOW_SIMPLIFICATION = true; const constexpr bool EXTRACT_ROUTE = false; const constexpr bool EXTRACT_ALTERNATIVE = true; Segments segment_list(raw_route, EXTRACT_ROUTE, config.zoom_level, ALLOW_SIMPLIFICATION, facade); json_result.values["route_summary"] = SummarizeRoute(raw_route, segment_list); json_result.values["via_points"] = ListViaPoints(raw_route); json_result.values["via_indices"] = ListViaIndices(segment_list); if (config.geometry) { json_result.values["route_geometry"] = GetGeometry(config.compression, segment_list); } if (config.print_instructions) { json_result.values["route_instructions"] = guidance::AnnotateRoute(segment_list.Get(), facade); } RouteNames route_names; if (raw_route.has_alternative()) { Segments alternate_segment_list(raw_route, EXTRACT_ALTERNATIVE, config.zoom_level, ALLOW_SIMPLIFICATION, facade); // Alternative Route Summaries are stored in an array to (down the line) allow multiple // alternatives util::json::Array json_alternate_route_summary_array; json_alternate_route_summary_array.values.emplace_back( SummarizeRoute(raw_route, alternate_segment_list)); json_result.values["alternative_summaries"] = json_alternate_route_summary_array; json_result.values["alternative_indices"] = ListViaIndices(alternate_segment_list); if (config.geometry) { auto alternate_geometry_string = GetGeometry(config.compression, alternate_segment_list); util::json::Array json_alternate_geometries_array; json_alternate_geometries_array.values.emplace_back( std::move(alternate_geometry_string)); json_result.values["alternative_geometries"] = json_alternate_geometries_array; } if (config.print_instructions) { util::json::Array json_alternate_annotations_array; json_alternate_annotations_array.values.emplace_back( guidance::AnnotateRoute(alternate_segment_list.Get(), facade)); json_result.values["alternative_instructions"] = json_alternate_annotations_array; } // generate names for both the main path and the alternative route auto path_segments = BuildRouteSegments(segment_list); auto alternate_segments = BuildRouteSegments(alternate_segment_list); route_names = extractRouteNames(path_segments, alternate_segments, facade); util::json::Array json_alternate_names_array; util::json::Array json_alternate_names; json_alternate_names.values.push_back(route_names.alternative_path_name_1); json_alternate_names.values.push_back(route_names.alternative_path_name_2); json_alternate_names_array.values.emplace_back(std::move(json_alternate_names)); json_result.values["alternative_names"] = json_alternate_names_array; json_result.values["found_alternative"] = util::json::True(); } else { json_result.values["found_alternative"] = util::json::False(); // generate names for the main route on its own auto path_segments = BuildRouteSegments(segment_list); std::vector<detail::Segment> alternate_segments; route_names = extractRouteNames(path_segments, alternate_segments, facade); } util::json::Array json_route_names; json_route_names.values.push_back(route_names.shortest_path_name_1); json_route_names.values.push_back(route_names.shortest_path_name_2); json_result.values["route_name"] = json_route_names; json_result.values["hint_data"] = BuildHintData(raw_route); }
SegmentList<DataFacadeT>::SegmentList(const InternalRouteResult &raw_route, const bool extract_alternative, const unsigned zoom_level, const bool allow_simplification, const DataFacade *facade) : total_distance(0), total_duration(0) { if (!raw_route.is_valid()) { return; } if (extract_alternative) { BOOST_ASSERT(raw_route.has_alternative()); InitRoute(raw_route.segment_end_coordinates.front().source_phantom, raw_route.alt_source_traversed_in_reverse.front()); AddLeg(raw_route.unpacked_alternative, raw_route.segment_end_coordinates.back().target_phantom, raw_route.alt_source_traversed_in_reverse.back(), false, facade); } else { InitRoute(raw_route.segment_end_coordinates.front().source_phantom, raw_route.source_traversed_in_reverse.front()); for (std::size_t raw_index = 0; raw_index < raw_route.segment_end_coordinates.size(); ++raw_index) { AddLeg(raw_route.unpacked_path_segments[raw_index], raw_route.segment_end_coordinates[raw_index].target_phantom, raw_route.target_traversed_in_reverse[raw_index], raw_route.is_via_leg(raw_index), facade); if (raw_route.is_via_leg(raw_index)) { const auto &source_phantom = raw_route.segment_end_coordinates[raw_index].target_phantom; if (raw_route.target_traversed_in_reverse[raw_index] != raw_route.source_traversed_in_reverse[raw_index + 1]) { bool traversed_in_reverse = raw_route.target_traversed_in_reverse[raw_index]; const extractor::TravelMode travel_mode = (traversed_in_reverse ? source_phantom.backward_travel_mode : source_phantom.forward_travel_mode); const bool constexpr IS_NECESSARY = true; const bool constexpr IS_VIA_LOCATION = true; segments.emplace_back(source_phantom.location, source_phantom.name_id, 0, 0.f, extractor::TurnInstruction::UTurn, IS_NECESSARY, IS_VIA_LOCATION, travel_mode); } } } } if (!allow_simplification) { // to prevent any simplifications, we mark all segments as necessary for (auto &segment : segments) { segment.necessary = true; } } Finalize(extract_alternative, raw_route, zoom_level, allow_simplification); }
osrm::json::Object submatchingToJSON(const osrm::matching::SubMatching &sub, const RouteParameters &route_parameters, const InternalRouteResult &raw_route) { osrm::json::Object subtrace; if (route_parameters.classify) { subtrace.values["confidence"] = sub.confidence; } JSONDescriptor<DataFacadeT> json_descriptor(facade); json_descriptor.SetConfig(route_parameters); subtrace.values["hint_data"] = json_descriptor.BuildHintData(raw_route); if (route_parameters.geometry || route_parameters.print_instructions) { DescriptionFactory factory; FixedPointCoordinate current_coordinate; factory.SetStartSegment(raw_route.segment_end_coordinates.front().source_phantom, raw_route.source_traversed_in_reverse.front()); for (const auto i : osrm::irange<std::size_t>(0, raw_route.unpacked_path_segments.size())) { for (const PathData &path_data : raw_route.unpacked_path_segments[i]) { current_coordinate = facade->GetCoordinateOfNode(path_data.node); factory.AppendSegment(current_coordinate, path_data); } factory.SetEndSegment(raw_route.segment_end_coordinates[i].target_phantom, raw_route.target_traversed_in_reverse[i], raw_route.is_via_leg(i)); } factory.Run(route_parameters.zoom_level); // we need because we don't run path simplification for (auto &segment : factory.path_description) { segment.necessary = true; } if (route_parameters.geometry) { subtrace.values["geometry"] = factory.AppendGeometryString(route_parameters.compression); } if (route_parameters.print_instructions) { std::vector<typename JSONDescriptor<DataFacadeT>::Segment> temp_segments; subtrace.values["instructions"] = json_descriptor.BuildTextualDescription(factory, temp_segments); } factory.BuildRouteSummary(factory.get_entire_length(), raw_route.shortest_path_length); osrm::json::Object json_route_summary; json_route_summary.values["total_distance"] = factory.summary.distance; json_route_summary.values["total_time"] = factory.summary.duration; subtrace.values["route_summary"] = json_route_summary; } subtrace.values["indices"] = osrm::json::make_array(sub.indices); osrm::json::Array points; for (const auto &node : sub.nodes) { points.values.emplace_back( osrm::json::make_array(node.location.lat / COORDINATE_PRECISION, node.location.lon / COORDINATE_PRECISION)); } subtrace.values["matched_points"] = points; osrm::json::Array names; for (const auto &node : sub.nodes) { names.values.emplace_back(facade->get_name_for_id(node.name_id)); } subtrace.values["matched_names"] = names; return subtrace; }
virtual void Run(const InternalRouteResult &raw_route, osrm::json::Object &json_result) override final { if (INVALID_EDGE_WEIGHT == raw_route.shortest_path_length) { // We do not need to do much, if there is no route ;-) return; } // check if first segment is non-zero BOOST_ASSERT(raw_route.unpacked_path_segments.size() == raw_route.segment_end_coordinates.size()); description_factory.SetStartSegment( raw_route.segment_end_coordinates.front().source_phantom, raw_route.source_traversed_in_reverse.front()); // for each unpacked segment add the leg to the description for (const auto i : osrm::irange<std::size_t>(0, raw_route.unpacked_path_segments.size())) { #ifndef NDEBUG const int added_segments = #endif DescribeLeg(raw_route.unpacked_path_segments[i], raw_route.segment_end_coordinates[i], raw_route.target_traversed_in_reverse[i], raw_route.is_via_leg(i)); BOOST_ASSERT(0 < added_segments); } description_factory.Run(config.zoom_level); if (config.geometry) { osrm::json::Value route_geometry = description_factory.AppendGeometryString(config.encode_geometry); json_result.values["route_geometry"] = route_geometry; } if (config.instructions) { osrm::json::Array json_route_instructions = BuildTextualDescription(description_factory, shortest_path_segments); json_result.values["route_instructions"] = json_route_instructions; } description_factory.BuildRouteSummary(description_factory.get_entire_length(), raw_route.shortest_path_length); osrm::json::Object json_route_summary; json_route_summary.values["total_distance"] = description_factory.summary.distance; json_route_summary.values["total_time"] = description_factory.summary.duration; json_route_summary.values["start_point"] = facade->get_name_for_id(description_factory.summary.source_name_id); json_route_summary.values["end_point"] = facade->get_name_for_id(description_factory.summary.target_name_id); json_result.values["route_summary"] = json_route_summary; BOOST_ASSERT(!raw_route.segment_end_coordinates.empty()); osrm::json::Array json_via_points_array; osrm::json::Array json_first_coordinate; json_first_coordinate.values.push_back( raw_route.segment_end_coordinates.front().source_phantom.location.lat / COORDINATE_PRECISION); json_first_coordinate.values.push_back( raw_route.segment_end_coordinates.front().source_phantom.location.lon / COORDINATE_PRECISION); json_via_points_array.values.push_back(json_first_coordinate); for (const PhantomNodes &nodes : raw_route.segment_end_coordinates) { std::string tmp; osrm::json::Array json_coordinate; json_coordinate.values.push_back(nodes.target_phantom.location.lat / COORDINATE_PRECISION); json_coordinate.values.push_back(nodes.target_phantom.location.lon / COORDINATE_PRECISION); json_via_points_array.values.push_back(json_coordinate); } json_result.values["via_points"] = json_via_points_array; osrm::json::Array json_via_indices_array; std::vector<unsigned> const &shortest_leg_end_indices = description_factory.GetViaIndices(); json_via_indices_array.values.insert(json_via_indices_array.values.end(), shortest_leg_end_indices.begin(), shortest_leg_end_indices.end()); json_result.values["via_indices"] = json_via_indices_array; // only one alternative route is computed at this time, so this is hardcoded if (INVALID_EDGE_WEIGHT != raw_route.alternative_path_length) { json_result.values["found_alternative"] = osrm::json::True(); BOOST_ASSERT(!raw_route.alt_source_traversed_in_reverse.empty()); alternate_description_factory.SetStartSegment( raw_route.segment_end_coordinates.front().source_phantom, raw_route.alt_source_traversed_in_reverse.front()); // Get all the coordinates for the computed route for (const PathData &path_data : raw_route.unpacked_alternative) { current = facade->GetCoordinateOfNode(path_data.node); alternate_description_factory.AppendSegment(current, path_data); } alternate_description_factory.SetEndSegment( raw_route.segment_end_coordinates.back().target_phantom, raw_route.alt_source_traversed_in_reverse.back()); alternate_description_factory.Run(config.zoom_level); if (config.geometry) { osrm::json::Value alternate_geometry_string = alternate_description_factory.AppendGeometryString(config.encode_geometry); osrm::json::Array json_alternate_geometries_array; json_alternate_geometries_array.values.push_back(alternate_geometry_string); json_result.values["alternative_geometries"] = json_alternate_geometries_array; } // Generate instructions for each alternative (simulated here) osrm::json::Array json_alt_instructions; osrm::json::Array json_current_alt_instructions; if (config.instructions) { json_current_alt_instructions = BuildTextualDescription(alternate_description_factory, alternative_path_segments); json_alt_instructions.values.push_back(json_current_alt_instructions); json_result.values["alternative_instructions"] = json_alt_instructions; } alternate_description_factory.BuildRouteSummary( alternate_description_factory.get_entire_length(), raw_route.alternative_path_length); osrm::json::Object json_alternate_route_summary; osrm::json::Array json_alternate_route_summary_array; json_alternate_route_summary.values["total_distance"] = alternate_description_factory.summary.distance; json_alternate_route_summary.values["total_time"] = alternate_description_factory.summary.duration; json_alternate_route_summary.values["start_point"] = facade->get_name_for_id(alternate_description_factory.summary.source_name_id); json_alternate_route_summary.values["end_point"] = facade->get_name_for_id(alternate_description_factory.summary.target_name_id); json_alternate_route_summary_array.values.push_back(json_alternate_route_summary); json_result.values["alternative_summaries"] = json_alternate_route_summary_array; std::vector<unsigned> const &alternate_leg_end_indices = alternate_description_factory.GetViaIndices(); osrm::json::Array json_altenative_indices_array; json_altenative_indices_array.values.insert(json_altenative_indices_array.values.end(), alternate_leg_end_indices.begin(), alternate_leg_end_indices.end()); json_result.values["alternative_indices"] = json_altenative_indices_array; } else { json_result.values["found_alternative"] = osrm::json::False(); } // Get Names for both routes RouteNames route_names = GenerateRouteNames(shortest_path_segments, alternative_path_segments, facade); osrm::json::Array json_route_names; json_route_names.values.push_back(route_names.shortest_path_name_1); json_route_names.values.push_back(route_names.shortest_path_name_2); json_result.values["route_name"] = json_route_names; if (INVALID_EDGE_WEIGHT != raw_route.alternative_path_length) { osrm::json::Array json_alternate_names_array; osrm::json::Array json_alternate_names; json_alternate_names.values.push_back(route_names.alternative_path_name_1); json_alternate_names.values.push_back(route_names.alternative_path_name_2); json_alternate_names_array.values.push_back(json_alternate_names); json_result.values["alternative_names"] = json_alternate_names_array; } json_result.values["hint_data"] = BuildHintData(raw_route); }