Take stop signs into account during routing
This commit is contained in:
parent
36f3a5eec8
commit
3558ec9db4
@ -26,6 +26,10 @@ namespace extractor
|
|||||||
*/
|
*/
|
||||||
class ExtractionContainers
|
class ExtractionContainers
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
using InputTrafficFlowControlNode = std::pair<OSMNodeID, TrafficFlowControlNodeDirection>;
|
||||||
|
|
||||||
|
private:
|
||||||
using ReferencedWays = std::unordered_map<OSMWayID, NodesOfWay>;
|
using ReferencedWays = std::unordered_map<OSMWayID, NodesOfWay>;
|
||||||
using ReferencedTrafficFlowControlNodes =
|
using ReferencedTrafficFlowControlNodes =
|
||||||
std::pair<std::unordered_set<OSMNodeID>, std::unordered_multimap<OSMNodeID, OSMNodeID>>;
|
std::pair<std::unordered_set<OSMNodeID>, std::unordered_multimap<OSMNodeID, OSMNodeID>>;
|
||||||
@ -34,15 +38,16 @@ class ExtractionContainers
|
|||||||
// node processing so that they can be referenced in the preparation phase.
|
// node processing so that they can be referenced in the preparation phase.
|
||||||
ReferencedWays IdentifyRestrictionWays();
|
ReferencedWays IdentifyRestrictionWays();
|
||||||
ReferencedWays IdentifyManeuverOverrideWays();
|
ReferencedWays IdentifyManeuverOverrideWays();
|
||||||
ReferencedTrafficFlowControlNodes IdentifyTrafficSignals();
|
|
||||||
ReferencedTrafficFlowControlNodes IdentifyStopSigns();
|
|
||||||
|
|
||||||
|
ReferencedTrafficFlowControlNodes IdentifyTrafficFlowControlNodes(
|
||||||
|
const std::vector<InputTrafficFlowControlNode> &external_stop_signs);
|
||||||
|
|
||||||
void PrepareNodes();
|
void PrepareNodes();
|
||||||
void PrepareManeuverOverrides(const ReferencedWays &maneuver_override_ways);
|
void PrepareManeuverOverrides(const ReferencedWays &maneuver_override_ways);
|
||||||
void PrepareRestrictions(const ReferencedWays &restriction_ways);
|
void PrepareRestrictions(const ReferencedWays &restriction_ways);
|
||||||
void PrepareTrafficSignals(const ReferencedTrafficFlowControlNodes &referenced_traffic_signals);
|
void PrepareTrafficFlowControlNodes(
|
||||||
void PrepareStopSigns(const ReferencedTrafficFlowControlNodes &referenced_stop_signs);
|
const ReferencedTrafficFlowControlNodes &referenced_traffic_control_nodes,
|
||||||
|
TrafficFlowControlNodes &internal_traffic_control_nodes);
|
||||||
|
|
||||||
void PrepareEdges(ScriptingEnvironment &scripting_environment);
|
void PrepareEdges(ScriptingEnvironment &scripting_environment);
|
||||||
|
|
||||||
@ -57,9 +62,6 @@ class ExtractionContainers
|
|||||||
using NameOffsets = std::vector<size_t>;
|
using NameOffsets = std::vector<size_t>;
|
||||||
using WayIDVector = std::vector<OSMWayID>;
|
using WayIDVector = std::vector<OSMWayID>;
|
||||||
using WayNodeIDOffsets = std::vector<size_t>;
|
using WayNodeIDOffsets = std::vector<size_t>;
|
||||||
using InputTrafficFlowControlNode = std::pair<OSMNodeID, TrafficFlowControlNodeDirection>;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<OSMNodeID> barrier_nodes;
|
std::vector<OSMNodeID> barrier_nodes;
|
||||||
NodeIDVector used_node_id_list;
|
NodeIDVector used_node_id_list;
|
||||||
|
@ -9,7 +9,6 @@ namespace osrm
|
|||||||
namespace extractor
|
namespace extractor
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
struct ExtractionNode
|
struct ExtractionNode
|
||||||
{
|
{
|
||||||
ExtractionNode() : traffic_lights(TrafficFlowControlNodeDirection::NONE), barrier(false) {}
|
ExtractionNode() : traffic_lights(TrafficFlowControlNodeDirection::NONE), barrier(false) {}
|
||||||
@ -23,7 +22,6 @@ struct ExtractionNode
|
|||||||
TrafficFlowControlNodeDirection traffic_lights;
|
TrafficFlowControlNodeDirection traffic_lights;
|
||||||
bool barrier;
|
bool barrier;
|
||||||
|
|
||||||
|
|
||||||
TrafficFlowControlNodeDirection stop_sign;
|
TrafficFlowControlNodeDirection stop_sign;
|
||||||
TrafficFlowControlNodeDirection give_way;
|
TrafficFlowControlNodeDirection give_way;
|
||||||
};
|
};
|
||||||
|
@ -76,7 +76,8 @@ struct ExtractionTurn
|
|||||||
const std::vector<ExtractionTurnLeg> &roads_on_the_right,
|
const std::vector<ExtractionTurnLeg> &roads_on_the_right,
|
||||||
const std::vector<ExtractionTurnLeg> &roads_on_the_left)
|
const std::vector<ExtractionTurnLeg> &roads_on_the_left)
|
||||||
: angle(180. - angle), number_of_roads(number_of_roads), is_u_turn(is_u_turn),
|
: angle(180. - angle), number_of_roads(number_of_roads), is_u_turn(is_u_turn),
|
||||||
has_traffic_light(has_traffic_light), has_stop_sign(has_stop_sign), is_left_hand_driving(is_left_hand_driving),
|
has_traffic_light(has_traffic_light), has_stop_sign(has_stop_sign),
|
||||||
|
is_left_hand_driving(is_left_hand_driving),
|
||||||
|
|
||||||
source_restricted(source_restricted), source_mode(source_mode),
|
source_restricted(source_restricted), source_mode(source_mode),
|
||||||
source_is_motorway(source_is_motorway), source_is_link(source_is_link),
|
source_is_motorway(source_is_motorway), source_is_link(source_is_link),
|
||||||
|
@ -73,7 +73,6 @@ class ExtractorCallbacks
|
|||||||
bool fallback_to_duration;
|
bool fallback_to_duration;
|
||||||
bool force_split_edges;
|
bool force_split_edges;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using ClassesMap = std::unordered_map<std::string, ClassData>;
|
using ClassesMap = std::unordered_map<std::string, ClassData>;
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@ namespace extractor
|
|||||||
//
|
//
|
||||||
// Impl. detail: namespace + enum instead of enum class to make Luabind happy
|
// Impl. detail: namespace + enum instead of enum class to make Luabind happy
|
||||||
|
|
||||||
|
|
||||||
// The traffic light annotation is extracted from node tags.
|
// The traffic light annotation is extracted from node tags.
|
||||||
// The directions in which the traffic light applies are relative to the way containing the node.
|
// The directions in which the traffic light applies are relative to the way containing the node.
|
||||||
enum class TrafficFlowControlNodeDirection : std::uint8_t
|
enum class TrafficFlowControlNodeDirection : std::uint8_t
|
||||||
|
@ -68,9 +68,9 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
|
|||||||
: m_edge_based_node_container(node_data_container), m_connectivity_checksum(0),
|
: m_edge_based_node_container(node_data_container), m_connectivity_checksum(0),
|
||||||
m_number_of_edge_based_nodes(0), m_coordinates(coordinates),
|
m_number_of_edge_based_nodes(0), m_coordinates(coordinates),
|
||||||
m_node_based_graph(node_based_graph), m_barrier_nodes(barrier_nodes),
|
m_node_based_graph(node_based_graph), m_barrier_nodes(barrier_nodes),
|
||||||
m_traffic_signals(traffic_signals), m_stop_signs(stop_signs), m_compressed_edge_container(compressed_edge_container),
|
m_traffic_signals(traffic_signals), m_stop_signs(stop_signs),
|
||||||
name_table(name_table), segregated_edges(segregated_edges),
|
m_compressed_edge_container(compressed_edge_container), name_table(name_table),
|
||||||
lane_description_map(lane_description_map)
|
segregated_edges(segregated_edges), lane_description_map(lane_description_map)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "extractor/name_table.hpp"
|
#include "extractor/name_table.hpp"
|
||||||
#include "extractor/restriction.hpp"
|
#include "extractor/restriction.hpp"
|
||||||
#include "extractor/serialization.hpp"
|
#include "extractor/serialization.hpp"
|
||||||
|
#include "extractor/traffic_signals.hpp"
|
||||||
#include "util/coordinate_calculation.hpp"
|
#include "util/coordinate_calculation.hpp"
|
||||||
#include "util/integer_range.hpp"
|
#include "util/integer_range.hpp"
|
||||||
|
|
||||||
@ -412,14 +413,14 @@ void ExtractionContainers::PrepareData(ScriptingEnvironment &scripting_environme
|
|||||||
{
|
{
|
||||||
const auto restriction_ways = IdentifyRestrictionWays();
|
const auto restriction_ways = IdentifyRestrictionWays();
|
||||||
const auto maneuver_override_ways = IdentifyManeuverOverrideWays();
|
const auto maneuver_override_ways = IdentifyManeuverOverrideWays();
|
||||||
const auto traffic_signals = IdentifyTrafficSignals();
|
const auto traffic_signals = IdentifyTrafficFlowControlNodes(external_traffic_signals);
|
||||||
const auto stop_signs = IdentifyStopSigns();
|
const auto stop_signs = IdentifyTrafficFlowControlNodes(external_stop_signs);
|
||||||
|
|
||||||
PrepareNodes();
|
PrepareNodes();
|
||||||
PrepareEdges(scripting_environment);
|
PrepareEdges(scripting_environment);
|
||||||
|
|
||||||
PrepareTrafficSignals(traffic_signals);
|
PrepareTrafficFlowControlNodes(traffic_signals, internal_traffic_signals);
|
||||||
PrepareStopSigns(stop_signs);
|
PrepareTrafficFlowControlNodes(stop_signs, internal_stop_signs);
|
||||||
|
|
||||||
PrepareManeuverOverrides(maneuver_override_ways);
|
PrepareManeuverOverrides(maneuver_override_ways);
|
||||||
PrepareRestrictions(restriction_ways);
|
PrepareRestrictions(restriction_ways);
|
||||||
@ -938,23 +939,23 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyManeuverOverr
|
|||||||
return maneuver_override_ways;
|
return maneuver_override_ways;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtractionContainers::PrepareTrafficSignals(
|
void ExtractionContainers::PrepareTrafficFlowControlNodes(
|
||||||
const ReferencedTrafficFlowControlNodes &referenced_traffic_signals)
|
const ReferencedTrafficFlowControlNodes &referenced_traffic_control_nodes,
|
||||||
|
TrafficFlowControlNodes &internal_traffic_control_nodes)
|
||||||
{
|
{
|
||||||
const auto &bidirectional_signal_nodes = referenced_traffic_signals.first;
|
const auto &bidirectional_traffic_control_nodes = referenced_traffic_control_nodes.first;
|
||||||
const auto &unidirectional_signal_segments = referenced_traffic_signals.second;
|
const auto &unidirectional_node_segments = referenced_traffic_control_nodes.second;
|
||||||
|
|
||||||
util::UnbufferedLog log;
|
util::UnbufferedLog log;
|
||||||
log << "Preparing traffic light signals for " << bidirectional_signal_nodes.size()
|
log << "Preparing traffic control nodes for " << bidirectional_traffic_control_nodes.size()
|
||||||
<< " bidirectional, " << unidirectional_signal_segments.size()
|
<< " bidirectional, " << unidirectional_node_segments.size() << " unidirectional nodes ...";
|
||||||
<< " unidirectional nodes ...";
|
|
||||||
TIMER_START(prepare_traffic_signals);
|
TIMER_START(prepare_traffic_signals);
|
||||||
|
|
||||||
std::unordered_set<NodeID> bidirectional;
|
std::unordered_set<NodeID> bidirectional;
|
||||||
std::unordered_set<std::pair<NodeID, NodeID>, boost::hash<std::pair<NodeID, NodeID>>>
|
std::unordered_set<std::pair<NodeID, NodeID>, boost::hash<std::pair<NodeID, NodeID>>>
|
||||||
unidirectional;
|
unidirectional;
|
||||||
|
|
||||||
for (const auto &osm_node : bidirectional_signal_nodes)
|
for (const auto &osm_node : bidirectional_traffic_control_nodes)
|
||||||
{
|
{
|
||||||
const auto node_id = mapExternalToInternalNodeID(
|
const auto node_id = mapExternalToInternalNodeID(
|
||||||
used_node_id_list.begin(), used_node_id_list.end(), osm_node);
|
used_node_id_list.begin(), used_node_id_list.end(), osm_node);
|
||||||
@ -963,7 +964,7 @@ void ExtractionContainers::PrepareTrafficSignals(
|
|||||||
bidirectional.insert(node_id);
|
bidirectional.insert(node_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const auto &to_from : unidirectional_signal_segments)
|
for (const auto &to_from : unidirectional_node_segments)
|
||||||
{
|
{
|
||||||
const auto to_node_id = mapExternalToInternalNodeID(
|
const auto to_node_id = mapExternalToInternalNodeID(
|
||||||
used_node_id_list.begin(), used_node_id_list.end(), to_from.first);
|
used_node_id_list.begin(), used_node_id_list.end(), to_from.first);
|
||||||
@ -975,61 +976,13 @@ void ExtractionContainers::PrepareTrafficSignals(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal_traffic_signals.bidirectional_nodes = std::move(bidirectional);
|
internal_traffic_control_nodes.bidirectional_nodes = std::move(bidirectional);
|
||||||
internal_traffic_signals.unidirectional_segments = std::move(unidirectional);
|
internal_traffic_control_nodes.unidirectional_segments = std::move(unidirectional);
|
||||||
|
|
||||||
TIMER_STOP(prepare_traffic_signals);
|
TIMER_STOP(prepare_traffic_signals);
|
||||||
log << "ok, after " << TIMER_SEC(prepare_traffic_signals) << "s";
|
log << "ok, after " << TIMER_SEC(prepare_traffic_signals) << "s";
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: copy-paste
|
|
||||||
void ExtractionContainers::PrepareStopSigns(const ReferencedTrafficFlowControlNodes &referenced_stop_signs) {
|
|
||||||
const auto &bidirectional_signal_nodes = referenced_stop_signs.first;
|
|
||||||
const auto &unidirectional_signal_segments = referenced_stop_signs.second;
|
|
||||||
|
|
||||||
util::UnbufferedLog log;
|
|
||||||
log << "Preparing traffic light signals for " << bidirectional_signal_nodes.size()
|
|
||||||
<< " bidirectional, " << unidirectional_signal_segments.size()
|
|
||||||
<< " unidirectional nodes ...";
|
|
||||||
TIMER_START(prepare_traffic_signals);
|
|
||||||
|
|
||||||
std::unordered_set<NodeID> bidirectional;
|
|
||||||
std::unordered_set<std::pair<NodeID, NodeID>, boost::hash<std::pair<NodeID, NodeID>>>
|
|
||||||
unidirectional;
|
|
||||||
|
|
||||||
for (const auto &osm_node : bidirectional_signal_nodes)
|
|
||||||
{
|
|
||||||
const auto node_id = mapExternalToInternalNodeID(
|
|
||||||
used_node_id_list.begin(), used_node_id_list.end(), osm_node);
|
|
||||||
if (node_id != SPECIAL_NODEID)
|
|
||||||
{
|
|
||||||
bidirectional.insert(node_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const auto &to_from : unidirectional_signal_segments)
|
|
||||||
{
|
|
||||||
const auto to_node_id = mapExternalToInternalNodeID(
|
|
||||||
used_node_id_list.begin(), used_node_id_list.end(), to_from.first);
|
|
||||||
const auto from_node_id = mapExternalToInternalNodeID(
|
|
||||||
used_node_id_list.begin(), used_node_id_list.end(), to_from.second);
|
|
||||||
if (from_node_id != SPECIAL_NODEID && to_node_id != SPECIAL_NODEID)
|
|
||||||
{
|
|
||||||
unidirectional.insert({from_node_id, to_node_id});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal_stop_signs.bidirectional_nodes = std::move(bidirectional);
|
|
||||||
internal_stop_signs.unidirectional_segments = std::move(unidirectional);
|
|
||||||
|
|
||||||
TIMER_STOP(prepare_traffic_signals);
|
|
||||||
log << "ok, after " << TIMER_SEC(prepare_traffic_signals) << "s";
|
|
||||||
}
|
|
||||||
|
|
||||||
// void ExtractionContainers::PrepareGiveWays(const ReferencedGiveWays &referenced_give_ways) {
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
void ExtractionContainers::PrepareManeuverOverrides(const ReferencedWays &maneuver_override_ways)
|
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) {
|
||||||
@ -1210,36 +1163,37 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyRestrictionWa
|
|||||||
return restriction_ways;
|
return restriction_ways;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: copy-paste
|
ExtractionContainers::ReferencedTrafficFlowControlNodes
|
||||||
ExtractionContainers::ReferencedTrafficFlowControlNodes ExtractionContainers::IdentifyStopSigns()
|
ExtractionContainers::IdentifyTrafficFlowControlNodes(
|
||||||
|
const std::vector<InputTrafficFlowControlNode> &external_nodes)
|
||||||
{
|
{
|
||||||
util::UnbufferedLog log;
|
util::UnbufferedLog log;
|
||||||
log << "Collecting traffic signal information on " << external_stop_signs.size()
|
log << "Collecting traffic nodes information on " << external_nodes.size() << " nodes...";
|
||||||
<< " signals...";
|
TIMER_START(identify_traffic_flow_control_nodes);
|
||||||
TIMER_START(identify_traffic_signals);
|
|
||||||
|
|
||||||
// Temporary store for nodes containing a unidirectional signal.
|
// Temporary store for nodes containing a unidirectional signal.
|
||||||
std::unordered_map<OSMNodeID, TrafficFlowControlNodeDirection> unidirectional_signals;
|
std::unordered_map<OSMNodeID, TrafficFlowControlNodeDirection> unidirectional_traffic_nodes;
|
||||||
|
|
||||||
// For each node that has a unidirectional traffic signal, we store the node(s)
|
// For each node that has a unidirectional traffic signal, we store the node(s)
|
||||||
// that lead up to the signal.
|
// that lead up to the signal.
|
||||||
std::unordered_multimap<OSMNodeID, OSMNodeID> signal_segments;
|
std::unordered_multimap<OSMNodeID, OSMNodeID> node_segments;
|
||||||
|
|
||||||
std::unordered_set<OSMNodeID> bidirectional_signals;
|
std::unordered_set<OSMNodeID> bidirectional_traffic_nodes;
|
||||||
|
|
||||||
const auto mark_signals = [&](auto const &traffic_signal) {
|
const auto mark_traffic_nodes = [&](auto const &traffic_control_node) {
|
||||||
if (traffic_signal.second == TrafficFlowControlNodeDirection::FORWARD ||
|
if (traffic_control_node.second == TrafficFlowControlNodeDirection::FORWARD ||
|
||||||
traffic_signal.second == TrafficFlowControlNodeDirection::REVERSE)
|
traffic_control_node.second == TrafficFlowControlNodeDirection::REVERSE)
|
||||||
{
|
{
|
||||||
unidirectional_signals.insert({traffic_signal.first, traffic_signal.second});
|
unidirectional_traffic_nodes.insert(
|
||||||
|
{traffic_control_node.first, traffic_control_node.second});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(traffic_signal.second == TrafficFlowControlNodeDirection::ALL);
|
BOOST_ASSERT(traffic_control_node.second == TrafficFlowControlNodeDirection::ALL);
|
||||||
bidirectional_signals.insert(traffic_signal.first);
|
bidirectional_traffic_nodes.insert(traffic_control_node.first);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
std::for_each(external_stop_signs.begin(), external_stop_signs.end(), mark_signals);
|
std::for_each(external_nodes.begin(), external_nodes.end(), mark_traffic_nodes);
|
||||||
|
|
||||||
// Extract all the segments that lead up to unidirectional traffic 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*/) {
|
||||||
@ -1250,15 +1204,15 @@ ExtractionContainers::ReferencedTrafficFlowControlNodes ExtractionContainers::Id
|
|||||||
|
|
||||||
for (auto node_it = node_start_offset; node_it < node_end_offset; node_it++)
|
for (auto node_it = node_start_offset; node_it < node_end_offset; node_it++)
|
||||||
{
|
{
|
||||||
const auto sig = unidirectional_signals.find(*node_it);
|
const auto sig = unidirectional_traffic_nodes.find(*node_it);
|
||||||
if (sig != unidirectional_signals.end())
|
if (sig != unidirectional_traffic_nodes.end())
|
||||||
{
|
{
|
||||||
if (sig->second == TrafficFlowControlNodeDirection::FORWARD)
|
if (sig->second == TrafficFlowControlNodeDirection::FORWARD)
|
||||||
{
|
{
|
||||||
if (node_it != node_start_offset)
|
if (node_it != node_start_offset)
|
||||||
{
|
{
|
||||||
// Previous node leads to signal
|
// Previous node leads to signal
|
||||||
signal_segments.insert({*node_it, *(node_it - 1)});
|
node_segments.insert({*node_it, *(node_it - 1)});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1267,7 +1221,7 @@ ExtractionContainers::ReferencedTrafficFlowControlNodes ExtractionContainers::Id
|
|||||||
if (node_it + 1 != node_end_offset)
|
if (node_it + 1 != node_end_offset)
|
||||||
{
|
{
|
||||||
// Next node leads to signal
|
// Next node leads to signal
|
||||||
signal_segments.insert({*node_it, *(node_it + 1)});
|
node_segments.insert({*node_it, *(node_it + 1)});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1276,7 +1230,7 @@ ExtractionContainers::ReferencedTrafficFlowControlNodes ExtractionContainers::Id
|
|||||||
util::for_each_indexed(ways_list.cbegin(), ways_list.cend(), set_segments);
|
util::for_each_indexed(ways_list.cbegin(), ways_list.cend(), set_segments);
|
||||||
|
|
||||||
util::for_each_pair(
|
util::for_each_pair(
|
||||||
signal_segments, [](const auto pair_a, const auto pair_b) {
|
node_segments, [](const auto pair_a, const auto pair_b) {
|
||||||
if (pair_a.first == pair_b.first)
|
if (pair_a.first == pair_b.first)
|
||||||
{
|
{
|
||||||
// If a node is appearing multiple times in this map, then it's ambiguous.
|
// If a node is appearing multiple times in this map, then it's ambiguous.
|
||||||
@ -1292,98 +1246,10 @@ ExtractionContainers::ReferencedTrafficFlowControlNodes ExtractionContainers::Id
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
TIMER_STOP(identify_traffic_signals);
|
TIMER_STOP(identify_traffic_flow_control_nodes);
|
||||||
log << "ok, after " << TIMER_SEC(identify_traffic_signals) << "s";
|
log << "ok, after " << TIMER_SEC(identify_traffic_flow_control_nodes) << "s";
|
||||||
|
|
||||||
return {std::move(bidirectional_signals), std::move(signal_segments)};
|
return {std::move(bidirectional_traffic_nodes), std::move(node_segments)};
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ExtractionContainers::ReferencedTrafficFlowControlNodes ExtractionContainers::IdentifyTrafficSignals()
|
|
||||||
{
|
|
||||||
util::UnbufferedLog log;
|
|
||||||
log << "Collecting traffic signal information on " << external_traffic_signals.size()
|
|
||||||
<< " signals...";
|
|
||||||
TIMER_START(identify_traffic_signals);
|
|
||||||
|
|
||||||
// Temporary store for nodes containing a unidirectional signal.
|
|
||||||
std::unordered_map<OSMNodeID, TrafficFlowControlNodeDirection> unidirectional_signals;
|
|
||||||
|
|
||||||
// For each node that has a unidirectional traffic signal, we store the node(s)
|
|
||||||
// that lead up to the signal.
|
|
||||||
std::unordered_multimap<OSMNodeID, OSMNodeID> signal_segments;
|
|
||||||
|
|
||||||
std::unordered_set<OSMNodeID> bidirectional_signals;
|
|
||||||
|
|
||||||
const auto mark_signals = [&](auto const &traffic_signal) {
|
|
||||||
if (traffic_signal.second == TrafficFlowControlNodeDirection::FORWARD ||
|
|
||||||
traffic_signal.second == TrafficFlowControlNodeDirection::REVERSE)
|
|
||||||
{
|
|
||||||
unidirectional_signals.insert({traffic_signal.first, traffic_signal.second});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(traffic_signal.second == TrafficFlowControlNodeDirection::ALL);
|
|
||||||
bidirectional_signals.insert(traffic_signal.first);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
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 node_start_offset =
|
|
||||||
used_node_id_list.begin() + way_node_id_offsets[way_list_idx];
|
|
||||||
const auto node_end_offset =
|
|
||||||
used_node_id_list.begin() + way_node_id_offsets[way_list_idx + 1];
|
|
||||||
|
|
||||||
for (auto node_it = node_start_offset; node_it < node_end_offset; node_it++)
|
|
||||||
{
|
|
||||||
const auto sig = unidirectional_signals.find(*node_it);
|
|
||||||
if (sig != unidirectional_signals.end())
|
|
||||||
{
|
|
||||||
if (sig->second == TrafficFlowControlNodeDirection::FORWARD)
|
|
||||||
{
|
|
||||||
if (node_it != node_start_offset)
|
|
||||||
{
|
|
||||||
// Previous node leads to signal
|
|
||||||
signal_segments.insert({*node_it, *(node_it - 1)});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(sig->second == TrafficFlowControlNodeDirection::REVERSE);
|
|
||||||
if (node_it + 1 != node_end_offset)
|
|
||||||
{
|
|
||||||
// Next node leads to signal
|
|
||||||
signal_segments.insert({*node_it, *(node_it + 1)});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
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) {
|
|
||||||
if (pair_a.first == pair_b.first)
|
|
||||||
{
|
|
||||||
// If a node is appearing multiple times in this map, then it's ambiguous.
|
|
||||||
// The node is an intersection and the traffic direction is being use for multiple
|
|
||||||
// ways. We can't be certain of the original intent. See:
|
|
||||||
// https://wiki.openstreetmap.org/wiki/Key:traffic_signals:direction
|
|
||||||
|
|
||||||
// OSRM will include the signal for all intersecting ways in the specified
|
|
||||||
// direction, but let's flag this as a concern.
|
|
||||||
util::Log(logWARNING)
|
|
||||||
<< "OSM node " << pair_a.first
|
|
||||||
<< " has a unidirectional traffic signal ambiguously applied to multiple ways";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
TIMER_STOP(identify_traffic_signals);
|
|
||||||
log << "ok, after " << TIMER_SEC(identify_traffic_signals) << "s";
|
|
||||||
|
|
||||||
return {std::move(bidirectional_signals), std::move(signal_segments)};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtractionContainers::PrepareRestrictions(const ReferencedWays &restriction_ways)
|
void ExtractionContainers::PrepareRestrictions(const ReferencedWays &restriction_ways)
|
||||||
|
@ -216,12 +216,14 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
|||||||
const bool has_forward_stop_sign = stop_signs.Has(node_u, node_v);
|
const bool has_forward_stop_sign = stop_signs.Has(node_u, node_v);
|
||||||
const bool has_reverse_stop_sign = stop_signs.Has(node_w, node_v);
|
const bool has_reverse_stop_sign = stop_signs.Has(node_w, node_v);
|
||||||
|
|
||||||
// TODO: can we have a case when we have both traffic signal and stop sign? how should we handle it?
|
// TODO: can we have a case when we have both traffic signal and stop sign? how
|
||||||
|
// should we handle it?
|
||||||
EdgeDuration forward_node_duration_penalty = MAXIMAL_EDGE_DURATION;
|
EdgeDuration forward_node_duration_penalty = MAXIMAL_EDGE_DURATION;
|
||||||
EdgeWeight forward_node_weight_penalty = INVALID_EDGE_WEIGHT;
|
EdgeWeight forward_node_weight_penalty = INVALID_EDGE_WEIGHT;
|
||||||
EdgeDuration reverse_node_duration_penalty = MAXIMAL_EDGE_DURATION;
|
EdgeDuration reverse_node_duration_penalty = MAXIMAL_EDGE_DURATION;
|
||||||
EdgeWeight reverse_node_weight_penalty = INVALID_EDGE_WEIGHT;
|
EdgeWeight reverse_node_weight_penalty = INVALID_EDGE_WEIGHT;
|
||||||
if (has_forward_signal || has_reverse_signal || has_forward_stop_sign || has_reverse_stop_sign)
|
if (has_forward_signal || has_reverse_signal || has_forward_stop_sign ||
|
||||||
|
has_reverse_stop_sign)
|
||||||
{
|
{
|
||||||
// we cannot handle this as node penalty, if it depends on turn direction
|
// we cannot handle this as node penalty, if it depends on turn direction
|
||||||
if (fwd_edge_data1.flags.restricted != fwd_edge_data2.flags.restricted)
|
if (fwd_edge_data1.flags.restricted != fwd_edge_data2.flags.restricted)
|
||||||
@ -258,7 +260,8 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
|||||||
roads_on_the_left);
|
roads_on_the_left);
|
||||||
scripting_environment.ProcessTurn(extraction_turn);
|
scripting_environment.ProcessTurn(extraction_turn);
|
||||||
|
|
||||||
std::cerr << "HAS STOP SIGN = " << extraction_turn.has_stop_sign << " " << extraction_turn.duration << std::endl;
|
std::cerr << "HAS STOP SIGN = " << extraction_turn.has_stop_sign << " "
|
||||||
|
<< extraction_turn.duration << std::endl;
|
||||||
|
|
||||||
auto update_direction_penalty =
|
auto update_direction_penalty =
|
||||||
[&extraction_turn, weight_multiplier](bool signal,
|
[&extraction_turn, weight_multiplier](bool signal,
|
||||||
@ -266,11 +269,13 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
|||||||
EdgeWeight &weight_penalty) {
|
EdgeWeight &weight_penalty) {
|
||||||
if (signal)
|
if (signal)
|
||||||
{
|
{
|
||||||
std::cerr << "DUR = " << extraction_turn.duration << " WEIGHT = " << extraction_turn.weight << std::endl;
|
std::cerr << "DUR = " << extraction_turn.duration
|
||||||
|
<< " WEIGHT = " << extraction_turn.weight << std::endl;
|
||||||
duration_penalty = extraction_turn.duration * SECOND_TO_DECISECOND;
|
duration_penalty = extraction_turn.duration * SECOND_TO_DECISECOND;
|
||||||
weight_penalty = extraction_turn.weight * weight_multiplier;
|
weight_penalty = extraction_turn.weight * weight_multiplier;
|
||||||
|
|
||||||
std::cerr << "DUR = " << duration_penalty << " WEIGHT = " << weight_penalty << std::endl;
|
std::cerr << "DUR = " << duration_penalty
|
||||||
|
<< " WEIGHT = " << weight_penalty << std::endl;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,7 +31,8 @@ NodeBasedGraphFactory::NodeBasedGraphFactory(
|
|||||||
coordinates(std::move(coordinates)), osm_node_ids(std::move(osm_node_ids))
|
coordinates(std::move(coordinates)), osm_node_ids(std::move(osm_node_ids))
|
||||||
{
|
{
|
||||||
BuildCompressedOutputGraph(edge_list);
|
BuildCompressedOutputGraph(edge_list);
|
||||||
Compress(scripting_environment, turn_restrictions, maneuver_overrides, traffic_signals, stop_signs);
|
Compress(
|
||||||
|
scripting_environment, turn_restrictions, maneuver_overrides, traffic_signals, stop_signs);
|
||||||
CompressGeometry();
|
CompressGeometry();
|
||||||
CompressAnnotationData();
|
CompressAnnotationData();
|
||||||
}
|
}
|
||||||
|
@ -1147,24 +1147,25 @@ void Sol2ScriptingEnvironment::ProcessTurn(ExtractionTurn &turn)
|
|||||||
case 2:
|
case 2:
|
||||||
if (context.has_turn_penalty_function)
|
if (context.has_turn_penalty_function)
|
||||||
{
|
{
|
||||||
std::cerr << "GOT TURN " << turn.has_stop_sign << " " << turn.has_traffic_light << std::endl;
|
std::cerr << "GOT TURN " << turn.has_stop_sign << " " << turn.has_traffic_light
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
context.turn_function(context.profile_table, std::ref(turn));
|
context.turn_function(context.profile_table, std::ref(turn));
|
||||||
|
|
||||||
// Turn weight falls back to the duration value in deciseconds
|
// Turn weight falls back to the duration value in deciseconds
|
||||||
// or uses the extracted unit-less weight value
|
// or uses the extracted unit-less weight value
|
||||||
if (context.properties.fallback_to_duration) {
|
if (context.properties.fallback_to_duration)
|
||||||
|
{
|
||||||
std::cerr << "FALLBACK\n";
|
std::cerr << "FALLBACK\n";
|
||||||
turn.weight = turn.duration;
|
turn.weight = turn.duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
// cap turn weight to max turn weight, which depend on weight precision
|
// cap turn weight to max turn weight, which depend on weight precision
|
||||||
turn.weight = std::min(turn.weight, context.properties.GetMaxTurnWeight());
|
turn.weight = std::min(turn.weight, context.properties.GetMaxTurnWeight());
|
||||||
std::cerr << "NO FALLBACK " << turn.weight << " " << turn.duration << std::endl;
|
std::cerr << "NO FALLBACK " << turn.weight << " " << turn.duration << std::endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user