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