Upgrade clang-format to version 15 (#6859)
This commit is contained in:
@@ -151,7 +151,8 @@ NBGToEBG EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const N
|
||||
|
||||
NodeID current_edge_source_coordinate_id = node_u;
|
||||
|
||||
const auto edge_id_to_segment_id = [](const NodeID edge_based_node_id) {
|
||||
const auto edge_id_to_segment_id = [](const NodeID edge_based_node_id)
|
||||
{
|
||||
if (edge_based_node_id == SPECIAL_NODEID)
|
||||
{
|
||||
return SegmentID{SPECIAL_SEGMENTID, false};
|
||||
@@ -409,7 +410,8 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedNodes(const WayRestrictionMap &way_re
|
||||
NodeID current_edge_source_coordinate_id = node_u;
|
||||
const EdgeData &forward_data = m_node_based_graph.GetEdgeData(eid);
|
||||
|
||||
const auto edge_id_to_segment_id = [](const NodeID edge_based_node_id) {
|
||||
const auto edge_id_to_segment_id = [](const NodeID edge_based_node_id)
|
||||
{
|
||||
if (edge_based_node_id == SPECIAL_NODEID)
|
||||
{
|
||||
return SegmentID{SPECIAL_SEGMENTID, false};
|
||||
@@ -532,7 +534,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
TurnPenalty turn_duration_penalty;
|
||||
};
|
||||
|
||||
auto const transfer_data = [&](const EdgeWithData &edge_with_data) {
|
||||
auto const transfer_data = [&](const EdgeWithData &edge_with_data)
|
||||
{
|
||||
m_edge_based_edge_list.push_back(edge_with_data.edge);
|
||||
turn_weight_penalties.push_back(edge_with_data.turn_weight_penalty);
|
||||
turn_duration_penalties.push_back(edge_with_data.turn_duration_penalty);
|
||||
@@ -568,7 +571,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
|
||||
// First part of the pipeline generates iterator ranges of IDs in sets of GRAINSIZE
|
||||
tbb::filter<void, tbb::blocked_range<NodeID>> generator_stage(
|
||||
tbb::filter_mode::serial_in_order, [&](tbb::flow_control &fc) {
|
||||
tbb::filter_mode::serial_in_order,
|
||||
[&](tbb::flow_control &fc)
|
||||
{
|
||||
if (current_node < node_count)
|
||||
{
|
||||
auto next_node = std::min(current_node + GRAINSIZE, node_count);
|
||||
@@ -599,7 +604,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
const auto &turn_angle,
|
||||
const auto &road_legs_on_the_right,
|
||||
const auto &road_legs_on_the_left,
|
||||
const auto &edge_geometries) {
|
||||
const auto &edge_geometries)
|
||||
{
|
||||
const auto &edge_data1 = m_node_based_graph.GetEdgeData(node_based_edge_from);
|
||||
const auto &edge_data2 = m_node_based_graph.GetEdgeData(node_based_edge_to);
|
||||
|
||||
@@ -710,7 +716,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
//
|
||||
tbb::filter<tbb::blocked_range<NodeID>, EdgesPipelineBufferPtr> processor_stage(
|
||||
tbb::filter_mode::parallel,
|
||||
[&](const tbb::blocked_range<NodeID> &intersection_node_range) {
|
||||
[&](const tbb::blocked_range<NodeID> &intersection_node_range)
|
||||
{
|
||||
auto buffer = std::make_shared<EdgesPipelineBuffer>();
|
||||
buffer->nodes_processed = intersection_node_range.size();
|
||||
|
||||
@@ -795,16 +802,16 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
const auto turn =
|
||||
std::find_if(connected_roads.begin(),
|
||||
connected_roads.end(),
|
||||
[edge = outgoing_edge.edge](const auto &road) {
|
||||
return road.eid == edge;
|
||||
});
|
||||
[edge = outgoing_edge.edge](const auto &road)
|
||||
{ return road.eid == edge; });
|
||||
OSRM_ASSERT(turn != connected_roads.end(),
|
||||
m_coordinates[intersection_node]);
|
||||
|
||||
std::vector<ExtractionTurnLeg> road_legs_on_the_right;
|
||||
std::vector<ExtractionTurnLeg> road_legs_on_the_left;
|
||||
|
||||
auto get_connected_road_info = [&](const auto &connected_edge) {
|
||||
auto get_connected_road_info = [&](const auto &connected_edge)
|
||||
{
|
||||
const auto &edge_data =
|
||||
m_node_based_graph.GetEdgeData(connected_edge.eid);
|
||||
|
||||
@@ -1012,9 +1019,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
auto const has_unconditional =
|
||||
std::any_of(restrictions.begin(),
|
||||
restrictions.end(),
|
||||
[](const auto &restriction) {
|
||||
return restriction->IsUnconditional();
|
||||
});
|
||||
[](const auto &restriction)
|
||||
{ return restriction->IsUnconditional(); });
|
||||
if (has_unconditional)
|
||||
continue;
|
||||
|
||||
@@ -1120,7 +1126,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
util::Percent routing_progress(log, node_count);
|
||||
std::vector<EdgeWithData> delayed_data;
|
||||
tbb::filter<EdgesPipelineBufferPtr, void> output_stage(
|
||||
tbb::filter_mode::serial_in_order, [&](auto buffer) {
|
||||
tbb::filter_mode::serial_in_order,
|
||||
[&](auto buffer)
|
||||
{
|
||||
routing_progress.PrintAddition(buffer->nodes_processed);
|
||||
|
||||
m_connectivity_checksum = buffer->checksum.update_checksum(m_connectivity_checksum);
|
||||
@@ -1140,7 +1148,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
|
||||
std::for_each(buffer->turn_to_ebn_map.begin(),
|
||||
buffer->turn_to_ebn_map.end(),
|
||||
[&global_turn_to_ebn_map](const auto &p) {
|
||||
[&global_turn_to_ebn_map](const auto &p)
|
||||
{
|
||||
// TODO: log conflicts here
|
||||
global_turn_to_ebn_map.insert(p);
|
||||
});
|
||||
@@ -1178,26 +1187,32 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
return std::vector<NodeID>{turn_edges.second.first, turn_edges.second.second};
|
||||
});
|
||||
|
||||
std::for_each(std::next(turns.begin()), turns.end(), [&](const auto &turn) {
|
||||
std::vector<std::vector<NodeID>> next_node_sequences;
|
||||
const auto next_turn_edges = global_turn_to_ebn_map.equal_range(turn);
|
||||
for (auto &node_sequence : node_sequences)
|
||||
{
|
||||
const auto found_it = std::find_if(
|
||||
next_turn_edges.first, next_turn_edges.second, [&](const auto &turn_edges) {
|
||||
const auto pre_turn_edge = turn_edges.second.first;
|
||||
return (node_sequence.back() == pre_turn_edge);
|
||||
});
|
||||
std::for_each(std::next(turns.begin()),
|
||||
turns.end(),
|
||||
[&](const auto &turn)
|
||||
{
|
||||
std::vector<std::vector<NodeID>> next_node_sequences;
|
||||
const auto next_turn_edges = global_turn_to_ebn_map.equal_range(turn);
|
||||
for (auto &node_sequence : node_sequences)
|
||||
{
|
||||
const auto found_it = std::find_if(
|
||||
next_turn_edges.first,
|
||||
next_turn_edges.second,
|
||||
[&](const auto &turn_edges)
|
||||
{
|
||||
const auto pre_turn_edge = turn_edges.second.first;
|
||||
return (node_sequence.back() == pre_turn_edge);
|
||||
});
|
||||
|
||||
if (found_it != next_turn_edges.second)
|
||||
{
|
||||
const auto post_turn_edge = found_it->second.second;
|
||||
node_sequence.push_back(post_turn_edge);
|
||||
next_node_sequences.push_back(std::move(node_sequence));
|
||||
}
|
||||
}
|
||||
node_sequences = std::move(next_node_sequences);
|
||||
});
|
||||
if (found_it != next_turn_edges.second)
|
||||
{
|
||||
const auto post_turn_edge = found_it->second.second;
|
||||
node_sequence.push_back(post_turn_edge);
|
||||
next_node_sequences.push_back(std::move(node_sequence));
|
||||
}
|
||||
}
|
||||
node_sequences = std::move(next_node_sequences);
|
||||
});
|
||||
|
||||
for (const auto &node_sequence : node_sequences)
|
||||
{
|
||||
@@ -1237,7 +1252,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
// Now, update the turn_id property on every EdgeBasedEdge - it will equal the position in the
|
||||
// m_edge_based_edge_list array for each object.
|
||||
tbb::parallel_for(tbb::blocked_range<NodeID>(0, m_edge_based_edge_list.size()),
|
||||
[this](const tbb::blocked_range<NodeID> &range) {
|
||||
[this](const tbb::blocked_range<NodeID> &range)
|
||||
{
|
||||
for (auto x = range.begin(), end = range.end(); x != end; ++x)
|
||||
{
|
||||
m_edge_based_edge_list[x].data.turn_id = x;
|
||||
|
||||
@@ -460,10 +460,10 @@ void ExtractionContainers::PrepareNodes()
|
||||
util::UnbufferedLog log;
|
||||
log << "Sorting all nodes ... " << std::flush;
|
||||
TIMER_START(sorting_nodes);
|
||||
tbb::parallel_sort(
|
||||
all_nodes_list.begin(), all_nodes_list.end(), [](const auto &left, const auto &right) {
|
||||
return left.node_id < right.node_id;
|
||||
});
|
||||
tbb::parallel_sort(all_nodes_list.begin(),
|
||||
all_nodes_list.end(),
|
||||
[](const auto &left, const auto &right)
|
||||
{ return left.node_id < right.node_id; });
|
||||
TIMER_STOP(sorting_nodes);
|
||||
log << "ok, after " << TIMER_SEC(sorting_nodes) << "s";
|
||||
}
|
||||
@@ -629,7 +629,8 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
|
||||
|
||||
// Remove all remaining edges. They are invalid because there are no corresponding nodes for
|
||||
// them. This happens when using osmosis with bbox or polygon to extract smaller areas.
|
||||
auto markSourcesInvalid = [](InternalExtractorEdge &edge) {
|
||||
auto markSourcesInvalid = [](InternalExtractorEdge &edge)
|
||||
{
|
||||
util::Log(logDEBUG) << "Found invalid node reference " << edge.result.source;
|
||||
edge.result.source = SPECIAL_NODEID;
|
||||
edge.result.osm_source_id = SPECIAL_OSM_NODEID;
|
||||
@@ -743,7 +744,8 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
|
||||
|
||||
// Remove all remaining edges. They are invalid because there are no corresponding nodes for
|
||||
// them. This happens when using osmosis with bbox or polygon to extract smaller areas.
|
||||
auto markTargetsInvalid = [](InternalExtractorEdge &edge) {
|
||||
auto markTargetsInvalid = [](InternalExtractorEdge &edge)
|
||||
{
|
||||
util::Log(logDEBUG) << "Found invalid node reference " << edge.result.target;
|
||||
edge.result.target = SPECIAL_NODEID;
|
||||
};
|
||||
@@ -898,7 +900,8 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyManeuverOverr
|
||||
<< " maneuver overrides...";
|
||||
TIMER_START(identify_maneuver_override_ways);
|
||||
|
||||
const auto mark_ids = [&](auto const &external_maneuver_override) {
|
||||
const auto mark_ids = [&](auto const &external_maneuver_override)
|
||||
{
|
||||
NodesOfWay dummy_segment{MAX_OSM_WAYID, {MAX_OSM_NODEID, MAX_OSM_NODEID}};
|
||||
const auto &turn_path = external_maneuver_override.turn_path;
|
||||
maneuver_override_ways[turn_path.From()] = dummy_segment;
|
||||
@@ -918,7 +921,8 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyManeuverOverr
|
||||
std::for_each(
|
||||
external_maneuver_overrides_list.begin(), external_maneuver_overrides_list.end(), mark_ids);
|
||||
|
||||
const auto set_ids = [&](size_t way_list_idx, auto const &way_id) {
|
||||
const auto set_ids = [&](size_t way_list_idx, auto const &way_id)
|
||||
{
|
||||
auto itr = maneuver_override_ways.find(way_id);
|
||||
if (itr != maneuver_override_ways.end())
|
||||
{
|
||||
@@ -984,7 +988,8 @@ void ExtractionContainers::PrepareTrafficSignals(
|
||||
|
||||
void ExtractionContainers::PrepareManeuverOverrides(const ReferencedWays &maneuver_override_ways)
|
||||
{
|
||||
auto const osm_node_to_internal_nbn = [&](auto const osm_node) {
|
||||
auto const osm_node_to_internal_nbn = [&](auto const osm_node)
|
||||
{
|
||||
auto internal = mapExternalToInternalNodeID(
|
||||
used_node_id_list.begin(), used_node_id_list.end(), osm_node);
|
||||
if (internal == SPECIAL_NODEID)
|
||||
@@ -994,8 +999,9 @@ void ExtractionContainers::PrepareManeuverOverrides(const ReferencedWays &maneuv
|
||||
return internal;
|
||||
};
|
||||
|
||||
const auto strings_to_turn_type_and_direction = [](const std::string &turn_string,
|
||||
const std::string &direction_string) {
|
||||
const auto strings_to_turn_type_and_direction =
|
||||
[](const std::string &turn_string, const std::string &direction_string)
|
||||
{
|
||||
auto result = std::make_pair(guidance::TurnType::MaxTurnType,
|
||||
guidance::DirectionModifier::MaxDirectionModifier);
|
||||
|
||||
@@ -1059,7 +1065,8 @@ void ExtractionContainers::PrepareManeuverOverrides(const ReferencedWays &maneuv
|
||||
// Returns true on successful transformation, false in case of invalid references.
|
||||
// Later, the UnresolvedManeuverOverride will be converted into a final ManeuverOverride
|
||||
// once the edge-based-node IDs are generated by the edge-based-graph-factory
|
||||
const auto transform = [&](const auto &external_type, auto &internal_type) {
|
||||
const auto transform = [&](const auto &external_type, auto &internal_type)
|
||||
{
|
||||
if (external_type.turn_path.Type() == TurnPathType::VIA_WAY_TURN_PATH)
|
||||
{
|
||||
auto const &external = external_type.turn_path.AsViaWayPath();
|
||||
@@ -1092,11 +1099,12 @@ void ExtractionContainers::PrepareManeuverOverrides(const ReferencedWays &maneuv
|
||||
};
|
||||
|
||||
const auto transform_into_internal_types =
|
||||
[&](const InputManeuverOverride &external_maneuver_override) {
|
||||
UnresolvedManeuverOverride internal_maneuver_override;
|
||||
if (transform(external_maneuver_override, internal_maneuver_override))
|
||||
internal_maneuver_overrides.push_back(std::move(internal_maneuver_override));
|
||||
};
|
||||
[&](const InputManeuverOverride &external_maneuver_override)
|
||||
{
|
||||
UnresolvedManeuverOverride internal_maneuver_override;
|
||||
if (transform(external_maneuver_override, internal_maneuver_override))
|
||||
internal_maneuver_overrides.push_back(std::move(internal_maneuver_override));
|
||||
};
|
||||
|
||||
// Transforming the overrides into the dedicated internal types
|
||||
{
|
||||
@@ -1124,7 +1132,8 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyRestrictionWa
|
||||
|
||||
// Enter invalid IDs into the map to indicate that we want to find out about
|
||||
// nodes of these ways.
|
||||
const auto mark_ids = [&](auto const &turn_restriction) {
|
||||
const auto mark_ids = [&](auto const &turn_restriction)
|
||||
{
|
||||
NodesOfWay dummy_segment{MAX_OSM_WAYID, {MAX_OSM_NODEID, MAX_OSM_NODEID}};
|
||||
const auto &turn_path = turn_restriction.turn_path;
|
||||
restriction_ways[turn_path.From()] = dummy_segment;
|
||||
@@ -1142,7 +1151,8 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyRestrictionWa
|
||||
std::for_each(restrictions_list.begin(), restrictions_list.end(), mark_ids);
|
||||
|
||||
// Update the values for all ways already sporting SPECIAL_NODEID
|
||||
const auto set_ids = [&](const size_t way_list_idx, auto const &way_id) {
|
||||
const auto set_ids = [&](const size_t way_list_idx, auto const &way_id)
|
||||
{
|
||||
auto itr = restriction_ways.find(way_id);
|
||||
if (itr != restriction_ways.end())
|
||||
{
|
||||
@@ -1178,7 +1188,8 @@ ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTra
|
||||
|
||||
std::unordered_set<OSMNodeID> bidirectional_signals;
|
||||
|
||||
const auto mark_signals = [&](auto const &traffic_signal) {
|
||||
const auto mark_signals = [&](auto const &traffic_signal)
|
||||
{
|
||||
if (traffic_signal.second == TrafficLightClass::DIRECTION_FORWARD ||
|
||||
traffic_signal.second == TrafficLightClass::DIRECTION_REVERSE)
|
||||
{
|
||||
@@ -1193,7 +1204,8 @@ ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTra
|
||||
std::for_each(external_traffic_signals.begin(), external_traffic_signals.end(), mark_signals);
|
||||
|
||||
// Extract all the segments that lead up to unidirectional traffic signals.
|
||||
const auto set_segments = [&](const size_t way_list_idx, auto const & /*unused*/) {
|
||||
const auto set_segments = [&](const size_t way_list_idx, auto const & /*unused*/)
|
||||
{
|
||||
const auto node_start_offset =
|
||||
used_node_id_list.begin() + way_node_id_offsets[way_list_idx];
|
||||
const auto node_end_offset =
|
||||
@@ -1227,7 +1239,9 @@ ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTra
|
||||
util::for_each_indexed(ways_list.cbegin(), ways_list.cend(), set_segments);
|
||||
|
||||
util::for_each_pair(
|
||||
signal_segments, [](const auto pair_a, const auto pair_b) {
|
||||
signal_segments,
|
||||
[](const auto pair_a, const auto pair_b)
|
||||
{
|
||||
if (pair_a.first == pair_b.first)
|
||||
{
|
||||
// If a node is appearing multiple times in this map, then it's ambiguous.
|
||||
@@ -1252,7 +1266,8 @@ ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTra
|
||||
void ExtractionContainers::PrepareRestrictions(const ReferencedWays &restriction_ways)
|
||||
{
|
||||
|
||||
auto const to_internal = [&](auto const osm_node) {
|
||||
auto const to_internal = [&](auto const osm_node)
|
||||
{
|
||||
auto internal = mapExternalToInternalNodeID(
|
||||
used_node_id_list.begin(), used_node_id_list.end(), osm_node);
|
||||
if (internal == SPECIAL_NODEID)
|
||||
@@ -1264,7 +1279,8 @@ void ExtractionContainers::PrepareRestrictions(const ReferencedWays &restriction
|
||||
|
||||
// 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 = [&](const auto &external_type, auto &internal_type) {
|
||||
const auto transform = [&](const auto &external_type, auto &internal_type)
|
||||
{
|
||||
if (external_type.turn_path.Type() == TurnPathType::VIA_WAY_TURN_PATH)
|
||||
{
|
||||
auto const &external = external_type.turn_path.AsViaWayPath();
|
||||
@@ -1293,7 +1309,8 @@ void ExtractionContainers::PrepareRestrictions(const ReferencedWays &restriction
|
||||
return internal_type.Valid();
|
||||
};
|
||||
|
||||
const auto transform_into_internal_types = [&](InputTurnRestriction &external_restriction) {
|
||||
const auto transform_into_internal_types = [&](InputTurnRestriction &external_restriction)
|
||||
{
|
||||
TurnRestriction restriction;
|
||||
if (transform(external_restriction, restriction))
|
||||
{
|
||||
|
||||
+21
-11
@@ -442,9 +442,12 @@ Extractor::ParsedOSMData Extractor::ParseOSMData(ScriptingEnvironment &scripting
|
||||
|
||||
ExtractionRelationContainer relations;
|
||||
|
||||
const auto buffer_reader = [](osmium::io::Reader &reader) {
|
||||
const auto buffer_reader = [](osmium::io::Reader &reader)
|
||||
{
|
||||
return tbb::filter<void, SharedBuffer>(
|
||||
tbb::filter_mode::serial_in_order, [&reader](tbb::flow_control &fc) {
|
||||
tbb::filter_mode::serial_in_order,
|
||||
[&reader](tbb::flow_control &fc)
|
||||
{
|
||||
if (auto buffer = reader.read())
|
||||
{
|
||||
return std::make_shared<osmium::memory::Buffer>(std::move(buffer));
|
||||
@@ -466,7 +469,9 @@ Extractor::ParsedOSMData Extractor::ParseOSMData(ScriptingEnvironment &scripting
|
||||
osmium_location_handler_type location_handler(location_cache);
|
||||
|
||||
tbb::filter<SharedBuffer, SharedBuffer> location_cacher(
|
||||
tbb::filter_mode::serial_in_order, [&location_handler](SharedBuffer buffer) {
|
||||
tbb::filter_mode::serial_in_order,
|
||||
[&location_handler](SharedBuffer buffer)
|
||||
{
|
||||
osmium::apply(buffer->begin(), buffer->end(), location_handler);
|
||||
return buffer;
|
||||
});
|
||||
@@ -475,7 +480,8 @@ Extractor::ParsedOSMData Extractor::ParseOSMData(ScriptingEnvironment &scripting
|
||||
tbb::filter<SharedBuffer, ParsedBuffer> buffer_transformer(
|
||||
tbb::filter_mode::parallel,
|
||||
// NOLINTNEXTLINE(performance-unnecessary-value-param)
|
||||
[&](const SharedBuffer buffer) {
|
||||
[&](const SharedBuffer buffer)
|
||||
{
|
||||
ParsedBuffer parsed_buffer;
|
||||
parsed_buffer.buffer = buffer;
|
||||
scripting_environment.ProcessElements(*buffer,
|
||||
@@ -495,7 +501,9 @@ Extractor::ParsedOSMData Extractor::ParseOSMData(ScriptingEnvironment &scripting
|
||||
unsigned number_of_restrictions = 0;
|
||||
unsigned number_of_maneuver_overrides = 0;
|
||||
tbb::filter<ParsedBuffer, void> buffer_storage(
|
||||
tbb::filter_mode::serial_in_order, [&](const ParsedBuffer &parsed_buffer) {
|
||||
tbb::filter_mode::serial_in_order,
|
||||
[&](const ParsedBuffer &parsed_buffer)
|
||||
{
|
||||
number_of_nodes += parsed_buffer.resulting_nodes.size();
|
||||
// put parsed objects thru extractor callbacks
|
||||
for (const auto &result : parsed_buffer.resulting_nodes)
|
||||
@@ -524,7 +532,8 @@ Extractor::ParsedOSMData Extractor::ParseOSMData(ScriptingEnvironment &scripting
|
||||
tbb::filter<SharedBuffer, std::shared_ptr<ExtractionRelationContainer>> buffer_relation_cache(
|
||||
tbb::filter_mode::parallel,
|
||||
// NOLINTNEXTLINE(performance-unnecessary-value-param)
|
||||
[&](const SharedBuffer buffer) {
|
||||
[&](const SharedBuffer buffer)
|
||||
{
|
||||
if (!buffer)
|
||||
return std::shared_ptr<ExtractionRelationContainer>{};
|
||||
|
||||
@@ -562,7 +571,8 @@ Extractor::ParsedOSMData Extractor::ParseOSMData(ScriptingEnvironment &scripting
|
||||
tbb::filter<std::shared_ptr<ExtractionRelationContainer>, void> buffer_storage_relation(
|
||||
tbb::filter_mode::serial_in_order,
|
||||
// NOLINTNEXTLINE(performance-unnecessary-value-param)
|
||||
[&](const std::shared_ptr<ExtractionRelationContainer> parsed_relations) {
|
||||
[&](const std::shared_ptr<ExtractionRelationContainer> parsed_relations)
|
||||
{
|
||||
number_of_relations += parsed_relations->GetRelationsNum();
|
||||
relations.Merge(std::move(*parsed_relations));
|
||||
});
|
||||
@@ -749,7 +759,8 @@ EdgeID Extractor::BuildEdgeExpandedGraph(
|
||||
segregated_edges,
|
||||
turn_lane_map);
|
||||
|
||||
const auto create_edge_based_edges = [&]() {
|
||||
const auto create_edge_based_edges = [&]()
|
||||
{
|
||||
// scoped to release intermediate data structures right after the call
|
||||
RestrictionMap unconditional_node_restriction_map(restriction_graph);
|
||||
ConditionalRestrictionMap conditional_node_restriction_map(restriction_graph);
|
||||
@@ -795,9 +806,8 @@ void Extractor::BuildRTree(std::vector<EdgeBasedNodeSegment> edge_based_node_seg
|
||||
auto start_point_count = std::accumulate(edge_based_node_segments.begin(),
|
||||
edge_based_node_segments.end(),
|
||||
0,
|
||||
[](const size_t so_far, const auto &segment) {
|
||||
return so_far + (segment.is_startpoint ? 1 : 0);
|
||||
});
|
||||
[](const size_t so_far, const auto &segment)
|
||||
{ return so_far + (segment.is_startpoint ? 1 : 0); });
|
||||
if (start_point_count == 0)
|
||||
{
|
||||
throw util::exception("There are no snappable edges left after processing. Are you "
|
||||
|
||||
@@ -140,7 +140,8 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
InternalExtractorEdge::WeightData forward_weight_data;
|
||||
InternalExtractorEdge::WeightData backward_weight_data;
|
||||
|
||||
const auto toValueByEdgeOrByMeter = [&nodes](const double by_way, const double by_meter) {
|
||||
const auto toValueByEdgeOrByMeter = [&nodes](const double by_way, const double by_meter)
|
||||
{
|
||||
using Value = detail::ByEdgeOrByMeterValue;
|
||||
// get value by weight per edge
|
||||
if (by_way >= 0)
|
||||
@@ -194,7 +195,8 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
}
|
||||
}
|
||||
|
||||
const auto classStringToMask = [this](const std::string &class_name) {
|
||||
const auto classStringToMask = [this](const std::string &class_name)
|
||||
{
|
||||
auto iter = classes_map.find(class_name);
|
||||
if (iter == classes_map.end())
|
||||
{
|
||||
@@ -212,7 +214,8 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
return iter->second;
|
||||
}
|
||||
};
|
||||
const auto classesToMask = [&](const auto &classes) {
|
||||
const auto classesToMask = [&](const auto &classes)
|
||||
{
|
||||
ClassData mask = 0;
|
||||
for (const auto &name_and_flag : classes)
|
||||
{
|
||||
@@ -232,7 +235,8 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
const ClassData forward_classes = classesToMask(parsed_way.forward_classes);
|
||||
const ClassData backward_classes = classesToMask(parsed_way.backward_classes);
|
||||
|
||||
const auto laneStringToDescription = [](const std::string &lane_string) -> TurnLaneDescription {
|
||||
const auto laneStringToDescription = [](const std::string &lane_string) -> TurnLaneDescription
|
||||
{
|
||||
if (lane_string.empty())
|
||||
return {};
|
||||
|
||||
@@ -332,7 +336,8 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
road_classification.SetNumberOfLanes(std::max(road_deduced_num_lanes, // len(turn:lanes)
|
||||
road_classification.GetNumberOfLanes()));
|
||||
|
||||
const auto GetNameID = [this, &parsed_way](bool is_forward) -> NameID {
|
||||
const auto GetNameID = [this, &parsed_way](bool is_forward) -> NameID
|
||||
{
|
||||
const std::string &ref = is_forward ? parsed_way.forward_ref : parsed_way.backward_ref;
|
||||
// Get the unique identifier for the street name, destination, and ref
|
||||
const auto name_iterator = string_map.find(MapKey(parsed_way.name,
|
||||
@@ -418,30 +423,31 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
forward_classes,
|
||||
parsed_way.forward_travel_mode,
|
||||
parsed_way.is_left_hand_driving});
|
||||
util::for_each_pair(
|
||||
nodes, [&](const osmium::NodeRef &first_node, const osmium::NodeRef &last_node) {
|
||||
NodeBasedEdgeWithOSM edge = {
|
||||
OSMNodeID{static_cast<std::uint64_t>(first_node.ref())},
|
||||
OSMNodeID{static_cast<std::uint64_t>(last_node.ref())},
|
||||
{0}, // weight
|
||||
{0}, // duration
|
||||
{0}, // distance
|
||||
{}, // geometry id
|
||||
static_cast<AnnotationID>(annotation_data_id),
|
||||
{true,
|
||||
in_backward_direction && !split_edge,
|
||||
split_edge,
|
||||
parsed_way.roundabout,
|
||||
parsed_way.circular,
|
||||
parsed_way.is_startpoint,
|
||||
parsed_way.forward_restricted,
|
||||
road_classification,
|
||||
parsed_way.highway_turn_classification,
|
||||
parsed_way.access_turn_classification}};
|
||||
util::for_each_pair(nodes,
|
||||
[&](const osmium::NodeRef &first_node, const osmium::NodeRef &last_node)
|
||||
{
|
||||
NodeBasedEdgeWithOSM edge = {
|
||||
OSMNodeID{static_cast<std::uint64_t>(first_node.ref())},
|
||||
OSMNodeID{static_cast<std::uint64_t>(last_node.ref())},
|
||||
{0}, // weight
|
||||
{0}, // duration
|
||||
{0}, // distance
|
||||
{}, // geometry id
|
||||
static_cast<AnnotationID>(annotation_data_id),
|
||||
{true,
|
||||
in_backward_direction && !split_edge,
|
||||
split_edge,
|
||||
parsed_way.roundabout,
|
||||
parsed_way.circular,
|
||||
parsed_way.is_startpoint,
|
||||
parsed_way.forward_restricted,
|
||||
road_classification,
|
||||
parsed_way.highway_turn_classification,
|
||||
parsed_way.access_turn_classification}};
|
||||
|
||||
external_memory.all_edges_list.push_back(
|
||||
InternalExtractorEdge(edge, forward_weight_data, forward_duration_data, {}));
|
||||
});
|
||||
external_memory.all_edges_list.push_back(InternalExtractorEdge(
|
||||
edge, forward_weight_data, forward_duration_data, {}));
|
||||
});
|
||||
}
|
||||
|
||||
if (in_backward_direction && (!in_forward_direction || split_edge))
|
||||
@@ -452,38 +458,38 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
backward_classes,
|
||||
parsed_way.backward_travel_mode,
|
||||
parsed_way.is_left_hand_driving});
|
||||
util::for_each_pair(
|
||||
nodes, [&](const osmium::NodeRef &first_node, const osmium::NodeRef &last_node) {
|
||||
NodeBasedEdgeWithOSM edge = {
|
||||
OSMNodeID{static_cast<std::uint64_t>(first_node.ref())},
|
||||
OSMNodeID{static_cast<std::uint64_t>(last_node.ref())},
|
||||
{0}, // weight
|
||||
{0}, // duration
|
||||
{0}, // distance
|
||||
{}, // geometry id
|
||||
static_cast<AnnotationID>(annotation_data_id),
|
||||
{false,
|
||||
true,
|
||||
split_edge,
|
||||
parsed_way.roundabout,
|
||||
parsed_way.circular,
|
||||
parsed_way.is_startpoint,
|
||||
parsed_way.backward_restricted,
|
||||
road_classification,
|
||||
parsed_way.highway_turn_classification,
|
||||
parsed_way.access_turn_classification}};
|
||||
util::for_each_pair(nodes,
|
||||
[&](const osmium::NodeRef &first_node, const osmium::NodeRef &last_node)
|
||||
{
|
||||
NodeBasedEdgeWithOSM edge = {
|
||||
OSMNodeID{static_cast<std::uint64_t>(first_node.ref())},
|
||||
OSMNodeID{static_cast<std::uint64_t>(last_node.ref())},
|
||||
{0}, // weight
|
||||
{0}, // duration
|
||||
{0}, // distance
|
||||
{}, // geometry id
|
||||
static_cast<AnnotationID>(annotation_data_id),
|
||||
{false,
|
||||
true,
|
||||
split_edge,
|
||||
parsed_way.roundabout,
|
||||
parsed_way.circular,
|
||||
parsed_way.is_startpoint,
|
||||
parsed_way.backward_restricted,
|
||||
road_classification,
|
||||
parsed_way.highway_turn_classification,
|
||||
parsed_way.access_turn_classification}};
|
||||
|
||||
external_memory.all_edges_list.push_back(
|
||||
InternalExtractorEdge(edge, backward_weight_data, backward_duration_data, {}));
|
||||
});
|
||||
external_memory.all_edges_list.push_back(InternalExtractorEdge(
|
||||
edge, backward_weight_data, backward_duration_data, {}));
|
||||
});
|
||||
}
|
||||
|
||||
std::transform(nodes.begin(),
|
||||
nodes.end(),
|
||||
std::back_inserter(external_memory.used_node_id_list),
|
||||
[](const osmium::NodeRef &ref) {
|
||||
return OSMNodeID{static_cast<std::uint64_t>(ref.ref())};
|
||||
});
|
||||
[](const osmium::NodeRef &ref)
|
||||
{ return OSMNodeID{static_cast<std::uint64_t>(ref.ref())}; });
|
||||
|
||||
auto way_id = OSMWayID{static_cast<std::uint64_t>(input_way.id())};
|
||||
external_memory.ways_list.push_back(way_id);
|
||||
|
||||
@@ -37,7 +37,8 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
// restriction path.
|
||||
std::unordered_set<NodeID> incompressible_via_nodes;
|
||||
|
||||
const auto remember_via_nodes = [&](const auto &restriction) {
|
||||
const auto remember_via_nodes = [&](const auto &restriction)
|
||||
{
|
||||
if (restriction.turn_path.Type() == TurnPathType::VIA_NODE_TURN_PATH)
|
||||
{
|
||||
incompressible_via_nodes.insert(restriction.turn_path.AsViaNodePath().via);
|
||||
@@ -186,16 +187,17 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
*/
|
||||
const auto selectAnnotation =
|
||||
[&node_data_container](const AnnotationID front_annotation,
|
||||
const AnnotationID back_annotation) {
|
||||
// A lane has tags: u - (front) - v - (back) - w
|
||||
// During contraction, we keep only one of the tags. Usually the one closer
|
||||
// to the intersection is preferred. If its empty, however, we keep the
|
||||
// non-empty one
|
||||
if (node_data_container[back_annotation].lane_description_id ==
|
||||
INVALID_LANE_DESCRIPTIONID)
|
||||
return front_annotation;
|
||||
return back_annotation;
|
||||
};
|
||||
const AnnotationID back_annotation)
|
||||
{
|
||||
// A lane has tags: u - (front) - v - (back) - w
|
||||
// During contraction, we keep only one of the tags. Usually the one closer
|
||||
// to the intersection is preferred. If its empty, however, we keep the
|
||||
// non-empty one
|
||||
if (node_data_container[back_annotation].lane_description_id ==
|
||||
INVALID_LANE_DESCRIPTIONID)
|
||||
return front_annotation;
|
||||
return back_annotation;
|
||||
};
|
||||
|
||||
graph.GetEdgeData(forward_e1).annotation_data = selectAnnotation(
|
||||
fwd_edge_data1.annotation_data, fwd_edge_data2.annotation_data);
|
||||
@@ -250,10 +252,10 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
roads_on_the_left);
|
||||
scripting_environment.ProcessTurn(extraction_turn);
|
||||
|
||||
auto update_direction_penalty = [&extraction_turn, weight_multiplier](
|
||||
bool signal,
|
||||
EdgeDuration &duration_penalty,
|
||||
EdgeWeight &weight_penalty) {
|
||||
auto update_direction_penalty =
|
||||
[&extraction_turn, weight_multiplier](
|
||||
bool signal, EdgeDuration &duration_penalty, EdgeWeight &weight_penalty)
|
||||
{
|
||||
if (signal)
|
||||
{
|
||||
duration_penalty = to_alias<EdgeDuration>(extraction_turn.duration *
|
||||
@@ -303,7 +305,8 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
auto apply_e2_to_e1 = [&graph](EdgeID edge1,
|
||||
EdgeID edge2,
|
||||
EdgeWeight &weight_penalty,
|
||||
EdgeDuration &duration_penalty) {
|
||||
EdgeDuration &duration_penalty)
|
||||
{
|
||||
auto &edge1_data = graph.GetEdgeData(edge1);
|
||||
const auto &edge2_data = graph.GetEdgeData(edge2);
|
||||
edge1_data.weight += edge2_data.weight;
|
||||
@@ -345,7 +348,8 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
// Set a dummy empty penalty weight if opposite value exists.
|
||||
auto set_dummy_penalty = [](EdgeWeight &weight_penalty,
|
||||
EdgeDuration &duration_penalty,
|
||||
EdgeWeight &other_weight_penalty) {
|
||||
EdgeWeight &other_weight_penalty)
|
||||
{
|
||||
if (weight_penalty == INVALID_EDGE_WEIGHT &&
|
||||
other_weight_penalty != INVALID_EDGE_WEIGHT)
|
||||
{
|
||||
|
||||
@@ -88,9 +88,8 @@ util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate(
|
||||
std::vector<util::Coordinate> coordinates) const
|
||||
{
|
||||
// check if the coordinate is equal to the interseciton coordinate
|
||||
const auto not_same_as_start = [&](const util::Coordinate coordinate) {
|
||||
return node_coordinates[traversed_in_reverse ? to_node : intersection_node] != coordinate;
|
||||
};
|
||||
const auto not_same_as_start = [&](const util::Coordinate coordinate)
|
||||
{ return node_coordinates[traversed_in_reverse ? to_node : intersection_node] != coordinate; };
|
||||
// this is only used for debug purposes in assertions. We don't want warnings about it
|
||||
(void)not_same_as_start;
|
||||
|
||||
@@ -176,7 +175,8 @@ util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate(
|
||||
* information on the very first turn angle (requires knowledge about previous road) and the
|
||||
* respective lane widths.
|
||||
*/
|
||||
const bool first_coordinate_is_far_away = [&first_distance, considered_lanes]() {
|
||||
const bool first_coordinate_is_far_away = [&first_distance, considered_lanes]()
|
||||
{
|
||||
const auto required_distance =
|
||||
considered_lanes * ASSUMED_LANE_WIDTH + LOOKAHEAD_DISTANCE_WITHOUT_LANES;
|
||||
return first_distance > required_distance;
|
||||
@@ -256,7 +256,8 @@ util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate(
|
||||
* possible negative:
|
||||
* http://www.openstreetmap.org/search?query=52.514503%2013.32252#map=19/52.51450/13.32252
|
||||
*/
|
||||
const auto straight_distance_and_index = [&]() {
|
||||
const auto straight_distance_and_index = [&]()
|
||||
{
|
||||
auto straight_distance = segment_distances[1];
|
||||
|
||||
std::size_t index;
|
||||
@@ -276,7 +277,8 @@ util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate(
|
||||
const auto straight_distance = straight_distance_and_index.second;
|
||||
const auto straight_index = straight_distance_and_index.first;
|
||||
|
||||
const bool starts_of_without_turn = [&]() {
|
||||
const bool starts_of_without_turn = [&]()
|
||||
{
|
||||
return straight_distance >=
|
||||
considered_lanes * ASSUMED_LANE_WIDTH + LOOKAHEAD_DISTANCE_WITHOUT_LANES;
|
||||
}();
|
||||
@@ -435,7 +437,8 @@ CoordinateExtractor::ExtractCoordinateAtLength(const double distance,
|
||||
auto length_cache_itr = length_cache.begin() + 1;
|
||||
// find the end of the segment containing the coordinate which is at least distance away
|
||||
const auto find_coordinate_at_distance = [distance, &accumulated_distance, &length_cache_itr](
|
||||
const util::Coordinate /*coordinate*/) mutable {
|
||||
const util::Coordinate /*coordinate*/) mutable
|
||||
{
|
||||
const auto result = (accumulated_distance + *length_cache_itr) >= distance;
|
||||
if (!result)
|
||||
{
|
||||
@@ -468,18 +471,19 @@ util::Coordinate CoordinateExtractor::ExtractCoordinateAtLength(
|
||||
// checks (via its state) for an accumulated distance
|
||||
const auto coordinate_at_distance =
|
||||
[distance, &accumulated_distance, last_coordinate = coordinates.front()](
|
||||
const util::Coordinate coordinate) mutable {
|
||||
const double segment_distance =
|
||||
util::coordinate_calculation::greatCircleDistance(last_coordinate, coordinate);
|
||||
const auto result = (accumulated_distance + segment_distance) >= distance;
|
||||
if (!result)
|
||||
{
|
||||
accumulated_distance += segment_distance;
|
||||
last_coordinate = coordinate;
|
||||
}
|
||||
const util::Coordinate coordinate) mutable
|
||||
{
|
||||
const double segment_distance =
|
||||
util::coordinate_calculation::greatCircleDistance(last_coordinate, coordinate);
|
||||
const auto result = (accumulated_distance + segment_distance) >= distance;
|
||||
if (!result)
|
||||
{
|
||||
accumulated_distance += segment_distance;
|
||||
last_coordinate = coordinate;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
return result;
|
||||
};
|
||||
|
||||
// find the begin of the segment containing the coordinate
|
||||
const auto coordinate_after =
|
||||
@@ -514,9 +518,8 @@ util::Coordinate CoordinateExtractor::GetCoordinateCloseToTurn(const NodeID from
|
||||
// the compressed edges contain node ids, we transfer them to coordinates accessing the
|
||||
// node_coordinates array
|
||||
const auto compressedGeometryToCoordinate =
|
||||
[this](const CompressedEdgeContainer::OnewayCompressedEdge &compressed_edge) {
|
||||
return node_coordinates[compressed_edge.node_id];
|
||||
};
|
||||
[this](const CompressedEdgeContainer::OnewayCompressedEdge &compressed_edge)
|
||||
{ return node_coordinates[compressed_edge.node_id]; };
|
||||
|
||||
// return the first coordinate that is reasonably far away from the start node
|
||||
const util::Coordinate start_coordinate = node_coordinates[start_node];
|
||||
@@ -526,10 +529,11 @@ util::Coordinate CoordinateExtractor::GetCoordinateCloseToTurn(const NodeID from
|
||||
// away from the first entry
|
||||
const auto far_enough_away =
|
||||
[start_coordinate, compressedGeometryToCoordinate](
|
||||
const CompressedEdgeContainer::OnewayCompressedEdge &compressed_edge) {
|
||||
return util::coordinate_calculation::greatCircleDistance(
|
||||
compressedGeometryToCoordinate(compressed_edge), start_coordinate) > 1;
|
||||
};
|
||||
const CompressedEdgeContainer::OnewayCompressedEdge &compressed_edge)
|
||||
{
|
||||
return util::coordinate_calculation::greatCircleDistance(
|
||||
compressedGeometryToCoordinate(compressed_edge), start_coordinate) > 1;
|
||||
};
|
||||
|
||||
// find the first coordinate, that is at least unequal to the begin of the edge
|
||||
if (traversed_in_reverse)
|
||||
@@ -614,7 +618,8 @@ CoordinateExtractor::GetMaxDeviation(std::vector<util::Coordinate>::const_iterat
|
||||
const util::Coordinate straight_end) const
|
||||
{
|
||||
// compute the deviation of a single coordinate from a straight line
|
||||
auto get_single_deviation = [&](const util::Coordinate coordinate) {
|
||||
auto get_single_deviation = [&](const util::Coordinate coordinate)
|
||||
{
|
||||
// find the projected coordinate
|
||||
auto coord_between = util::coordinate_calculation::projectPointOnSegment(
|
||||
straight_begin, straight_end, coordinate)
|
||||
@@ -626,10 +631,11 @@ CoordinateExtractor::GetMaxDeviation(std::vector<util::Coordinate>::const_iterat
|
||||
|
||||
// note: we don't accumulate here but rather compute the maximum. The functor passed here is not
|
||||
// summing up anything.
|
||||
return std::accumulate(
|
||||
range_begin, range_end, 0.0, [&](const double current, const util::Coordinate coordinate) {
|
||||
return std::max(current, get_single_deviation(coordinate));
|
||||
});
|
||||
return std::accumulate(range_begin,
|
||||
range_end,
|
||||
0.0,
|
||||
[&](const double current, const util::Coordinate coordinate)
|
||||
{ return std::max(current, get_single_deviation(coordinate)); });
|
||||
}
|
||||
|
||||
bool CoordinateExtractor::IsCurve(const std::vector<util::Coordinate> &coordinates,
|
||||
@@ -645,7 +651,8 @@ bool CoordinateExtractor::IsCurve(const std::vector<util::Coordinate> &coordinat
|
||||
return true;
|
||||
|
||||
// TODO we might have to fix this to better compensate for errors due to repeated coordinates
|
||||
const bool takes_an_actual_turn = [&coordinates]() {
|
||||
const bool takes_an_actual_turn = [&coordinates]()
|
||||
{
|
||||
const auto begin_bearing =
|
||||
util::coordinate_calculation::bearing(coordinates[0], coordinates[1]);
|
||||
const auto end_bearing = util::coordinate_calculation::bearing(
|
||||
@@ -660,7 +667,8 @@ bool CoordinateExtractor::IsCurve(const std::vector<util::Coordinate> &coordinat
|
||||
|
||||
const auto get_deviation = [](const util::Coordinate line_start,
|
||||
const util::Coordinate line_end,
|
||||
const util::Coordinate point) {
|
||||
const util::Coordinate point)
|
||||
{
|
||||
// find the projected coordinate
|
||||
auto coord_between =
|
||||
util::coordinate_calculation::projectPointOnSegment(line_start, line_end, point).second;
|
||||
@@ -669,19 +677,22 @@ bool CoordinateExtractor::IsCurve(const std::vector<util::Coordinate> &coordinat
|
||||
};
|
||||
|
||||
// a curve needs to be on one side of the coordinate array
|
||||
const bool all_same_side = [&]() {
|
||||
const bool all_same_side = [&]()
|
||||
{
|
||||
if (coordinates.size() <= 3)
|
||||
return true;
|
||||
|
||||
const bool ccw = util::coordinate_calculation::isCCW(
|
||||
coordinates.front(), coordinates.back(), coordinates[1]);
|
||||
|
||||
return std::all_of(
|
||||
coordinates.begin() + 2, coordinates.end() - 1, [&](const util::Coordinate coordinate) {
|
||||
const bool compare_ccw = util::coordinate_calculation::isCCW(
|
||||
coordinates.front(), coordinates.back(), coordinate);
|
||||
return ccw == compare_ccw;
|
||||
});
|
||||
return std::all_of(coordinates.begin() + 2,
|
||||
coordinates.end() - 1,
|
||||
[&](const util::Coordinate coordinate)
|
||||
{
|
||||
const bool compare_ccw = util::coordinate_calculation::isCCW(
|
||||
coordinates.front(), coordinates.back(), coordinate);
|
||||
return ccw == compare_ccw;
|
||||
});
|
||||
}();
|
||||
|
||||
if (!all_same_side)
|
||||
@@ -694,13 +705,16 @@ bool CoordinateExtractor::IsCurve(const std::vector<util::Coordinate> &coordinat
|
||||
double maximum_deviation = 0;
|
||||
|
||||
std::tie(has_up_down_deviation, maximum_deviation_index, maximum_deviation) =
|
||||
[&coordinates, get_deviation]() -> std::tuple<bool, std::size_t, double> {
|
||||
const auto increasing = [&](const util::Coordinate lhs, const util::Coordinate rhs) {
|
||||
[&coordinates, get_deviation]() -> std::tuple<bool, std::size_t, double>
|
||||
{
|
||||
const auto increasing = [&](const util::Coordinate lhs, const util::Coordinate rhs)
|
||||
{
|
||||
return get_deviation(coordinates.front(), coordinates.back(), lhs) <
|
||||
get_deviation(coordinates.front(), coordinates.back(), rhs);
|
||||
};
|
||||
|
||||
const auto decreasing = [&](const util::Coordinate lhs, const util::Coordinate rhs) {
|
||||
const auto decreasing = [&](const util::Coordinate lhs, const util::Coordinate rhs)
|
||||
{
|
||||
return get_deviation(coordinates.front(), coordinates.back(), lhs) >
|
||||
get_deviation(coordinates.front(), coordinates.back(), rhs);
|
||||
};
|
||||
@@ -744,7 +758,8 @@ bool CoordinateExtractor::IsCurve(const std::vector<util::Coordinate> &coordinat
|
||||
|
||||
BOOST_ASSERT(coordinates.size() >= 3);
|
||||
// Compute all turn angles along the road
|
||||
const auto turn_angles = [coordinates]() {
|
||||
const auto turn_angles = [coordinates]()
|
||||
{
|
||||
std::vector<double> turn_angles;
|
||||
turn_angles.reserve(coordinates.size() - 2);
|
||||
for (std::size_t index = 0; index + 2 < coordinates.size(); ++index)
|
||||
@@ -755,10 +770,9 @@ bool CoordinateExtractor::IsCurve(const std::vector<util::Coordinate> &coordinat
|
||||
return turn_angles;
|
||||
}();
|
||||
|
||||
const bool curve_is_valid = [&turn_angles,
|
||||
&segment_distances,
|
||||
&segment_length,
|
||||
&considered_lane_width]() {
|
||||
const bool curve_is_valid =
|
||||
[&turn_angles, &segment_distances, &segment_length, &considered_lane_width]()
|
||||
{
|
||||
// internal state for our lamdae
|
||||
bool last_was_straight = false;
|
||||
// a turn angle represents two segments between three coordinates. We initialize the
|
||||
@@ -769,8 +783,9 @@ bool CoordinateExtractor::IsCurve(const std::vector<util::Coordinate> &coordinat
|
||||
// every call to the lamda requires a call to the distances. They need to be aligned
|
||||
BOOST_ASSERT(segment_distances.size() == turn_angles.size() + 2);
|
||||
|
||||
const auto detect_invalid_curve = [&](const double previous_angle,
|
||||
const double current_angle) {
|
||||
const auto detect_invalid_curve =
|
||||
[&](const double previous_angle, const double current_angle)
|
||||
{
|
||||
const auto both_actually_turn =
|
||||
(util::angularDeviation(previous_angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE) &&
|
||||
(util::angularDeviation(current_angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE);
|
||||
@@ -822,7 +837,8 @@ bool CoordinateExtractor::IsDirectOffset(const std::vector<util::Coordinate> &co
|
||||
const std::uint8_t considered_lanes) const
|
||||
{
|
||||
// check if a given length is with half a lane of the assumed lane offset
|
||||
const auto IsCloseToLaneDistance = [considered_lanes](const double width) {
|
||||
const auto IsCloseToLaneDistance = [considered_lanes](const double width)
|
||||
{
|
||||
// a road usually is connected to the middle of the lanes. So the lane-offset has to
|
||||
// consider half to road
|
||||
const auto lane_offset = 0.5 * considered_lanes * ASSUMED_LANE_WIDTH;
|
||||
@@ -856,7 +872,8 @@ bool CoordinateExtractor::IsDirectOffset(const std::vector<util::Coordinate> &co
|
||||
const auto segment_offset_past_thirty_meters =
|
||||
std::find_if(segment_distances.begin() + offset_index,
|
||||
segment_distances.end(),
|
||||
[accumulated_distance = 0.](const auto value) mutable {
|
||||
[accumulated_distance = 0.](const auto value) mutable
|
||||
{
|
||||
accumulated_distance += value;
|
||||
return value >= 30;
|
||||
});
|
||||
@@ -888,20 +905,21 @@ CoordinateExtractor::PrepareLengthCache(const std::vector<util::Coordinate> &coo
|
||||
// sentinel
|
||||
// NOLINTNEXTLINE(bugprone-unused-return-value)
|
||||
// We're only interested in the side effect of the lambda, not the return value
|
||||
[[maybe_unused]] auto _ = std::find_if(
|
||||
std::next(std::begin(coordinates)),
|
||||
std::end(coordinates),
|
||||
[last_coordinate = coordinates.front(),
|
||||
limit,
|
||||
&segment_distances,
|
||||
accumulated_distance = 0.](const util::Coordinate current_coordinate) mutable {
|
||||
const auto distance = util::coordinate_calculation::greatCircleDistance(
|
||||
last_coordinate, current_coordinate);
|
||||
accumulated_distance += distance;
|
||||
last_coordinate = current_coordinate;
|
||||
segment_distances.push_back(distance);
|
||||
return accumulated_distance >= limit;
|
||||
});
|
||||
[[maybe_unused]] auto _ =
|
||||
std::find_if(std::next(std::begin(coordinates)),
|
||||
std::end(coordinates),
|
||||
[last_coordinate = coordinates.front(),
|
||||
limit,
|
||||
&segment_distances,
|
||||
accumulated_distance = 0.](const util::Coordinate current_coordinate) mutable
|
||||
{
|
||||
const auto distance = util::coordinate_calculation::greatCircleDistance(
|
||||
last_coordinate, current_coordinate);
|
||||
accumulated_distance += distance;
|
||||
last_coordinate = current_coordinate;
|
||||
segment_distances.push_back(distance);
|
||||
return accumulated_distance >= limit;
|
||||
});
|
||||
return segment_distances;
|
||||
}
|
||||
|
||||
@@ -916,19 +934,18 @@ CoordinateExtractor::TrimCoordinatesToLength(std::vector<util::Coordinate> coord
|
||||
double distance_to_current_coordinate = 0;
|
||||
std::size_t coordinate_index = 0;
|
||||
|
||||
const auto compute_length =
|
||||
[&coordinate_index, &distance_to_current_coordinate, &coordinates]() {
|
||||
const auto new_distance =
|
||||
distance_to_current_coordinate +
|
||||
util::coordinate_calculation::greatCircleDistance(coordinates[coordinate_index - 1],
|
||||
coordinates[coordinate_index]);
|
||||
return new_distance;
|
||||
};
|
||||
|
||||
const auto read_length_from_cache = [&length_cache, &coordinate_index]() {
|
||||
return length_cache[coordinate_index];
|
||||
const auto compute_length = [&coordinate_index, &distance_to_current_coordinate, &coordinates]()
|
||||
{
|
||||
const auto new_distance =
|
||||
distance_to_current_coordinate +
|
||||
util::coordinate_calculation::greatCircleDistance(coordinates[coordinate_index - 1],
|
||||
coordinates[coordinate_index]);
|
||||
return new_distance;
|
||||
};
|
||||
|
||||
const auto read_length_from_cache = [&length_cache, &coordinate_index]()
|
||||
{ return length_cache[coordinate_index]; };
|
||||
|
||||
bool use_cache = !length_cache.empty();
|
||||
|
||||
if (use_cache && length_cache.back() < desired_length && coordinates.size() >= 2)
|
||||
@@ -1044,8 +1061,9 @@ CoordinateExtractor::SampleCoordinates(const std::vector<util::Coordinate> &coor
|
||||
|
||||
double carry_length = 0., total_length = 0.;
|
||||
// interpolate coordinates as long as we are not past the desired length
|
||||
const auto add_samples_until_length_limit = [&](const util::Coordinate previous_coordinate,
|
||||
const util::Coordinate current_coordinate) {
|
||||
const auto add_samples_until_length_limit =
|
||||
[&](const util::Coordinate previous_coordinate, const util::Coordinate current_coordinate)
|
||||
{
|
||||
// pretend to have found an element and stop the sampling
|
||||
if (total_length > max_sample_length)
|
||||
return true;
|
||||
|
||||
@@ -67,9 +67,8 @@ getEdgeCoordinates(const extractor::CompressedEdgeContainer &compressed_geometri
|
||||
std::transform(geometry.begin(),
|
||||
geometry.end(),
|
||||
std::back_inserter(result),
|
||||
[&node_coordinates](const auto &compressed_edge) {
|
||||
return node_coordinates[compressed_edge.node_id];
|
||||
});
|
||||
[&node_coordinates](const auto &compressed_edge)
|
||||
{ return node_coordinates[compressed_edge.node_id]; });
|
||||
|
||||
// filter duplicated coordinates
|
||||
result.erase(std::unique(result.begin(), result.end()), result.end());
|
||||
@@ -95,7 +94,8 @@ double findClosestOppositeBearing(const IntersectionEdgeGeometries &edge_geometr
|
||||
const auto min = std::min_element(
|
||||
edge_geometries.begin(),
|
||||
edge_geometries.end(),
|
||||
[bearing = util::bearing::reverse(bearing)](const auto &lhs, const auto &rhs) {
|
||||
[bearing = util::bearing::reverse(bearing)](const auto &lhs, const auto &rhs)
|
||||
{
|
||||
return util::angularDeviation(lhs.perceived_bearing, bearing) <
|
||||
util::angularDeviation(rhs.perceived_bearing, bearing);
|
||||
});
|
||||
@@ -128,7 +128,7 @@ std::pair<bool, double> findMergedBearing(const util::NodeBasedDynamicGraph &gra
|
||||
{
|
||||
// In some intersections, turning roads can introduce artificial turns if we merge here.
|
||||
// Consider a scenario like:
|
||||
//
|
||||
//
|
||||
// a . g - f
|
||||
// | .
|
||||
// | .
|
||||
@@ -136,7 +136,7 @@ std::pair<bool, double> findMergedBearing(const util::NodeBasedDynamicGraph &gra
|
||||
// d-b--------e
|
||||
// |
|
||||
// c
|
||||
//
|
||||
//
|
||||
// Merging `bgf` and `be` would introduce an angle, even though d-b-e is perfectly straight
|
||||
// We don't change the angle, if such an opposite road exists
|
||||
return {false, entry.perceived_bearing};
|
||||
@@ -239,9 +239,10 @@ getIntersectionOutgoingGeometries(const util::NodeBasedDynamicGraph &graph,
|
||||
}
|
||||
|
||||
// Sort edges in the clockwise bearings order
|
||||
std::sort(edge_geometries.begin(), edge_geometries.end(), [](const auto &lhs, const auto &rhs) {
|
||||
return lhs.perceived_bearing < rhs.perceived_bearing;
|
||||
});
|
||||
std::sort(edge_geometries.begin(),
|
||||
edge_geometries.end(),
|
||||
[](const auto &lhs, const auto &rhs)
|
||||
{ return lhs.perceived_bearing < rhs.perceived_bearing; });
|
||||
return edge_geometries;
|
||||
}
|
||||
} // namespace
|
||||
@@ -317,9 +318,8 @@ getIntersectionGeometries(const util::NodeBasedDynamicGraph &graph,
|
||||
neighbor_geometries.begin(),
|
||||
std::find_if(neighbor_geometries.begin(),
|
||||
neighbor_geometries.end(),
|
||||
[&graph, &intersection_node](const auto &road) {
|
||||
return graph.GetTarget(road.eid) == intersection_node;
|
||||
}));
|
||||
[&graph, &intersection_node](const auto &road)
|
||||
{ return graph.GetTarget(road.eid) == intersection_node; }));
|
||||
BOOST_ASSERT(static_cast<std::size_t>(neighbor_curr) != neighbor_geometries.size());
|
||||
const auto neighbor_prev = (neighbor_curr + neighbor_edges - 1) % neighbor_edges;
|
||||
const auto neighbor_next = (neighbor_curr + 1) % neighbor_edges;
|
||||
@@ -403,10 +403,11 @@ getIntersectionGeometries(const util::NodeBasedDynamicGraph &graph,
|
||||
|
||||
inline auto findEdge(const IntersectionEdgeGeometries &geometries, const EdgeID &edge)
|
||||
{
|
||||
const auto it = std::lower_bound(
|
||||
geometries.begin(), geometries.end(), edge, [](const auto &geometry, const auto edge) {
|
||||
return geometry.eid < edge;
|
||||
});
|
||||
const auto it =
|
||||
std::lower_bound(geometries.begin(),
|
||||
geometries.end(),
|
||||
edge,
|
||||
[](const auto &geometry, const auto edge) { return geometry.eid < edge; });
|
||||
BOOST_ASSERT(it != geometries.end() && it->eid == edge);
|
||||
return it;
|
||||
}
|
||||
@@ -425,9 +426,10 @@ template <typename RestrictionsRange>
|
||||
bool isTurnRestricted(const RestrictionsRange &restrictions, const NodeID to)
|
||||
{
|
||||
// Check if any of the restrictions would prevent a turn to 'to'
|
||||
return std::any_of(restrictions.begin(), restrictions.end(), [&to](const auto &restriction) {
|
||||
return restriction->IsTurnRestricted(to);
|
||||
});
|
||||
return std::any_of(restrictions.begin(),
|
||||
restrictions.end(),
|
||||
[&to](const auto &restriction)
|
||||
{ return restriction->IsTurnRestricted(to); });
|
||||
}
|
||||
|
||||
bool isTurnAllowed(const util::NodeBasedDynamicGraph &graph,
|
||||
@@ -614,9 +616,8 @@ IntersectionView convertToIntersectionView(const util::NodeBasedDynamicGraph &gr
|
||||
IntersectionViewData uturn{{SPECIAL_EDGEID, 0., 0., 0.}, false, 0.};
|
||||
std::size_t allowed_uturns_number = 0;
|
||||
|
||||
const auto is_uturn = [](const auto angle) {
|
||||
return std::fabs(angle) < std::numeric_limits<double>::epsilon();
|
||||
};
|
||||
const auto is_uturn = [](const auto angle)
|
||||
{ return std::fabs(angle) < std::numeric_limits<double>::epsilon(); };
|
||||
|
||||
for (const auto &outgoing_edge : outgoing_edges)
|
||||
{
|
||||
@@ -665,9 +666,9 @@ IntersectionView convertToIntersectionView(const util::NodeBasedDynamicGraph &gr
|
||||
// 2) use turn angle if the smallest arc between turn and initial angles passes 0°
|
||||
const auto use_turn_angle = (turn_angle > 270 && initial_angle < 90) ||
|
||||
(turn_angle < 90 && initial_angle > 270);
|
||||
const auto adjusted_angle = is_uturn(initial_angle)
|
||||
? (turn_angle > 180. ? 360. : 0.)
|
||||
: use_turn_angle ? turn_angle : initial_angle;
|
||||
const auto adjusted_angle = is_uturn(initial_angle) ? (turn_angle > 180. ? 360. : 0.)
|
||||
: use_turn_angle ? turn_angle
|
||||
: initial_angle;
|
||||
pre_intersection_view.push_back({road, adjusted_angle});
|
||||
}
|
||||
}
|
||||
@@ -680,12 +681,11 @@ IntersectionView convertToIntersectionView(const util::NodeBasedDynamicGraph &gr
|
||||
}
|
||||
|
||||
// Order roads in counter-clockwise order starting from the U-turn edge in the OSM order
|
||||
std::stable_sort(pre_intersection_view.begin(),
|
||||
pre_intersection_view.end(),
|
||||
[](const auto &lhs, const auto &rhs) {
|
||||
return std::tie(lhs.second, lhs.first.angle) <
|
||||
std::tie(rhs.second, rhs.first.angle);
|
||||
});
|
||||
std::stable_sort(
|
||||
pre_intersection_view.begin(),
|
||||
pre_intersection_view.end(),
|
||||
[](const auto &lhs, const auto &rhs)
|
||||
{ return std::tie(lhs.second, lhs.first.angle) < std::tie(rhs.second, rhs.first.angle); });
|
||||
|
||||
// Adjust perceived bearings to keep the initial OSM order with respect to the first edge
|
||||
for (auto curr = pre_intersection_view.begin(), next = std::next(curr);
|
||||
@@ -706,9 +706,8 @@ IntersectionView convertToIntersectionView(const util::NodeBasedDynamicGraph &gr
|
||||
|
||||
auto no_uturn = std::none_of(pre_intersection_view.begin(),
|
||||
pre_intersection_view.end(),
|
||||
[&is_uturn](const IntersectionViewDataWithAngle &road) {
|
||||
return is_uturn(road.first.angle);
|
||||
});
|
||||
[&is_uturn](const IntersectionViewDataWithAngle &road)
|
||||
{ return is_uturn(road.first.angle); });
|
||||
// After all of this, if we now don't have a u-turn, let's add one to the intersection.
|
||||
// This is a hack to fix the triggered assertion ( see:
|
||||
// https://github.com/Project-OSRM/osrm-backend/issues/6218 ). Ideally we would fix this more
|
||||
|
||||
@@ -27,7 +27,8 @@ inline auto makeCheckRoadForName(const NameID name_id,
|
||||
const SuffixTable &suffix_table)
|
||||
{
|
||||
return [name_id, &node_based_graph, &node_data_container, &name_table, &suffix_table](
|
||||
const MergableRoadDetector::MergableRoadData &road) {
|
||||
const MergableRoadDetector::MergableRoadData &road)
|
||||
{
|
||||
// since we filter here, we don't want any other name than the one we are looking for
|
||||
const auto road_name_id =
|
||||
node_data_container
|
||||
@@ -89,9 +90,8 @@ bool MergableRoadDetector::CanMergeRoad(const NodeID intersection_node,
|
||||
* / -- \
|
||||
* a ---- b - - /
|
||||
*/
|
||||
const auto road_target = [this](const MergableRoadData &road) {
|
||||
return node_based_graph.GetTarget(road.eid);
|
||||
};
|
||||
const auto road_target = [this](const MergableRoadData &road)
|
||||
{ return node_based_graph.GetTarget(road.eid); };
|
||||
|
||||
// TODO might have to skip over trivial intersections
|
||||
if (road_target(lhs) == intersection_node || road_target(rhs) == intersection_node)
|
||||
@@ -262,7 +262,8 @@ bool MergableRoadDetector::IsNarrowTriangle(const NodeID intersection_node,
|
||||
if (angularDeviation(connector_turn->angle, ORTHOGONAL_ANGLE) > NARROW_TURN_ANGLE)
|
||||
return false;
|
||||
|
||||
const auto num_lanes = [this](const MergableRoadData &road) {
|
||||
const auto num_lanes = [this](const MergableRoadData &road)
|
||||
{
|
||||
return std::max<std::uint8_t>(
|
||||
node_based_graph.GetEdgeData(road.eid).flags.road_classification.GetNumberOfLanes(), 1);
|
||||
};
|
||||
@@ -308,7 +309,8 @@ bool MergableRoadDetector::IsCircularShape(const NodeID intersection_node,
|
||||
node_restriction_map,
|
||||
barrier_nodes,
|
||||
turn_lanes_data);
|
||||
const auto getCoordinatesAlongWay = [&](const EdgeID edge_id, const double max_length) {
|
||||
const auto getCoordinatesAlongWay = [&](const EdgeID edge_id, const double max_length)
|
||||
{
|
||||
LengthLimitedCoordinateAccumulator accumulator(coordinate_extractor, max_length);
|
||||
SelectStraightmostRoadByNameAndOnlyChoice selector(
|
||||
node_data_container.GetAnnotation(node_based_graph.GetEdgeData(edge_id).annotation_data)
|
||||
@@ -380,7 +382,8 @@ bool MergableRoadDetector::HaveSameDirection(const NodeID intersection_node,
|
||||
node_restriction_map,
|
||||
barrier_nodes,
|
||||
turn_lanes_data);
|
||||
const auto getCoordinatesAlongWay = [&](const EdgeID edge_id, const double max_length) {
|
||||
const auto getCoordinatesAlongWay = [&](const EdgeID edge_id, const double max_length)
|
||||
{
|
||||
LengthLimitedCoordinateAccumulator accumulator(coordinate_extractor, max_length);
|
||||
SelectStraightmostRoadByNameAndOnlyChoice selector(
|
||||
node_data_container.GetAnnotation(node_based_graph.GetEdgeData(edge_id).annotation_data)
|
||||
@@ -424,7 +427,8 @@ bool MergableRoadDetector::HaveSameDirection(const NodeID intersection_node,
|
||||
/* extract the number of lanes for a road
|
||||
* restricts a vector to the last two thirds of the length
|
||||
*/
|
||||
const auto prune = [](auto &data_vector) {
|
||||
const auto prune = [](auto &data_vector)
|
||||
{
|
||||
BOOST_ASSERT(data_vector.size() >= 3);
|
||||
// erase the first third of the vector
|
||||
data_vector.erase(data_vector.begin(), data_vector.begin() + data_vector.size() / 3);
|
||||
@@ -493,7 +497,8 @@ bool MergableRoadDetector::IsTrafficIsland(const NodeID intersection_node,
|
||||
return false;
|
||||
|
||||
// check if all entries at the destination or at the source are the same
|
||||
const auto all_same_name_and_degree_three = [this](const NodeID nid) {
|
||||
const auto all_same_name_and_degree_three = [this](const NodeID nid)
|
||||
{
|
||||
// check if the intersection found has degree three
|
||||
if (node_based_graph.GetOutDegree(nid) != 3)
|
||||
return false;
|
||||
@@ -505,7 +510,8 @@ bool MergableRoadDetector::IsTrafficIsland(const NodeID intersection_node,
|
||||
.GetAnnotation(node_based_graph.GetEdgeData(range.front()).annotation_data)
|
||||
.name_id;
|
||||
|
||||
const auto has_required_name = [this, required_name_id](const auto edge_id) {
|
||||
const auto has_required_name = [this, required_name_id](const auto edge_id)
|
||||
{
|
||||
const auto road_name_id =
|
||||
node_data_container
|
||||
.GetAnnotation(node_based_graph.GetEdgeData(edge_id).annotation_data)
|
||||
@@ -562,7 +568,8 @@ bool MergableRoadDetector::IsLinkRoad(const NodeID intersection_node,
|
||||
barrier_nodes,
|
||||
turn_lanes_data,
|
||||
next_intersection_parameters);
|
||||
const auto extract_name_id = [this](const MergableRoadData &road) {
|
||||
const auto extract_name_id = [this](const MergableRoadData &road)
|
||||
{
|
||||
return node_data_container
|
||||
.GetAnnotation(node_based_graph.GetEdgeData(road.eid).annotation_data)
|
||||
.name_id;
|
||||
|
||||
@@ -74,10 +74,12 @@ boost::optional<EdgeID> SelectRoadByNameOnlyChoiceAndStraightness::operator()(
|
||||
const EdgeBasedNodeDataContainer &node_data_container) const
|
||||
{
|
||||
BOOST_ASSERT(!intersection.empty());
|
||||
const auto comparator = [&](const IntersectionViewData &lhs, const IntersectionViewData &rhs) {
|
||||
const auto comparator = [&](const IntersectionViewData &lhs, const IntersectionViewData &rhs)
|
||||
{
|
||||
// the score of an elemnt results in an ranking preferring valid entries, if required over
|
||||
// invalid requested name_ids over non-requested narrow deviations over non-narrow
|
||||
const auto score = [&](const IntersectionViewData &road) {
|
||||
const auto score = [&](const IntersectionViewData &road)
|
||||
{
|
||||
double result_score = 0;
|
||||
// since angular deviation is limited by 0-180, we add 360 for invalid
|
||||
if (requires_entry && !road.entry_allowed)
|
||||
@@ -127,10 +129,12 @@ boost::optional<EdgeID> SelectStraightmostRoadByNameAndOnlyChoice::operator()(
|
||||
if (intersection.size() == 1)
|
||||
return {};
|
||||
|
||||
const auto comparator = [&](const IntersectionViewData &lhs, const IntersectionViewData &rhs) {
|
||||
const auto comparator = [&](const IntersectionViewData &lhs, const IntersectionViewData &rhs)
|
||||
{
|
||||
// the score of an elemnt results in an ranking preferring valid entries, if required over
|
||||
// invalid requested name_ids over non-requested narrow deviations over non-narrow
|
||||
const auto score = [&](const IntersectionViewData &road) {
|
||||
const auto score = [&](const IntersectionViewData &road)
|
||||
{
|
||||
double result_score = 0;
|
||||
// since angular deviation is limited by 0-180, we add 360 for invalid
|
||||
if (requires_entry && !road.entry_allowed)
|
||||
@@ -149,8 +153,11 @@ boost::optional<EdgeID> SelectStraightmostRoadByNameAndOnlyChoice::operator()(
|
||||
return score(lhs) < score(rhs);
|
||||
};
|
||||
|
||||
const auto count_desired_name =
|
||||
std::count_if(std::begin(intersection), std::end(intersection), [&](const auto &road) {
|
||||
const auto count_desired_name = std::count_if(
|
||||
std::begin(intersection),
|
||||
std::end(intersection),
|
||||
[&](const auto &road)
|
||||
{
|
||||
return node_data_container
|
||||
.GetAnnotation(node_based_graph.GetEdgeData(road.eid).annotation_data)
|
||||
.name_id == desired_name_id;
|
||||
|
||||
@@ -65,7 +65,8 @@ void LocationDependentData::loadLocationDependentData(
|
||||
|
||||
const auto &features_array = geojson["features"].GetArray();
|
||||
|
||||
auto convert_value = [](const auto &property) -> property_t {
|
||||
auto convert_value = [](const auto &property) -> property_t
|
||||
{
|
||||
if (property.IsString())
|
||||
return std::string(property.GetString());
|
||||
if (property.IsNumber())
|
||||
@@ -75,7 +76,8 @@ void LocationDependentData::loadLocationDependentData(
|
||||
return {};
|
||||
};
|
||||
|
||||
auto collect_properties = [this, &convert_value](const auto &object) -> std::size_t {
|
||||
auto collect_properties = [this, &convert_value](const auto &object) -> std::size_t
|
||||
{
|
||||
properties_t object_properties;
|
||||
for (const auto &property : object)
|
||||
{
|
||||
@@ -86,18 +88,21 @@ void LocationDependentData::loadLocationDependentData(
|
||||
return index;
|
||||
};
|
||||
|
||||
auto index_polygon = [this, &bounding_boxes](const auto &rings, auto properties_index) {
|
||||
auto index_polygon = [this, &bounding_boxes](const auto &rings, auto properties_index)
|
||||
{
|
||||
// At least an outer ring in polygon https://tools.ietf.org/html/rfc7946#section-3.1.6
|
||||
BOOST_ASSERT(rings.Size() > 0);
|
||||
|
||||
auto to_point = [](const auto &json) -> point_t {
|
||||
auto to_point = [](const auto &json) -> point_t
|
||||
{
|
||||
util::validateCoordinate(json);
|
||||
const auto &coords = json.GetArray();
|
||||
return {coords[0].GetDouble(), coords[1].GetDouble()};
|
||||
};
|
||||
|
||||
std::vector<segment_t> segments;
|
||||
auto append_ring_segments = [&segments, &to_point](const auto &coordinates_array) -> box_t {
|
||||
auto append_ring_segments = [&segments, &to_point](const auto &coordinates_array) -> box_t
|
||||
{
|
||||
using coord_t = boost::geometry::traits::coordinate_type<point_t>::type;
|
||||
auto x_min = std::numeric_limits<coord_t>::max();
|
||||
auto y_min = std::numeric_limits<coord_t>::max();
|
||||
@@ -208,68 +213,72 @@ LocationDependentData::FindByKey(const std::vector<std::size_t> &property_indexe
|
||||
std::vector<std::size_t> LocationDependentData::GetPropertyIndexes(const point_t &point) const
|
||||
{
|
||||
std::vector<std::size_t> result;
|
||||
auto inserter = [this, &result](const rtree_t::value_type &rtree_entry) {
|
||||
auto inserter = [this, &result](const rtree_t::value_type &rtree_entry)
|
||||
{
|
||||
const auto properties_index = polygons[rtree_entry.second].second;
|
||||
result.push_back(properties_index);
|
||||
};
|
||||
|
||||
// Search the R-tree and collect a Lua table of tags that correspond to the location
|
||||
rtree.query(boost::geometry::index::intersects(point) &&
|
||||
boost::geometry::index::satisfies([this, &point](const rtree_t::value_type &v) {
|
||||
// Simple point-in-polygon algorithm adapted from
|
||||
// https://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
|
||||
rtree.query(
|
||||
boost::geometry::index::intersects(point) &&
|
||||
boost::geometry::index::satisfies(
|
||||
[this, &point](const rtree_t::value_type &v)
|
||||
{
|
||||
// Simple point-in-polygon algorithm adapted from
|
||||
// https://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
|
||||
|
||||
const auto &envelop = v.first;
|
||||
const auto &bands = polygons[v.second].first;
|
||||
const auto &envelop = v.first;
|
||||
const auto &bands = polygons[v.second].first;
|
||||
|
||||
const auto y_min = envelop.min_corner().y();
|
||||
const auto y_max = envelop.max_corner().y();
|
||||
const auto dy = (y_max - y_min) / bands.size();
|
||||
const auto y_min = envelop.min_corner().y();
|
||||
const auto y_max = envelop.max_corner().y();
|
||||
const auto dy = (y_max - y_min) / bands.size();
|
||||
|
||||
std::size_t band = (point.y() - y_min) / dy;
|
||||
if (band >= bands.size())
|
||||
{
|
||||
band = bands.size() - 1;
|
||||
std::size_t band = (point.y() - y_min) / dy;
|
||||
if (band >= bands.size())
|
||||
{
|
||||
band = bands.size() - 1;
|
||||
}
|
||||
|
||||
bool inside = false;
|
||||
|
||||
for (const auto &segment : bands[band])
|
||||
{
|
||||
const auto point_x = point.x(), point_y = point.y();
|
||||
const auto from_x = segment.first.x(), from_y = segment.first.y();
|
||||
const auto to_x = segment.second.x(), to_y = segment.second.y();
|
||||
|
||||
if (to_y == from_y)
|
||||
{ // handle horizontal segments: check if on boundary or skip
|
||||
if ((to_y == point_y) &&
|
||||
(from_x == point_x || (to_x > point_x) != (from_x > point_x)))
|
||||
return true;
|
||||
continue;
|
||||
}
|
||||
|
||||
bool inside = false;
|
||||
|
||||
for (const auto &segment : bands[band])
|
||||
if ((to_y > point_y) != (from_y > point_y))
|
||||
{
|
||||
const auto point_x = point.x(), point_y = point.y();
|
||||
const auto from_x = segment.first.x(), from_y = segment.first.y();
|
||||
const auto to_x = segment.second.x(), to_y = segment.second.y();
|
||||
const auto ax = to_x - from_x;
|
||||
const auto ay = to_y - from_y;
|
||||
const auto tx = point_x - from_x;
|
||||
const auto ty = point_y - from_y;
|
||||
|
||||
if (to_y == from_y)
|
||||
{ // handle horizontal segments: check if on boundary or skip
|
||||
if ((to_y == point_y) &&
|
||||
(from_x == point_x || (to_x > point_x) != (from_x > point_x)))
|
||||
return true;
|
||||
continue;
|
||||
}
|
||||
const auto cross_product = tx * ay - ax * ty;
|
||||
|
||||
if ((to_y > point_y) != (from_y > point_y))
|
||||
if (cross_product == 0)
|
||||
return true;
|
||||
|
||||
if ((ay > 0) == (cross_product > 0))
|
||||
{
|
||||
const auto ax = to_x - from_x;
|
||||
const auto ay = to_y - from_y;
|
||||
const auto tx = point_x - from_x;
|
||||
const auto ty = point_y - from_y;
|
||||
|
||||
const auto cross_product = tx * ay - ax * ty;
|
||||
|
||||
if (cross_product == 0)
|
||||
return true;
|
||||
|
||||
if ((ay > 0) == (cross_product > 0))
|
||||
{
|
||||
inside = !inside;
|
||||
}
|
||||
inside = !inside;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return inside;
|
||||
}),
|
||||
boost::make_function_output_iterator(std::ref(inserter)));
|
||||
return inside;
|
||||
}),
|
||||
boost::make_function_output_iterator(std::ref(inserter)));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -46,27 +46,31 @@ void NodeBasedGraphFactory::BuildCompressedOutputGraph(const std::vector<NodeBas
|
||||
util::NodeBasedDynamicGraphFromEdges(number_of_node_based_nodes, edge_list);
|
||||
|
||||
// check whether the graph is sane
|
||||
BOOST_ASSERT([this]() {
|
||||
for (const auto nbg_node_u : util::irange(0u, compressed_output_graph.GetNumberOfNodes()))
|
||||
BOOST_ASSERT(
|
||||
[this]()
|
||||
{
|
||||
for (EdgeID nbg_edge_id : compressed_output_graph.GetAdjacentEdgeRange(nbg_node_u))
|
||||
for (const auto nbg_node_u :
|
||||
util::irange(0u, compressed_output_graph.GetNumberOfNodes()))
|
||||
{
|
||||
// we cannot have invalid edge-ids in the graph
|
||||
if (nbg_edge_id == SPECIAL_EDGEID)
|
||||
return false;
|
||||
for (EdgeID nbg_edge_id : compressed_output_graph.GetAdjacentEdgeRange(nbg_node_u))
|
||||
{
|
||||
// we cannot have invalid edge-ids in the graph
|
||||
if (nbg_edge_id == SPECIAL_EDGEID)
|
||||
return false;
|
||||
|
||||
const auto nbg_node_v = compressed_output_graph.GetTarget(nbg_edge_id);
|
||||
const auto nbg_node_v = compressed_output_graph.GetTarget(nbg_edge_id);
|
||||
|
||||
auto reverse = compressed_output_graph.FindEdge(nbg_node_v, nbg_node_u);
|
||||
auto reverse = compressed_output_graph.FindEdge(nbg_node_v, nbg_node_u);
|
||||
|
||||
// found an edge that is reversed in both directions, should be two distinct edges
|
||||
if (compressed_output_graph.GetEdgeData(nbg_edge_id).reversed &&
|
||||
compressed_output_graph.GetEdgeData(reverse).reversed)
|
||||
return false;
|
||||
// found an edge that is reversed in both directions, should be two distinct
|
||||
// edges
|
||||
if (compressed_output_graph.GetEdgeData(nbg_edge_id).reversed &&
|
||||
compressed_output_graph.GetEdgeData(reverse).reversed)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}());
|
||||
return true;
|
||||
}());
|
||||
}
|
||||
|
||||
void NodeBasedGraphFactory::Compress(ScriptingEnvironment &scripting_environment,
|
||||
@@ -208,13 +212,15 @@ void NodeBasedGraphFactory::CompressAnnotationData()
|
||||
}
|
||||
|
||||
// remove unreferenced entries, shifting other entries to the front
|
||||
const auto new_end =
|
||||
std::remove_if(annotation_data.begin(), annotation_data.end(), [&](auto const &data) {
|
||||
// both elements are considered equal (to remove the second
|
||||
// one) if the annotation mapping of the second one is
|
||||
// invalid
|
||||
return data.name_id == INVALID_NAMEID;
|
||||
});
|
||||
const auto new_end = std::remove_if(annotation_data.begin(),
|
||||
annotation_data.end(),
|
||||
[&](auto const &data)
|
||||
{
|
||||
// both elements are considered equal (to remove the
|
||||
// second one) if the annotation mapping of the second
|
||||
// one is invalid
|
||||
return data.name_id == INVALID_NAMEID;
|
||||
});
|
||||
|
||||
const auto old_size = annotation_data.size();
|
||||
// remove all remaining elements
|
||||
|
||||
@@ -123,9 +123,10 @@ struct transferBuilder
|
||||
for (const auto &suffix_node : suffix_nodes)
|
||||
{
|
||||
const auto &edges = rg.GetEdges(suffix_node);
|
||||
const auto edge_it = std::find_if(edges.begin(), edges.end(), [&to](const auto &edge) {
|
||||
return edge.node_based_to == to && !edge.is_transfer;
|
||||
});
|
||||
const auto edge_it = std::find_if(
|
||||
edges.begin(),
|
||||
edges.end(),
|
||||
[&to](const auto &edge) { return edge.node_based_to == to && !edge.is_transfer; });
|
||||
if (edge_it != edges.end())
|
||||
{
|
||||
*(new_suffix_it++) = edge_it->target;
|
||||
@@ -154,18 +155,22 @@ struct transferBuilder
|
||||
// the transfer
|
||||
const auto &restrictions = rg.GetRestrictions(cur_node);
|
||||
const auto is_restricted =
|
||||
std::any_of(restrictions.begin(), restrictions.end(), [&](const auto &restriction) {
|
||||
return restriction->IsTurnRestricted(suffix_edge.node_based_to) &&
|
||||
restriction->IsUnconditional();
|
||||
});
|
||||
std::any_of(restrictions.begin(),
|
||||
restrictions.end(),
|
||||
[&](const auto &restriction)
|
||||
{
|
||||
return restriction->IsTurnRestricted(suffix_edge.node_based_to) &&
|
||||
restriction->IsUnconditional();
|
||||
});
|
||||
if (is_restricted)
|
||||
continue;
|
||||
|
||||
const auto &edges = rg.GetEdges(cur_node);
|
||||
// Check that the suffix edge is not a next edge along the current path.
|
||||
const auto can_transfer = std::none_of(edges.begin(), edges.end(), [&](auto &edge) {
|
||||
return edge.node_based_to == suffix_edge.node_based_to;
|
||||
});
|
||||
const auto can_transfer = std::none_of(
|
||||
edges.begin(),
|
||||
edges.end(),
|
||||
[&](auto &edge) { return edge.node_based_to == suffix_edge.node_based_to; });
|
||||
if (can_transfer)
|
||||
{
|
||||
insertEdge(rg,
|
||||
@@ -186,9 +191,9 @@ struct transferBuilder
|
||||
|
||||
this->next_suffixes(from, to);
|
||||
|
||||
std::for_each(suffix_nodes.begin(), suffix_nodes.end(), [&](const auto &suffix_node) {
|
||||
this->add_suffix_transfer(suffix_node);
|
||||
});
|
||||
std::for_each(suffix_nodes.begin(),
|
||||
suffix_nodes.end(),
|
||||
[&](const auto &suffix_node) { this->add_suffix_transfer(suffix_node); });
|
||||
|
||||
for (const auto &suffix_node : suffix_nodes)
|
||||
{
|
||||
@@ -207,7 +212,8 @@ struct transferBuilder
|
||||
template <typename builder_type>
|
||||
void buildGraph(RestrictionGraph &rg, const std::vector<TurnRestriction> &restrictions)
|
||||
{
|
||||
const auto run_builder = [&](const auto &restriction) {
|
||||
const auto run_builder = [&](const auto &restriction)
|
||||
{
|
||||
builder_type builder(rg);
|
||||
|
||||
builder.start(restriction.turn_path.From(), restriction.turn_path.FirstVia());
|
||||
@@ -248,9 +254,9 @@ RestrictionGraph constructRestrictionGraph(const std::vector<TurnRestriction> &t
|
||||
// Start renumbering
|
||||
const auto permutation = util::orderingToPermutation(ordering);
|
||||
util::inplacePermutation(rg.nodes.begin(), rg.nodes.end(), permutation);
|
||||
std::for_each(rg.edges.begin(), rg.edges.end(), [&](auto &edge) {
|
||||
edge.target = permutation[edge.target];
|
||||
});
|
||||
std::for_each(rg.edges.begin(),
|
||||
rg.edges.end(),
|
||||
[&](auto &edge) { edge.target = permutation[edge.target]; });
|
||||
rg.num_via_nodes = std::count(is_via_node.begin(), is_via_node.end(), true);
|
||||
for (auto &entry : rg.via_edge_to_node)
|
||||
{
|
||||
|
||||
@@ -245,7 +245,8 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
"valid",
|
||||
&osmium::Location::valid);
|
||||
|
||||
auto get_location_tag = [](auto &context, const auto &location, const char *key) {
|
||||
auto get_location_tag = [](auto &context, const auto &location, const char *key)
|
||||
{
|
||||
if (context.location_dependent_data.empty())
|
||||
return sol::object(context.state);
|
||||
|
||||
@@ -272,7 +273,8 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
"get_nodes",
|
||||
[](const osmium::Way &way) { return sol::as_table(&way.nodes()); },
|
||||
"get_location_tag",
|
||||
[&context, &get_location_tag](const osmium::Way &way, const char *key) {
|
||||
[&context, &get_location_tag](const osmium::Way &way, const char *key)
|
||||
{
|
||||
// HEURISTIC: use a single node (last) of the way to localize the way
|
||||
// For more complicated scenarios a proper merging of multiple tags
|
||||
// at one or many locations must be provided
|
||||
@@ -292,9 +294,8 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
"version",
|
||||
&osmium::Node::version,
|
||||
"get_location_tag",
|
||||
[&context, &get_location_tag](const osmium::Node &node, const char *key) {
|
||||
return get_location_tag(context, node.location(), key);
|
||||
});
|
||||
[&context, &get_location_tag](const osmium::Node &node, const char *key)
|
||||
{ return get_location_tag(context, node.location(), key); });
|
||||
|
||||
context.state.new_enum("traffic_lights",
|
||||
"none",
|
||||
@@ -310,7 +311,8 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
"ResultNode",
|
||||
"traffic_lights",
|
||||
sol::property([](const ExtractionNode &node) { return node.traffic_lights; },
|
||||
[](ExtractionNode &node, const sol::object &obj) {
|
||||
[](ExtractionNode &node, const sol::object &obj)
|
||||
{
|
||||
if (obj.is<bool>())
|
||||
{
|
||||
// The old approach of assigning a boolean traffic light
|
||||
@@ -361,7 +363,8 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
sol::property(&ExtractionWay::GetName, &ExtractionWay::SetName),
|
||||
"ref", // backward compatibility
|
||||
sol::property(&ExtractionWay::GetForwardRef,
|
||||
[](ExtractionWay &way, const char *ref) {
|
||||
[](ExtractionWay &way, const char *ref)
|
||||
{
|
||||
way.SetForwardRef(ref);
|
||||
way.SetBackwardRef(ref);
|
||||
}),
|
||||
@@ -420,7 +423,8 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
sol::property([](const ExtractionWay &way) { return way.access_turn_classification; },
|
||||
[](ExtractionWay &way, int flag) { way.access_turn_classification = flag; }));
|
||||
|
||||
auto getTypedRefBySol = [](const sol::object &obj) -> ExtractionRelation::OsmIDTyped {
|
||||
auto getTypedRefBySol = [](const sol::object &obj) -> ExtractionRelation::OsmIDTyped
|
||||
{
|
||||
if (obj.is<osmium::Way>())
|
||||
{
|
||||
osmium::Way *way = obj.as<osmium::Way *>();
|
||||
@@ -456,20 +460,19 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
"get_value_by_key",
|
||||
[](ExtractionRelation &rel, const char *key) -> const char * { return rel.GetAttr(key); },
|
||||
"get_role",
|
||||
[&getTypedRefBySol](ExtractionRelation &rel, const sol::object &obj) -> const char * {
|
||||
return rel.GetRole(getTypedRefBySol(obj));
|
||||
});
|
||||
[&getTypedRefBySol](ExtractionRelation &rel, const sol::object &obj) -> const char *
|
||||
{ return rel.GetRole(getTypedRefBySol(obj)); });
|
||||
|
||||
context.state.new_usertype<ExtractionRelationContainer>(
|
||||
"ExtractionRelationContainer",
|
||||
"get_relations",
|
||||
[&getTypedRefBySol](ExtractionRelationContainer &cont, const sol::object &obj)
|
||||
-> const ExtractionRelationContainer::RelationIDList & {
|
||||
return cont.GetRelations(getTypedRefBySol(obj));
|
||||
},
|
||||
-> const ExtractionRelationContainer::RelationIDList &
|
||||
{ return cont.GetRelations(getTypedRefBySol(obj)); },
|
||||
"relation",
|
||||
[](ExtractionRelationContainer &cont, const ExtractionRelation::OsmIDTyped &rel_id)
|
||||
-> const ExtractionRelation & { return cont.GetRelationData(rel_id); });
|
||||
[](ExtractionRelationContainer &cont,
|
||||
const ExtractionRelation::OsmIDTyped &rel_id) -> const ExtractionRelation &
|
||||
{ return cont.GetRelationData(rel_id); });
|
||||
|
||||
context.state.new_usertype<NodeBasedEdgeClassification>(
|
||||
"NodeBasedEdgeClassification",
|
||||
@@ -489,17 +492,14 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
"restricted",
|
||||
sol::property([](NodeBasedEdgeClassification &c) -> bool { return c.restricted; }),
|
||||
"road_classification",
|
||||
sol::property([](NodeBasedEdgeClassification &c) -> RoadClassification {
|
||||
return c.road_classification;
|
||||
}),
|
||||
sol::property([](NodeBasedEdgeClassification &c) -> RoadClassification
|
||||
{ return c.road_classification; }),
|
||||
"highway_turn_classification",
|
||||
sol::property([](NodeBasedEdgeClassification &c) -> uint8_t {
|
||||
return c.highway_turn_classification;
|
||||
}),
|
||||
sol::property([](NodeBasedEdgeClassification &c) -> uint8_t
|
||||
{ return c.highway_turn_classification; }),
|
||||
"access_turn_classification",
|
||||
sol::property([](NodeBasedEdgeClassification &c) -> uint8_t {
|
||||
return c.access_turn_classification;
|
||||
}));
|
||||
sol::property([](NodeBasedEdgeClassification &c) -> uint8_t
|
||||
{ return c.access_turn_classification; }));
|
||||
|
||||
context.state.new_usertype<ExtractionSegment>("ExtractionSegment",
|
||||
"source",
|
||||
@@ -517,10 +517,12 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
|
||||
// Keep in mind .location is available only if .pbf is preprocessed to set the location with the
|
||||
// ref using osmium command "osmium add-locations-to-ways"
|
||||
context.state.new_usertype<osmium::NodeRef>(
|
||||
"NodeRef", "id", &osmium::NodeRef::ref, "location", [](const osmium::NodeRef &nref) {
|
||||
return nref.location();
|
||||
});
|
||||
context.state.new_usertype<osmium::NodeRef>("NodeRef",
|
||||
"id",
|
||||
&osmium::NodeRef::ref,
|
||||
"location",
|
||||
[](const osmium::NodeRef &nref)
|
||||
{ return nref.location(); });
|
||||
|
||||
context.state.new_usertype<InternalExtractorEdge>("EdgeSource",
|
||||
"source_coordinate",
|
||||
@@ -576,7 +578,8 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
util::Log() << "Using profile api version " << context.api_version;
|
||||
|
||||
// version-dependent parts of the api
|
||||
auto initV2Context = [&]() {
|
||||
auto initV2Context = [&]()
|
||||
{
|
||||
// clear global not used in v2
|
||||
context.state["properties"] = sol::nullopt;
|
||||
|
||||
@@ -667,26 +670,31 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
}
|
||||
};
|
||||
|
||||
auto initialize_V3_extraction_turn = [&]() {
|
||||
auto initialize_V3_extraction_turn = [&]()
|
||||
{
|
||||
context.state.new_usertype<ExtractionTurn>(
|
||||
"ExtractionTurn",
|
||||
"angle",
|
||||
&ExtractionTurn::angle,
|
||||
"turn_type",
|
||||
sol::property([](const ExtractionTurn &turn) {
|
||||
if (turn.number_of_roads > 2 || turn.source_mode != turn.target_mode ||
|
||||
turn.is_u_turn)
|
||||
return osrm::guidance::TurnType::Turn;
|
||||
else
|
||||
return osrm::guidance::TurnType::NoTurn;
|
||||
}),
|
||||
sol::property(
|
||||
[](const ExtractionTurn &turn)
|
||||
{
|
||||
if (turn.number_of_roads > 2 || turn.source_mode != turn.target_mode ||
|
||||
turn.is_u_turn)
|
||||
return osrm::guidance::TurnType::Turn;
|
||||
else
|
||||
return osrm::guidance::TurnType::NoTurn;
|
||||
}),
|
||||
"direction_modifier",
|
||||
sol::property([](const ExtractionTurn &turn) {
|
||||
if (turn.is_u_turn)
|
||||
return osrm::guidance::DirectionModifier::UTurn;
|
||||
else
|
||||
return osrm::guidance::DirectionModifier::Straight;
|
||||
}),
|
||||
sol::property(
|
||||
[](const ExtractionTurn &turn)
|
||||
{
|
||||
if (turn.is_u_turn)
|
||||
return osrm::guidance::DirectionModifier::UTurn;
|
||||
else
|
||||
return osrm::guidance::DirectionModifier::Straight;
|
||||
}),
|
||||
"has_traffic_light",
|
||||
&ExtractionTurn::has_traffic_light,
|
||||
"weight",
|
||||
|
||||
@@ -12,7 +12,8 @@ TurnPathCompressor::TurnPathCompressor(std::vector<TurnRestriction> &restriction
|
||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides)
|
||||
{
|
||||
// Track all turn paths by their respective start/via/end nodes.
|
||||
auto index = [&](auto &element) {
|
||||
auto index = [&](auto &element)
|
||||
{
|
||||
starts.insert({element.From(), &element});
|
||||
ends.insert({element.To(), &element});
|
||||
if (element.Type() == TurnPathType::VIA_WAY_TURN_PATH)
|
||||
@@ -44,7 +45,8 @@ void TurnPathCompressor::Compress(const NodeID from, const NodeID via, const Nod
|
||||
std::back_inserter(start_ptrs),
|
||||
[](const auto pair) { return pair.second; });
|
||||
|
||||
const auto update_start = [&](auto ptr) {
|
||||
const auto update_start = [&](auto ptr)
|
||||
{
|
||||
if (ptr->Type() == TurnPathType::VIA_NODE_TURN_PATH)
|
||||
{
|
||||
|
||||
@@ -97,7 +99,8 @@ void TurnPathCompressor::Compress(const NodeID from, const NodeID via, const Nod
|
||||
std::back_inserter(end_ptrs),
|
||||
[](const auto pair) { return pair.second; });
|
||||
|
||||
const auto update_end = [&](auto ptr) {
|
||||
const auto update_end = [&](auto ptr)
|
||||
{
|
||||
if (ptr->Type() == TurnPathType::VIA_NODE_TURN_PATH)
|
||||
{
|
||||
auto &node_ptr = ptr->AsViaNodePath();
|
||||
@@ -145,7 +148,8 @@ void TurnPathCompressor::Compress(const NodeID from, const NodeID via, const Nod
|
||||
// remove compressed node from all via paths
|
||||
auto all_vias_range = vias.equal_range(via);
|
||||
|
||||
const auto update_via = [&](auto restriction_pair) {
|
||||
const auto update_via = [&](auto restriction_pair)
|
||||
{
|
||||
BOOST_ASSERT(restriction_pair.second->Type() == TurnPathType::VIA_WAY_TURN_PATH);
|
||||
auto &way_ptr = restriction_pair.second->AsViaWayPath();
|
||||
BOOST_ASSERT(std::find(way_ptr.via.begin(), way_ptr.via.end(), via) != way_ptr.via.end());
|
||||
|
||||
@@ -18,7 +18,8 @@ std::vector<T> removeInvalidTurnPaths(std::vector<T> turn_relations,
|
||||
log << "Removing invalid " << T::Name() << "s...";
|
||||
TIMER_START(remove_invalid_turn_paths);
|
||||
|
||||
const auto is_valid_edge = [&node_based_graph](const auto from, const auto to) {
|
||||
const auto is_valid_edge = [&node_based_graph](const auto from, const auto to)
|
||||
{
|
||||
const auto eid = node_based_graph.FindEdge(from, to);
|
||||
if (eid == SPECIAL_EDGEID)
|
||||
{
|
||||
@@ -35,26 +36,29 @@ std::vector<T> removeInvalidTurnPaths(std::vector<T> turn_relations,
|
||||
return true;
|
||||
};
|
||||
|
||||
const auto is_valid_node = [is_valid_edge](const auto &via_node_path) {
|
||||
const auto is_valid_node = [is_valid_edge](const auto &via_node_path)
|
||||
{
|
||||
return is_valid_edge(via_node_path.from, via_node_path.via) &&
|
||||
is_valid_edge(via_node_path.via, via_node_path.to);
|
||||
};
|
||||
|
||||
const auto is_valid_way = [is_valid_edge](const auto &via_way_path) {
|
||||
const auto is_valid_way = [is_valid_edge](const auto &via_way_path)
|
||||
{
|
||||
if (!is_valid_edge(via_way_path.from, via_way_path.via.front()))
|
||||
return false;
|
||||
|
||||
const auto invalid_it = std::adjacent_find(
|
||||
via_way_path.via.begin(), via_way_path.via.end(), [&](auto via_from, auto via_to) {
|
||||
return !is_valid_edge(via_from, via_to);
|
||||
});
|
||||
const auto invalid_it = std::adjacent_find(via_way_path.via.begin(),
|
||||
via_way_path.via.end(),
|
||||
[&](auto via_from, auto via_to)
|
||||
{ return !is_valid_edge(via_from, via_to); });
|
||||
if (invalid_it != via_way_path.via.end())
|
||||
return false;
|
||||
|
||||
return is_valid_edge(via_way_path.via.back(), via_way_path.to);
|
||||
};
|
||||
|
||||
const auto is_invalid = [is_valid_way, is_valid_node](const auto &turn_relation) {
|
||||
const auto is_invalid = [is_valid_way, is_valid_node](const auto &turn_relation)
|
||||
{
|
||||
if (turn_relation.turn_path.Type() == TurnPathType::VIA_NODE_TURN_PATH)
|
||||
{
|
||||
return !is_valid_node(turn_relation.turn_path.AsViaNodePath());
|
||||
|
||||
@@ -38,9 +38,10 @@ bool WayRestrictionMap::IsRestricted(DuplicatedNodeID duplicated_node, const Nod
|
||||
// Checks if a turn to 'to' is restricted
|
||||
BOOST_ASSERT(duplicated_node < restriction_graph.num_via_nodes);
|
||||
const auto &restrictions = restriction_graph.GetRestrictions(duplicated_node);
|
||||
return std::any_of(restrictions.begin(), restrictions.end(), [&to](const auto &restriction) {
|
||||
return restriction->IsTurnRestricted(to);
|
||||
});
|
||||
return std::any_of(restrictions.begin(),
|
||||
restrictions.end(),
|
||||
[&to](const auto &restriction)
|
||||
{ return restriction->IsTurnRestricted(to); });
|
||||
}
|
||||
|
||||
std::vector<const TurnRestriction *>
|
||||
|
||||
Reference in New Issue
Block a user