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";
 }
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
    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;
    }
Ejemplo n.º 5
0
    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);
    }