restructure for review remarks
This commit is contained in:
@@ -194,7 +194,7 @@ void EdgeBasedGraphFactory::Run(ScriptingEnvironment &scripting_environment,
|
||||
const std::string &turn_duration_penalties_filename,
|
||||
const std::string &turn_penalties_index_filename,
|
||||
const std::string &cnbg_ebg_mapping_path,
|
||||
const RestrictionMap &restriction_map,
|
||||
const RestrictionMap &node_restriction_map,
|
||||
const WayRestrictionMap &way_restriction_map)
|
||||
{
|
||||
TIMER_START(renumber);
|
||||
@@ -215,7 +215,7 @@ void EdgeBasedGraphFactory::Run(ScriptingEnvironment &scripting_environment,
|
||||
turn_weight_penalties_filename,
|
||||
turn_duration_penalties_filename,
|
||||
turn_penalties_index_filename,
|
||||
restriction_map,
|
||||
node_restriction_map,
|
||||
way_restriction_map);
|
||||
|
||||
TIMER_STOP(generate_edges);
|
||||
@@ -228,7 +228,7 @@ void EdgeBasedGraphFactory::Run(ScriptingEnvironment &scripting_environment,
|
||||
|
||||
/// Renumbers all _forward_ edges and sets the edge_id.
|
||||
/// A specific numbering is not important. Any unique ID will do.
|
||||
/// Returns the number of edge based nodes.
|
||||
/// Returns the number of edge-based nodes.
|
||||
unsigned EdgeBasedGraphFactory::RenumberEdges()
|
||||
{
|
||||
// heuristic: node-based graph node is a simple intersection with four edges (edge-based nodes)
|
||||
@@ -363,8 +363,10 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedNodes(const WayRestrictionMap &way_re
|
||||
BOOST_ASSERT(m_edge_based_node_segments.size() == m_edge_based_node_is_startpoint.size());
|
||||
BOOST_ASSERT(m_number_of_edge_based_nodes == m_edge_based_node_weights.size());
|
||||
|
||||
util::Log() << "Generated " << m_number_of_edge_based_nodes << " nodes and "
|
||||
<< m_edge_based_node_segments.size() << " segments in edge-expanded graph";
|
||||
util::Log() << "Generated " << m_number_of_edge_based_nodes << " nodes ("
|
||||
<< way_restriction_map.NumberOfDuplicatedNodes()
|
||||
<< " of which are duplicates) and " << m_edge_based_node_segments.size()
|
||||
<< " segments in edge-expanded graph";
|
||||
|
||||
return mapping;
|
||||
}
|
||||
@@ -377,7 +379,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
const std::string &turn_weight_penalties_filename,
|
||||
const std::string &turn_duration_penalties_filename,
|
||||
const std::string &turn_penalties_index_filename,
|
||||
const RestrictionMap &restriction_map,
|
||||
const RestrictionMap &node_restriction_map,
|
||||
const WayRestrictionMap &way_restriction_map)
|
||||
{
|
||||
|
||||
@@ -399,7 +401,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
SuffixTable street_name_suffix_table(scripting_environment);
|
||||
guidance::TurnAnalysis turn_analysis(*m_node_based_graph,
|
||||
m_coordinates,
|
||||
restriction_map,
|
||||
node_restriction_map,
|
||||
m_barrier_nodes,
|
||||
m_compressed_edge_container,
|
||||
name_table,
|
||||
@@ -492,24 +494,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
std::vector<EdgeWithData> delayed_data;
|
||||
};
|
||||
|
||||
// add into delayed data
|
||||
const auto delayed_inserter = [](const auto &edge_with_data, auto &buffer) {
|
||||
buffer.delayed_data.push_back(edge_with_data);
|
||||
};
|
||||
|
||||
// add into main data
|
||||
const auto continuous_inserter = [](const auto &edge_with_data, auto &buffer) {
|
||||
buffer.continuous_data.edges_list.push_back(edge_with_data.edge);
|
||||
buffer.continuous_data.turn_indexes.push_back(edge_with_data.turn_index);
|
||||
buffer.continuous_data.turn_weight_penalties.push_back(
|
||||
edge_with_data.turn_weight_penalty);
|
||||
buffer.continuous_data.turn_duration_penalties.push_back(
|
||||
edge_with_data.turn_duration_penalty);
|
||||
buffer.continuous_data.turn_data_container.push_back(edge_with_data.turn_data);
|
||||
};
|
||||
|
||||
// Generate edges for either artificial nodes or the main graph
|
||||
const auto generate_edges = [this, &scripting_environment, weight_multiplier](
|
||||
const auto generate_edge = [this, &scripting_environment, weight_multiplier](
|
||||
// what nodes will be used? In most cases this will be the id stored in the edge_data.
|
||||
// In case of duplicated nodes (e.g. due to via-way restrictions), one/both of these
|
||||
// might refer to a newly added edge based node
|
||||
@@ -522,11 +508,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
const auto node_based_edge_to,
|
||||
const auto &intersection,
|
||||
const auto &turn,
|
||||
const auto entry_class_id,
|
||||
// we require a sorted output, additional nodes are collected and added after the
|
||||
// sorting is done Here we can specify how/where to add the data
|
||||
auto inserter,
|
||||
auto &output_buffer) {
|
||||
const auto entry_class_id) {
|
||||
const EdgeData &edge_data1 = m_node_based_graph->GetEdgeData(node_based_edge_from);
|
||||
const EdgeData &edge_data2 = m_node_based_graph->GetEdgeData(node_based_edge_to);
|
||||
|
||||
@@ -593,11 +575,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
lookup::TurnIndexBlock turn_index_block = {from_node, via_node, to_node};
|
||||
|
||||
// insert data into the designated buffer
|
||||
inserter(
|
||||
EdgeWithData{
|
||||
edge_based_edge, turn_index_block, weight_penalty, duration_penalty, turn_data},
|
||||
output_buffer);
|
||||
|
||||
return EdgeWithData{
|
||||
edge_based_edge, turn_index_block, weight_penalty, duration_penalty, turn_data};
|
||||
};
|
||||
|
||||
// Second part of the pipeline is where the intersection analysis is done for
|
||||
@@ -735,17 +714,28 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
m_node_based_graph->GetTarget(turn.eid),
|
||||
m_number_of_edge_based_nodes);
|
||||
|
||||
generate_edges(edge_data1.edge_id,
|
||||
target_id,
|
||||
node_along_road_entering,
|
||||
incoming_edge,
|
||||
node_at_center_of_intersection,
|
||||
turn.eid,
|
||||
intersection,
|
||||
turn,
|
||||
entry_class_id,
|
||||
continuous_inserter,
|
||||
*buffer);
|
||||
{ // scope to forget edge_with_data after
|
||||
const auto edge_with_data =
|
||||
generate_edge(edge_data1.edge_id,
|
||||
target_id,
|
||||
node_along_road_entering,
|
||||
incoming_edge,
|
||||
node_at_center_of_intersection,
|
||||
turn.eid,
|
||||
intersection,
|
||||
turn,
|
||||
entry_class_id);
|
||||
|
||||
buffer->continuous_data.edges_list.push_back(edge_with_data.edge);
|
||||
buffer->continuous_data.turn_indexes.push_back(
|
||||
edge_with_data.turn_index);
|
||||
buffer->continuous_data.turn_weight_penalties.push_back(
|
||||
edge_with_data.turn_weight_penalty);
|
||||
buffer->continuous_data.turn_duration_penalties.push_back(
|
||||
edge_with_data.turn_duration_penalty);
|
||||
buffer->continuous_data.turn_data_container.push_back(
|
||||
edge_with_data.turn_data);
|
||||
}
|
||||
|
||||
// when turning off a a via-way turn restriction, we need to not only
|
||||
// handle the normal edges for the way, but also add turns for every
|
||||
@@ -775,7 +765,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
if (is_restricted)
|
||||
return;
|
||||
|
||||
generate_edges(
|
||||
// add into delayed data
|
||||
auto edge_with_data = generate_edge(
|
||||
NodeID(from_id),
|
||||
m_node_based_graph->GetEdgeData(turn.eid).edge_id,
|
||||
node_along_road_entering,
|
||||
@@ -784,10 +775,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
turn.eid,
|
||||
intersection,
|
||||
turn,
|
||||
entry_class_id,
|
||||
delayed_inserter,
|
||||
*buffer);
|
||||
entry_class_id);
|
||||
|
||||
buffer->delayed_data.push_back(std::move(edge_with_data));
|
||||
};
|
||||
|
||||
std::for_each(duplicated_nodes.begin(),
|
||||
@@ -812,38 +802,38 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
|
||||
std::vector<EdgeWithData> delayed_data;
|
||||
|
||||
auto const append_data_to_output = [&](IntersectionData const &data) {
|
||||
// NOTE: potential overflow here if we hit 2^32 routable edges
|
||||
m_edge_based_edge_list.append(data.edges_list.begin(), data.edges_list.end());
|
||||
|
||||
BOOST_ASSERT(m_edge_based_edge_list.size() <= std::numeric_limits<NodeID>::max());
|
||||
|
||||
turn_weight_penalties.insert(turn_weight_penalties.end(),
|
||||
data.turn_weight_penalties.begin(),
|
||||
data.turn_weight_penalties.end());
|
||||
turn_duration_penalties.insert(turn_duration_penalties.end(),
|
||||
data.turn_duration_penalties.begin(),
|
||||
data.turn_duration_penalties.end());
|
||||
turn_data_container.append(data.turn_data_container);
|
||||
turn_indexes_write_buffer.insert(turn_indexes_write_buffer.end(),
|
||||
data.turn_indexes.begin(),
|
||||
data.turn_indexes.end());
|
||||
|
||||
// Buffer writes to reduce syscall count
|
||||
if (turn_indexes_write_buffer.size() >= TURN_INDEX_WRITE_BUFFER_SIZE)
|
||||
{
|
||||
turn_penalties_index_file.WriteFrom(turn_indexes_write_buffer.data(),
|
||||
turn_indexes_write_buffer.size());
|
||||
turn_indexes_write_buffer.clear();
|
||||
}
|
||||
};
|
||||
|
||||
// Last part of the pipeline puts all the calculated data into the serial buffers
|
||||
tbb::filter_t<std::shared_ptr<PipelineBuffer>, void> output_stage(
|
||||
tbb::filter::serial_in_order, [&](const std::shared_ptr<PipelineBuffer> buffer) {
|
||||
nodes_completed += buffer->nodes_processed;
|
||||
progress.PrintStatus(nodes_completed);
|
||||
append_data_to_output(buffer->continuous_data);
|
||||
|
||||
// for readability
|
||||
const auto &data = buffer->continuous_data;
|
||||
// NOTE: potential overflow here if we hit 2^32 routable edges
|
||||
m_edge_based_edge_list.append(data.edges_list.begin(), data.edges_list.end());
|
||||
|
||||
BOOST_ASSERT(m_edge_based_edge_list.size() <= std::numeric_limits<NodeID>::max());
|
||||
|
||||
turn_weight_penalties.insert(turn_weight_penalties.end(),
|
||||
data.turn_weight_penalties.begin(),
|
||||
data.turn_weight_penalties.end());
|
||||
turn_duration_penalties.insert(turn_duration_penalties.end(),
|
||||
data.turn_duration_penalties.begin(),
|
||||
data.turn_duration_penalties.end());
|
||||
turn_data_container.append(data.turn_data_container);
|
||||
turn_indexes_write_buffer.insert(turn_indexes_write_buffer.end(),
|
||||
data.turn_indexes.begin(),
|
||||
data.turn_indexes.end());
|
||||
|
||||
// Buffer writes to reduce syscall count
|
||||
if (turn_indexes_write_buffer.size() >= TURN_INDEX_WRITE_BUFFER_SIZE)
|
||||
{
|
||||
turn_penalties_index_file.WriteFrom(turn_indexes_write_buffer.data(),
|
||||
turn_indexes_write_buffer.size());
|
||||
turn_indexes_write_buffer.clear();
|
||||
}
|
||||
|
||||
delayed_data.insert(
|
||||
delayed_data.end(), buffer->delayed_data.begin(), buffer->delayed_data.end());
|
||||
});
|
||||
@@ -927,7 +917,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
util::Log() << " contains " << m_edge_based_edge_list.size() << " edges";
|
||||
util::Log() << " skips " << restricted_turns_counter << " turns, "
|
||||
"defined by "
|
||||
<< restriction_map.size() << " restrictions";
|
||||
<< node_restriction_map.size() << " restrictions";
|
||||
util::Log() << " skips " << skipped_uturns_counter << " U turns";
|
||||
util::Log() << " skips " << skipped_barrier_turns_counter << " turns over barriers";
|
||||
}
|
||||
|
||||
@@ -660,41 +660,44 @@ void ExtractionContainers::PrepareRestrictions()
|
||||
// contain the start/end nodes of each way that is part of an restriction
|
||||
std::unordered_map<OSMWayID, FirstAndLastSegmentOfWay> referenced_ways;
|
||||
|
||||
// enter invalid IDs into the above maps to indicate that we want to find out about start/end
|
||||
// nodes of these ways
|
||||
const auto mark_ids = [&](auto const &turn_restriction) {
|
||||
FirstAndLastSegmentOfWay dummy_segment{
|
||||
MAX_OSM_WAYID, MAX_OSM_NODEID, MAX_OSM_NODEID, MAX_OSM_NODEID, MAX_OSM_NODEID};
|
||||
if (turn_restriction.Type() == RestrictionType::WAY_RESTRICTION)
|
||||
{
|
||||
const auto &way = turn_restriction.AsWayRestriction();
|
||||
referenced_ways[way.from] = dummy_segment;
|
||||
referenced_ways[way.to] = dummy_segment;
|
||||
referenced_ways[way.via] = dummy_segment;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(turn_restriction.Type() == RestrictionType::NODE_RESTRICTION);
|
||||
const auto &node = turn_restriction.AsNodeRestriction();
|
||||
referenced_ways[node.from] = dummy_segment;
|
||||
referenced_ways[node.to] = dummy_segment;
|
||||
}
|
||||
};
|
||||
|
||||
// update the values for all edges already sporting SPECIAL_NODEID
|
||||
const auto set_ids = [&](auto const &start_end) {
|
||||
auto itr = referenced_ways.find(start_end.way_id);
|
||||
if (itr != referenced_ways.end())
|
||||
itr->second = start_end;
|
||||
};
|
||||
|
||||
// prepare for extracting source/destination nodes for all restrictions
|
||||
{
|
||||
util::UnbufferedLog log;
|
||||
log << "Collecting start/end information on " << restrictions_list.size()
|
||||
<< " restrictions...";
|
||||
TIMER_START(prepare_restrictions);
|
||||
|
||||
const auto mark_ids = [&](auto const &turn_restriction) {
|
||||
FirstAndLastSegmentOfWay dummy_segment{
|
||||
MAX_OSM_WAYID, MAX_OSM_NODEID, MAX_OSM_NODEID, MAX_OSM_NODEID, MAX_OSM_NODEID};
|
||||
if (turn_restriction.Type() == RestrictionType::WAY_RESTRICTION)
|
||||
{
|
||||
const auto &way = turn_restriction.AsWayRestriction();
|
||||
referenced_ways[way.from] = dummy_segment;
|
||||
referenced_ways[way.to] = dummy_segment;
|
||||
referenced_ways[way.via] = dummy_segment;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(turn_restriction.Type() == RestrictionType::NODE_RESTRICTION);
|
||||
const auto &node = turn_restriction.AsNodeRestriction();
|
||||
referenced_ways[node.from] = dummy_segment;
|
||||
referenced_ways[node.to] = dummy_segment;
|
||||
}
|
||||
};
|
||||
|
||||
std::for_each(restrictions_list.begin(), restrictions_list.end(), mark_ids);
|
||||
|
||||
// enter invalid IDs into the above maps to indicate that we want to find out about
|
||||
// start/end
|
||||
// nodes of these ways
|
||||
// update the values for all edges already sporting SPECIAL_NODEID
|
||||
const auto set_ids = [&](auto const &start_end) {
|
||||
auto itr = referenced_ways.find(start_end.way_id);
|
||||
if (itr != referenced_ways.end())
|
||||
itr->second = start_end;
|
||||
};
|
||||
|
||||
std::for_each(way_start_end_id_list.cbegin(), way_start_end_id_list.cend(), set_ids);
|
||||
TIMER_STOP(prepare_restrictions);
|
||||
log << "ok, after " << TIMER_SEC(prepare_restrictions) << "s";
|
||||
@@ -710,8 +713,6 @@ void ExtractionContainers::PrepareRestrictions()
|
||||
return internal;
|
||||
};
|
||||
|
||||
// Given:
|
||||
// a -- b - ????????? - c -- d
|
||||
// Given
|
||||
// a -- b - ????????? - c -- d as via segment
|
||||
// and either
|
||||
@@ -720,6 +721,8 @@ void ExtractionContainers::PrepareRestrictions()
|
||||
// (d,e) or (j,a) as entry-segment
|
||||
auto const find_node_restriction =
|
||||
[&](auto const &segment, auto const &via_segment, auto const via_node) {
|
||||
// In case of way-restrictions, via-node will be set to MAX_OSM_NODEID to signal that
|
||||
// the node is not present.
|
||||
// connected at the front of the segment
|
||||
if (via_node == MAX_OSM_NODEID || segment.first_segment_source_id == via_node)
|
||||
{
|
||||
@@ -779,8 +782,10 @@ void ExtractionContainers::PrepareRestrictions()
|
||||
return find_node_restriction(from_segment_itr->second, to_segment_itr->second, via_node);
|
||||
};
|
||||
|
||||
// transform an OSMRestriction (based on WayIDs) into an OSRM restriction (base on NodeIDs)
|
||||
// returns true on successful transformation, false in case of invalid references
|
||||
// Transform an OSMRestriction (based on WayIDs) into an OSRM restriction (base on NodeIDs).
|
||||
// Returns true on successful transformation, false in case of invalid references.
|
||||
// Based on the auto type deduction, this transfor handles both conditional and unconditional
|
||||
// turn restrictions.
|
||||
const auto transform = [&](const auto &external_type, auto &internal_type) {
|
||||
if (external_type.Type() == RestrictionType::WAY_RESTRICTION)
|
||||
{
|
||||
@@ -837,7 +842,7 @@ void ExtractionContainers::PrepareRestrictions()
|
||||
TurnRestriction restriction;
|
||||
restriction.is_only = external_restriction.is_only;
|
||||
if (transform(external_restriction, restriction))
|
||||
unconditional_turn_restrictions.push_back(restriction);
|
||||
unconditional_turn_restrictions.push_back(std::move(restriction));
|
||||
}
|
||||
// conditional turn restriction
|
||||
else
|
||||
@@ -846,7 +851,7 @@ void ExtractionContainers::PrepareRestrictions()
|
||||
restriction.is_only = external_restriction.is_only;
|
||||
restriction.condition = std::move(external_restriction.condition);
|
||||
if (transform(external_restriction, restriction))
|
||||
conditional_turn_restrictions.push_back(restriction);
|
||||
conditional_turn_restrictions.push_back(std::move(restriction));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -12,13 +12,13 @@ namespace extractor
|
||||
|
||||
RestrictionCompressor::RestrictionCompressor(std::vector<TurnRestriction> &restrictions)
|
||||
{
|
||||
// add a node restriction ptr to the heads/tails maps, needs to be a reference!
|
||||
// add a node restriction ptr to the starts/ends maps, needs to be a reference!
|
||||
auto index = [&](auto &element) {
|
||||
heads.insert(std::make_pair(element.from, &element));
|
||||
tails.insert(std::make_pair(element.to, &element));
|
||||
starts.insert(std::make_pair(element.from, &element));
|
||||
ends.insert(std::make_pair(element.to, &element));
|
||||
};
|
||||
// !needs to be reference, so we can get the correct address
|
||||
const auto index_heads_and_tails = [&](auto &restriction) {
|
||||
const auto index_starts_and_ends = [&](auto &restriction) {
|
||||
if (restriction.Type() == RestrictionType::WAY_RESTRICTION)
|
||||
{
|
||||
auto &way_restriction = restriction.AsWayRestriction();
|
||||
@@ -33,21 +33,21 @@ RestrictionCompressor::RestrictionCompressor(std::vector<TurnRestriction> &restr
|
||||
}
|
||||
};
|
||||
|
||||
// add all restrictions as their respective head-tail pointers
|
||||
std::for_each(restrictions.begin(), restrictions.end(), index_heads_and_tails);
|
||||
// add all restrictions as their respective startend pointers
|
||||
std::for_each(restrictions.begin(), restrictions.end(), index_starts_and_ends);
|
||||
}
|
||||
|
||||
void RestrictionCompressor::Compress(const NodeID from, const NodeID via, const NodeID to)
|
||||
{
|
||||
const auto get_value = [](const auto pair) { return pair.second; };
|
||||
// extract all startptrs and move them from via to from.
|
||||
auto all_starts_range = starts.equal_range(via);
|
||||
std::vector<NodeRestriction *> start_ptrs;
|
||||
std::transform(all_starts_range.first,
|
||||
all_starts_range.second,
|
||||
std::back_inserter(start_ptrs),
|
||||
[](const auto pair) { return pair.second; });
|
||||
|
||||
// extract all head ptrs and move them from via to from.
|
||||
auto all_heads_range = heads.equal_range(via);
|
||||
std::vector<NodeRestriction *> head_ptrs;
|
||||
std::transform(
|
||||
all_heads_range.first, all_heads_range.second, std::back_inserter(head_ptrs), get_value);
|
||||
|
||||
const auto update_head = [&](auto ptr) {
|
||||
const auto update_start = [&](auto ptr) {
|
||||
// ____ | from - p.from | via - p.via | to - p.to | ____
|
||||
BOOST_ASSERT(ptr->from == via);
|
||||
if (ptr->via == to)
|
||||
@@ -62,21 +62,23 @@ void RestrictionCompressor::Compress(const NodeID from, const NodeID via, const
|
||||
}
|
||||
};
|
||||
|
||||
std::for_each(head_ptrs.begin(), head_ptrs.end(), update_head);
|
||||
|
||||
const auto reinsert_head = [&](auto ptr) { heads.insert(std::make_pair(ptr->from, ptr)); };
|
||||
std::for_each(start_ptrs.begin(), start_ptrs.end(), update_start);
|
||||
|
||||
// update the ptrs in our mapping
|
||||
heads.erase(via);
|
||||
std::for_each(head_ptrs.begin(), head_ptrs.end(), reinsert_head);
|
||||
starts.erase(via);
|
||||
|
||||
// extract all tail ptrs and move them from via to to
|
||||
auto all_tails_range = tails.equal_range(via);
|
||||
std::vector<NodeRestriction *> tail_ptrs;
|
||||
std::transform(
|
||||
all_tails_range.first, all_tails_range.second, std::back_inserter(tail_ptrs), get_value);
|
||||
const auto reinsert_start = [&](auto ptr) { starts.insert(std::make_pair(ptr->from, ptr)); };
|
||||
std::for_each(start_ptrs.begin(), start_ptrs.end(), reinsert_start);
|
||||
|
||||
const auto update_tail = [&](auto ptr) {
|
||||
// extract all end ptrs and move them from via to to
|
||||
auto all_ends_range = ends.equal_range(via);
|
||||
std::vector<NodeRestriction *> end_ptrs;
|
||||
std::transform(all_ends_range.first,
|
||||
all_ends_range.second,
|
||||
std::back_inserter(end_ptrs),
|
||||
[](const auto pair) { return pair.second; });
|
||||
|
||||
const auto update_end = [&](auto ptr) {
|
||||
BOOST_ASSERT(ptr->to == via);
|
||||
// p.from | ____ - p.via | from - p.to | via - ____ | to
|
||||
if (ptr->via == from)
|
||||
@@ -90,14 +92,13 @@ void RestrictionCompressor::Compress(const NodeID from, const NodeID via, const
|
||||
ptr->to = from;
|
||||
}
|
||||
};
|
||||
std::for_each(end_ptrs.begin(), end_ptrs.end(), update_end);
|
||||
|
||||
const auto reinsert_tail = [&](auto ptr) { tails.insert(std::make_pair(ptr->to, ptr)); };
|
||||
// update end ptrs in mapping
|
||||
ends.erase(via);
|
||||
|
||||
std::for_each(tail_ptrs.begin(), tail_ptrs.end(), update_tail);
|
||||
|
||||
// update tail ptrs in mapping
|
||||
tails.erase(via);
|
||||
std::for_each(tail_ptrs.begin(), tail_ptrs.end(), reinsert_tail);
|
||||
const auto reinsert_end = [&](auto ptr) { ends.insert(std::make_pair(ptr->to, ptr)); };
|
||||
std::for_each(end_ptrs.begin(), end_ptrs.end(), reinsert_end);
|
||||
}
|
||||
|
||||
} // namespace extractor
|
||||
|
||||
@@ -78,8 +78,9 @@ removeInvalidRestrictions(std::vector<TurnRestriction> restrictions,
|
||||
}
|
||||
};
|
||||
|
||||
restrictions.erase(std::remove_if(restrictions.begin(), restrictions.end(), is_invalid),
|
||||
restrictions.end());
|
||||
const auto end_valid_restrictions =
|
||||
std::remove_if(restrictions.begin(), restrictions.end(), is_invalid);
|
||||
restrictions.erase(end_valid_restrictions, restrictions.end());
|
||||
|
||||
return restrictions;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "extractor/way_restriction_map.hpp"
|
||||
#include "util/for_each_pair.hpp"
|
||||
|
||||
#include <iterator>
|
||||
#include <tuple>
|
||||
@@ -45,12 +46,10 @@ WayRestrictionMap::WayRestrictionMap(const std::vector<TurnRestriction> &turn_re
|
||||
};
|
||||
std::for_each(turn_restrictions.begin(), turn_restrictions.end(), extract_restrictions);
|
||||
|
||||
const auto as_duplicated_node =
|
||||
[](auto const &restriction) -> std::tuple<NodeID, NodeID, NodeID> {
|
||||
const auto as_duplicated_node = [](auto const &restriction) {
|
||||
auto &way = restriction.AsWayRestriction();
|
||||
// group restrictions by the via-way. On same via-ways group by from
|
||||
return std::make_tuple(
|
||||
way.in_restriction.via, way.out_restriction.via, way.in_restriction.from);
|
||||
return std::tie(way.in_restriction.via, way.out_restriction.via, way.in_restriction.from);
|
||||
};
|
||||
|
||||
const auto by_duplicated_node = [&](auto const &lhs, auto const &rhs) {
|
||||
@@ -59,16 +58,14 @@ WayRestrictionMap::WayRestrictionMap(const std::vector<TurnRestriction> &turn_re
|
||||
|
||||
std::sort(restriction_data.begin(), restriction_data.end(), by_duplicated_node);
|
||||
|
||||
std::size_t index = 0, duplication_id = 0;
|
||||
// map all way restrictions into access containers
|
||||
const auto prepare_way_restriction = [this, &index, &duplication_id, as_duplicated_node](
|
||||
const auto &restriction) {
|
||||
for (RestrictionID index = 0; index < restriction_data.size(); ++index)
|
||||
{
|
||||
const auto &restriction = restriction_data[index];
|
||||
const auto &way = restriction.AsWayRestriction();
|
||||
restriction_starts.insert(
|
||||
std::make_pair(std::make_pair(way.in_restriction.from, way.in_restriction.via), index));
|
||||
++index;
|
||||
};
|
||||
std::for_each(restriction_data.begin(), restriction_data.end(), prepare_way_restriction);
|
||||
|
||||
std::size_t offset = 1;
|
||||
// the first group starts at 0
|
||||
@@ -81,9 +78,8 @@ WayRestrictionMap::WayRestrictionMap(const std::vector<TurnRestriction> &turn_re
|
||||
if (as_duplicated_node(lhs) != as_duplicated_node(rhs))
|
||||
duplicated_node_groups.push_back(offset);
|
||||
++offset;
|
||||
return false; // continue until the end
|
||||
};
|
||||
std::adjacent_find(restriction_data.begin(), restriction_data.end(), add_offset_on_new_groups);
|
||||
util::for_each_pair(restriction_data.begin(), restriction_data.end(), add_offset_on_new_groups);
|
||||
duplicated_node_groups.push_back(restriction_data.size());
|
||||
}
|
||||
|
||||
@@ -110,17 +106,17 @@ bool WayRestrictionMap::IsViaWay(const NodeID from, const NodeID to) const
|
||||
return way.out_restriction.from == from && way.out_restriction.via == to;
|
||||
}
|
||||
|
||||
std::size_t WayRestrictionMap::AsDuplicatedNodeID(const std::size_t restriction_id) const
|
||||
DuplicatedNodeID WayRestrictionMap::AsDuplicatedNodeID(const RestrictionID restriction_id) const
|
||||
{
|
||||
return std::distance(duplicated_node_groups.begin(),
|
||||
std::upper_bound(duplicated_node_groups.begin(),
|
||||
duplicated_node_groups.end(),
|
||||
restriction_id)) -
|
||||
1;
|
||||
const auto upper_bound_restriction = std::upper_bound(
|
||||
duplicated_node_groups.begin(), duplicated_node_groups.end(), restriction_id);
|
||||
const auto distance_to_upper_bound =
|
||||
std::distance(duplicated_node_groups.begin(), upper_bound_restriction);
|
||||
return distance_to_upper_bound - 1;
|
||||
}
|
||||
|
||||
util::range<std::size_t> WayRestrictionMap::DuplicatedNodeIDs(const NodeID from,
|
||||
const NodeID to) const
|
||||
util::range<DuplicatedNodeID> WayRestrictionMap::DuplicatedNodeIDs(const NodeID from,
|
||||
const NodeID to) const
|
||||
{
|
||||
const auto duplicated_node_range_itr = std::equal_range(
|
||||
restriction_data.begin(), restriction_data.end(), std::make_tuple(from, to), FindViaWay());
|
||||
@@ -129,16 +125,16 @@ util::range<std::size_t> WayRestrictionMap::DuplicatedNodeIDs(const NodeID from,
|
||||
return std::distance(restriction_data.begin(), itr);
|
||||
};
|
||||
|
||||
return util::irange<std::size_t>(
|
||||
return util::irange<DuplicatedNodeID>(
|
||||
AsDuplicatedNodeID(as_restriction_id(duplicated_node_range_itr.first)),
|
||||
AsDuplicatedNodeID(as_restriction_id(duplicated_node_range_itr.second)));
|
||||
}
|
||||
|
||||
bool WayRestrictionMap::IsRestricted(std::size_t duplicated_node, const NodeID to) const
|
||||
bool WayRestrictionMap::IsRestricted(DuplicatedNodeID duplicated_node, const NodeID to) const
|
||||
{
|
||||
// loop over all restrictions associated with the node. Mark as restricted based on
|
||||
// is_only/restricted targets
|
||||
for (std::size_t restriction_index = duplicated_node_groups[duplicated_node];
|
||||
for (RestrictionID restriction_index = duplicated_node_groups[duplicated_node];
|
||||
restriction_index != duplicated_node_groups[duplicated_node + 1];
|
||||
++restriction_index)
|
||||
{
|
||||
@@ -153,11 +149,6 @@ bool WayRestrictionMap::IsRestricted(std::size_t duplicated_node, const NodeID t
|
||||
return false;
|
||||
}
|
||||
|
||||
TurnRestriction const &WayRestrictionMap::GetRestriction(const std::size_t id) const
|
||||
{
|
||||
return restriction_data[id];
|
||||
}
|
||||
|
||||
std::vector<WayRestrictionMap::ViaWay> WayRestrictionMap::DuplicatedNodeRepresentatives() const
|
||||
{
|
||||
std::vector<ViaWay> result;
|
||||
@@ -167,7 +158,7 @@ std::vector<WayRestrictionMap::ViaWay> WayRestrictionMap::DuplicatedNodeRepresen
|
||||
std::back_inserter(result),
|
||||
[&](auto const representative_id) -> ViaWay {
|
||||
auto &way = restriction_data[representative_id].AsWayRestriction();
|
||||
return {representative_id, way.in_restriction.via, way.out_restriction.via};
|
||||
return {way.in_restriction.via, way.out_restriction.via};
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user