relative waypoint locations

This commit is contained in:
Moritz Kobitzsch 2016-02-25 10:01:16 +01:00 committed by Patrick Niklaus
parent 7dfe91bba0
commit df00b99d84
8 changed files with 79 additions and 29 deletions

View File

@ -39,7 +39,8 @@ class MatchAPI final : public RouteAPI
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);
sub_routes[index].target_traversed_in_reverse,
nullptr);
route.values["confidence"] = sub_matchings[index].confidence;
routes.values.push_back(std::move(route));
}
@ -62,7 +63,7 @@ class MatchAPI final : public RouteAPI
{
MatchingIndex() = default;
MatchingIndex(unsigned sub_matching_index_, unsigned point_index_)
: sub_matching_index(sub_matching_index_), point_index(point_index_)
: sub_matching_index(sub_matching_index_), point_index(point_index_)
{
}

View File

@ -16,8 +16,11 @@
#include "engine/internal_route_result.hpp"
#include "util/coordinate.hpp"
#include "util/integer_range.hpp"
#include <vector>
namespace osrm
{
namespace engine
@ -33,21 +36,24 @@ class RouteAPI : public BaseAPI
{
}
void MakeResponse(const InternalRouteResult &raw_route, util::json::Object &response) const
void MakeResponse(const InternalRouteResult &raw_route,
util::json::Object &response,
const std::vector<util::Coordinate> *const locations) 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);
raw_route.source_traversed_in_reverse, raw_route.target_traversed_in_reverse,
locations);
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);
raw_route.alt_target_traversed_in_reverse, locations);
}
response.values["waypoints"] = BaseAPI::MakeWaypoints(raw_route.segment_end_coordinates);
response.values["routes"] = std::move(routes);
@ -70,7 +76,8 @@ class RouteAPI : public BaseAPI
util::json::Object MakeRoute(const std::vector<PhantomNodes> &segment_end_coordinates,
std::vector<std::vector<PathData>> unpacked_path_segments,
const std::vector<bool> &source_traversed_in_reverse,
const std::vector<bool> &target_traversed_in_reverse) const
const std::vector<bool> &target_traversed_in_reverse,
const std::vector<util::Coordinate> *const locations) const
{
std::vector<guidance::RouteLeg> legs;
std::vector<guidance::LegGeometry> leg_geometries;
@ -78,7 +85,8 @@ class RouteAPI : public BaseAPI
legs.reserve(number_of_legs);
leg_geometries.reserve(number_of_legs);
unpacked_path_segments = guidance::postProcess( std::move(unpacked_path_segments) );
unpacked_path_segments = guidance::postProcess(std::move(unpacked_path_segments));
BOOST_ASSERT(locations.size() == number_of_legs + 1);
for (auto idx : util::irange(0UL, number_of_legs))
{
const auto &phantoms = segment_end_coordinates[idx];
@ -95,9 +103,18 @@ class RouteAPI : public BaseAPI
if (parameters.steps)
{
const auto getLoc = [](const std::vector<util::Coordinate> *const locations,
int idx) -> boost::optional<util::Coordinate>
{
if (locations)
return (*locations)[idx];
return {};
};
leg.steps = guidance::assembleSteps(
BaseAPI::facade, path_data, leg_geometry, phantoms.source_phantom,
phantoms.target_phantom, reversed_source, reversed_target);
phantoms.target_phantom, reversed_source, reversed_target,
getLoc(locations, idx), getLoc(locations, idx + 1));
;
}
leg_geometries.push_back(std::move(leg_geometry));

View File

@ -28,7 +28,8 @@ class TripAPI final : public RouteAPI
void MakeResponse(const std::vector<std::vector<NodeID>> &sub_trips,
const std::vector<InternalRouteResult> &sub_routes,
const std::vector<PhantomNode> &phantoms,
util::json::Object &response) const
util::json::Object &response,
const std::vector<std::vector<util::Coordinate>> * const coordinates) const
{
auto number_of_routes = sub_trips.size();
util::json::Array routes;
@ -39,7 +40,8 @@ class TripAPI final : public RouteAPI
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);
sub_routes[index].target_traversed_in_reverse,
coordinates ? &((*coordinates)[index]) : nullptr);
routes.values.push_back(std::move(route));
}
response.values["waypoints"] = MakeWaypoints(sub_trips, phantoms);

View File

