Support maneuver relations (#4676)

This commit is contained in:
Daniel Patterson
2018-02-10 05:32:09 +11:00
committed by GitHub
parent 1aed13500d
commit 5531cace7f
46 changed files with 1474 additions and 89 deletions
+105 -11
View File
@@ -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";