Allow specifing a weight for routing that is independent of duration
This commit is contained in:
committed by
Patrick Niklaus
parent
e463733138
commit
279f8aabfb
@@ -82,7 +82,9 @@ class Contractor
|
||||
std::vector<extractor::EdgeBasedEdge> &edge_based_edge_list,
|
||||
std::vector<EdgeWeight> &node_weights,
|
||||
const std::string &edge_segment_lookup_path,
|
||||
const std::string &edge_penalty_path,
|
||||
const std::string &turn_weight_penalties_path,
|
||||
const std::string &turn_duration_penalties_path,
|
||||
const std::string &turn_penalties_index_path,
|
||||
const std::vector<std::string> &segment_speed_path,
|
||||
const std::vector<std::string> &turn_penalty_path,
|
||||
const std::string &nodes_filename,
|
||||
|
||||
@@ -49,7 +49,9 @@ struct ContractorConfig
|
||||
graph_output_path = osrm_input_path.string() + ".hsgr";
|
||||
edge_based_graph_path = osrm_input_path.string() + ".ebg";
|
||||
edge_segment_lookup_path = osrm_input_path.string() + ".edge_segment_lookup";
|
||||
edge_penalty_path = osrm_input_path.string() + ".edge_penalties";
|
||||
turn_weight_penalties_path = osrm_input_path.string() + ".turn_weight_penalties";
|
||||
turn_duration_penalties_path = osrm_input_path.string() + ".turn_duration_penalties";
|
||||
turn_penalties_index_path = osrm_input_path.string() + ".turn_penalties_index";
|
||||
node_based_graph_path = osrm_input_path.string() + ".nodes";
|
||||
geometry_path = osrm_input_path.string() + ".geometry";
|
||||
rtree_leaf_path = osrm_input_path.string() + ".fileIndex";
|
||||
@@ -66,7 +68,9 @@ struct ContractorConfig
|
||||
std::string edge_based_graph_path;
|
||||
|
||||
std::string edge_segment_lookup_path;
|
||||
std::string edge_penalty_path;
|
||||
std::string turn_weight_penalties_path;
|
||||
std::string turn_duration_penalties_path;
|
||||
std::string turn_penalties_index_path;
|
||||
std::string node_based_graph_path;
|
||||
std::string geometry_path;
|
||||
std::string rtree_leaf_path;
|
||||
|
||||
@@ -16,7 +16,7 @@ struct ContractorEdgeData
|
||||
is_original_via_node_ID(false)
|
||||
{
|
||||
}
|
||||
ContractorEdgeData(unsigned weight,
|
||||
ContractorEdgeData(EdgeWeight weight,
|
||||
unsigned original_edges,
|
||||
unsigned id,
|
||||
bool shortcut,
|
||||
@@ -26,7 +26,7 @@ struct ContractorEdgeData
|
||||
shortcut(shortcut), forward(forward), backward(backward), is_original_via_node_ID(false)
|
||||
{
|
||||
}
|
||||
unsigned weight;
|
||||
EdgeWeight weight;
|
||||
unsigned id;
|
||||
unsigned originalEdges : 28;
|
||||
bool shortcut : 1;
|
||||
|
||||
@@ -18,8 +18,11 @@ struct ContractorHeapData
|
||||
bool target = false;
|
||||
};
|
||||
|
||||
using ContractorHeap = util::
|
||||
BinaryHeap<NodeID, NodeID, int, ContractorHeapData, util::XORFastHashStorage<NodeID, NodeID>>;
|
||||
using ContractorHeap = util::BinaryHeap<NodeID,
|
||||
NodeID,
|
||||
EdgeWeight,
|
||||
ContractorHeapData,
|
||||
util::XORFastHashStorage<NodeID, NodeID>>;
|
||||
|
||||
} // namespace contractor
|
||||
} // namespace osrm
|
||||
|
||||
@@ -200,7 +200,7 @@ class GraphContractor
|
||||
|
||||
dijkstra.Clear();
|
||||
dijkstra.Insert(source, 0, ContractorHeapData{});
|
||||
int max_weight = 0;
|
||||
EdgeWeight max_weight = 0;
|
||||
unsigned number_of_targets = 0;
|
||||
|
||||
for (auto out_edge : contractor_graph->GetAdjacentEdgeRange(node))
|
||||
@@ -294,8 +294,8 @@ class GraphContractor
|
||||
const NodeID target = contractor_graph->GetTarget(out_edge);
|
||||
if (target == node)
|
||||
continue;
|
||||
const int path_weight = in_data.weight + out_data.weight;
|
||||
const int weight = dijkstra.GetKey(target);
|
||||
const EdgeWeight path_weight = in_data.weight + out_data.weight;
|
||||
const EdgeWeight weight = dijkstra.GetKey(target);
|
||||
if (path_weight < weight)
|
||||
{
|
||||
if (RUNSIMULATION)
|
||||
|
||||
@@ -32,7 +32,7 @@ std::vector<ContractorEdge> adaptToContractorInput(InputEdgeContainer input_edge
|
||||
#endif
|
||||
edges.emplace_back(input_edge.source,
|
||||
input_edge.target,
|
||||
static_cast<unsigned int>(std::max(input_edge.weight, 1)),
|
||||
std::max(input_edge.weight, 1),
|
||||
1,
|
||||
input_edge.edge_id,
|
||||
false,
|
||||
@@ -41,7 +41,7 @@ std::vector<ContractorEdge> adaptToContractorInput(InputEdgeContainer input_edge
|
||||
|
||||
edges.emplace_back(input_edge.target,
|
||||
input_edge.source,
|
||||
static_cast<unsigned int>(std::max(input_edge.weight, 1)),
|
||||
std::max(input_edge.weight, 1),
|
||||
1,
|
||||
input_edge.edge_id,
|
||||
false,
|
||||
|
||||
@@ -31,7 +31,7 @@ struct QueryEdge
|
||||
// node. Otherwise we see the edge based node to access node data.
|
||||
NodeID id : 31;
|
||||
bool shortcut : 1;
|
||||
int weight : 30;
|
||||
EdgeWeight weight : 30;
|
||||
bool forward : 1;
|
||||
bool backward : 1;
|
||||
} data;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -19,8 +19,9 @@ class CompressedEdgeContainer
|
||||
struct OnewayCompressedEdge
|
||||
{
|
||||
public:
|
||||
NodeID node_id; // refers to an internal node-based-node
|
||||
EdgeWeight weight; // the weight of the edge leading to this node
|
||||
NodeID node_id; // refers to an internal node-based-node
|
||||
EdgeWeight weight; // the weight of the edge leading to this node
|
||||
EdgeWeight duration; // the duration of the edge leading to this node
|
||||
};
|
||||
|
||||
using OnewayEdgeBucket = std::vector<OnewayCompressedEdge>;
|
||||
@@ -31,10 +32,14 @@ class CompressedEdgeContainer
|
||||
const NodeID via_node_id,
|
||||
const NodeID target_node,
|
||||
const EdgeWeight weight1,
|
||||
const EdgeWeight weight2);
|
||||
const EdgeWeight weight2,
|
||||
const EdgeWeight duration1,
|
||||
const EdgeWeight duration2);
|
||||
|
||||
void
|
||||
AddUncompressedEdge(const EdgeID edge_id, const NodeID target_node, const EdgeWeight weight);
|
||||
void AddUncompressedEdge(const EdgeID edge_id,
|
||||
const NodeID target_node,
|
||||
const EdgeWeight weight,
|
||||
const EdgeWeight duration);
|
||||
|
||||
void InitializeBothwayVector();
|
||||
unsigned ZipEdges(const unsigned f_edge_pos, const unsigned r_edge_pos);
|
||||
@@ -62,6 +67,8 @@ class CompressedEdgeContainer
|
||||
std::vector<NodeID> m_compressed_geometry_nodes;
|
||||
std::vector<EdgeWeight> m_compressed_geometry_fwd_weights;
|
||||
std::vector<EdgeWeight> m_compressed_geometry_rev_weights;
|
||||
std::vector<EdgeWeight> m_compressed_geometry_fwd_durations;
|
||||
std::vector<EdgeWeight> m_compressed_geometry_rev_durations;
|
||||
std::vector<unsigned> m_free_list;
|
||||
std::unordered_map<EdgeID, unsigned> m_edge_id_to_list_index_map;
|
||||
std::unordered_map<EdgeID, unsigned> m_forward_edge_id_to_zipped_index_map;
|
||||
|
||||
@@ -30,9 +30,13 @@ struct EdgeBasedEdge
|
||||
NodeID target;
|
||||
NodeID edge_id;
|
||||
EdgeWeight weight : 30;
|
||||
bool forward : 1;
|
||||
bool backward : 1;
|
||||
std::uint32_t forward : 1;
|
||||
std::uint32_t backward : 1;
|
||||
};
|
||||
static_assert(sizeof(extractor::EdgeBasedEdge) == 16,
|
||||
"Size of extractor::EdgeBasedEdge type is "
|
||||
"bigger than expected. This will influence "
|
||||
"memory consumption.");
|
||||
|
||||
// Impl.
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "extractor/compressed_edge_container.hpp"
|
||||
#include "extractor/edge_based_edge.hpp"
|
||||
#include "extractor/edge_based_node.hpp"
|
||||
#include "extractor/extraction_turn.hpp"
|
||||
#include "extractor/original_edge_data.hpp"
|
||||
#include "extractor/profile_properties.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
@@ -65,15 +66,25 @@ struct SegmentBlock
|
||||
static_assert(sizeof(SegmentBlock) == 20, "SegmentBlock is not packed correctly");
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct PenaltyBlock
|
||||
struct TurnPenaltiesHeader
|
||||
{
|
||||
//! the number of penalties in each block
|
||||
std::uint64_t number_of_penalties;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
static_assert(std::is_trivial<TurnPenaltiesHeader>::value, "TurnPenaltiesHeader is not trivial");
|
||||
static_assert(sizeof(TurnPenaltiesHeader) == 8, "TurnPenaltiesHeader is not packed correctly");
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct TurnIndexBlock
|
||||
{
|
||||
std::uint32_t fixed_penalty;
|
||||
OSMNodeID from_id;
|
||||
OSMNodeID via_id;
|
||||
OSMNodeID to_id;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
static_assert(sizeof(PenaltyBlock) == 28, "PenaltyBlock is not packed correctly");
|
||||
static_assert(std::is_trivial<TurnIndexBlock>::value, "TurnIndexBlock is not trivial");
|
||||
static_assert(sizeof(TurnIndexBlock) == 24, "TurnIndexBlock is not packed correctly");
|
||||
}
|
||||
|
||||
class EdgeBasedGraphFactory
|
||||
@@ -98,7 +109,9 @@ class EdgeBasedGraphFactory
|
||||
const std::string &original_edge_data_filename,
|
||||
const std::string &turn_lane_data_filename,
|
||||
const std::string &edge_segment_lookup_filename,
|
||||
const std::string &edge_penalty_filename,
|
||||
const std::string &turn_weight_penalties_filename,
|
||||
const std::string &turn_duration_penalties_filename,
|
||||
const std::string &turn_penalties_index_filename,
|
||||
const bool generate_edge_lookup);
|
||||
|
||||
// The following get access functions destroy the content in the factory
|
||||
@@ -157,14 +170,15 @@ class EdgeBasedGraphFactory
|
||||
std::vector<guidance::TurnLaneType::Mask> &turn_lane_masks;
|
||||
guidance::LaneDescriptionMap &lane_description_map;
|
||||
|
||||
void CompressGeometry();
|
||||
unsigned RenumberEdges();
|
||||
void GenerateEdgeExpandedNodes();
|
||||
void GenerateEdgeExpandedEdges(ScriptingEnvironment &scripting_environment,
|
||||
const std::string &original_edge_data_filename,
|
||||
const std::string &turn_lane_data_filename,
|
||||
const std::string &edge_segment_lookup_filename,
|
||||
const std::string &edge_fixed_penalties_filename,
|
||||
const std::string &turn_weight_penalties_filename,
|
||||
const std::string &turn_duration_penalties_filename,
|
||||
const std::string &turn_penalties_index_filename,
|
||||
const bool generate_edge_lookup);
|
||||
|
||||
void InsertEdgeBasedNode(const NodeID u, const NodeID v);
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef OSRM_EXTRACTION_SEGMENT_HPP
|
||||
#define OSRM_EXTRACTION_SEGMENT_HPP
|
||||
|
||||
#include <util/coordinate.hpp>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
struct ExtractionSegment
|
||||
{
|
||||
ExtractionSegment(const osrm::util::Coordinate source_,
|
||||
const osrm::util::Coordinate target_,
|
||||
double distance_,
|
||||
double weight_,
|
||||
double duration_)
|
||||
: source(source_), target(target_), distance(distance_), weight(weight_),
|
||||
duration(duration_)
|
||||
{
|
||||
}
|
||||
|
||||
const osrm::util::Coordinate source;
|
||||
const osrm::util::Coordinate target;
|
||||
const double distance;
|
||||
double weight;
|
||||
double duration;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef OSRM_EXTRACTION_TURN_HPP
|
||||
#define OSRM_EXTRACTION_TURN_HPP
|
||||
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
|
||||
#include <extractor/guidance/intersection.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
struct ExtractionTurn
|
||||
{
|
||||
ExtractionTurn(const guidance::ConnectedRoad &turn, bool has_traffic_light)
|
||||
: angle(180. - turn.angle), turn_type(turn.instruction.type),
|
||||
direction_modifier(turn.instruction.direction_modifier),
|
||||
has_traffic_light(has_traffic_light), weight(0.), duration(0.)
|
||||
{
|
||||
}
|
||||
|
||||
const double angle;
|
||||
const guidance::TurnType::Enum turn_type;
|
||||
const guidance::DirectionModifier::Enum direction_modifier;
|
||||
const bool has_traffic_light;
|
||||
double weight;
|
||||
double duration;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -42,7 +42,10 @@ struct ExtractionWay
|
||||
{
|
||||
forward_speed = -1;
|
||||
backward_speed = -1;
|
||||
forward_rate = -1;
|
||||
backward_rate = -1;
|
||||
duration = -1;
|
||||
weight = -1;
|
||||
roundabout = false;
|
||||
circular = false;
|
||||
is_startpoint = true;
|
||||
@@ -84,9 +87,16 @@ struct ExtractionWay
|
||||
}
|
||||
const char *GetTurnLanesBackward() const { return turn_lanes_backward.c_str(); }
|
||||
|
||||
// speed in km/h
|
||||
double forward_speed;
|
||||
double backward_speed;
|
||||
// weight per meter
|
||||
double forward_rate;
|
||||
double backward_rate;
|
||||
// duration of the whole way in both directions
|
||||
double duration;
|
||||
// weight of the whole way in both directions
|
||||
double weight;
|
||||
std::string name;
|
||||
std::string ref;
|
||||
std::string pronunciation;
|
||||
|
||||
@@ -43,6 +43,7 @@ class ExtractionContainers;
|
||||
struct InputRestrictionContainer;
|
||||
struct ExtractionNode;
|
||||
struct ExtractionWay;
|
||||
struct ProfileProperties;
|
||||
|
||||
/**
|
||||
* This class is used by the extractor with the results of the
|
||||
@@ -61,9 +62,11 @@ class ExtractorCallbacks
|
||||
std::unordered_map<MapKey, MapVal> string_map;
|
||||
guidance::LaneDescriptionMap lane_description_map;
|
||||
ExtractionContainers &external_memory;
|
||||
bool fallback_to_duration;
|
||||
|
||||
public:
|
||||
explicit ExtractorCallbacks(ExtractionContainers &extraction_containers);
|
||||
explicit ExtractorCallbacks(ExtractionContainers &extraction_containers,
|
||||
const ProfileProperties &properties);
|
||||
|
||||
ExtractorCallbacks(const ExtractorCallbacks &) = delete;
|
||||
ExtractorCallbacks &operator=(const ExtractorCallbacks &) = delete;
|
||||
|
||||
@@ -71,7 +71,9 @@ struct ExtractorConfig
|
||||
rtree_nodes_output_path = basepath + ".osrm.ramIndex";
|
||||
rtree_leafs_output_path = basepath + ".osrm.fileIndex";
|
||||
edge_segment_lookup_path = basepath + ".osrm.edge_segment_lookup";
|
||||
edge_penalty_path = basepath + ".osrm.edge_penalties";
|
||||
turn_duration_penalties_path = basepath + ".osrm.turn_duration_penalties";
|
||||
turn_weight_penalties_path = basepath + ".osrm.turn_weight_penalties";
|
||||
turn_penalties_index_path = basepath + ".osrm.turn_penalties_index";
|
||||
edge_based_node_weights_output_path = basepath + ".osrm.enw";
|
||||
profile_properties_output_path = basepath + ".osrm.properties";
|
||||
intersection_class_data_output_path = basepath + ".osrm.icd";
|
||||
@@ -95,12 +97,14 @@ struct ExtractorConfig
|
||||
std::string rtree_leafs_output_path;
|
||||
std::string profile_properties_output_path;
|
||||
std::string intersection_class_data_output_path;
|
||||
std::string turn_weight_penalties_path;
|
||||
std::string turn_duration_penalties_path;
|
||||
|
||||
unsigned requested_num_threads;
|
||||
unsigned small_component_size;
|
||||
|
||||
bool generate_edge_lookup;
|
||||
std::string edge_penalty_path;
|
||||
std::string turn_penalties_index_path;
|
||||
std::string edge_segment_lookup_path;
|
||||
|
||||
bool use_metadata;
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
#ifndef INTERNAL_EXTRACTOR_EDGE_HPP
|
||||
#define INTERNAL_EXTRACTOR_EDGE_HPP
|
||||
|
||||
#include "extractor/guidance/road_classification.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "extractor/node_based_edge.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "osrm/coordinate.hpp"
|
||||
#include "util/strong_typedef.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include "extractor/guidance/road_classification.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "osrm/coordinate.hpp"
|
||||
#include <mapbox/variant.hpp>
|
||||
#include <utility>
|
||||
|
||||
namespace osrm
|
||||
@@ -17,31 +18,37 @@ namespace osrm
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// these are used for duration based mode of transportations like ferries
|
||||
OSRM_STRONG_TYPEDEF(double, ValueByEdge)
|
||||
OSRM_STRONG_TYPEDEF(double, ValueByMeter)
|
||||
using ByEdgeOrByMeterValue = mapbox::util::variant<detail::ValueByEdge, detail::ValueByMeter>;
|
||||
|
||||
struct ToValueByEdge
|
||||
{
|
||||
ToValueByEdge(double distance_) : distance(distance_) {}
|
||||
|
||||
ValueByEdge operator()(const ValueByMeter by_meter) const
|
||||
{
|
||||
return ValueByEdge{distance / static_cast<double>(by_meter)};
|
||||
}
|
||||
|
||||
ValueByEdge operator()(const ValueByEdge by_edge) const { return by_edge; }
|
||||
|
||||
double distance;
|
||||
};
|
||||
}
|
||||
|
||||
struct InternalExtractorEdge
|
||||
{
|
||||
// specify the type of the weight data
|
||||
enum class WeightType : char
|
||||
{
|
||||
INVALID,
|
||||
SPEED,
|
||||
EDGE_DURATION,
|
||||
WAY_DURATION,
|
||||
};
|
||||
|
||||
struct WeightData
|
||||
{
|
||||
WeightData() : duration(0.0), type(WeightType::INVALID) {}
|
||||
|
||||
union {
|
||||
double duration;
|
||||
double speed;
|
||||
};
|
||||
WeightType type;
|
||||
};
|
||||
using WeightData = detail::ByEdgeOrByMeterValue;
|
||||
using DurationData = detail::ByEdgeOrByMeterValue;
|
||||
|
||||
explicit InternalExtractorEdge()
|
||||
: result(MIN_OSM_NODEID,
|
||||
MIN_OSM_NODEID,
|
||||
SPECIAL_NODEID,
|
||||
0,
|
||||
0,
|
||||
false, // forward
|
||||
@@ -52,7 +59,8 @@ struct InternalExtractorEdge
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
false,
|
||||
guidance::TurnLaneType::empty,
|
||||
guidance::RoadClassification())
|
||||
guidance::RoadClassification()),
|
||||
weight_data(detail::ValueByMeter{0.0}), duration_data(detail::ValueByMeter{0.0})
|
||||
{
|
||||
}
|
||||
|
||||
@@ -60,6 +68,7 @@ struct InternalExtractorEdge
|
||||
OSMNodeID target,
|
||||
NodeID name_id,
|
||||
WeightData weight_data,
|
||||
DurationData duration_data,
|
||||
bool forward,
|
||||
bool backward,
|
||||
bool roundabout,
|
||||
@@ -68,11 +77,13 @@ struct InternalExtractorEdge
|
||||
TravelMode travel_mode,
|
||||
bool is_split,
|
||||
LaneDescriptionID lane_description,
|
||||
guidance::RoadClassification road_classification)
|
||||
guidance::RoadClassification road_classification,
|
||||
util::Coordinate source_coordinate)
|
||||
: result(source,
|
||||
target,
|
||||
name_id,
|
||||
0,
|
||||
0,
|
||||
forward,
|
||||
backward,
|
||||
roundabout,
|
||||
@@ -82,7 +93,8 @@ struct InternalExtractorEdge
|
||||
is_split,
|
||||
lane_description,
|
||||
std::move(road_classification)),
|
||||
weight_data(std::move(weight_data))
|
||||
weight_data(std::move(weight_data)), duration_data(std::move(duration_data)),
|
||||
source_coordinate(std::move(source_coordinate))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -90,6 +102,8 @@ struct InternalExtractorEdge
|
||||
NodeBasedEdgeWithOSM result;
|
||||
// intermediate edge weight
|
||||
WeightData weight_data;
|
||||
// intermediate edge duration
|
||||
DurationData duration_data;
|
||||
// coordinate of the source node
|
||||
util::Coordinate source_coordinate;
|
||||
|
||||
@@ -98,8 +112,9 @@ struct InternalExtractorEdge
|
||||
{
|
||||
return InternalExtractorEdge(MIN_OSM_NODEID,
|
||||
MIN_OSM_NODEID,
|
||||
0,
|
||||
WeightData(),
|
||||
SPECIAL_NODEID,
|
||||
detail::ValueByMeter{0.0},
|
||||
detail::ValueByMeter{0.0},
|
||||
false, // forward
|
||||
false, // backward
|
||||
false, // roundabout
|
||||
@@ -108,14 +123,16 @@ struct InternalExtractorEdge
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
false,
|
||||
INVALID_LANE_DESCRIPTIONID,
|
||||
guidance::RoadClassification());
|
||||
guidance::RoadClassification(),
|
||||
util::Coordinate());
|
||||
}
|
||||
static InternalExtractorEdge max_osm_value()
|
||||
{
|
||||
return InternalExtractorEdge(MAX_OSM_NODEID,
|
||||
MAX_OSM_NODEID,
|
||||
SPECIAL_NODEID,
|
||||
WeightData(),
|
||||
detail::ValueByMeter{0.0},
|
||||
detail::ValueByMeter{0.0},
|
||||
false, // forward
|
||||
false, // backward
|
||||
false, // roundabout
|
||||
@@ -124,7 +141,8 @@ struct InternalExtractorEdge
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
false,
|
||||
INVALID_LANE_DESCRIPTIONID,
|
||||
guidance::RoadClassification());
|
||||
guidance::RoadClassification(),
|
||||
util::Coordinate());
|
||||
}
|
||||
|
||||
static InternalExtractorEdge min_internal_value()
|
||||
|
||||
@@ -19,6 +19,7 @@ struct NodeBasedEdge
|
||||
NodeID target,
|
||||
NodeID name_id,
|
||||
EdgeWeight weight,
|
||||
EdgeWeight duration,
|
||||
bool forward,
|
||||
bool backward,
|
||||
bool roundabout,
|
||||
@@ -35,12 +36,13 @@ struct NodeBasedEdge
|
||||
NodeID target;
|
||||
NodeID name_id;
|
||||
EdgeWeight weight;
|
||||
bool forward : 1;
|
||||
bool backward : 1;
|
||||
bool roundabout : 1;
|
||||
bool circular : 1;
|
||||
bool startpoint : 1;
|
||||
bool is_split : 1;
|
||||
EdgeWeight duration;
|
||||
std::uint8_t forward : 1;
|
||||
std::uint8_t backward : 1;
|
||||
std::uint8_t roundabout : 1;
|
||||
std::uint8_t circular : 1;
|
||||
std::uint8_t startpoint : 1;
|
||||
std::uint8_t is_split : 1;
|
||||
TravelMode travel_mode : 4;
|
||||
LaneDescriptionID lane_description_id;
|
||||
guidance::RoadClassification road_classification;
|
||||
@@ -52,6 +54,7 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge
|
||||
OSMNodeID target,
|
||||
NodeID name_id,
|
||||
EdgeWeight weight,
|
||||
EdgeWeight duration,
|
||||
bool forward,
|
||||
bool backward,
|
||||
bool roundabout,
|
||||
@@ -69,9 +72,10 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge
|
||||
// Impl.
|
||||
|
||||
inline NodeBasedEdge::NodeBasedEdge()
|
||||
: source(SPECIAL_NODEID), target(SPECIAL_NODEID), name_id(0), weight(0), forward(false),
|
||||
backward(false), roundabout(false), circular(false), startpoint(true), is_split(false),
|
||||
travel_mode(false), lane_description_id(INVALID_LANE_DESCRIPTIONID)
|
||||
: source(SPECIAL_NODEID), target(SPECIAL_NODEID), name_id(0), weight(0), duration(0),
|
||||
forward(false), backward(false), roundabout(false), circular(false), startpoint(true),
|
||||
is_split(false), travel_mode(TRAVEL_MODE_INACCESSIBLE),
|
||||
lane_description_id(INVALID_LANE_DESCRIPTIONID)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -79,6 +83,7 @@ inline NodeBasedEdge::NodeBasedEdge(NodeID source,
|
||||
NodeID target,
|
||||
NodeID name_id,
|
||||
EdgeWeight weight,
|
||||
EdgeWeight duration,
|
||||
bool forward,
|
||||
bool backward,
|
||||
bool roundabout,
|
||||
@@ -88,10 +93,10 @@ inline NodeBasedEdge::NodeBasedEdge(NodeID source,
|
||||
bool is_split,
|
||||
const LaneDescriptionID lane_description_id,
|
||||
guidance::RoadClassification road_classification)
|
||||
: source(source), target(target), name_id(name_id), weight(weight), forward(forward),
|
||||
backward(backward), roundabout(roundabout), circular(circular), startpoint(startpoint),
|
||||
is_split(is_split), travel_mode(travel_mode), lane_description_id(lane_description_id),
|
||||
road_classification(std::move(road_classification))
|
||||
: source(source), target(target), name_id(name_id), weight(weight), duration(duration),
|
||||
forward(forward), backward(backward), roundabout(roundabout), circular(circular),
|
||||
startpoint(startpoint), is_split(is_split), travel_mode(travel_mode),
|
||||
lane_description_id(lane_description_id), road_classification(std::move(road_classification))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -116,6 +121,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(OSMNodeID source,
|
||||
OSMNodeID target,
|
||||
NodeID name_id,
|
||||
EdgeWeight weight,
|
||||
EdgeWeight duration,
|
||||
bool forward,
|
||||
bool backward,
|
||||
bool roundabout,
|
||||
@@ -129,6 +135,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(OSMNodeID source,
|
||||
SPECIAL_NODEID,
|
||||
name_id,
|
||||
weight,
|
||||
duration,
|
||||
forward,
|
||||
backward,
|
||||
roundabout,
|
||||
@@ -142,6 +149,11 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(OSMNodeID source,
|
||||
{
|
||||
}
|
||||
|
||||
static_assert(sizeof(extractor::NodeBasedEdge) == 28,
|
||||
"Size of extractor::NodeBasedEdge type is "
|
||||
"bigger than expected. This will influence "
|
||||
"memory consumption.");
|
||||
|
||||
} // ns extractor
|
||||
} // ns osrm
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef PROFILE_PROPERTIES_HPP
|
||||
#define PROFILE_PROPERTIES_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
|
||||
namespace osrm
|
||||
@@ -12,11 +14,18 @@ const constexpr auto DEFAULT_MAX_SPEED = 180 / 3.6; // 180kmph -> m/s
|
||||
|
||||
struct ProfileProperties
|
||||
{
|
||||
enum
|
||||
{
|
||||
MAX_WEIGHT_NAME_LENGTH = 255
|
||||
};
|
||||
|
||||
ProfileProperties()
|
||||
: traffic_signal_penalty(0), u_turn_penalty(0),
|
||||
max_speed_for_map_matching(DEFAULT_MAX_SPEED), continue_straight_at_waypoint(true),
|
||||
use_turn_restrictions(false), left_hand_driving(false)
|
||||
use_turn_restrictions(false), left_hand_driving(false), fallback_to_duration(true),
|
||||
weight_name{"duration"}
|
||||
{
|
||||
BOOST_ASSERT(weight_name[MAX_WEIGHT_NAME_LENGTH] == '\0');
|
||||
}
|
||||
|
||||
double GetUturnPenalty() const { return u_turn_penalty / 10.; }
|
||||
@@ -40,14 +49,38 @@ struct ProfileProperties
|
||||
max_speed_for_map_matching = max_speed_for_map_matching_;
|
||||
}
|
||||
|
||||
void SetWeightName(const std::string &name)
|
||||
{
|
||||
auto count = std::min<std::size_t>(name.length(), MAX_WEIGHT_NAME_LENGTH) + 1;
|
||||
std::copy_n(name.c_str(), count, weight_name);
|
||||
// Make sure this is always zero terminated
|
||||
BOOST_ASSERT(weight_name[count - 1] == '\0');
|
||||
BOOST_ASSERT(weight_name[MAX_WEIGHT_NAME_LENGTH] == '\0');
|
||||
// Set lazy fallback flag
|
||||
fallback_to_duration = name == "duration";
|
||||
}
|
||||
|
||||
std::string GetWeightName() const
|
||||
{
|
||||
// Make sure this is always zero terminated
|
||||
BOOST_ASSERT(weight_name[MAX_WEIGHT_NAME_LENGTH] == '\0');
|
||||
return std::string(weight_name);
|
||||
}
|
||||
|
||||
//! penalty to cross a traffic light in deci-seconds
|
||||
int traffic_signal_penalty;
|
||||
std::int32_t traffic_signal_penalty;
|
||||
//! penalty to do a uturn in deci-seconds
|
||||
int u_turn_penalty;
|
||||
std::int32_t u_turn_penalty;
|
||||
double max_speed_for_map_matching;
|
||||
//! depending on the profile, force the routing to always continue in the same direction
|
||||
bool continue_straight_at_waypoint;
|
||||
//! flag used for restriction parser (e.g. used for the walk profile)
|
||||
bool use_turn_restrictions;
|
||||
bool left_hand_driving;
|
||||
bool fallback_to_duration;
|
||||
//! stores the name of the weight (e.g. 'duration', 'distance', 'safety')
|
||||
char weight_name[MAX_WEIGHT_NAME_LENGTH + 1];
|
||||
unsigned weight_precision = 1;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,8 @@ namespace extractor
|
||||
class RestrictionParser;
|
||||
struct ExtractionNode;
|
||||
struct ExtractionWay;
|
||||
struct ExtractionTurn;
|
||||
struct ExtractionSegment;
|
||||
|
||||
/**
|
||||
* Abstract class that handles processing osmium ways, nodes and relation objects by applying
|
||||
@@ -53,11 +55,9 @@ class ScriptingEnvironment
|
||||
virtual std::vector<std::string> GetNameSuffixList() = 0;
|
||||
virtual std::vector<std::string> GetRestrictions() = 0;
|
||||
virtual void SetupSources() = 0;
|
||||
virtual int32_t GetTurnPenalty(double angle) = 0;
|
||||
virtual void ProcessSegment(const osrm::util::Coordinate &source,
|
||||
const osrm::util::Coordinate &target,
|
||||
double distance,
|
||||
InternalExtractorEdge::WeightData &weight) = 0;
|
||||
virtual void ProcessTurn(ExtractionTurn &turn) = 0;
|
||||
virtual void ProcessSegment(ExtractionSegment &segment) = 0;
|
||||
|
||||
virtual void
|
||||
ProcessElements(const std::vector<osmium::memory::Buffer::const_iterator> &osm_elements,
|
||||
const RestrictionParser &restriction_parser,
|
||||
|
||||
@@ -45,7 +45,7 @@ class Sol2ScriptingEnvironment final : public ScriptingEnvironment
|
||||
{
|
||||
public:
|
||||
static const constexpr int SUPPORTED_MIN_API_VERSION = 0;
|
||||
static const constexpr int SUPPORTED_MAX_API_VERSION = 0;
|
||||
static const constexpr int SUPPORTED_MAX_API_VERSION = 1;
|
||||
|
||||
explicit Sol2ScriptingEnvironment(const std::string &file_name);
|
||||
~Sol2ScriptingEnvironment() override = default;
|
||||
@@ -57,11 +57,9 @@ class Sol2ScriptingEnvironment final : public ScriptingEnvironment
|
||||
std::vector<std::string> GetNameSuffixList() override;
|
||||
std::vector<std::string> GetRestrictions() override;
|
||||
void SetupSources() override;
|
||||
int32_t GetTurnPenalty(double angle) override;
|
||||
void ProcessSegment(const osrm::util::Coordinate &source,
|
||||
const osrm::util::Coordinate &target,
|
||||
double distance,
|
||||
InternalExtractorEdge::WeightData &weight) override;
|
||||
void ProcessTurn(ExtractionTurn &turn) override;
|
||||
void ProcessSegment(ExtractionSegment &segment) override;
|
||||
|
||||
void
|
||||
ProcessElements(const std::vector<osmium::memory::Buffer::const_iterator> &osm_elements,
|
||||
const RestrictionParser &restriction_parser,
|
||||
|
||||
@@ -28,6 +28,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#ifndef TRAVEL_MODE_HPP
|
||||
#define TRAVEL_MODE_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
@@ -35,7 +37,7 @@ namespace extractor
|
||||
|
||||
// This is a char instead of a typed enum, so that we can
|
||||
// pack it into e.g. a "TravelMode mode : 4" packed bitfield
|
||||
using TravelMode = unsigned char;
|
||||
using TravelMode = std::uint8_t;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "util/exception_utils.hpp"
|
||||
#include "util/log.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
@@ -33,6 +35,8 @@ const constexpr char *block_id_to_name[] = {"NAME_OFFSETS",
|
||||
"GEOMETRIES_NODE_LIST",
|
||||
"GEOMETRIES_FWD_WEIGHT_LIST",
|
||||
"GEOMETRIES_REV_WEIGHT_LIST",
|
||||
"GEOMETRIES_FWD_DURATION_LIST",
|
||||
"GEOMETRIES_REV_DURATION_LIST",
|
||||
"HSGR_CHECKSUM",
|
||||
"TIMESTAMP",
|
||||
"FILE_INDEX_PATH",
|
||||
@@ -52,7 +56,9 @@ const constexpr char *block_id_to_name[] = {"NAME_OFFSETS",
|
||||
"POST_TURN_BEARING",
|
||||
"TURN_LANE_DATA",
|
||||
"LANE_DESCRIPTION_OFFSETS",
|
||||
"LANE_DESCRIPTION_MASKS"};
|
||||
"LANE_DESCRIPTION_MASKS",
|
||||
"TURN_WEIGHT_PENALTIES",
|
||||
"TURN_DURATION_PENALTIES"};
|
||||
|
||||
struct DataLayout
|
||||
{
|
||||
@@ -75,6 +81,8 @@ struct DataLayout
|
||||
GEOMETRIES_NODE_LIST,
|
||||
GEOMETRIES_FWD_WEIGHT_LIST,
|
||||
GEOMETRIES_REV_WEIGHT_LIST,
|
||||
GEOMETRIES_FWD_DURATION_LIST,
|
||||
GEOMETRIES_REV_DURATION_LIST,
|
||||
HSGR_CHECKSUM,
|
||||
TIMESTAMP,
|
||||
FILE_INDEX_PATH,
|
||||
@@ -95,6 +103,8 @@ struct DataLayout
|
||||
TURN_LANE_DATA,
|
||||
LANE_DESCRIPTION_OFFSETS,
|
||||
LANE_DESCRIPTION_MASKS,
|
||||
TURN_WEIGHT_PENALTIES,
|
||||
TURN_DURATION_PENALTIES,
|
||||
NUM_BLOCKS
|
||||
};
|
||||
|
||||
@@ -127,6 +137,7 @@ struct DataLayout
|
||||
uint64_t result = 0;
|
||||
for (auto i = 0; i < NUM_BLOCKS; i++)
|
||||
{
|
||||
BOOST_ASSERT(entry_align[i] > 0);
|
||||
result += 2 * sizeof(CANARY) + GetBlockSize((BlockID)i) + entry_align[i];
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -60,6 +60,8 @@ struct StorageConfig final
|
||||
boost::filesystem::path core_data_path;
|
||||
boost::filesystem::path geometries_path;
|
||||
boost::filesystem::path timestamp_path;
|
||||
boost::filesystem::path turn_weight_penalties_path;
|
||||
boost::filesystem::path turn_duration_penalties_path;
|
||||
boost::filesystem::path datasource_names_path;
|
||||
boost::filesystem::path datasource_indexes_path;
|
||||
boost::filesystem::path names_data_path;
|
||||
|
||||
@@ -12,9 +12,8 @@ namespace util
|
||||
{
|
||||
|
||||
// implements a singleton, i.e. there is one and only one conviguration object
|
||||
class FingerPrint
|
||||
struct FingerPrint
|
||||
{
|
||||
public:
|
||||
static FingerPrint GetValid();
|
||||
|
||||
bool IsValid() const;
|
||||
@@ -36,6 +35,7 @@ class FingerPrint
|
||||
|
||||
static_assert(sizeof(FingerPrint) == 8, "FingerPrint has unexpected size");
|
||||
static_assert(std::is_trivial<FingerPrint>::value, "FingerPrint needs to be trivial.");
|
||||
static_assert(std::is_pod<FingerPrint>::value, "FingerPrint needs to be a POD.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,14 +18,15 @@ namespace util
|
||||
struct NodeBasedEdgeData
|
||||
{
|
||||
NodeBasedEdgeData()
|
||||
: distance(INVALID_EDGE_WEIGHT), edge_id(SPECIAL_NODEID),
|
||||
: weight(INVALID_EDGE_WEIGHT), duration(INVALID_EDGE_WEIGHT), edge_id(SPECIAL_NODEID),
|
||||
name_id(std::numeric_limits<unsigned>::max()), reversed(false), roundabout(false),
|
||||
circular(false), travel_mode(TRAVEL_MODE_INACCESSIBLE),
|
||||
lane_description_id(INVALID_LANE_DESCRIPTIONID)
|
||||
{
|
||||
}
|
||||
|
||||
NodeBasedEdgeData(int distance,
|
||||
NodeBasedEdgeData(EdgeWeight weight,
|
||||
EdgeWeight duration,
|
||||
unsigned edge_id,
|
||||
unsigned name_id,
|
||||
bool reversed,
|
||||
@@ -34,13 +35,14 @@ struct NodeBasedEdgeData
|
||||
bool startpoint,
|
||||
extractor::TravelMode travel_mode,
|
||||
const LaneDescriptionID lane_description_id)
|
||||
: distance(distance), edge_id(edge_id), name_id(name_id), reversed(reversed),
|
||||
roundabout(roundabout), circular(circular), startpoint(startpoint),
|
||||
: weight(weight), duration(duration), edge_id(edge_id), name_id(name_id),
|
||||
reversed(reversed), roundabout(roundabout), circular(circular), startpoint(startpoint),
|
||||
travel_mode(travel_mode), lane_description_id(lane_description_id)
|
||||
{
|
||||
}
|
||||
|
||||
int distance;
|
||||
EdgeWeight weight;
|
||||
EdgeWeight duration;
|
||||
unsigned edge_id;
|
||||
unsigned name_id;
|
||||
bool reversed : 1;
|
||||
@@ -78,9 +80,8 @@ NodeBasedDynamicGraphFromEdges(NodeID number_of_nodes,
|
||||
input_edge_list,
|
||||
[](NodeBasedDynamicGraph::InputEdge &output_edge,
|
||||
const extractor::NodeBasedEdge &input_edge) {
|
||||
output_edge.data.distance = static_cast<int>(input_edge.weight);
|
||||
BOOST_ASSERT(output_edge.data.distance > 0);
|
||||
|
||||
output_edge.data.weight = input_edge.weight;
|
||||
output_edge.data.duration = input_edge.duration;
|
||||
output_edge.data.roundabout = input_edge.roundabout;
|
||||
output_edge.data.circular = input_edge.circular;
|
||||
output_edge.data.name_id = input_edge.name_id;
|
||||
@@ -88,6 +89,9 @@ NodeBasedDynamicGraphFromEdges(NodeID number_of_nodes,
|
||||
output_edge.data.startpoint = input_edge.startpoint;
|
||||
output_edge.data.road_classification = input_edge.road_classification;
|
||||
output_edge.data.lane_description_id = input_edge.lane_description_id;
|
||||
|
||||
BOOST_ASSERT(output_edge.data.weight > 0);
|
||||
BOOST_ASSERT(output_edge.data.duration > 0);
|
||||
});
|
||||
|
||||
tbb::parallel_sort(edges_list.begin(), edges_list.end());
|
||||
|
||||
@@ -58,6 +58,7 @@ using NodeID = std::uint32_t;
|
||||
using EdgeID = std::uint32_t;
|
||||
using NameID = std::uint32_t;
|
||||
using EdgeWeight = std::int32_t;
|
||||
using TurnPenalty = std::int16_t; // turn penalty in 100ms units
|
||||
|
||||
using LaneID = std::uint8_t;
|
||||
static const LaneID INVALID_LANEID = std::numeric_limits<LaneID>::max();
|
||||
@@ -83,6 +84,7 @@ static const NameID INVALID_NAMEID = std::numeric_limits<NameID>::max();
|
||||
static const NameID EMPTY_NAMEID = 0;
|
||||
static const unsigned INVALID_COMPONENTID = 0;
|
||||
static const EdgeWeight INVALID_EDGE_WEIGHT = std::numeric_limits<EdgeWeight>::max();
|
||||
static const TurnPenalty INVALID_TURN_PENALTY = std::numeric_limits<TurnPenalty>::max();
|
||||
|
||||
using DatasourceID = std::uint8_t;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user