compress traffic signals

- handle penalties within edges (not phantom nodes)
 - changes model from providing penalties on turns to using additional segments
This commit is contained in:
Moritz Kobitzsch
2017-07-20 14:03:39 +02:00
parent f0d3cf4e43
commit bbcf343e40
17 changed files with 209 additions and 69 deletions
+22 -9
View File
@@ -103,14 +103,17 @@ SegmentDuration CompressedEdgeContainer::ClipDuration(const SegmentDuration dura
// ----------> via_node_id -----------> target_node_id
// weight_1 weight_2
// duration_1 duration_2
void CompressedEdgeContainer::CompressEdge(const EdgeID edge_id_1,
const EdgeID edge_id_2,
const NodeID via_node_id,
const NodeID target_node_id,
const EdgeWeight weight1,
const EdgeWeight weight2,
const EdgeDuration duration1,
const EdgeDuration duration2)
void CompressedEdgeContainer::CompressEdge(
const EdgeID edge_id_1,
const EdgeID edge_id_2,
const NodeID via_node_id,
const NodeID target_node_id,
const EdgeWeight weight1,
const EdgeWeight weight2,
const EdgeDuration duration1,
const EdgeDuration duration2,
const boost::optional<EdgeWeight> node_weight_penalty,
const boost::optional<EdgeDuration> node_duration_penalty)
{
// remove super-trivial geometries
BOOST_ASSERT(SPECIAL_EDGEID != edge_id_1);
@@ -151,9 +154,11 @@ void CompressedEdgeContainer::CompressEdge(const EdgeID edge_id_1,
std::vector<OnewayCompressedEdge> &edge_bucket_list1 =
m_compressed_oneway_geometries[edge_bucket_id1];
bool was_empty = edge_bucket_list1.empty();
// note we don't save the start coordinate: it is implicitly given by edge 1
// weight1 is the distance to the (currently) last coordinate in the bucket
if (edge_bucket_list1.empty())
if (was_empty)
{
edge_bucket_list1.emplace_back(
OnewayCompressedEdge{via_node_id, ClipWeight(weight1), ClipDuration(duration1)});
@@ -162,6 +167,14 @@ void CompressedEdgeContainer::CompressEdge(const EdgeID edge_id_1,
BOOST_ASSERT(0 < edge_bucket_list1.size());
BOOST_ASSERT(!edge_bucket_list1.empty());
// if the via-node offers a penalty, we add the weight of the penalty as an artificial
// segment that references SPECIAL_NODEID
if (node_weight_penalty && node_duration_penalty)
{
edge_bucket_list1.emplace_back(OnewayCompressedEdge{
via_node_id, ClipWeight(*node_weight_penalty), ClipDuration(*node_duration_penalty)});
}
if (HasEntryForID(edge_id_2))
{
// second edge is not atomic anymore
@@ -168,6 +168,11 @@ NBGToEBG EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const N
m_compressed_edge_container.GetBucketReference(edge_id_2)[segment_count - 1 - i]
.node_id);
const NodeID current_edge_target_coordinate_id = forward_geometry[i].node_id;
// don't add node-segments for penalties
if (current_edge_target_coordinate_id == current_edge_source_coordinate_id)
continue;
BOOST_ASSERT(current_edge_target_coordinate_id != current_edge_source_coordinate_id);
// build edges
+4 -4
View File
@@ -616,17 +616,17 @@ void ExtractionContainers::WriteNodes(storage::io::FileWriter &file_out) const
util::UnbufferedLog log;
log << "Writing traffic light nodes ... ";
TIMER_START(write_nodes);
std::vector<NodeID> internal_traffic_lights;
for (const auto osm_id : traffic_lights)
std::vector<NodeID> internal_traffic_signals;
for (const auto osm_id : traffic_signals)
{
const auto node_id = mapExternalToInternalNodeID(
used_node_id_list.begin(), used_node_id_list.end(), osm_id);
if (node_id != SPECIAL_NODEID)
{
internal_traffic_lights.push_back(node_id);
internal_traffic_signals.push_back(node_id);
}
}
storage::serialization::write(file_out, internal_traffic_lights);
storage::serialization::write(file_out, internal_traffic_signals);
log << "ok, after " << TIMER_SEC(write_nodes) << "s";
}
+5 -4
View File
@@ -454,15 +454,16 @@ Extractor::BuildEdgeExpandedGraph(ScriptingEnvironment &scripting_environment,
guidance::LaneDescriptionMap &turn_lane_map)
{
std::unordered_set<NodeID> barrier_nodes;
std::unordered_set<NodeID> traffic_lights;
std::unordered_set<NodeID> traffic_signals;
auto node_based_graph =
LoadNodeBasedGraph(barrier_nodes, traffic_lights, coordinates, osm_node_ids);
LoadNodeBasedGraph(barrier_nodes, traffic_signals, coordinates, osm_node_ids);
CompressedEdgeContainer compressed_edge_container;
GraphCompressor graph_compressor;
graph_compressor.Compress(barrier_nodes,
traffic_lights,
traffic_signals,
scripting_environment,
turn_restrictions,
*node_based_graph,
compressed_edge_container);
@@ -474,7 +475,7 @@ Extractor::BuildEdgeExpandedGraph(ScriptingEnvironment &scripting_environment,
EdgeBasedGraphFactory edge_based_graph_factory(node_based_graph,
compressed_edge_container,
barrier_nodes,
traffic_lights,
traffic_signals,
coordinates,
osm_node_ids,
scripting_environment.GetProfileProperties(),
+1 -1
View File
@@ -69,7 +69,7 @@ void ExtractorCallbacks::ProcessNode(const osmium::Node &input_node,
}
if (result_node.traffic_lights)
{
external_memory.traffic_lights.push_back(id);
external_memory.traffic_signals.push_back(id);
}
}
+41 -6
View File
@@ -1,6 +1,8 @@
#include "extractor/graph_compressor.hpp"
#include "extractor/compressed_edge_container.hpp"
#include "extractor/extraction_turn.hpp"
#include "extractor/guidance/intersection.hpp"
#include "extractor/restriction.hpp"
#include "extractor/restriction_compressor.hpp"
@@ -19,7 +21,8 @@ namespace extractor
{
void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
const std::unordered_set<NodeID> &traffic_lights,
const std::unordered_set<NodeID> &traffic_signals,
ScriptingEnvironment &scripting_environment,
std::vector<TurnRestriction> &turn_restrictions,
util::NodeBasedDynamicGraph &graph,
CompressedEdgeContainer &geometry_compressor)
@@ -50,6 +53,8 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
std::for_each(turn_restrictions.begin(), turn_restrictions.end(), remember_via_nodes);
{
const auto weight_multiplier =
scripting_environment.GetProfileProperties().GetWeightMultiplier();
util::UnbufferedLog log;
util::Percent progress(log, original_number_of_nodes);
@@ -184,13 +189,31 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
graph.GetEdgeData(reverse_e2).lane_description_id = selectLaneID(
rev_edge_data2.lane_description_id, rev_edge_data1.lane_description_id);
/*
// Do not compress edge if it crosses a traffic signal.
// This can't be done in CanCombineWith, becase we only store the
// traffic signals in the `traffic_lights` list, which EdgeData
// traffic signals in the `traffic signal` list, which EdgeData
// doesn't have access to.
const bool has_node_penalty = traffic_lights.find(node_v) != traffic_lights.end();
*/
const bool has_node_penalty = traffic_signals.find(node_v) != traffic_signals.end();
boost::optional<EdgeDuration> node_duration_penalty = boost::none;
boost::optional<EdgeWeight> node_weight_penalty = boost::none;
if (has_node_penalty)
continue;
{
// generate an artifical turn for the turn penalty generation
ExtractionTurn extraction_turn(true);
extraction_turn.source_restricted = fwd_edge_data1.restricted;
extraction_turn.target_restricted = fwd_edge_data2.restricted;
// we cannot handle this as node penalty, if it depends on turn direction
if (extraction_turn.source_restricted != extraction_turn.target_restricted)
continue;
scripting_environment.ProcessTurn(extraction_turn);
node_duration_penalty = extraction_turn.duration * 10;
node_weight_penalty = extraction_turn.weight * weight_multiplier;
}
// Get weights before graph is modified
const auto forward_weight1 = fwd_edge_data1.weight;
@@ -217,6 +240,14 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
graph.GetEdgeData(forward_e1).duration += forward_duration2;
graph.GetEdgeData(reverse_e1).duration += reverse_duration2;
if (node_weight_penalty && node_duration_penalty)
{
graph.GetEdgeData(forward_e1).weight += *node_weight_penalty;
graph.GetEdgeData(reverse_e1).weight += *node_weight_penalty;
graph.GetEdgeData(forward_e1).duration += *node_duration_penalty;
graph.GetEdgeData(reverse_e1).duration += *node_duration_penalty;
}
// extend e1's to targets of e2's
graph.SetTarget(forward_e1, node_w);
graph.SetTarget(reverse_e1, node_u);
@@ -236,7 +267,9 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
forward_weight1,
forward_weight2,
forward_duration1,
forward_duration2);
forward_duration2,
node_weight_penalty,
node_duration_penalty);
geometry_compressor.CompressEdge(reverse_e1,
reverse_e2,
node_v,
@@ -244,7 +277,9 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
reverse_weight1,
reverse_weight2,
reverse_duration1,
reverse_duration2);
reverse_duration2,
node_weight_penalty,
node_duration_penalty);
}
}
}