refactor restriction parsing / extraction to actual types
Makes turn restrictions into dedicated structures and diferentiates between them via a variant. Ensures that we do not accidentally mess up ID types within our application. In addition this improves the restriction performance by only parsing all edges once at the cost of (at the time of writing) 22MB in terms of main memory usage.
This commit is contained in:
@@ -139,7 +139,7 @@ void ExtractionContainers::PrepareData(ScriptingEnvironment &scripting_environme
|
||||
WriteEdges(file_out);
|
||||
|
||||
PrepareRestrictions();
|
||||
WriteRestrictions(restrictions_file_name);
|
||||
WriteConditionalRestrictions(restrictions_file_name);
|
||||
WriteCharData(name_file_name);
|
||||
}
|
||||
|
||||
@@ -633,46 +633,19 @@ void ExtractionContainers::WriteNodes(storage::io::FileWriter &file_out) const
|
||||
util::Log() << "Processed " << max_internal_node_id << " nodes";
|
||||
}
|
||||
|
||||
void ExtractionContainers::WriteRestrictions(const std::string &path)
|
||||
void ExtractionContainers::WriteConditionalRestrictions(const std::string &path)
|
||||
{
|
||||
// serialize restrictions
|
||||
std::uint64_t written_restriction_count = 0;
|
||||
std::uint64_t written_restriction_count = conditional_turn_restrictions.size();
|
||||
storage::io::FileWriter restrictions_out_file(path,
|
||||
storage::io::FileWriter::GenerateFingerprint);
|
||||
|
||||
restrictions_out_file.WriteElementCount64(written_restriction_count);
|
||||
|
||||
for (const auto &restriction_container : restrictions_list)
|
||||
{
|
||||
if (SPECIAL_NODEID != restriction_container.restriction.from.node &&
|
||||
SPECIAL_NODEID != restriction_container.restriction.via.node &&
|
||||
SPECIAL_NODEID != restriction_container.restriction.to.node)
|
||||
{
|
||||
if (!restriction_container.restriction.condition.empty())
|
||||
{
|
||||
// write conditional turn restrictions to disk, for use in contractor later
|
||||
extractor::serialization::write(restrictions_out_file,
|
||||
restriction_container.restriction);
|
||||
++written_restriction_count;
|
||||
}
|
||||
else
|
||||
{
|
||||
// save unconditional turn restriction to memory, for use in ebg later
|
||||
unconditional_turn_restrictions.push_back(
|
||||
std::move(restriction_container.restriction));
|
||||
}
|
||||
}
|
||||
}
|
||||
restrictions_out_file.SkipToBeginning();
|
||||
restrictions_out_file.WriteElementCount64(written_restriction_count);
|
||||
util::Log() << "number of restrictions saved to memory: "
|
||||
<< unconditional_turn_restrictions.size();
|
||||
serialization::write(restrictions_out_file, conditional_turn_restrictions);
|
||||
util::Log() << "number of conditional restrictions written to disk: "
|
||||
<< written_restriction_count;
|
||||
}
|
||||
|
||||
void ExtractionContainers::PrepareRestrictions()
|
||||
{
|
||||
|
||||
{
|
||||
util::UnbufferedLog log;
|
||||
log << "Sorting used ways ... ";
|
||||
@@ -684,211 +657,211 @@ void ExtractionContainers::PrepareRestrictions()
|
||||
log << "ok, after " << TIMER_SEC(sort_ways) << "s";
|
||||
}
|
||||
|
||||
// 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[OSMWayID{way.from}] = dummy_segment;
|
||||
referenced_ways[OSMWayID{way.to}] = dummy_segment;
|
||||
referenced_ways[OSMWayID{way.via}] = dummy_segment;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(turn_restriction.Type() == RestrictionType::NODE_RESTRICTION);
|
||||
const auto &node = turn_restriction.AsNodeRestriction();
|
||||
referenced_ways[OSMWayID{node.from}] = dummy_segment;
|
||||
referenced_ways[OSMWayID{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 << "Sorting " << restrictions_list.size() << " restriction. by from... ";
|
||||
TIMER_START(sort_restrictions);
|
||||
tbb::parallel_sort(
|
||||
restrictions_list.begin(), restrictions_list.end(), CmpRestrictionContainerByFrom());
|
||||
TIMER_STOP(sort_restrictions);
|
||||
log << "ok, after " << TIMER_SEC(sort_restrictions) << "s";
|
||||
log << "Collecting start/end information on " << restrictions_list.size()
|
||||
<< " restrictions...";
|
||||
TIMER_START(prepare_restrictions);
|
||||
std::for_each(restrictions_list.begin(), restrictions_list.end(), mark_ids);
|
||||
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";
|
||||
}
|
||||
|
||||
{
|
||||
util::UnbufferedLog log;
|
||||
log << "Fixing restriction starts ... " << std::flush;
|
||||
TIMER_START(fix_restriction_starts);
|
||||
auto restrictions_iterator = restrictions_list.begin();
|
||||
auto way_start_and_end_iterator = way_start_end_id_list.cbegin();
|
||||
const auto restrictions_list_end = restrictions_list.end();
|
||||
const auto way_start_end_id_list_end = way_start_end_id_list.cend();
|
||||
|
||||
while (way_start_and_end_iterator != way_start_end_id_list_end &&
|
||||
restrictions_iterator != restrictions_list_end)
|
||||
auto const to_internal = [&](auto const osm_node) {
|
||||
auto internal = mapExternalToInternalNodeID(
|
||||
used_node_id_list.begin(), used_node_id_list.end(), OSMNodeID{osm_node});
|
||||
if (internal == SPECIAL_NODEID)
|
||||
{
|
||||
if (way_start_and_end_iterator->way_id <
|
||||
OSMWayID{static_cast<std::uint32_t>(restrictions_iterator->restriction.from.way)})
|
||||
util::Log(logDEBUG) << "Restriction references invalid node: " << osm_node;
|
||||
}
|
||||
return internal;
|
||||
};
|
||||
|
||||
// Given:
|
||||
// a -- b - ????????? - c -- d
|
||||
// Given
|
||||
// a -- b - ????????? - c -- d as via segment
|
||||
// and either
|
||||
// d -- e - ????????? - f -- g or
|
||||
// h -- i - ????????? - j -- a
|
||||
// (d,e) or (j,a) as entry-segment
|
||||
auto const find_node_restriction =
|
||||
[&](auto const &segment, auto const &via_segment, auto const via_node) {
|
||||
// connected at the front of the segment
|
||||
if (via_node == MAX_OSM_NODEID || segment.first_segment_source_id == via_node)
|
||||
{
|
||||
++way_start_and_end_iterator;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (way_start_and_end_iterator->way_id >
|
||||
OSMWayID{static_cast<std::uint32_t>(restrictions_iterator->restriction.from.way)})
|
||||
{
|
||||
util::Log(logDEBUG) << "Restriction references invalid way: "
|
||||
<< restrictions_iterator->restriction.from.way;
|
||||
restrictions_iterator->restriction.from.node = SPECIAL_NODEID;
|
||||
++restrictions_iterator;
|
||||
continue;
|
||||
}
|
||||
|
||||
BOOST_ASSERT(
|
||||
way_start_and_end_iterator->way_id ==
|
||||
OSMWayID{static_cast<std::uint32_t>(restrictions_iterator->restriction.from.way)});
|
||||
|
||||
// we do not remap the via id yet, since we will need it for the to node as well
|
||||
const OSMNodeID via_osm_node_id =
|
||||
OSMNodeID{restrictions_iterator->restriction.via.node};
|
||||
|
||||
// check if via is actually valid, if not invalidate
|
||||
auto via_node_id = mapExternalToInternalNodeID(
|
||||
used_node_id_list.begin(), used_node_id_list.end(), via_osm_node_id);
|
||||
if (via_node_id == SPECIAL_NODEID)
|
||||
{
|
||||
util::Log(logDEBUG) << "Restriction references invalid node: " << via_osm_node_id;
|
||||
restrictions_iterator->restriction.via.node = SPECIAL_NODEID;
|
||||
++restrictions_iterator;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (way_start_and_end_iterator->first_segment_source_id == via_osm_node_id)
|
||||
{
|
||||
// assign new from node id
|
||||
const auto from_node_id = mapExternalToInternalNodeID(
|
||||
used_node_id_list.begin(),
|
||||
used_node_id_list.end(),
|
||||
way_start_and_end_iterator->first_segment_target_id);
|
||||
if (from_node_id == SPECIAL_NODEID)
|
||||
if (segment.first_segment_source_id == via_segment.first_segment_source_id)
|
||||
{
|
||||
util::Log(logDEBUG) << "Way references invalid node: "
|
||||
<< way_start_and_end_iterator->first_segment_target_id;
|
||||
restrictions_iterator->restriction.from.node = SPECIAL_NODEID;
|
||||
++restrictions_iterator;
|
||||
++way_start_and_end_iterator;
|
||||
continue;
|
||||
return NodeRestriction{to_internal(segment.first_segment_target_id),
|
||||
to_internal(segment.first_segment_source_id),
|
||||
to_internal(via_segment.first_segment_target_id)};
|
||||
}
|
||||
restrictions_iterator->restriction.from.node = from_node_id;
|
||||
}
|
||||
else if (way_start_and_end_iterator->last_segment_target_id == via_osm_node_id)
|
||||
{
|
||||
// assign new from node id
|
||||
const auto from_node_id =
|
||||
mapExternalToInternalNodeID(used_node_id_list.begin(),
|
||||
used_node_id_list.end(),
|
||||
way_start_and_end_iterator->last_segment_source_id);
|
||||
if (from_node_id == SPECIAL_NODEID)
|
||||
else if (segment.first_segment_source_id == via_segment.last_segment_target_id)
|
||||
{
|
||||
util::Log(logDEBUG) << "Way references invalid node: "
|
||||
<< way_start_and_end_iterator->last_segment_target_id;
|
||||
restrictions_iterator->restriction.from.node = SPECIAL_NODEID;
|
||||
++restrictions_iterator;
|
||||
++way_start_and_end_iterator;
|
||||
continue;
|
||||
return NodeRestriction{to_internal(segment.first_segment_target_id),
|
||||
to_internal(segment.first_segment_source_id),
|
||||
to_internal(via_segment.last_segment_source_id)};
|
||||
}
|
||||
restrictions_iterator->restriction.from.node = from_node_id;
|
||||
}
|
||||
else
|
||||
|
||||
// connected at the end of the segment
|
||||
if (via_node == MAX_OSM_NODEID || segment.last_segment_target_id == via_node)
|
||||
{
|
||||
// if it's neither, this is an invalid restriction
|
||||
restrictions_iterator->restriction.from.node = SPECIAL_NODEID;
|
||||
if (segment.last_segment_target_id == via_segment.first_segment_source_id)
|
||||
{
|
||||
return NodeRestriction{to_internal(segment.last_segment_source_id),
|
||||
to_internal(segment.last_segment_target_id),
|
||||
to_internal(via_segment.first_segment_target_id)};
|
||||
}
|
||||
else if (segment.last_segment_target_id == via_segment.last_segment_target_id)
|
||||
{
|
||||
return NodeRestriction{to_internal(segment.last_segment_source_id),
|
||||
to_internal(segment.last_segment_target_id),
|
||||
to_internal(via_segment.last_segment_source_id)};
|
||||
}
|
||||
}
|
||||
++restrictions_iterator;
|
||||
|
||||
// unconnected
|
||||
util::Log(logDEBUG) << "Restriction references unconnected way: " << segment.way_id;
|
||||
return NodeRestriction{SPECIAL_NODEID, SPECIAL_NODEID, SPECIAL_NODEID};
|
||||
};
|
||||
|
||||
// translate the turn from one segment onto another into a node restriction (the ways can only
|
||||
// be connected at a single location)
|
||||
auto const get_node_restriction_from_OSM_ids = [&](
|
||||
auto const from_id, auto const to_id, const OSMNodeID via_node = MAX_OSM_NODEID) {
|
||||
auto const from_segment_itr = referenced_ways.find(OSMWayID{from_id});
|
||||
if (from_segment_itr->second.way_id != OSMWayID{from_id})
|
||||
{
|
||||
util::Log(logDEBUG) << "Restriction references invalid way: " << from_id;
|
||||
return NodeRestriction{SPECIAL_NODEID, SPECIAL_NODEID, SPECIAL_NODEID};
|
||||
}
|
||||
|
||||
TIMER_STOP(fix_restriction_starts);
|
||||
log << "ok, after " << TIMER_SEC(fix_restriction_starts) << "s";
|
||||
}
|
||||
|
||||
{
|
||||
util::UnbufferedLog log;
|
||||
log << "Sorting restrictions. by to ... " << std::flush;
|
||||
TIMER_START(sort_restrictions_to);
|
||||
tbb::parallel_sort(
|
||||
restrictions_list.begin(), restrictions_list.end(), CmpRestrictionContainerByTo());
|
||||
TIMER_STOP(sort_restrictions_to);
|
||||
log << "ok, after " << TIMER_SEC(sort_restrictions_to) << "s";
|
||||
}
|
||||
|
||||
{
|
||||
util::UnbufferedLog log;
|
||||
log << "Fixing restriction ends ... " << std::flush;
|
||||
TIMER_START(fix_restriction_ends);
|
||||
auto restrictions_iterator = restrictions_list.begin();
|
||||
auto way_start_and_end_iterator = way_start_end_id_list.cbegin();
|
||||
const auto way_start_end_id_list_end_ = way_start_end_id_list.cend();
|
||||
const auto restrictions_list_end_ = restrictions_list.end();
|
||||
|
||||
while (way_start_and_end_iterator != way_start_end_id_list_end_ &&
|
||||
restrictions_iterator != restrictions_list_end_)
|
||||
auto const to_segment_itr = referenced_ways.find(OSMWayID{to_id});
|
||||
if (to_segment_itr->second.way_id != OSMWayID{to_id})
|
||||
{
|
||||
if (way_start_and_end_iterator->way_id <
|
||||
OSMWayID{static_cast<std::uint32_t>(restrictions_iterator->restriction.to.way)})
|
||||
{
|
||||
++way_start_and_end_iterator;
|
||||
continue;
|
||||
}
|
||||
if (restrictions_iterator->restriction.from.node == SPECIAL_NODEID ||
|
||||
restrictions_iterator->restriction.via.node == SPECIAL_NODEID)
|
||||
{
|
||||
++restrictions_iterator;
|
||||
continue;
|
||||
}
|
||||
if (way_start_and_end_iterator->way_id >
|
||||
OSMWayID{static_cast<std::uint32_t>(restrictions_iterator->restriction.to.way)})
|
||||
{
|
||||
util::Log(logDEBUG) << "Restriction references invalid way: "
|
||||
<< restrictions_iterator->restriction.to.way;
|
||||
restrictions_iterator->restriction.to.way = SPECIAL_NODEID;
|
||||
++restrictions_iterator;
|
||||
continue;
|
||||
}
|
||||
BOOST_ASSERT(
|
||||
way_start_and_end_iterator->way_id ==
|
||||
OSMWayID{static_cast<std::uint32_t>(restrictions_iterator->restriction.to.way)});
|
||||
const OSMNodeID via_osm_node_id =
|
||||
OSMNodeID{restrictions_iterator->restriction.via.node};
|
||||
|
||||
// assign new via node id
|
||||
const auto via_node_id = mapExternalToInternalNodeID(
|
||||
used_node_id_list.begin(), used_node_id_list.end(), via_osm_node_id);
|
||||
BOOST_ASSERT(via_node_id != SPECIAL_NODEID);
|
||||
restrictions_iterator->restriction.via.node = via_node_id;
|
||||
|
||||
if (way_start_and_end_iterator->first_segment_source_id == via_osm_node_id)
|
||||
{
|
||||
const auto to_node_id = mapExternalToInternalNodeID(
|
||||
used_node_id_list.begin(),
|
||||
used_node_id_list.end(),
|
||||
way_start_and_end_iterator->first_segment_target_id);
|
||||
if (to_node_id == SPECIAL_NODEID)
|
||||
{
|
||||
util::Log(logDEBUG) << "Way references invalid node: "
|
||||
<< way_start_and_end_iterator->first_segment_source_id;
|
||||
restrictions_iterator->restriction.to.node = SPECIAL_NODEID;
|
||||
++restrictions_iterator;
|
||||
++way_start_and_end_iterator;
|
||||
continue;
|
||||
}
|
||||
restrictions_iterator->restriction.to.node = to_node_id;
|
||||
}
|
||||
else if (way_start_and_end_iterator->last_segment_target_id == via_osm_node_id)
|
||||
{
|
||||
const auto to_node_id =
|
||||
mapExternalToInternalNodeID(used_node_id_list.begin(),
|
||||
used_node_id_list.end(),
|
||||
way_start_and_end_iterator->last_segment_source_id);
|
||||
if (to_node_id == SPECIAL_NODEID)
|
||||
{
|
||||
util::Log(logDEBUG) << "Way references invalid node: "
|
||||
<< way_start_and_end_iterator->last_segment_source_id;
|
||||
restrictions_iterator->restriction.to.node = SPECIAL_NODEID;
|
||||
++restrictions_iterator;
|
||||
++way_start_and_end_iterator;
|
||||
continue;
|
||||
}
|
||||
restrictions_iterator->restriction.to.node = to_node_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if it's neither, this is an invalid restriction
|
||||
restrictions_iterator->restriction.to.node = SPECIAL_NODEID;
|
||||
}
|
||||
++restrictions_iterator;
|
||||
util::Log(logDEBUG) << "Restriction references invalid way: " << to_id;
|
||||
return NodeRestriction{SPECIAL_NODEID, SPECIAL_NODEID, SPECIAL_NODEID};
|
||||
}
|
||||
TIMER_STOP(fix_restriction_ends);
|
||||
log << "ok, after " << TIMER_SEC(fix_restriction_ends) << "s";
|
||||
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
|
||||
const auto transform = [&](auto const &external_type, auto &internal_type) {
|
||||
if (external_type.Type() == RestrictionType::WAY_RESTRICTION)
|
||||
{
|
||||
auto const &external = external_type.AsWayRestriction();
|
||||
// check if we were able to resolve all the involved ways
|
||||
auto const from_restriction =
|
||||
get_node_restriction_from_OSM_ids(external.from, external.via);
|
||||
auto const to_restriction =
|
||||
get_node_restriction_from_OSM_ids(external.via, external.to);
|
||||
|
||||
// failed to translate either of the involved nodes?
|
||||
if (!from_restriction.Valid() || !to_restriction.Valid())
|
||||
return false;
|
||||
|
||||
// point located at both via and segment is alway on `second`, to FSSF is the order we
|
||||
// need
|
||||
WayRestriction way_restriction{from_restriction, to_restriction};
|
||||
internal_type.node_or_way = std::move(way_restriction);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(external_type.Type() == RestrictionType::NODE_RESTRICTION);
|
||||
auto const &external = external_type.AsNodeRestriction();
|
||||
auto const via_node = to_internal(external.via);
|
||||
|
||||
// check if we were able to resolve all the involved ways
|
||||
auto restriction = get_node_restriction_from_OSM_ids(
|
||||
external.from, external.to, OSMNodeID{external.via});
|
||||
|
||||
if (!restriction.Valid())
|
||||
{
|
||||
std::cout << " >>> Invalid" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (restriction.via != via_node)
|
||||
{
|
||||
util::Log(logDEBUG) << "Restriction references invalid way: " << external.via;
|
||||
return false;
|
||||
}
|
||||
|
||||
internal_type.node_or_way = std::move(restriction);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// wrapper function to handle distinction between conditional and unconditional turn
|
||||
// restrictions
|
||||
const auto transform_into_internal_types = [&](auto &external_restriction) {
|
||||
// unconditional restriction
|
||||
if (external_restriction.condition.empty())
|
||||
{
|
||||
TurnRestriction restriction;
|
||||
restriction.flags = external_restriction.flags;
|
||||
if (transform(external_restriction, restriction))
|
||||
unconditional_turn_restrictions.push_back(restriction);
|
||||
}
|
||||
// conditional turn restriction
|
||||
else
|
||||
{
|
||||
ConditionalTurnRestriction restriction;
|
||||
restriction.flags = external_restriction.flags;
|
||||
restriction.condition = std::move(external_restriction.condition);
|
||||
if (transform(external_restriction, restriction))
|
||||
conditional_turn_restrictions.push_back(restriction);
|
||||
}
|
||||
};
|
||||
|
||||
// Transforming the restrictions into the dedicated internal types
|
||||
{
|
||||
util::UnbufferedLog log;
|
||||
log << "Collecting start/end information on " << restrictions_list.size()
|
||||
<< " restrictions...";
|
||||
TIMER_START(transform);
|
||||
std::for_each(
|
||||
restrictions_list.begin(), restrictions_list.end(), transform_into_internal_types);
|
||||
TIMER_STOP(transform);
|
||||
log << "ok, after " << TIMER_SEC(transform) << "s";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
@@ -259,7 +259,7 @@ Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment,
|
||||
SharedBuffer buffer;
|
||||
std::vector<std::pair<const osmium::Node &, ExtractionNode>> resulting_nodes;
|
||||
std::vector<std::pair<const osmium::Way &, ExtractionWay>> resulting_ways;
|
||||
std::vector<boost::optional<InputRestrictionContainer>> resulting_restrictions;
|
||||
std::vector<InputConditionalTurnRestriction> resulting_restrictions;
|
||||
};
|
||||
|
||||
tbb::filter_t<void, SharedBuffer> buffer_reader(
|
||||
@@ -454,7 +454,6 @@ Extractor::BuildEdgeExpandedGraph(ScriptingEnvironment &scripting_environment,
|
||||
std::unordered_set<NodeID> barrier_nodes;
|
||||
std::unordered_set<NodeID> traffic_lights;
|
||||
|
||||
auto restriction_map = std::make_shared<RestrictionMap>(turn_restrictions);
|
||||
auto node_based_graph =
|
||||
LoadNodeBasedGraph(barrier_nodes, traffic_lights, coordinates, osm_node_ids);
|
||||
|
||||
@@ -462,12 +461,13 @@ Extractor::BuildEdgeExpandedGraph(ScriptingEnvironment &scripting_environment,
|
||||
GraphCompressor graph_compressor;
|
||||
graph_compressor.Compress(barrier_nodes,
|
||||
traffic_lights,
|
||||
*restriction_map,
|
||||
turn_restrictions,
|
||||
*node_based_graph,
|
||||
compressed_edge_container);
|
||||
|
||||
util::NameTable name_table(config.GetPath(".osrm.names").string());
|
||||
|
||||
auto restriction_map = std::make_shared<RestrictionMap>(turn_restrictions);
|
||||
EdgeBasedGraphFactory edge_based_graph_factory(
|
||||
node_based_graph,
|
||||
compressed_edge_container,
|
||||
|
||||
@@ -73,19 +73,12 @@ void ExtractorCallbacks::ProcessNode(const osmium::Node &input_node,
|
||||
}
|
||||
}
|
||||
|
||||
void ExtractorCallbacks::ProcessRestriction(
|
||||
const boost::optional<InputRestrictionContainer> &restriction)
|
||||
void ExtractorCallbacks::ProcessRestriction(const InputConditionalTurnRestriction &restriction)
|
||||
{
|
||||
if (restriction)
|
||||
{
|
||||
external_memory.restrictions_list.push_back(restriction.get());
|
||||
// util::Log() << "from: " << restriction.get().restriction.from.node <<
|
||||
// ",via: " << restriction.get().restriction.via.node <<
|
||||
// ", to: " << restriction.get().restriction.to.node <<
|
||||
// ", only: " << (restriction.get().restriction.flags.is_only ?
|
||||
// "y" : "n");
|
||||
}
|
||||
external_memory.restrictions_list.push_back(restriction);
|
||||
// util::Log() << restriction.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the geometry contained in the ```input_way``` and the tags computed
|
||||
* by the lua profile inside ```parsed_way``` and computes all edge segments.
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
#include "extractor/graph_compressor.hpp"
|
||||
|
||||
#include "extractor/compressed_edge_container.hpp"
|
||||
#include "extractor/restriction_map.hpp"
|
||||
#include "extractor/restriction.hpp"
|
||||
#include "extractor/restriction_compressor.hpp"
|
||||
|
||||
#include "util/dynamic_graph.hpp"
|
||||
#include "util/node_based_graph.hpp"
|
||||
#include "util/percent.hpp"
|
||||
|
||||
#include "util/log.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
@@ -15,13 +20,35 @@ namespace extractor
|
||||
|
||||
void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const std::unordered_set<NodeID> &traffic_lights,
|
||||
RestrictionMap &restriction_map,
|
||||
std::vector<TurnRestriction> &turn_restrictions,
|
||||
util::NodeBasedDynamicGraph &graph,
|
||||
CompressedEdgeContainer &geometry_compressor)
|
||||
{
|
||||
const unsigned original_number_of_nodes = graph.GetNumberOfNodes();
|
||||
const unsigned original_number_of_edges = graph.GetNumberOfEdges();
|
||||
|
||||
RestrictionCompressor restriction_compressor(turn_restrictions);
|
||||
|
||||
// we do not compress turn restrictions on degree two nodes. These nodes are usually used to
|
||||
// indicated `directed` barriers
|
||||
std::unordered_set<NodeID> restriction_via_nodes;
|
||||
|
||||
const auto remember_via_nodes = [&](const auto &restriction) {
|
||||
if (restriction.Type() == RestrictionType::NODE_RESTRICTION)
|
||||
{
|
||||
const auto &node = restriction.AsNodeRestriction();
|
||||
restriction_via_nodes.insert(node.via);
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(restriction.Type() == RestrictionType::WAY_RESTRICTION);
|
||||
const auto &way = restriction.AsWayRestriction();
|
||||
restriction_via_nodes.insert(way.in_restriction.via);
|
||||
restriction_via_nodes.insert(way.out_restriction.via);
|
||||
}
|
||||
};
|
||||
std::for_each(turn_restrictions.begin(), turn_restrictions.end(), remember_via_nodes);
|
||||
|
||||
{
|
||||
util::UnbufferedLog log;
|
||||
util::Percent progress(log, original_number_of_nodes);
|
||||
@@ -43,7 +70,7 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
}
|
||||
|
||||
// check if v is a via node for a turn restriction, i.e. a 'directed' barrier node
|
||||
if (restriction_map.IsViaNode(node_v))
|
||||
if (restriction_via_nodes.count(node_v))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -199,11 +226,7 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
graph.DeleteEdge(node_v, reverse_e2);
|
||||
|
||||
// update any involved turn restrictions
|
||||
restriction_map.FixupStartingTurnRestriction(node_u, node_v, node_w);
|
||||
restriction_map.FixupArrivingTurnRestriction(node_u, node_v, node_w, graph);
|
||||
|
||||
restriction_map.FixupStartingTurnRestriction(node_w, node_v, node_u);
|
||||
restriction_map.FixupArrivingTurnRestriction(node_w, node_v, node_u, graph);
|
||||
restriction_compressor.Compress(node_u, node_v, node_w);
|
||||
|
||||
// store compressed geometry in container
|
||||
geometry_compressor.CompressEdge(forward_e1,
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
#include "extractor/restriction_compressor.hpp"
|
||||
#include "extractor/restriction.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/assert.hpp>
|
||||
#include <utility>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
RestrictionCompressor::RestrictionCompressor(std::vector<TurnRestriction> &restrictions)
|
||||
{
|
||||
// add a node restriction ptr to the heads/tails 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));
|
||||
};
|
||||
// !needs to be reference, so we can get the correct address
|
||||
const auto index_heads_and_tails = [&](auto &restriction) {
|
||||
if (restriction.Type() == RestrictionType::WAY_RESTRICTION)
|
||||
{
|
||||
auto &way_restriction = restriction.AsWayRestriction();
|
||||
index(way_restriction.in_restriction);
|
||||
index(way_restriction.out_restriction);
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(restriction.Type() == RestrictionType::NODE_RESTRICTION);
|
||||
auto &node_restriction = restriction.AsNodeRestriction();
|
||||
index(node_restriction);
|
||||
}
|
||||
};
|
||||
|
||||
// add all restrictions as their respective head-tail pointers
|
||||
std::for_each(restrictions.begin(), restrictions.end(), index_heads_and_tails);
|
||||
}
|
||||
|
||||
void RestrictionCompressor::Compress(const NodeID from, const NodeID via, const NodeID to)
|
||||
{
|
||||
const auto get_value = [](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) {
|
||||
// ____ | from - p.from | via - p.via | to - p.to | ____
|
||||
BOOST_ASSERT(ptr->from == via);
|
||||
if (ptr->via == to)
|
||||
{
|
||||
ptr->from = from;
|
||||
}
|
||||
// ____ | to - p.from | via - p.via | from - p.to | ____
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(ptr->via == from);
|
||||
ptr->from = to;
|
||||
}
|
||||
};
|
||||
|
||||
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)); };
|
||||
|
||||
// update the ptrs in our mapping
|
||||
heads.erase(via);
|
||||
std::for_each(head_ptrs.begin(), head_ptrs.end(), reinsert_head);
|
||||
|
||||
// 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 update_tail = [&](auto ptr) {
|
||||
BOOST_ASSERT(ptr->to == via);
|
||||
// p.from | ____ - p.via | from - p.to | via - ____ | to
|
||||
if (ptr->via == from)
|
||||
{
|
||||
ptr->to = to;
|
||||
}
|
||||
// p.from | ____ - p.via | to - p.to | via - ____ | from
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(ptr->via == to);
|
||||
ptr->to = from;
|
||||
}
|
||||
};
|
||||
|
||||
const auto reinsert_tail = [&](auto ptr) { tails.insert(std::make_pair(ptr->to, ptr)); };
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "extractor/restriction_map.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
@@ -11,17 +13,23 @@ RestrictionMap::RestrictionMap(const std::vector<TurnRestriction> &restriction_l
|
||||
// a pair of starting edge and a list of all end nodes
|
||||
for (auto &restriction : restriction_list)
|
||||
{
|
||||
// only handle node restrictions here
|
||||
if (restriction.Type() == RestrictionType::WAY_RESTRICTION)
|
||||
continue;
|
||||
|
||||
const auto &node_restriction = restriction.AsNodeRestriction();
|
||||
BOOST_ASSERT(node_restriction.Valid());
|
||||
// This downcasting is OK because when this is called, the node IDs have been
|
||||
// renumbered into internal values, which should be well under 2^32
|
||||
// This will be a problem if we have more than 2^32 actual restrictions
|
||||
BOOST_ASSERT(restriction.from.node < std::numeric_limits<NodeID>::max());
|
||||
BOOST_ASSERT(restriction.via.node < std::numeric_limits<NodeID>::max());
|
||||
m_restriction_start_nodes.insert(restriction.from.node);
|
||||
m_no_turn_via_node_set.insert(restriction.via.node);
|
||||
BOOST_ASSERT(node_restriction.from < std::numeric_limits<NodeID>::max());
|
||||
BOOST_ASSERT(node_restriction.via < std::numeric_limits<NodeID>::max());
|
||||
m_restriction_start_nodes.insert(node_restriction.from);
|
||||
m_no_turn_via_node_set.insert(node_restriction.via);
|
||||
|
||||
// This explicit downcasting is also OK for the same reason.
|
||||
RestrictionSource restriction_source = {static_cast<NodeID>(restriction.from.node),
|
||||
static_cast<NodeID>(restriction.via.node)};
|
||||
RestrictionSource restriction_source = {static_cast<NodeID>(node_restriction.from),
|
||||
static_cast<NodeID>(node_restriction.via)};
|
||||
|
||||
std::size_t index;
|
||||
auto restriction_iter = m_restriction_map.find(restriction_source);
|
||||
@@ -47,8 +55,7 @@ RestrictionMap::RestrictionMap(const std::vector<TurnRestriction> &restriction_l
|
||||
}
|
||||
}
|
||||
++m_count;
|
||||
BOOST_ASSERT(restriction.to.node < std::numeric_limits<NodeID>::max());
|
||||
m_restriction_bucket_list.at(index).emplace_back(restriction.to.node,
|
||||
m_restriction_bucket_list.at(index).emplace_back(node_restriction.to,
|
||||
restriction.flags.is_only);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,14 +54,13 @@ RestrictionParser::RestrictionParser(bool use_turn_restrictions_,
|
||||
* in the corresponding profile. We use it for both namespacing restrictions, as in
|
||||
* restriction:motorcar as well as whitelisting if its in except:motorcar.
|
||||
*/
|
||||
std::vector<InputRestrictionContainer>
|
||||
boost::optional<InputConditionalTurnRestriction>
|
||||
RestrictionParser::TryParse(const osmium::Relation &relation) const
|
||||
{
|
||||
std::vector<InputRestrictionContainer> parsed_restrictions;
|
||||
// return if turn restrictions should be ignored
|
||||
if (!use_turn_restrictions)
|
||||
{
|
||||
return {};
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
osmium::tags::KeyFilter filter(false);
|
||||
@@ -90,14 +89,14 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const
|
||||
// if it's not a restriction, continue;
|
||||
if (std::distance(fi_begin, fi_end) == 0)
|
||||
{
|
||||
return {};
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
// check if the restriction should be ignored
|
||||
const char *except = relation.get_value_by_key("except");
|
||||
if (except != nullptr && ShouldIgnoreRestriction(except))
|
||||
{
|
||||
return {};
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
bool is_only_restriction = false;
|
||||
@@ -119,11 +118,17 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const
|
||||
}
|
||||
else // unrecognized value type
|
||||
{
|
||||
return {};
|
||||
return boost::none;
|
||||
}
|
||||
}
|
||||
|
||||
InputRestrictionContainer restriction_container(is_only_restriction);
|
||||
// we pretend every restriction is a conditional restriction. If we do not find any restriction,
|
||||
// we can trim away the vector after parsing
|
||||
InputConditionalTurnRestriction restriction_container;
|
||||
restriction_container.flags.is_only = is_only_restriction;
|
||||
|
||||
boost::optional<std::uint64_t> from = boost::none, via = boost::none, to = boost::none;
|
||||
bool is_node_restriction;
|
||||
|
||||
for (const auto &member : relation.members())
|
||||
{
|
||||
@@ -136,33 +141,35 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const
|
||||
switch (member.type())
|
||||
{
|
||||
case osmium::item_type::node:
|
||||
{
|
||||
|
||||
// Make sure nodes appear only in the role if a via node
|
||||
if (0 == strcmp("from", role) || 0 == strcmp("to", role))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
BOOST_ASSERT(0 == strcmp("via", role));
|
||||
|
||||
via = static_cast<std::uint64_t>(member.ref());
|
||||
is_node_restriction = true;
|
||||
// set via node id
|
||||
restriction_container.restriction.via.node = member.ref();
|
||||
break;
|
||||
|
||||
}
|
||||
case osmium::item_type::way:
|
||||
BOOST_ASSERT(0 == strcmp("from", role) || 0 == strcmp("to", role) ||
|
||||
0 == strcmp("via", role));
|
||||
if (0 == strcmp("from", role))
|
||||
{
|
||||
restriction_container.restriction.from.way = member.ref();
|
||||
from = static_cast<std::uint64_t>(member.ref());
|
||||
}
|
||||
else if (0 == strcmp("to", role))
|
||||
{
|
||||
restriction_container.restriction.to.way = member.ref();
|
||||
to = static_cast<std::uint64_t>(member.ref());
|
||||
}
|
||||
else if (0 == strcmp("via", role))
|
||||
{
|
||||
via = static_cast<std::uint64_t>(member.ref());
|
||||
is_node_restriction = false;
|
||||
}
|
||||
// else if (0 == strcmp("via", role))
|
||||
// {
|
||||
// not yet suppported
|
||||
// restriction_container.restriction.via.way = member.ref();
|
||||
// }
|
||||
break;
|
||||
case osmium::item_type::relation:
|
||||
// not yet supported, but who knows what the future holds...
|
||||
@@ -194,20 +201,29 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const
|
||||
std::vector<util::OpeningHours> hours = util::ParseOpeningHours(p.condition);
|
||||
// found unrecognized condition, continue
|
||||
if (hours.empty())
|
||||
return {};
|
||||
return boost::none;
|
||||
|
||||
restriction_container.restriction.condition = std::move(hours);
|
||||
restriction_container.condition = std::move(hours);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// push back a copy of turn restriction
|
||||
if (restriction_container.restriction.via.node != SPECIAL_NODEID &&
|
||||
restriction_container.restriction.from.node != SPECIAL_NODEID &&
|
||||
restriction_container.restriction.to.node != SPECIAL_NODEID)
|
||||
parsed_restrictions.push_back(restriction_container);
|
||||
|
||||
return parsed_restrictions;
|
||||
if (from && via && to)
|
||||
{
|
||||
if (is_node_restriction)
|
||||
{
|
||||
restriction_container.node_or_way = InputNodeRestriction{*from, *via, *to};
|
||||
}
|
||||
else
|
||||
{
|
||||
restriction_container.node_or_way = InputWayRestriction{*from, *via, *to};
|
||||
}
|
||||
return restriction_container;
|
||||
}
|
||||
else
|
||||
{
|
||||
return boost::none;
|
||||
}
|
||||
}
|
||||
|
||||
bool RestrictionParser::ShouldIgnoreRestriction(const std::string &except_tag_string) const
|
||||
|
||||
@@ -613,11 +613,10 @@ void Sol2ScriptingEnvironment::ProcessElements(
|
||||
const RestrictionParser &restriction_parser,
|
||||
std::vector<std::pair<const osmium::Node &, ExtractionNode>> &resulting_nodes,
|
||||
std::vector<std::pair<const osmium::Way &, ExtractionWay>> &resulting_ways,
|
||||
std::vector<boost::optional<InputRestrictionContainer>> &resulting_restrictions)
|
||||
std::vector<InputConditionalTurnRestriction> &resulting_restrictions)
|
||||
{
|
||||
ExtractionNode result_node;
|
||||
ExtractionWay result_way;
|
||||
std::vector<InputRestrictionContainer> result_res;
|
||||
auto &local_context = this->GetSol2Context();
|
||||
|
||||
for (auto entity = buffer.cbegin(), end = buffer.cend(); entity != end; ++entity)
|
||||
@@ -645,14 +644,15 @@ void Sol2ScriptingEnvironment::ProcessElements(
|
||||
static_cast<const osmium::Way &>(*entity), std::move(result_way)));
|
||||
break;
|
||||
case osmium::item_type::relation:
|
||||
result_res.clear();
|
||||
result_res =
|
||||
{
|
||||
auto result_res =
|
||||
restriction_parser.TryParse(static_cast<const osmium::Relation &>(*entity));
|
||||
for (const InputRestrictionContainer &r : result_res)
|
||||
if (result_res)
|
||||
{
|
||||
resulting_restrictions.push_back(r);
|
||||
resulting_restrictions.push_back(*result_res);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
+30
-29
@@ -444,22 +444,18 @@ updateTurnPenalties(const UpdaterConfig &config,
|
||||
}
|
||||
|
||||
bool IsRestrictionValid(const Timezoner &tz_handler,
|
||||
const extractor::TurnRestriction &turn,
|
||||
const std::vector<util::Coordinate> &coordinates,
|
||||
const extractor::PackedOSMIDs &osm_node_ids)
|
||||
const extractor::ConditionalTurnRestriction &turn,
|
||||
const std::vector<util::Coordinate> &coordinates)
|
||||
{
|
||||
const auto via_node = osm_node_ids[turn.via.node];
|
||||
const auto from_node = osm_node_ids[turn.from.node];
|
||||
const auto to_node = osm_node_ids[turn.to.node];
|
||||
if (turn.condition.empty())
|
||||
{
|
||||
osrm::util::Log(logWARNING) << "Condition parsing failed for the turn " << from_node
|
||||
<< " -> " << via_node << " -> " << to_node;
|
||||
return false;
|
||||
}
|
||||
BOOST_ASSERT(!turn.condition.empty());
|
||||
|
||||
const auto lon = static_cast<double>(toFloating(coordinates[turn.via.node].lon));
|
||||
const auto lat = static_cast<double>(toFloating(coordinates[turn.via.node].lat));
|
||||
// we utilize the via node (first on ways) to represent the turn restriction
|
||||
auto const via = turn.Type() == extractor::RestrictionType::WAY_RESTRICTION
|
||||
? turn.AsWayRestriction().in_restriction.to
|
||||
: turn.AsNodeRestriction().via;
|
||||
|
||||
const auto lon = static_cast<double>(toFloating(coordinates[via].lon));
|
||||
const auto lat = static_cast<double>(toFloating(coordinates[via].lat));
|
||||
const auto &condition = turn.condition;
|
||||
|
||||
// Get local time of the restriction
|
||||
@@ -482,9 +478,8 @@ bool IsRestrictionValid(const Timezoner &tz_handler,
|
||||
std::vector<std::uint64_t>
|
||||
updateConditionalTurns(const UpdaterConfig &config,
|
||||
std::vector<TurnPenalty> &turn_weight_penalties,
|
||||
const std::vector<extractor::TurnRestriction> &conditional_turns,
|
||||
const std::vector<extractor::ConditionalTurnRestriction> &conditional_turns,
|
||||
std::vector<util::Coordinate> &coordinates,
|
||||
extractor::PackedOSMIDs &osm_node_ids,
|
||||
Timezoner time_zone_handler)
|
||||
{
|
||||
// Mapped file pointer for turn indices
|
||||
@@ -501,18 +496,28 @@ updateConditionalTurns(const UpdaterConfig &config,
|
||||
std::unordered_set<std::tuple<NodeID, NodeID, NodeID>,
|
||||
std::hash<std::tuple<NodeID, NodeID, NodeID>>>
|
||||
is_no_set;
|
||||
for (const auto &c : conditional_turns)
|
||||
for (const auto &node_or_way : conditional_turns)
|
||||
{
|
||||
// only add restrictions to the lookups if the restriction is valid now
|
||||
if (!IsRestrictionValid(time_zone_handler, c, coordinates, osm_node_ids))
|
||||
// TODO handle conditional turn restrictions for via-ways (look-up doesn't work here)
|
||||
// https://github.com/Project-OSRM/osrm-backend/issues/2681#issuecomment-313376385
|
||||
if (node_or_way.Type() == extractor::RestrictionType::WAY_RESTRICTION)
|
||||
continue;
|
||||
if (c.flags.is_only)
|
||||
|
||||
if (!IsRestrictionValid(time_zone_handler, node_or_way, coordinates))
|
||||
continue;
|
||||
|
||||
// TODO get rid of this, when we can handle way restrictions
|
||||
const auto &c = node_or_way.AsNodeRestriction();
|
||||
|
||||
// only add restrictions to the lookups if the restriction is valid now
|
||||
|
||||
if (node_or_way.flags.is_only)
|
||||
{
|
||||
is_only_lookup.lookup.push_back({std::make_tuple(c.from.node, c.via.node), c.to.node});
|
||||
is_only_lookup.lookup.push_back({std::make_tuple(c.from, c.via), c.to});
|
||||
}
|
||||
else
|
||||
{
|
||||
is_no_set.insert({std::make_tuple(c.from.node, c.via.node, c.to.node)});
|
||||
is_no_set.insert({std::make_tuple(c.from, c.via, c.to)});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -633,7 +638,7 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
|
||||
load_profile_properties);
|
||||
}
|
||||
|
||||
std::vector<extractor::TurnRestriction> conditional_turns;
|
||||
std::vector<extractor::ConditionalTurnRestriction> conditional_turns;
|
||||
if (update_conditional_turns)
|
||||
{
|
||||
using storage::io::FileReader;
|
||||
@@ -691,12 +696,8 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
|
||||
}
|
||||
const Timezoner time_zone_handler = Timezoner(config.tz_file_path, config.valid_now);
|
||||
|
||||
auto updated_turn_penalties = updateConditionalTurns(config,
|
||||
turn_weight_penalties,
|
||||
conditional_turns,
|
||||
coordinates,
|
||||
osm_node_ids,
|
||||
time_zone_handler);
|
||||
auto updated_turn_penalties = updateConditionalTurns(
|
||||
config, turn_weight_penalties, conditional_turns, coordinates, time_zone_handler);
|
||||
const auto offset = updated_segments.size();
|
||||
updated_segments.resize(offset + updated_turn_penalties.size());
|
||||
// we need to re-compute all edges that have updated turn penalties.
|
||||
|
||||
Reference in New Issue
Block a user