Allow specifing a weight for routing that is independent of duration

This commit is contained in:
Patrick Niklaus
2016-05-12 18:50:10 +02:00
committed by Patrick Niklaus
parent e463733138
commit 279f8aabfb
85 changed files with 2100 additions and 853 deletions
+2 -1
View File
@@ -87,7 +87,8 @@ util::json::Object makeRouteStep(guidance::RouteStep step, util::json::Value geo
util::json::Object makeRoute(const guidance::Route &route,
util::json::Array legs,
boost::optional<util::json::Value> geometry);
boost::optional<util::json::Value> geometry,
const char *weight_name);
// Creates a Waypoint without Hint, see the Hint overload below
util::json::Object makeWaypoint(const util::Coordinate location, std::string name);
+7 -2
View File
@@ -221,21 +221,24 @@ class RouteAPI : public BaseAPI
{
util::json::Array durations;
util::json::Array distances;
util::json::Array weights;
util::json::Array nodes;
util::json::Array datasources;
auto &leg_geometry = leg_geometries[idx];
durations.values.reserve(leg_geometry.annotations.size());
distances.values.reserve(leg_geometry.annotations.size());
weights.values.reserve(leg_geometry.annotations.size());
nodes.values.reserve(leg_geometry.osm_node_ids.size());
datasources.values.reserve(leg_geometry.annotations.size());
std::for_each(leg_geometry.annotations.begin(),
leg_geometry.annotations.end(),
[this, &durations, &distances, &datasources](
[this, &durations, &distances, &weights, &datasources](
const guidance::LegGeometry::Annotation &step) {
durations.values.push_back(step.duration);
distances.values.push_back(step.distance);
weights.values.push_back(step.weight);
datasources.values.push_back(step.datasource);
});
std::for_each(leg_geometry.osm_node_ids.begin(),
@@ -246,6 +249,7 @@ class RouteAPI : public BaseAPI
util::json::Object annotation;
annotation.values["distance"] = std::move(distances);
annotation.values["duration"] = std::move(durations);
annotation.values["weight"] = std::move(weights);
annotation.values["nodes"] = std::move(nodes);
annotation.values["datasources"] = std::move(datasources);
annotations.push_back(std::move(annotation));
@@ -256,7 +260,8 @@ class RouteAPI : public BaseAPI
json::makeRouteLegs(std::move(legs),
std::move(step_geometries),
std::move(annotations)),
std::move(json_overview));
std::move(json_overview),
facade.GetWeightName());
return result;
}
@@ -88,10 +88,14 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
util::ShM<NodeID, true>::vector m_geometry_node_list;
util::ShM<EdgeWeight, true>::vector m_geometry_fwd_weight_list;
util::ShM<EdgeWeight, true>::vector m_geometry_rev_weight_list;
util::ShM<EdgeWeight, true>::vector m_geometry_fwd_duration_list;
util::ShM<EdgeWeight, true>::vector m_geometry_rev_duration_list;
util::ShM<bool, true>::vector m_is_core_node;
util::ShM<DatasourceID, true>::vector m_datasource_list;
util::ShM<std::uint32_t, true>::vector m_lane_description_offsets;
util::ShM<extractor::guidance::TurnLaneType::Mask, true>::vector m_lane_description_masks;
util::ShM<TurnPenalty, true>::vector m_turn_weight_penalties;
util::ShM<TurnPenalty, true>::vector m_turn_duration_penalties;
util::ShM<char, true>::vector m_datasource_name_data;
util::ShM<std::size_t, true>::vector m_datasource_name_offsets;
@@ -311,6 +315,29 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
m_is_core_node = std::move(is_core_node);
}
void InitializeTurnPenalties(storage::DataLayout &data_layout, char *memory_block)
{
auto turn_weight_penalties_ptr = data_layout.GetBlockPtr<TurnPenalty>(
memory_block, storage::DataLayout::TURN_WEIGHT_PENALTIES);
m_turn_weight_penalties = util::ShM<TurnPenalty, true>::vector(
turn_weight_penalties_ptr,
data_layout.num_entries[storage::DataLayout::TURN_WEIGHT_PENALTIES]);
if (data_layout.num_entries[storage::DataLayout::TURN_DURATION_PENALTIES] == 0)
{ // Fallback to turn weight penalties that are turn duration penalties in deciseconds
m_turn_duration_penalties = util::ShM<TurnPenalty, true>::vector(
turn_weight_penalties_ptr,
data_layout.num_entries[storage::DataLayout::TURN_WEIGHT_PENALTIES]);
}
else
{
auto turn_duration_penalties_ptr = data_layout.GetBlockPtr<TurnPenalty>(
memory_block, storage::DataLayout::TURN_DURATION_PENALTIES);
m_turn_duration_penalties = util::ShM<TurnPenalty, true>::vector(
turn_duration_penalties_ptr,
data_layout.num_entries[storage::DataLayout::TURN_DURATION_PENALTIES]);
}
}
void InitializeGeometryPointers(storage::DataLayout &data_layout, char *memory_block)
{
auto geometries_index_ptr =
@@ -346,6 +373,20 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
datasources_list_ptr, data_layout.num_entries[storage::DataLayout::DATASOURCES_LIST]);
m_datasource_list = std::move(datasources_list);
auto geometries_fwd_duration_list_ptr = data_layout.GetBlockPtr<EdgeWeight>(
memory_block, storage::DataLayout::GEOMETRIES_FWD_DURATION_LIST);
util::ShM<EdgeWeight, true>::vector geometry_fwd_duration_list(
geometries_fwd_duration_list_ptr,
data_layout.num_entries[storage::DataLayout::GEOMETRIES_FWD_DURATION_LIST]);
m_geometry_fwd_duration_list = std::move(geometry_fwd_duration_list);
auto geometries_rev_duration_list_ptr = data_layout.GetBlockPtr<EdgeWeight>(
memory_block, storage::DataLayout::GEOMETRIES_REV_DURATION_LIST);
util::ShM<EdgeWeight, true>::vector geometry_rev_duration_list(
geometries_rev_duration_list_ptr,
data_layout.num_entries[storage::DataLayout::GEOMETRIES_REV_DURATION_LIST]);
m_geometry_rev_duration_list = std::move(geometry_rev_duration_list);
auto datasource_name_data_ptr =
data_layout.GetBlockPtr<char>(memory_block, storage::DataLayout::DATASOURCE_NAME_DATA);
util::ShM<char, true>::vector datasource_name_data(
@@ -406,6 +447,7 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
InitializeGraphPointer(data_layout, memory_block);
InitializeChecksumPointer(data_layout, memory_block);
InitializeNodeAndEdgeInformationPointers(data_layout, memory_block);
InitializeTurnPenalties(data_layout, memory_block);
InitializeGeometryPointers(data_layout, memory_block);
InitializeTimestampPointer(data_layout, memory_block);
InitializeViaNodeListPointer(data_layout, memory_block);
@@ -535,6 +577,55 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
return result_nodes;
}
virtual std::vector<EdgeWeight>
GetUncompressedForwardDurations(const EdgeID id) const override final
{
/*
* EdgeWeights's for geometries are stored in one place for
* both forward and reverse segments along the same bi-
* directional edge. The m_geometry_indices stores
* refences to where to find the beginning of the bi-
* directional edge in the m_geometry_fwd_weight_list vector.
* */
const unsigned begin = m_geometry_indices.at(id) + 1;
const unsigned end = m_geometry_indices.at(id + 1);
std::vector<EdgeWeight> result_durations;
result_durations.resize(end - begin);
std::copy(m_geometry_fwd_duration_list.begin() + begin,
m_geometry_fwd_duration_list.begin() + end,
result_durations.begin());
return result_durations;
}
virtual std::vector<EdgeWeight>
GetUncompressedReverseDurations(const EdgeID id) const override final
{
/*
* EdgeWeights for geometries are stored in one place for
* both forward and reverse segments along the same bi-
* directional edge. The m_geometry_indices stores
* refences to where to find the beginning of the bi-
* directional edge in the m_geometry_rev_weight_list vector. For
* reverse durations of bi-directional edges, edges 1 to
* n-1 of that edge need to be read in reverse.
*/
const unsigned begin = m_geometry_indices.at(id);
const unsigned end = m_geometry_indices.at(id + 1) - 1;
std::vector<EdgeWeight> result_durations;
result_durations.resize(end - begin);
std::copy(
m_geometry_rev_duration_list.rbegin() + (m_geometry_rev_duration_list.size() - end),
m_geometry_rev_duration_list.rbegin() + (m_geometry_rev_duration_list.size() - begin),
result_durations.begin());
return result_durations;
}
virtual std::vector<EdgeWeight>
GetUncompressedForwardWeights(const EdgeID id) const override final
{
@@ -588,6 +679,18 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
return m_via_geometry_list.at(id);
}
virtual TurnPenalty GetWeightPenaltyForEdgeID(const unsigned id) const override final
{
BOOST_ASSERT(m_turn_weight_penalties.size() > id);
return m_turn_weight_penalties[id];
}
virtual TurnPenalty GetDurationPenaltyForEdgeID(const unsigned id) const override final
{
BOOST_ASSERT(m_turn_duration_penalties.size() > id);
return m_turn_duration_penalties[id];
}
extractor::guidance::TurnInstruction
GetTurnInstructionForEdgeID(const EdgeID id) const override final
{
@@ -886,6 +989,13 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
return m_profile_properties->max_speed_for_map_matching;
}
const char *GetWeightName() const override final { return m_profile_properties->weight_name; }
unsigned GetWeightPrecision() const override final
{
return m_profile_properties->weight_precision;
}
BearingClassID GetBearingClassID(const NodeID id) const override final
{
return m_bearing_class_id_table.at(id);
+13 -1
View File
@@ -85,12 +85,20 @@ class BaseDataFacade
virtual std::vector<NodeID> GetUncompressedReverseGeometry(const EdgeID id) const = 0;
virtual TurnPenalty GetWeightPenaltyForEdgeID(const unsigned id) const = 0;
virtual TurnPenalty GetDurationPenaltyForEdgeID(const unsigned id) const = 0;
// Gets the weight values for each segment in an uncompressed geometry.
// Should always be 1 shorter than GetUncompressedGeometry
virtual std::vector<EdgeWeight> GetUncompressedForwardWeights(const EdgeID id) const = 0;
virtual std::vector<EdgeWeight> GetUncompressedReverseWeights(const EdgeID id) const = 0;
// Gets the duration values for each segment in an uncompressed geometry.
// Should always be 1 shorter than GetUncompressedGeometry
virtual std::vector<EdgeWeight> GetUncompressedForwardDurations(const EdgeID id) const = 0;
virtual std::vector<EdgeWeight> GetUncompressedReverseDurations(const EdgeID id) const = 0;
// Returns the data source ids that were used to supply the edge
// weights. Will return an empty array when only the base profile is used.
virtual std::vector<DatasourceID> GetUncompressedForwardDatasources(const EdgeID id) const = 0;
@@ -177,6 +185,10 @@ class BaseDataFacade
virtual double GetMapMatchingMaxSpeed() const = 0;
virtual const char *GetWeightName() const = 0;
virtual unsigned GetWeightPrecision() const = 0;
virtual BearingClassID GetBearingClassID(const NodeID id) const = 0;
virtual util::guidance::TurnBearing PreTurnBearing(const EdgeID eid) const = 0;
+16 -6
View File
@@ -369,19 +369,24 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// Find the node-based-edge that this belongs to, and directly
// calculate the forward_weight, forward_offset, reverse_weight, reverse_offset
int forward_offset = 0, forward_weight = 0;
int reverse_offset = 0, reverse_weight = 0;
EdgeWeight forward_offset = 0, forward_weight = 0, forward_duration = 0;
EdgeWeight reverse_offset = 0, reverse_weight = 0, reverse_duration = 0;
const std::vector<EdgeWeight> forward_weight_vector =
datafacade.GetUncompressedForwardWeights(data.packed_geometry_id);
const std::vector<EdgeWeight> reverse_weight_vector =
datafacade.GetUncompressedReverseWeights(data.packed_geometry_id);
const std::vector<EdgeWeight> forward_duration_vector =
datafacade.GetUncompressedForwardDurations(data.packed_geometry_id);
const std::vector<EdgeWeight> reverse_duration_vector =
datafacade.GetUncompressedReverseDurations(data.packed_geometry_id);
for (std::size_t i = 0; i < data.fwd_segment_position; i++)
{
forward_offset += forward_weight_vector[i];
}
forward_weight = forward_weight_vector[data.fwd_segment_position];
forward_duration = forward_duration_vector[data.fwd_segment_position];
BOOST_ASSERT(data.fwd_segment_position < reverse_weight_vector.size());
@@ -392,22 +397,27 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
}
reverse_weight =
reverse_weight_vector[reverse_weight_vector.size() - data.fwd_segment_position - 1];
reverse_duration =
reverse_duration_vector[reverse_duration_vector.size() - data.fwd_segment_position - 1];
ratio = std::min(1.0, std::max(0.0, ratio));
if (data.forward_segment_id.id != SPECIAL_SEGMENTID)
{
forward_weight *= ratio;
forward_weight = static_cast<EdgeWeight>(forward_weight * ratio);
forward_duration = static_cast<EdgeWeight>(forward_duration * ratio);
}
if (data.reverse_segment_id.id != SPECIAL_SEGMENTID)
{
const EdgeWeight difference = reverse_weight * ratio;
reverse_weight -= difference;
reverse_weight -= static_cast<EdgeWeight>(reverse_weight * ratio);
reverse_duration -= static_cast<EdgeWeight>(reverse_duration * ratio);
}
auto transformed = PhantomNodeWithDistance{PhantomNode{data,
forward_weight,
forward_offset,
reverse_weight,
forward_duration,
reverse_duration,
forward_offset,
reverse_offset,
point_on_segment,
input_coordinate},
@@ -75,8 +75,11 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
}
prev_coordinate = coordinate;
geometry.annotations.emplace_back(LegGeometry::Annotation{
current_distance, path_point.duration_until_turn / 10., path_point.datasource_id});
geometry.annotations.emplace_back(
LegGeometry::Annotation{current_distance,
path_point.duration_until_turn / 10.,
path_point.weight_until_turn / 10.,
path_point.datasource_id});
geometry.locations.push_back(std::move(coordinate));
geometry.osm_node_ids.push_back(facade.GetOSMNodeIDOfNode(path_point.turn_via_node));
}
@@ -89,10 +92,14 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
const std::vector<DatasourceID> forward_datasources =
facade.GetUncompressedForwardDatasources(target_node.packed_geometry_id);
// FIXME this is wrong. We need to check for traversal direction here
// and for the case of a local path (target and source on the same edge)
geometry.annotations.emplace_back(
LegGeometry::Annotation{current_distance,
target_node.forward_duration / 10.,
target_node.forward_weight / 10.,
forward_datasources[target_node.fwd_segment_position]});
geometry.segment_offsets.push_back(geometry.locations.size());
geometry.locations.push_back(target_node.location);
+11 -16
View File
@@ -79,7 +79,7 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const std::vector<PathDa
return NamedSegment{point.duration_until_turn, index++, point.name_id};
});
const auto target_duration =
target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight;
target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration;
if (target_duration > 1)
segments.push_back({target_duration, index++, target_node.name_id});
// this makes sure that the segment with the lowest position comes first
@@ -130,18 +130,14 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
const bool needs_summary)
{
const auto target_duration =
(target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight) /
10.;
(target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration);
auto distance = std::accumulate(
leg_geometry.segment_distances.begin(), leg_geometry.segment_distances.end(), 0.);
auto duration = std::accumulate(route_data.begin(),
route_data.end(),
0.,
[](const double sum, const PathData &data) {
return sum + data.duration_until_turn;
}) /
10.;
auto duration = std::accumulate(
route_data.begin(), route_data.end(), 0, [](const double sum, const PathData &data) {
return sum + data.duration_until_turn;
});
// s
// |
@@ -155,10 +151,10 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
// The duration of the turn (a,c) -> (c,e) will be the duration of (a,c) (e.g. the duration
// of (a,b,c)).
// The phantom node of s will contain:
// `forward_weight`: duration of (a,s)
// `forward_duration`: duration of (a,s)
// `forward_offset`: 0 (its the first segment)
// The phantom node of t will contain:
// `forward_weight`: duration of (d,t)
// `forward_duration`: duration of (d,t)
// `forward_offset`: duration of (c, d)
// path_data will have entries for (s,b), (b, c), (c, d) but (d, t) is only
// caputed by the phantom node. So we need to add the target duration here.
@@ -167,9 +163,8 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
duration = duration + target_duration;
if (route_data.empty())
{
duration -= (target_traversed_in_reverse ? source_node.reverse_weight
: source_node.forward_weight) /
10.0;
duration -= (target_traversed_in_reverse ? source_node.reverse_duration
: source_node.forward_duration);
}
std::string summary;
@@ -201,7 +196,7 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
summary = boost::algorithm::join(summary_names, ", ");
}
return RouteLeg{duration, distance, summary, {}};
return RouteLeg{duration / 10., distance, summary, {}};
}
} // namespace guidance
+22 -7
View File
@@ -41,14 +41,20 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
const bool source_traversed_in_reverse,
const bool target_traversed_in_reverse)
{
const double constexpr ZERO_DURATION = 0., ZERO_DISTANCE = 0.;
const double weight_multiplier = std::pow(10., facade.GetWeightPrecision());
const double constexpr ZERO_DURATION = 0., ZERO_DISTANCE = 0., ZERO_WEIGHT = 0;
const constexpr char *NO_ROTARY_NAME = "";
const EdgeWeight source_duration =
const EdgeWeight source_weight =
source_traversed_in_reverse ? source_node.reverse_weight : source_node.forward_weight;
const EdgeWeight source_duration =
source_traversed_in_reverse ? source_node.reverse_duration : source_node.forward_duration;
const auto source_mode = source_traversed_in_reverse ? source_node.backward_travel_mode
: source_node.forward_travel_mode;
const EdgeWeight target_duration =
target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration;
const EdgeWeight target_weight =
target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight;
const auto target_mode = target_traversed_in_reverse ? target_node.backward_travel_mode
: target_node.forward_travel_mode;
@@ -84,7 +90,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
// but a RouteStep is with regard to the segment after the turn.
// We need to skip the first segment because it is already covered by the
// initial start of a route
int segment_duration = 0;
EdgeWeight segment_duration = 0;
EdgeWeight segment_weight = 0;
// some name changes are not announced in our processing. For these, we have to keep the
// first name on the segment
@@ -93,11 +100,12 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
{
const auto &path_point = leg_data[leg_data_index];
segment_duration += path_point.duration_until_turn;
segment_weight += path_point.weight_until_turn;
// all changes to this check have to be matched with assemble_geometry
if (path_point.turn_instruction.type != extractor::guidance::TurnType::NoTurn)
{
BOOST_ASSERT(segment_duration >= 0);
BOOST_ASSERT(segment_weight >= 0);
const auto name = facade.GetNameForID(step_name_id);
const auto ref = facade.GetRefForID(step_name_id);
const auto pronunciation = facade.GetPronunciationForID(step_name_id);
@@ -111,8 +119,9 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
destinations.to_string(),
NO_ROTARY_NAME,
NO_ROTARY_NAME,
segment_duration / 10.0,
segment_duration / 10.,
distance,
segment_weight / weight_multiplier,
path_point.travel_mode,
maneuver,
leg_geometry.FrontIndex(segment_index),
@@ -173,10 +182,12 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
0};
segment_index++;
segment_duration = 0;
segment_weight = 0;
}
}
const auto distance = leg_geometry.segment_distances[segment_index];
const int duration = segment_duration + target_duration;
const EdgeWeight duration = segment_duration + target_duration;
const EdgeWeight weight = segment_weight + target_weight;
BOOST_ASSERT(duration >= 0);
steps.push_back(RouteStep{step_name_id,
facade.GetNameForID(step_name_id).to_string(),
@@ -187,6 +198,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
NO_ROTARY_NAME,
duration / 10.,
distance,
weight / weight_multiplier,
target_mode,
maneuver,
leg_geometry.FrontIndex(segment_index),
@@ -202,7 +214,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
// |---| source_duration
// |---------| target_duration
int duration = target_duration - source_duration;
const EdgeWeight duration = target_duration - source_duration;
const EdgeWeight weight = target_weight - source_weight;
BOOST_ASSERT(duration >= 0);
steps.push_back(RouteStep{source_node.name_id,
@@ -214,6 +227,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
NO_ROTARY_NAME,
duration / 10.,
leg_geometry.segment_distances[segment_index],
weight / weight_multiplier,
source_mode,
std::move(maneuver),
leg_geometry.FrontIndex(segment_index),
@@ -251,6 +265,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
NO_ROTARY_NAME,
ZERO_DURATION,
ZERO_DISTANCE,
ZERO_WEIGHT,
target_mode,
std::move(maneuver),
leg_geometry.locations.size() - 1,
+3 -2
View File
@@ -37,8 +37,9 @@ struct LegGeometry
// Per-coordinate metadata
struct Annotation
{
double distance;
double duration;
double distance; // distance in meters
double duration; // duration in seconds
double weight; // weight value
DatasourceID datasource;
};
std::vector<Annotation> annotations;
+6 -2
View File
@@ -64,8 +64,9 @@ struct RouteStep
std::string destinations;
std::string rotary_name;
std::string rotary_pronunciation;
double duration;
double distance;
double duration; // duration in seconds
double distance; // distance in meters
double weight; // weight value
extractor::TravelMode mode;
StepManeuver maneuver;
// indices into the locations array stored the LegGeometry
@@ -117,6 +118,7 @@ inline void RouteStep::Invalidate()
rotary_pronunciation.clear();
duration = 0;
distance = 0;
weight = 0;
mode = TRAVEL_MODE_INACCESSIBLE;
maneuver = getInvalidStepManeuver();
geometry_begin = 0;
@@ -132,6 +134,7 @@ inline RouteStep &RouteStep::AddInFront(const RouteStep &preceeding_step)
BOOST_ASSERT(mode == preceeding_step.mode);
duration += preceeding_step.duration;
distance += preceeding_step.distance;
weight += preceeding_step.weight;
geometry_begin = preceeding_step.geometry_begin;
intersections.insert(intersections.begin(),
@@ -148,6 +151,7 @@ inline RouteStep &RouteStep::ElongateBy(const RouteStep &following_step)
BOOST_ASSERT(mode == following_step.mode);
duration += following_step.duration;
distance += following_step.distance;
weight += following_step.weight;
geometry_end = following_step.geometry_end;
intersections.insert(intersections.end(),
+2 -2
View File
@@ -63,8 +63,8 @@ struct Hint
friend std::ostream &operator<<(std::ostream &, const Hint &);
};
static_assert(sizeof(Hint) == 56 + 4, "Hint is bigger than expected");
constexpr std::size_t ENCODED_HINT_SIZE = 80;
static_assert(sizeof(Hint) == 64 + 4, "Hint is bigger than expected");
constexpr std::size_t ENCODED_HINT_SIZE = 92;
static_assert(ENCODED_HINT_SIZE / 4 * 3 >= sizeof(Hint),
"ENCODED_HINT_SIZE does not match size of Hint");
}
+2
View File
@@ -24,6 +24,8 @@ struct PathData
NodeID turn_via_node;
// name of the street that leads to the turn
unsigned name_id;
// weight that is traveled on the segment until the turn is reached
EdgeWeight weight_until_turn;
// duration that is traveled on the segment until the turn is reached
EdgeWeight duration_until_turn;
// instruction to execute at the turn
+35 -22
View File
@@ -49,10 +49,12 @@ struct PhantomNode
PhantomNode(SegmentID forward_segment_id,
SegmentID reverse_segment_id,
unsigned name_id,
int forward_weight,
int reverse_weight,
int forward_offset,
int reverse_offset,
EdgeWeight forward_weight,
EdgeWeight reverse_weight,
EdgeWeight forward_duration,
EdgeWeight reverse_duration,
EdgeWeight forward_offset,
EdgeWeight reverse_offset,
unsigned packed_geometry_id_,
bool is_tiny_component,
unsigned component_id,
@@ -63,6 +65,7 @@ struct PhantomNode
extractor::TravelMode backward_travel_mode)
: forward_segment_id(forward_segment_id), reverse_segment_id(reverse_segment_id),
name_id(name_id), forward_weight(forward_weight), reverse_weight(reverse_weight),
forward_duration(forward_duration), reverse_duration(reverse_duration),
forward_offset(forward_offset), reverse_offset(reverse_offset),
packed_geometry_id(packed_geometry_id_), component{component_id, is_tiny_component},
location(std::move(location)), input_location(std::move(input_location)),
@@ -75,20 +78,21 @@ struct PhantomNode
: forward_segment_id{SPECIAL_SEGMENTID, false},
reverse_segment_id{SPECIAL_SEGMENTID, false},
name_id(std::numeric_limits<unsigned>::max()), forward_weight(INVALID_EDGE_WEIGHT),
reverse_weight(INVALID_EDGE_WEIGHT), forward_offset(0), reverse_offset(0),
reverse_weight(INVALID_EDGE_WEIGHT), forward_duration(INVALID_EDGE_WEIGHT),
reverse_duration(INVALID_EDGE_WEIGHT), forward_offset(0), reverse_offset(0),
packed_geometry_id(SPECIAL_GEOMETRYID), component{INVALID_COMPONENTID, false},
fwd_segment_position(0), forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
{
}
int GetForwardWeightPlusOffset() const
EdgeWeight GetForwardWeightPlusOffset() const
{
BOOST_ASSERT(forward_segment_id.enabled);
return forward_offset + forward_weight;
}
int GetReverseWeightPlusOffset() const
EdgeWeight GetReverseWeightPlusOffset() const
{
BOOST_ASSERT(reverse_segment_id.enabled);
return reverse_offset + reverse_weight;
@@ -102,6 +106,8 @@ struct PhantomNode
(reverse_segment_id.id < number_of_nodes)) &&
((forward_weight != INVALID_EDGE_WEIGHT) ||
(reverse_weight != INVALID_EDGE_WEIGHT)) &&
((forward_duration != INVALID_EDGE_WEIGHT) ||
(reverse_duration != INVALID_EDGE_WEIGHT)) &&
(component.id != INVALID_COMPONENTID) && (name_id != INVALID_NAMEID);
}
@@ -116,19 +122,22 @@ struct PhantomNode
template <class OtherT>
explicit PhantomNode(const OtherT &other,
int forward_weight_,
int forward_offset_,
int reverse_weight_,
int reverse_offset_,
const util::Coordinate location_,
const util::Coordinate input_location_)
EdgeWeight forward_weight,
EdgeWeight reverse_weight,
EdgeWeight forward_duration,
EdgeWeight reverse_duration,
EdgeWeight forward_offset,
EdgeWeight reverse_offset,
const util::Coordinate location,
const util::Coordinate input_location)
: forward_segment_id{other.forward_segment_id},
reverse_segment_id{other.reverse_segment_id}, name_id{other.name_id},
forward_weight{forward_weight_}, reverse_weight{reverse_weight_},
forward_offset{forward_offset_}, reverse_offset{reverse_offset_},
forward_weight{forward_weight}, reverse_weight{reverse_weight},
forward_duration{forward_duration}, reverse_duration{reverse_duration},
forward_offset{forward_offset}, reverse_offset{reverse_offset},
packed_geometry_id{other.packed_geometry_id},
component{other.component.id, other.component.is_tiny}, location{location_},
input_location{input_location_}, fwd_segment_position{other.fwd_segment_position},
component{other.component.id, other.component.is_tiny}, location{location},
input_location{input_location}, fwd_segment_position{other.fwd_segment_position},
forward_travel_mode{other.forward_travel_mode},
backward_travel_mode{other.backward_travel_mode}
{
@@ -137,10 +146,12 @@ struct PhantomNode
SegmentID forward_segment_id;
SegmentID reverse_segment_id;
unsigned name_id;
int forward_weight;
int reverse_weight;
int forward_offset;
int reverse_offset;
EdgeWeight forward_weight;
EdgeWeight reverse_weight;
EdgeWeight forward_duration;
EdgeWeight reverse_duration;
EdgeWeight forward_offset;
EdgeWeight reverse_offset;
unsigned packed_geometry_id;
struct ComponentType
{
@@ -158,7 +169,7 @@ struct PhantomNode
extractor::TravelMode backward_travel_mode;
};
static_assert(sizeof(PhantomNode) == 56, "PhantomNode has more padding then expected");
static_assert(sizeof(PhantomNode) == 64, "PhantomNode has more padding then expected");
using PhantomNodePair = std::pair<PhantomNode, PhantomNode>;
@@ -188,6 +199,8 @@ inline std::ostream &operator<<(std::ostream &out, const PhantomNode &pn)
<< "name: " << pn.name_id << ", "
<< "fwd-w: " << pn.forward_weight << ", "
<< "rev-w: " << pn.reverse_weight << ", "
<< "fwd-d: " << pn.forward_duration << ", "
<< "rev-d: " << pn.reverse_duration << ", "
<< "fwd-o: " << pn.forward_offset << ", "
<< "rev-o: " << pn.reverse_offset << ", "
<< "geom: " << pn.packed_geometry_id << ", "
@@ -91,7 +91,7 @@ class AlternativeRouting final : private BasicRoutingInterface
QueryHeap &heap1,
QueryHeap &heap2,
NodeID *middle_node,
int *upper_bound_to_shortest_path_weight,
EdgeWeight *upper_bound_to_shortest_path_weight,
std::vector<NodeID> &search_space_intersection,
std::vector<SearchSpaceEdge> &search_space,
const EdgeWeight min_edge_offset) const
@@ -100,14 +100,14 @@ class AlternativeRouting final : private BasicRoutingInterface
QueryHeap &reverse_heap = (is_forward_directed ? heap2 : heap1);
const NodeID node = forward_heap.DeleteMin();
const int weight = forward_heap.GetKey(node);
const EdgeWeight weight = forward_heap.GetKey(node);
// const NodeID parentnode = forward_heap.GetData(node).parent;
// util::Log() << (is_forward_directed ? "[fwd] " : "[rev] ") << "settled
// edge ("
// << parentnode << "," << node << "), dist: " << weight;
const int scaled_weight =
static_cast<int>((weight + min_edge_offset) / (1. + VIAPATH_EPSILON));
const auto scaled_weight =
static_cast<EdgeWeight>((weight + min_edge_offset) / (1. + VIAPATH_EPSILON));
if ((INVALID_EDGE_WEIGHT != *upper_bound_to_shortest_path_weight) &&
(scaled_weight > *upper_bound_to_shortest_path_weight))
{
@@ -120,7 +120,7 @@ class AlternativeRouting final : private BasicRoutingInterface
if (reverse_heap.WasInserted(node))
{
search_space_intersection.emplace_back(node);
const int new_weight = reverse_heap.GetKey(node) + weight;
const EdgeWeight new_weight = reverse_heap.GetKey(node) + weight;
if (new_weight < *upper_bound_to_shortest_path_weight)
{
if (new_weight >= 0)
@@ -139,7 +139,7 @@ class AlternativeRouting final : private BasicRoutingInterface
{
// check whether there is a loop present at the node
const auto loop_weight = super::GetLoopWeight(facade, node);
const int new_weight_with_loop = new_weight + loop_weight;
const EdgeWeight new_weight_with_loop = new_weight + loop_weight;
if (loop_weight != INVALID_EDGE_WEIGHT &&
new_weight_with_loop <= *upper_bound_to_shortest_path_weight)
{
@@ -158,10 +158,10 @@ class AlternativeRouting final : private BasicRoutingInterface
if (edge_is_forward_directed)
{
const NodeID to = facade->GetTarget(edge);
const int edge_weight = data.weight;
const EdgeWeight edge_weight = data.weight;
BOOST_ASSERT(edge_weight > 0);
const int to_weight = weight + edge_weight;
const EdgeWeight to_weight = weight + edge_weight;
// New Node discovered -> Add to Heap + Node Info Storage
if (!forward_heap.WasInserted(to))
@@ -76,10 +76,10 @@ class ManyToManyRouting final : public BasicRoutingInterface
if (direction_flag)
{
const NodeID to = facade->GetTarget(edge);
const int edge_weight = data.weight;
const EdgeWeight edge_weight = data.weight;
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
const int to_weight = weight + edge_weight;
const EdgeWeight to_weight = weight + edge_weight;
// New Node discovered -> Add to Heap + Node Info Storage
if (!query_heap.WasInserted(to))
@@ -111,7 +111,7 @@ class ManyToManyRouting final : public BasicRoutingInterface
if (reverse_flag)
{
const NodeID to = facade->GetTarget(edge);
const int edge_weight = data.weight;
const EdgeWeight edge_weight = data.weight;
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
if (query_heap.WasInserted(to))
{
@@ -122,12 +122,15 @@ class BasicRoutingInterface
const auto geometry_index = facade->GetGeometryIndexForEdgeID(edge_data.id);
std::vector<NodeID> id_vector;
std::vector<EdgeWeight> weight_vector;
std::vector<EdgeWeight> duration_vector;
std::vector<DatasourceID> datasource_vector;
if (geometry_index.forward)
{
id_vector = facade->GetUncompressedForwardGeometry(geometry_index.id);
weight_vector = facade->GetUncompressedForwardWeights(geometry_index.id);
duration_vector = facade->GetUncompressedForwardDurations(geometry_index.id);
datasource_vector =
facade->GetUncompressedForwardDatasources(geometry_index.id);
}
@@ -135,17 +138,14 @@ class BasicRoutingInterface
{
id_vector = facade->GetUncompressedReverseGeometry(geometry_index.id);
weight_vector = facade->GetUncompressedReverseWeights(geometry_index.id);
duration_vector = facade->GetUncompressedReverseDurations(geometry_index.id);
datasource_vector =
facade->GetUncompressedReverseDatasources(geometry_index.id);
}
BOOST_ASSERT(id_vector.size() > 0);
BOOST_ASSERT(weight_vector.size() > 0);
BOOST_ASSERT(datasource_vector.size() > 0);
const auto total_weight =
std::accumulate(weight_vector.begin(), weight_vector.end(), 0);
BOOST_ASSERT(weight_vector.size() == id_vector.size() - 1);
BOOST_ASSERT(duration_vector.size() == id_vector.size() - 1);
const bool is_first_segment = unpacked_path.empty();
const std::size_t start_index =
@@ -165,6 +165,7 @@ class BasicRoutingInterface
PathData{id_vector[segment_idx + 1],
name_index,
weight_vector[segment_idx],
duration_vector[segment_idx],
extractor::guidance::TurnInstruction::NO_TURN(),
{{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID},
travel_mode,
@@ -179,7 +180,10 @@ class BasicRoutingInterface
unpacked_path.back().entry_classid = facade->GetEntryClassID(edge_data.id);
unpacked_path.back().turn_instruction = turn_instruction;
unpacked_path.back().duration_until_turn += (edge_data.weight - total_weight);
unpacked_path.back().duration_until_turn +=
facade->GetDurationPenaltyForEdgeID(edge_data.id);
unpacked_path.back().weight_until_turn +=
facade->GetWeightPenaltyForEdgeID(edge_data.id);
unpacked_path.back().pre_turn_bearing = facade->PreTurnBearing(edge_data.id);
unpacked_path.back().post_turn_bearing = facade->PostTurnBearing(edge_data.id);
});
@@ -187,6 +191,7 @@ class BasicRoutingInterface
std::size_t start_index = 0, end_index = 0;
std::vector<unsigned> id_vector;
std::vector<EdgeWeight> weight_vector;
std::vector<EdgeWeight> duration_vector;
std::vector<DatasourceID> datasource_vector;
const bool is_local_path = (phantom_node_pair.source_phantom.packed_geometry_id ==
phantom_node_pair.target_phantom.packed_geometry_id) &&
@@ -200,6 +205,9 @@ class BasicRoutingInterface
weight_vector = facade->GetUncompressedReverseWeights(
phantom_node_pair.target_phantom.packed_geometry_id);
duration_vector = facade->GetUncompressedReverseDurations(
phantom_node_pair.target_phantom.packed_geometry_id);
datasource_vector = facade->GetUncompressedReverseDatasources(
phantom_node_pair.target_phantom.packed_geometry_id);
@@ -225,6 +233,9 @@ class BasicRoutingInterface
weight_vector = facade->GetUncompressedForwardWeights(
phantom_node_pair.target_phantom.packed_geometry_id);
duration_vector = facade->GetUncompressedForwardDurations(
phantom_node_pair.target_phantom.packed_geometry_id);
datasource_vector = facade->GetUncompressedForwardDatasources(
phantom_node_pair.target_phantom.packed_geometry_id);
}
@@ -245,6 +256,7 @@ class BasicRoutingInterface
id_vector[start_index < end_index ? segment_idx + 1 : segment_idx - 1],
phantom_node_pair.target_phantom.name_id,
weight_vector[segment_idx],
duration_vector[segment_idx],
extractor::guidance::TurnInstruction::NO_TURN(),
{{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID},
target_traversed_in_reverse ? phantom_node_pair.target_phantom.backward_travel_mode
@@ -260,6 +272,9 @@ class BasicRoutingInterface
const auto source_weight = start_traversed_in_reverse
? phantom_node_pair.source_phantom.reverse_weight
: phantom_node_pair.source_phantom.forward_weight;
const auto source_duration = start_traversed_in_reverse
? phantom_node_pair.source_phantom.reverse_duration
: phantom_node_pair.source_phantom.forward_duration;
// The above code will create segments for (v, w), (w,x), (x, y) and (y, Z).
// However the first segment duration needs to be adjusted to the fact that the source
// phantom is in the middle of the segment. We do this by subtracting v--s from the
@@ -273,8 +288,10 @@ class BasicRoutingInterface
// TODO this creates a scenario where it's possible the duration from a phantom
// node to the first turn would be the same as from end to end of a segment,
// which is obviously incorrect and not ideal...
unpacked_path.front().weight_until_turn =
std::max(unpacked_path.front().weight_until_turn - source_weight, 0);
unpacked_path.front().duration_until_turn =
std::max(unpacked_path.front().duration_until_turn - source_weight, 0);
std::max(unpacked_path.front().duration_until_turn - source_duration, 0);
}
// there is no equivalent to a node-based node in an edge-expanded graph.
+2 -2
View File
@@ -19,8 +19,8 @@ struct HeapData
struct SearchEngineData
{
using QueryHeap =
util::BinaryHeap<NodeID, NodeID, int, HeapData, util::UnorderedMapStorage<NodeID, int>>;
using QueryHeap = util::
BinaryHeap<NodeID, NodeID, EdgeWeight, HeapData, util::UnorderedMapStorage<NodeID, int>>;
using SearchEngineHeapPtr = boost::thread_specific_ptr<QueryHeap>;
static SearchEngineHeapPtr forward_heap_1;