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; }
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); }
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); }