@ -14,6 +14,7 @@
#include "extractor/travel_mode.hpp"
#include <vector>
#include <boost/optional.hpp>
namespace osrm
{
@ -45,10 +46,8 @@ inline StepManeuver stepManeuverFromGeometry(TurnInstruction instruction,
return StepManeuver{turn_coordinate, pre_turn_bearing, post_turn_bearing, instruction, exit};
}
}
template <typename DataFacadeT>
std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
const std::vector<PathData> &leg_data,
@ -56,7 +55,9 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
const PhantomNode &source_node,
const PhantomNode &target_node,
const bool source_traversed_in_reverse,
const bool target_traversed_in_reverse)
const bool target_traversed_in_reverse,
boost::optional<util::Coordinate> source_location,
boost::optional<util::Coordinate> target_location)
{
const auto source_duration =
(source_traversed_in_reverse ? source_node.GetReverseWeightPlusOffset()
@ -77,12 +78,21 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
std::vector<RouteStep> steps;
steps.reserve(number_of_segments);
// TODO do computation based on distance and choose better next vertex
BOOST_ASSERT(leg_geometry.size() >= 4); // source, phantom, closest positions on way
const auto initial_modifier =
source_location
? angleToDirectionModifier(util::coordinate_calculation::computeAngle(
source_location.get(), leg_geometry.locations[0], leg_geometry.locations[1]))
: DirectionModifier::UTurn;
auto segment_index = 0;
if (leg_data.size() > 0)
{
StepManeuver maneuver = detail::stepManeuverFromGeometry(
TurnInstruction{TurnType::Location, DirectionModifier::Straight}, leg_geometry,
segment_index, INVALID_EXIT_NR);
StepManeuver maneuver =
detail::stepManeuverFromGeometry(TurnInstruction{TurnType::Location, initial_modifier},
leg_geometry, segment_index, INVALID_EXIT_NR);
// TODO fix this: it makes no sense
// PathData saves the information we need of the segment _before_ the turn,
@ -119,23 +129,27 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
// x---*---*---*---z compressed edge
// |-------| duration
StepManeuver maneuver = {source_node.location, 0., 0.,
TurnInstruction{TurnType::Location, DirectionModifier::Straight},
TurnInstruction{TurnType::Location, initial_modifier},
INVALID_EXIT_NR};
steps.push_back(RouteStep{
source_node.name_id, facade.get_name_for_id(source_node.name_id),
target_duration - source_duration, leg_geometry.segment_distances[segment_index],
source_mode, std::move(maneuver), leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1});
steps.push_back(RouteStep{source_node.name_id, facade.get_name_for_id(source_node.name_id),
target_duration - source_duration,
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 final_modifier =
target_location ? angleToDirectionModifier(util::coordinate_calculation::computeAngle(
*(leg_geometry.locations.end() - 3),
*(leg_geometry.locations.end() - 1), target_location.get()))
: 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.,
TurnInstruction{TurnType::Location, DirectionModifier::Straight},
INVALID_EXIT_NR},
TurnInstruction{TurnType::Location, final_modifier}, INVALID_EXIT_NR},
leg_geometry.locations.size(), leg_geometry.locations.size()});
return steps;

View File

@ -69,6 +69,16 @@ enum TurnType // at the moment we can support 32 turn types, without increasing
Notification // Travel Mode Changes`
};
inline bool isValidModifier( const TurnType type, const DirectionModifier modifier )
{
if( type == TurnType::Location &&
modifier != DirectionModifier::Left
&& modifier != DirectionModifier::Straight
&& modifier != DirectionModifier::Right )
return false;
return true;
}
const constexpr char *turn_type_names[] = {"invalid",
"no turn",
"waypoint",

View File

@ -100,8 +100,9 @@ util::json::Object makeStepManeuver(const guidance::StepManeuver &maneuver)
{
util::json::Object step_maneuver;
step_maneuver.values["type"] = detail::instructionTypeToString(maneuver.instruction.type);
step_maneuver.values["modifier"] =
detail::instructionModifierToString(maneuver.instruction.direction_modifier);
if( isValidModifier( maneuver.instruction.type, maneuver.instruction.direction_modifier )
step_maneuver.values["modifier"] =
detail::instructionModifierToString(maneuver.instruction.direction_modifier);
step_maneuver.values["location"] = detail::coordinateToLonLat(maneuver.location);
step_maneuver.values["bearing_before"] = maneuver.bearing_before;
step_maneuver.values["bearing_after"] = maneuver.bearing_after;

View File

@ -243,13 +243,18 @@ Status TripPlugin::HandleRequest(const api::TripParameters &parameters,
// compute all round trip routes
std::vector<InternalRouteResult> routes;
routes.reserve(trips.size());
for (auto &trip : trips)
std::vector<std::vector<util::Coordinate>> ordered_coordinates;
ordered_coordinates.reserve(trips.size());
for (const auto &trip : trips)
{
routes.push_back(ComputeRoute(snapped_phantoms, parameters, trip));
ordered_coordinates.push_back( std::vector<util::Coordinate>() );
for( const auto nid : trip )
ordered_coordinates.back().push_back( parameters.coordinates[nid] );
}
api::TripAPI trip_api{BasePlugin::facade, parameters};
trip_api.MakeResponse(trips, routes, snapped_phantoms, json_result);
trip_api.MakeResponse(trips, routes, snapped_phantoms, json_result, &ordered_coordinates);
return Status::Ok;
}

View File

@ -87,7 +87,7 @@ Status ViaRoutePlugin::HandleRequest(const api::RouteParameters &route_parameter
if (raw_route.is_valid())
{
api::RouteAPI route_api{BasePlugin::facade, route_parameters};
route_api.MakeResponse(raw_route, json_result);
route_api.MakeResponse(raw_route, json_result, &route_parameters.coordinates);
}
else
{