Support maneuver relations (#4676)
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <tbb/blocked_range.h>
|
||||
@@ -219,15 +220,18 @@ NBGToEBG EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const N
|
||||
return NBGToEBG{node_u, node_v, nbe_to_ebn_mapping[edge_id_1], nbe_to_ebn_mapping[edge_id_2]};
|
||||
}
|
||||
|
||||
void EdgeBasedGraphFactory::Run(ScriptingEnvironment &scripting_environment,
|
||||
const std::string &turn_weight_penalties_filename,
|
||||
const std::string &turn_duration_penalties_filename,
|
||||
const std::string &turn_penalties_index_filename,
|
||||
const std::string &cnbg_ebg_mapping_path,
|
||||
const std::string &conditional_penalties_filename,
|
||||
const RestrictionMap &node_restriction_map,
|
||||
const ConditionalRestrictionMap &conditional_node_restriction_map,
|
||||
const WayRestrictionMap &way_restriction_map)
|
||||
void EdgeBasedGraphFactory::Run(
|
||||
ScriptingEnvironment &scripting_environment,
|
||||
const std::string &turn_weight_penalties_filename,
|
||||
const std::string &turn_duration_penalties_filename,
|
||||
const std::string &turn_penalties_index_filename,
|
||||
const std::string &cnbg_ebg_mapping_path,
|
||||
const std::string &conditional_penalties_filename,
|
||||
const std::string &maneuver_overrides_filename,
|
||||
const RestrictionMap &node_restriction_map,
|
||||
const ConditionalRestrictionMap &conditional_node_restriction_map,
|
||||
const WayRestrictionMap &way_restriction_map,
|
||||
const std::vector<UnresolvedManeuverOverride> &unresolved_maneuver_overrides)
|
||||
{
|
||||
TIMER_START(renumber);
|
||||
m_number_of_edge_based_nodes =
|
||||
@@ -252,9 +256,11 @@ void EdgeBasedGraphFactory::Run(ScriptingEnvironment &scripting_environment,
|
||||
turn_duration_penalties_filename,
|
||||
turn_penalties_index_filename,
|
||||
conditional_penalties_filename,
|
||||
maneuver_overrides_filename,
|
||||
node_restriction_map,
|
||||
conditional_node_restriction_map,
|
||||
way_restriction_map);
|
||||
way_restriction_map,
|
||||
unresolved_maneuver_overrides);
|
||||
|
||||
TIMER_STOP(generate_edges);
|
||||
|
||||
@@ -407,9 +413,11 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
const std::string &turn_duration_penalties_filename,
|
||||
const std::string &turn_penalties_index_filename,
|
||||
const std::string &conditional_penalties_filename,
|
||||
const std::string &maneuver_overrides_filename,
|
||||
const RestrictionMap &node_restriction_map,
|
||||
const ConditionalRestrictionMap &conditional_restriction_map,
|
||||
const WayRestrictionMap &way_restriction_map)
|
||||
const WayRestrictionMap &way_restriction_map,
|
||||
const std::vector<UnresolvedManeuverOverride> &unresolved_maneuver_overrides)
|
||||
{
|
||||
util::Log() << "Generating edge-expanded edges ";
|
||||
|
||||
@@ -434,6 +442,10 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
std::vector<TurnPenalty> turn_weight_penalties;
|
||||
std::vector<TurnPenalty> turn_duration_penalties;
|
||||
|
||||
// Now, renumber all our maneuver overrides to use edge-based-nodes
|
||||
std::vector<StorageManeuverOverride> storage_maneuver_overrides;
|
||||
std::vector<NodeID> maneuver_override_sequences;
|
||||
|
||||
const auto weight_multiplier =
|
||||
scripting_environment.GetProfileProperties().GetWeightMultiplier();
|
||||
|
||||
@@ -482,12 +494,16 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
std::vector<EdgeWithData> delayed_data; // may need this
|
||||
std::vector<Conditional> conditionals;
|
||||
|
||||
std::unordered_map<NodeBasedTurn, std::pair<NodeID, NodeID>> turn_to_ebn_map;
|
||||
|
||||
util::ConnectivityChecksum checksum;
|
||||
};
|
||||
using EdgesPipelineBufferPtr = std::shared_ptr<EdgesPipelineBuffer>;
|
||||
|
||||
m_connectivity_checksum = 0;
|
||||
|
||||
std::unordered_map<NodeBasedTurn, std::pair<NodeID, NodeID>> global_turn_to_ebn_map;
|
||||
|
||||
// going over all nodes (which form the center of an intersection), we compute all possible
|
||||
// turns along these intersections.
|
||||
NodeID current_node = 0;
|
||||
@@ -847,6 +863,30 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
m_node_based_graph.GetTarget(outgoing_edge.edge),
|
||||
m_number_of_edge_based_nodes);
|
||||
|
||||
/***************************/
|
||||
|
||||
const auto edgetarget =
|
||||
m_node_based_graph.GetTarget(outgoing_edge.edge);
|
||||
|
||||
// TODO: this loop is not optimized - once we have a few
|
||||
// overrides available, we should index this for faster
|
||||
// lookups
|
||||
for (auto & override : unresolved_maneuver_overrides)
|
||||
{
|
||||
for (auto &turn : override.turn_sequence)
|
||||
{
|
||||
if (turn.from == incoming_edge.node &&
|
||||
turn.via == intersection_node && turn.to == edgetarget)
|
||||
{
|
||||
const auto &ebn_from =
|
||||
nbe_to_ebn_mapping[incoming_edge.edge];
|
||||
const auto &ebn_to = target_id;
|
||||
buffer->turn_to_ebn_map[turn] =
|
||||
std::make_pair(ebn_from, ebn_to);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{ // scope to forget edge_with_data after
|
||||
const auto edge_with_data_and_condition =
|
||||
generate_edge(nbe_to_ebn_mapping[incoming_edge.edge],
|
||||
@@ -997,6 +1037,13 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
// Copy via-way restrictions delayed data
|
||||
delayed_data.insert(
|
||||
delayed_data.end(), buffer->delayed_data.begin(), buffer->delayed_data.end());
|
||||
|
||||
std::for_each(buffer->turn_to_ebn_map.begin(),
|
||||
buffer->turn_to_ebn_map.end(),
|
||||
[&global_turn_to_ebn_map](const auto &p) {
|
||||
// TODO: log conflicts here
|
||||
global_turn_to_ebn_map.insert(p);
|
||||
});
|
||||
});
|
||||
|
||||
// Now, execute the pipeline. The value of "5" here was chosen by experimentation
|
||||
@@ -1010,6 +1057,39 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
// NOTE: buffer.delayed_data and buffer.delayed_turn_data have the same index
|
||||
std::for_each(delayed_data.begin(), delayed_data.end(), transfer_data);
|
||||
|
||||
// Now, replace node-based-node ID values in the `node_sequence` with
|
||||
// the edge-based-node values we found and stored in the `turn_to_ebn_map`
|
||||
for (auto &unresolved_override : unresolved_maneuver_overrides)
|
||||
{
|
||||
StorageManeuverOverride storage_override;
|
||||
storage_override.instruction_node = unresolved_override.instruction_node;
|
||||
storage_override.override_type = unresolved_override.override_type;
|
||||
storage_override.direction = unresolved_override.direction;
|
||||
|
||||
std::vector<NodeID> node_sequence(unresolved_override.turn_sequence.size() + 1,
|
||||
SPECIAL_NODEID);
|
||||
|
||||
for (std::int64_t i = unresolved_override.turn_sequence.size() - 1; i >= 0; --i)
|
||||
{
|
||||
const auto v = global_turn_to_ebn_map.find(unresolved_override.turn_sequence[i]);
|
||||
if (v != global_turn_to_ebn_map.end())
|
||||
{
|
||||
node_sequence[i] = v->second.first;
|
||||
node_sequence[i + 1] = v->second.second;
|
||||
}
|
||||
}
|
||||
storage_override.node_sequence_offset_begin = maneuver_override_sequences.size();
|
||||
storage_override.node_sequence_offset_end =
|
||||
maneuver_override_sequences.size() + node_sequence.size();
|
||||
|
||||
storage_override.start_node = node_sequence.front();
|
||||
|
||||
maneuver_override_sequences.insert(
|
||||
maneuver_override_sequences.end(), node_sequence.begin(), node_sequence.end());
|
||||
|
||||
storage_maneuver_overrides.push_back(storage_override);
|
||||
}
|
||||
|
||||
// Flush the turn_indexes_write_buffer if it's not empty
|
||||
if (!turn_indexes_write_buffer.empty())
|
||||
{
|
||||
@@ -1018,6 +1098,20 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
turn_indexes_write_buffer.clear();
|
||||
}
|
||||
}
|
||||
{
|
||||
util::Log() << "Sorting and writing " << storage_maneuver_overrides.size()
|
||||
<< " maneuver overrides...";
|
||||
|
||||
// Sort by `from_node`, so that later lookups can be done with a binary search.
|
||||
std::sort(storage_maneuver_overrides.begin(),
|
||||
storage_maneuver_overrides.end(),
|
||||
[](const auto &a, const auto &b) { return a.start_node < b.start_node; });
|
||||
// write conditional turn penalties into the restrictions file
|
||||
storage::io::FileWriter writer(maneuver_overrides_filename,
|
||||
storage::io::FileWriter::GenerateFingerprint);
|
||||
extractor::serialization::write(
|
||||
writer, storage_maneuver_overrides, maneuver_override_sequences);
|
||||
}
|
||||
|
||||
util::Log() << "done.";
|
||||
util::Log() << "Renumbering turns";
|
||||
|
||||
Reference in New Issue
Block a user