Compare commits
19 Commits
master
...
sf-stop-si
Author | SHA1 | Date | |
---|---|---|---|
|
04ee126297 | ||
|
3f7a629db8 | ||
|
750826215f | ||
|
ee008e75e5 | ||
|
3080be59ed | ||
|
a7142ee737 | ||
|
eb72ca4941 | ||
|
b887e72d0b | ||
|
be1b86657c | ||
|
62298cf409 | ||
|
c28a6832d7 | ||
|
97883178fa | ||
|
350862d177 | ||
|
4432756de1 | ||
|
3558ec9db4 | ||
|
36f3a5eec8 | ||
|
72ea34f3b7 | ||
|
7f635f2ed6 | ||
|
8a4af59838 |
@ -9,6 +9,7 @@
|
||||
- CHANGED: Make edge metrics strongly typed [#6420](https://github.com/Project-OSRM/osrm-backend/pull/6420)
|
||||
- FIXED: Typo in file name src/util/timed_historgram.cpp -> src/util/timed_histogram.cpp [#6428](https://github.com/Project-OSRM/osrm-backend/issues/6428)
|
||||
- Routing:
|
||||
- ADDED: Stop and give way signs are now taken into account in car profile. [#6426](https://github.com/Project-OSRM/osrm-backend/pull/6426)
|
||||
- FIXED: Fix adding traffic signal penalties during compression [#6419](https://github.com/Project-OSRM/osrm-backend/pull/6419)
|
||||
# 5.27.1
|
||||
- Changes from 5.27.0
|
||||
|
77
features/car/give_way_sign_penalties.feature
Normal file
77
features/car/give_way_sign_penalties.feature
Normal file
@ -0,0 +1,77 @@
|
||||
@routing @car @give_way_sign
|
||||
Feature: Car - Handle give way signs
|
||||
|
||||
Background:
|
||||
Given the profile "car"
|
||||
|
||||
Scenario: Car - Encounters a give way sign
|
||||
Given the node map
|
||||
"""
|
||||
a-1-b-2-c
|
||||
|
||||
d-3-e-4-f
|
||||
|
||||
g-h-i k-l-m
|
||||
| |
|
||||
j n
|
||||
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abc | primary |
|
||||
| def | primary |
|
||||
| ghi | primary |
|
||||
| klm | primary |
|
||||
| hj | primary |
|
||||
| ln | primary |
|
||||
|
||||
And the nodes
|
||||
| node | highway |
|
||||
| e | give_way |
|
||||
| l | give_way |
|
||||
|
||||
# TODO: give way signs with no direction has no any impact on routing at the moment
|
||||
When I route I should get
|
||||
| from | to | time | # |
|
||||
| 1 | 2 | 11.1s | no turn with no give way |
|
||||
| 3 | 4 | 11.1s | no turn with give way |
|
||||
| g | j | 18.7s | turn with no give way |
|
||||
| k | n | 18.7s | turn with give way |
|
||||
|
||||
|
||||
Scenario: Car - Give way direction
|
||||
Given the node map
|
||||
"""
|
||||
a-1-b-2-c
|
||||
|
||||
d-3-e-4-f
|
||||
|
||||
g-5-h-6-i
|
||||
|
||||
j-7-k-8-l
|
||||
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abc | primary |
|
||||
| def | primary |
|
||||
| ghi | primary |
|
||||
| jkl | primary |
|
||||
|
||||
And the nodes
|
||||
| node | highway | direction |
|
||||
| e | give_way | |
|
||||
| h | give_way | forward |
|
||||
| k | give_way | backward |
|
||||
When I route I should get
|
||||
| from | to | time | weight | # |
|
||||
| 1 | 2 | 11.1s | 11.1 | no turn with no give way |
|
||||
| 2 | 1 | 11.1s | 11.1 | no turn with no give way |
|
||||
| 3 | 4 | 11.1s | 11.1 | no turn with give way |
|
||||
| 4 | 3 | 11.1s | 11.1 | no turn with give way |
|
||||
| 5 | 6 | 12.6s | 12.6 | no turn with give way |
|
||||
| 6 | 5 | 11.1s | 11.1 | no turn with no give way |
|
||||
| 7 | 8 | 11.1s | 11.1 | no turn with no give way |
|
||||
| 8 | 7 | 12.6s | 12.6 | no turn with give way |
|
77
features/car/stop_sign_penalties.feature
Normal file
77
features/car/stop_sign_penalties.feature
Normal file
@ -0,0 +1,77 @@
|
||||
@routing @car @stop_sign
|
||||
Feature: Car - Handle stop signs
|
||||
|
||||
Background:
|
||||
Given the profile "car"
|
||||
|
||||
Scenario: Car - Encounters a stop sign
|
||||
Given the node map
|
||||
"""
|
||||
a-1-b-2-c
|
||||
|
||||
d-3-e-4-f
|
||||
|
||||
g-h-i k-l-m
|
||||
| |
|
||||
j n
|
||||
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abc | primary |
|
||||
| def | primary |
|
||||
| ghi | primary |
|
||||
| klm | primary |
|
||||
| hj | primary |
|
||||
| ln | primary |
|
||||
|
||||
And the nodes
|
||||
| node | highway |
|
||||
| e | stop |
|
||||
| l | stop |
|
||||
|
||||
# TODO: stop signs with no direction has no any impact on routing at the moment
|
||||
When I route I should get
|
||||
| from | to | time | # |
|
||||
| 1 | 2 | 11.1s | no turn with no stop sign |
|
||||
| 3 | 4 | 11.1s | no turn with stop sign |
|
||||
| g | j | 18.7s | turn with no stop sign |
|
||||
| k | n | 18.7s | turn with stop sign |
|
||||
|
||||
Scenario: Car - Stop sign direction
|
||||
Given the node map
|
||||
"""
|
||||
a-1-b-2-c
|
||||
|
||||
d-3-e-4-f
|
||||
|
||||
g-5-h-6-i
|
||||
|
||||
j-7-k-8-l
|
||||
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abc | primary |
|
||||
| def | primary |
|
||||
| ghi | primary |
|
||||
| jkl | primary |
|
||||
|
||||
And the nodes
|
||||
| node | highway | direction |
|
||||
| e | stop | |
|
||||
| h | stop | forward |
|
||||
| k | stop | backward |
|
||||
|
||||
When I route I should get
|
||||
| from | to | time | weight | # |
|
||||
| 1 | 2 | 11.1s | 11.1 | no turn with no stop sign |
|
||||
| 2 | 1 | 11.1s | 11.1 | no turn with no stop sign |
|
||||
| 3 | 4 | 11.1s | 11.1 | no turn with stop sign |
|
||||
| 4 | 3 | 11.1s | 11.1 | no turn with stop sign |
|
||||
| 5 | 6 | 13.1s | 13.1 | no turn with stop sign |
|
||||
| 6 | 5 | 11.1s | 11.1 | no turn with no stop sign |
|
||||
| 7 | 8 | 11.1s | 11.1 | no turn with no stop sign |
|
||||
| 8 | 7 | 13.1s | 13.1 | no turn with stop sign |
|
@ -1,7 +1,6 @@
|
||||
@routing @testbot @turn_function
|
||||
Feature: Turn Function Information
|
||||
|
||||
|
||||
Background:
|
||||
Given the profile file
|
||||
"""
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include "storage/io.hpp"
|
||||
#include "traffic_signals.hpp"
|
||||
#include "traffic_flow_control_nodes.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
@ -69,7 +69,9 @@ class EdgeBasedGraphFactory
|
||||
EdgeBasedNodeDataContainer &node_data_container,
|
||||
const CompressedEdgeContainer &compressed_edge_container,
|
||||
const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const TrafficSignals &traffic_signals,
|
||||
const TrafficFlowControlNodes &traffic_signals,
|
||||
const TrafficFlowControlNodes &stop_signs,
|
||||
const TrafficFlowControlNodes &give_way_signs,
|
||||
const std::vector<util::Coordinate> &coordinates,
|
||||
const NameTable &name_table,
|
||||
const std::unordered_set<EdgeID> &segregated_edges,
|
||||
@ -135,7 +137,10 @@ class EdgeBasedGraphFactory
|
||||
const util::NodeBasedDynamicGraph &m_node_based_graph;
|
||||
|
||||
const std::unordered_set<NodeID> &m_barrier_nodes;
|
||||
const TrafficSignals &m_traffic_signals;
|
||||
const TrafficFlowControlNodes &m_traffic_signals;
|
||||
const TrafficFlowControlNodes &m_stop_signs;
|
||||
const TrafficFlowControlNodes &m_give_way_signs;
|
||||
|
||||
const CompressedEdgeContainer &m_compressed_edge_container;
|
||||
|
||||
const NameTable &name_table;
|
||||
|
@ -8,8 +8,7 @@
|
||||
#include "extractor/scripting_environment.hpp"
|
||||
|
||||
#include "storage/tar_fwd.hpp"
|
||||
#include "traffic_lights.hpp"
|
||||
#include "traffic_signals.hpp"
|
||||
#include "traffic_flow_control_nodes.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
@ -27,20 +26,29 @@ namespace extractor
|
||||
*/
|
||||
class ExtractionContainers
|
||||
{
|
||||
public:
|
||||
using InputTrafficFlowControlNode = std::pair<OSMNodeID, TrafficFlowControlNodeDirection>;
|
||||
|
||||
private:
|
||||
using ReferencedWays = std::unordered_map<OSMWayID, NodesOfWay>;
|
||||
using ReferencedTrafficSignals =
|
||||
using ReferencedTrafficFlowControlNodes =
|
||||
std::pair<std::unordered_set<OSMNodeID>, std::unordered_multimap<OSMNodeID, OSMNodeID>>;
|
||||
// The relationship between way and nodes is lost during node preparation.
|
||||
// We identify the ways and nodes relevant to restrictions/overrides/signals prior to
|
||||
// node processing so that they can be referenced in the preparation phase.
|
||||
ReferencedWays IdentifyRestrictionWays();
|
||||
ReferencedWays IdentifyManeuverOverrideWays();
|
||||
ReferencedTrafficSignals IdentifyTrafficSignals();
|
||||
|
||||
ReferencedTrafficFlowControlNodes IdentifyTrafficFlowControlNodes(
|
||||
const std::vector<InputTrafficFlowControlNode> &external_traffic_control_nodes);
|
||||
|
||||
void PrepareNodes();
|
||||
void PrepareManeuverOverrides(const ReferencedWays &maneuver_override_ways);
|
||||
void PrepareRestrictions(const ReferencedWays &restriction_ways);
|
||||
void PrepareTrafficSignals(const ReferencedTrafficSignals &referenced_traffic_signals);
|
||||
void PrepareTrafficFlowControlNodes(
|
||||
const ReferencedTrafficFlowControlNodes &referenced_traffic_control_nodes,
|
||||
TrafficFlowControlNodes &internal_traffic_control_nodes);
|
||||
|
||||
void PrepareEdges(ScriptingEnvironment &scripting_environment);
|
||||
|
||||
void WriteCharData(const std::string &file_name);
|
||||
@ -54,7 +62,6 @@ class ExtractionContainers
|
||||
using NameOffsets = std::vector<size_t>;
|
||||
using WayIDVector = std::vector<OSMWayID>;
|
||||
using WayNodeIDOffsets = std::vector<size_t>;
|
||||
using InputTrafficSignal = std::pair<OSMNodeID, TrafficLightClass::Direction>;
|
||||
|
||||
std::vector<OSMNodeID> barrier_nodes;
|
||||
NodeIDVector used_node_id_list;
|
||||
@ -69,8 +76,14 @@ class ExtractionContainers
|
||||
|
||||
unsigned max_internal_node_id;
|
||||
|
||||
std::vector<InputTrafficSignal> external_traffic_signals;
|
||||
TrafficSignals internal_traffic_signals;
|
||||
std::vector<InputTrafficFlowControlNode> external_traffic_signals;
|
||||
TrafficFlowControlNodes internal_traffic_signals;
|
||||
|
||||
std::vector<InputTrafficFlowControlNode> external_stop_signs;
|
||||
TrafficFlowControlNodes internal_stop_signs;
|
||||
|
||||
std::vector<InputTrafficFlowControlNode> external_give_ways;
|
||||
TrafficFlowControlNodes internal_give_way_signs;
|
||||
|
||||
std::vector<NodeBasedEdge> used_edges;
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
#ifndef EXTRACTION_NODE_HPP
|
||||
#define EXTRACTION_NODE_HPP
|
||||
|
||||
#include "traffic_lights.hpp"
|
||||
#include "traffic_flow_control_nodes.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@ -10,14 +11,19 @@ namespace extractor
|
||||
|
||||
struct ExtractionNode
|
||||
{
|
||||
ExtractionNode() : traffic_lights(TrafficLightClass::NONE), barrier(false) {}
|
||||
ExtractionNode() : traffic_lights(TrafficFlowControlNodeDirection::NONE), barrier(false) {}
|
||||
void clear()
|
||||
{
|
||||
traffic_lights = TrafficLightClass::NONE;
|
||||
traffic_lights = TrafficFlowControlNodeDirection::NONE;
|
||||
stop_sign = TrafficFlowControlNodeDirection::NONE;
|
||||
give_way = TrafficFlowControlNodeDirection::NONE;
|
||||
barrier = false;
|
||||
}
|
||||
TrafficLightClass::Direction traffic_lights;
|
||||
TrafficFlowControlNodeDirection traffic_lights;
|
||||
bool barrier;
|
||||
|
||||
TrafficFlowControlNodeDirection stop_sign;
|
||||
TrafficFlowControlNodeDirection give_way;
|
||||
};
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
@ -51,6 +51,8 @@ struct ExtractionTurn
|
||||
int number_of_roads,
|
||||
bool is_u_turn,
|
||||
bool has_traffic_light,
|
||||
bool has_stop_sign,
|
||||
bool has_give_way_sign,
|
||||
bool is_left_hand_driving,
|
||||
bool source_restricted,
|
||||
TravelMode source_mode,
|
||||
@ -75,7 +77,8 @@ struct ExtractionTurn
|
||||
const std::vector<ExtractionTurnLeg> &roads_on_the_right,
|
||||
const std::vector<ExtractionTurnLeg> &roads_on_the_left)
|
||||
: angle(180. - angle), number_of_roads(number_of_roads), is_u_turn(is_u_turn),
|
||||
has_traffic_light(has_traffic_light), is_left_hand_driving(is_left_hand_driving),
|
||||
has_traffic_light(has_traffic_light), has_stop_sign(has_stop_sign),
|
||||
has_give_way_sign(has_give_way_sign), is_left_hand_driving(is_left_hand_driving),
|
||||
|
||||
source_restricted(source_restricted), source_mode(source_mode),
|
||||
source_is_motorway(source_is_motorway), source_is_link(source_is_link),
|
||||
@ -100,6 +103,8 @@ struct ExtractionTurn
|
||||
const int number_of_roads;
|
||||
const bool is_u_turn;
|
||||
const bool has_traffic_light;
|
||||
const bool has_stop_sign;
|
||||
const bool has_give_way_sign;
|
||||
const bool is_left_hand_driving;
|
||||
|
||||
// source info
|
||||
|
@ -43,7 +43,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
|
||||
#include "restriction_graph.hpp"
|
||||
#include "traffic_signals.hpp"
|
||||
#include "traffic_flow_control_nodes.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
namespace osrm
|
||||
@ -66,7 +66,9 @@ class Extractor
|
||||
LaneDescriptionMap turn_lane_map;
|
||||
std::vector<TurnRestriction> turn_restrictions;
|
||||
std::vector<UnresolvedManeuverOverride> unresolved_maneuver_overrides;
|
||||
TrafficSignals traffic_signals;
|
||||
TrafficFlowControlNodes traffic_signals;
|
||||
TrafficFlowControlNodes stop_signs;
|
||||
TrafficFlowControlNodes give_way_signs;
|
||||
std::unordered_set<NodeID> barriers;
|
||||
std::vector<util::Coordinate> osm_coordinates;
|
||||
extractor::PackedOSMIDs osm_node_ids;
|
||||
@ -86,7 +88,9 @@ class Extractor
|
||||
const std::vector<util::Coordinate> &coordinates,
|
||||
const CompressedEdgeContainer &compressed_edge_container,
|
||||
const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const TrafficSignals &traffic_signals,
|
||||
const TrafficFlowControlNodes &traffic_signals,
|
||||
const TrafficFlowControlNodes &stop_signs,
|
||||
const TrafficFlowControlNodes &give_way_signs,
|
||||
const RestrictionGraph &restriction_graph,
|
||||
const std::unordered_set<EdgeID> &segregated_edges,
|
||||
const NameTable &name_table,
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace osmium
|
||||
{
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "extractor/scripting_environment.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include "traffic_signals.hpp"
|
||||
#include "traffic_flow_control_nodes.hpp"
|
||||
#include "util/node_based_graph.hpp"
|
||||
|
||||
#include <memory>
|
||||
@ -26,7 +26,9 @@ class GraphCompressor
|
||||
|
||||
public:
|
||||
void Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const TrafficSignals &traffic_signals,
|
||||
const TrafficFlowControlNodes &traffic_signals,
|
||||
const TrafficFlowControlNodes &stop_signs,
|
||||
const TrafficFlowControlNodes &give_way_signs,
|
||||
ScriptingEnvironment &scripting_environment,
|
||||
std::vector<TurnRestriction> &turn_restrictions,
|
||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "extractor/packed_osm_ids.hpp"
|
||||
#include "extractor/scripting_environment.hpp"
|
||||
|
||||
#include "traffic_signals.hpp"
|
||||
#include "traffic_flow_control_nodes.hpp"
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/node_based_graph.hpp"
|
||||
|
||||
@ -41,7 +41,9 @@ class NodeBasedGraphFactory
|
||||
NodeBasedGraphFactory(ScriptingEnvironment &scripting_environment,
|
||||
std::vector<TurnRestriction> &turn_restrictions,
|
||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
||||
const TrafficSignals &traffic_signals,
|
||||
const TrafficFlowControlNodes &traffic_signals,
|
||||
const TrafficFlowControlNodes &stop_signs,
|
||||
const TrafficFlowControlNodes &give_way_signs,
|
||||
std::unordered_set<NodeID> &&barriers,
|
||||
std::vector<util::Coordinate> &&coordinates,
|
||||
extractor::PackedOSMIDs &&osm_node_ids,
|
||||
@ -73,7 +75,9 @@ class NodeBasedGraphFactory
|
||||
void Compress(ScriptingEnvironment &scripting_environment,
|
||||
std::vector<TurnRestriction> &turn_restrictions,
|
||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
||||
const TrafficSignals &traffic_signals);
|
||||
const TrafficFlowControlNodes &traffic_signals,
|
||||
const TrafficFlowControlNodes &stop_signs,
|
||||
const TrafficFlowControlNodes &give_way_signs);
|
||||
|
||||
// Most ways are bidirectional, making the geometry in forward and backward direction the same,
|
||||
// except for reversal. We make use of this fact by keeping only one representation of the
|
||||
|
@ -11,17 +11,29 @@ namespace osrm
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
struct TrafficSignals
|
||||
// The direction annotation is extracted from node tags.
|
||||
// The directions in which traffic flow object applies are relative to the way containing the node.
|
||||
enum class TrafficFlowControlNodeDirection : std::uint8_t
|
||||
{
|
||||
NONE = 0,
|
||||
ALL = 1,
|
||||
FORWARD = 2,
|
||||
REVERSE = 3
|
||||
};
|
||||
|
||||
// represents traffic lights, stop signs, give way signs, etc.
|
||||
struct TrafficFlowControlNodes
|
||||
{
|
||||
std::unordered_set<NodeID> bidirectional_nodes;
|
||||
std::unordered_set<std::pair<NodeID, NodeID>, boost::hash<std::pair<NodeID, NodeID>>>
|
||||
unidirectional_segments;
|
||||
|
||||
inline bool HasSignal(NodeID from, NodeID to) const
|
||||
inline bool Has(NodeID from, NodeID to) const
|
||||
{
|
||||
return bidirectional_nodes.count(to) > 0 || unidirectional_segments.count({from, to}) > 0;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
@ -1,25 +0,0 @@
|
||||
#ifndef OSRM_EXTRACTOR_TRAFFIC_LIGHTS_DATA_HPP_
|
||||
#define OSRM_EXTRACTOR_TRAFFIC_LIGHTS_DATA_HPP_
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
namespace TrafficLightClass
|
||||
{
|
||||
// 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.
|
||||
enum Direction
|
||||
{
|
||||
NONE = 0,
|
||||
DIRECTION_ALL = 1,
|
||||
DIRECTION_FORWARD = 2,
|
||||
DIRECTION_REVERSE = 3
|
||||
};
|
||||
} // namespace TrafficLightClass
|
||||
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif // OSRM_EXTRACTOR_TRAFFIC_LIGHTS_DATA_HPP_
|
@ -7,6 +7,8 @@ Sequence = require('lib/sequence')
|
||||
Handlers = require("lib/way_handlers")
|
||||
Relations = require("lib/relations")
|
||||
TrafficSignal = require("lib/traffic_signal")
|
||||
StopSign = require("lib/stop_sign")
|
||||
GiveWay = require("lib/give_way")
|
||||
find_access_tag = require("lib/access").find_access_tag
|
||||
limit = require("lib/maxspeed").limit
|
||||
Utils = require("lib/utils")
|
||||
@ -28,6 +30,8 @@ function setup()
|
||||
use_turn_restrictions = true,
|
||||
left_hand_driving = false,
|
||||
traffic_light_penalty = 2,
|
||||
stop_sign_penalty = 2,
|
||||
give_way_sign_penalty = 1.5
|
||||
},
|
||||
|
||||
default_mode = mode.driving,
|
||||
@ -362,6 +366,12 @@ function process_node(profile, node, result, relations)
|
||||
|
||||
-- check if node is a traffic light
|
||||
result.traffic_lights = TrafficSignal.get_value(node)
|
||||
|
||||
-- check if node is stop sign
|
||||
result.stop_sign = StopSign.get_value(node)
|
||||
|
||||
-- check if node is a give way sign
|
||||
result.give_way = GiveWay.get_value(node)
|
||||
end
|
||||
|
||||
function process_way(profile, way, result, relations)
|
||||
@ -471,9 +481,14 @@ function process_turn(profile, turn)
|
||||
local turn_bias = turn.is_left_hand_driving and 1. / profile.turn_bias or profile.turn_bias
|
||||
|
||||
if turn.has_traffic_light then
|
||||
turn.duration = profile.properties.traffic_light_penalty
|
||||
turn.duration = profile.properties.traffic_light_penalty
|
||||
elseif turn.has_stop_sign then
|
||||
turn.duration = profile.properties.stop_sign_penalty
|
||||
elseif turn.has_give_way_sign then
|
||||
turn.duration = profile.properties.give_way_sign_penalty
|
||||
end
|
||||
|
||||
|
||||
if turn.number_of_roads > 2 or turn.source_mode ~= turn.target_mode or turn.is_u_turn then
|
||||
if turn.angle >= 0 then
|
||||
turn.duration = turn.duration + turn_penalty / (1 + math.exp( -((13 / turn_bias) * turn.angle/180 - 6.5*turn_bias)))
|
||||
|
9
profiles/lib/give_way.lua
Normal file
9
profiles/lib/give_way.lua
Normal file
@ -0,0 +1,9 @@
|
||||
local GiveWay = {}
|
||||
|
||||
TrafficFlowControlNode = require("lib/traffic_flow_control_node")
|
||||
|
||||
function GiveWay.get_value(node)
|
||||
return TrafficFlowControlNode.get_value(node, "give_way")
|
||||
end
|
||||
|
||||
return GiveWay
|
10
profiles/lib/stop_sign.lua
Normal file
10
profiles/lib/stop_sign.lua
Normal file
@ -0,0 +1,10 @@
|
||||
local StopSign = {}
|
||||
|
||||
TrafficFlowControlNode = require("lib/traffic_flow_control_node")
|
||||
|
||||
function StopSign.get_value(node)
|
||||
return TrafficFlowControlNode.get_value(node, "stop")
|
||||
end
|
||||
|
||||
return StopSign
|
||||
|
21
profiles/lib/traffic_flow_control_node.lua
Normal file
21
profiles/lib/traffic_flow_control_node.lua
Normal file
@ -0,0 +1,21 @@
|
||||
local TrafficFlowControlNode = {}
|
||||
|
||||
function TrafficFlowControlNode.get_value(node, tag_name)
|
||||
local tag = node:get_value_by_key("highway")
|
||||
if tag_name == tag then
|
||||
local direction = node:get_value_by_key("direction")
|
||||
if direction then
|
||||
if "forward" == direction then
|
||||
return traffic_flow_control_direction.direction_forward
|
||||
end
|
||||
if "backward" == direction then
|
||||
return traffic_flow_control_direction.direction_reverse
|
||||
end
|
||||
end
|
||||
return traffic_flow_control_direction.direction_all
|
||||
end
|
||||
return traffic_flow_control_direction.none
|
||||
end
|
||||
|
||||
return TrafficFlowControlNode
|
||||
|
@ -9,10 +9,10 @@ function TrafficSignal.get_value(node)
|
||||
local direction = node:get_value_by_key("traffic_signals:direction")
|
||||
if direction then
|
||||
if "forward" == direction then
|
||||
return traffic_lights.direction_forward
|
||||
return traffic_flow_control_direction.direction_forward
|
||||
end
|
||||
if "backward" == direction then
|
||||
return traffic_lights.direction_reverse
|
||||
return traffic_flow_control_direction.direction_reverse
|
||||
end
|
||||
end
|
||||
-- return traffic_lights.direction_all
|
||||
|
@ -45,7 +45,9 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
|
||||
EdgeBasedNodeDataContainer &node_data_container,
|
||||
const CompressedEdgeContainer &compressed_edge_container,
|
||||
const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const TrafficSignals &traffic_signals,
|
||||
const TrafficFlowControlNodes &traffic_signals,
|
||||
const TrafficFlowControlNodes &stop_signs,
|
||||
const TrafficFlowControlNodes &give_way_signs,
|
||||
const std::vector<util::Coordinate> &coordinates,
|
||||
const NameTable &name_table,
|
||||
const std::unordered_set<EdgeID> &segregated_edges,
|
||||
@ -53,7 +55,8 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
|
||||
: m_edge_based_node_container(node_data_container), m_connectivity_checksum(0),
|
||||
m_number_of_edge_based_nodes(0), m_coordinates(coordinates),
|
||||
m_node_based_graph(node_based_graph), m_barrier_nodes(barrier_nodes),
|
||||
m_traffic_signals(traffic_signals), m_compressed_edge_container(compressed_edge_container),
|
||||
m_traffic_signals(traffic_signals), m_stop_signs(stop_signs),
|
||||
m_give_way_signs(give_way_signs), m_compressed_edge_container(compressed_edge_container),
|
||||
name_table(name_table), segregated_edges(segregated_edges),
|
||||
lane_description_map(lane_description_map)
|
||||
{
|
||||
@ -629,7 +632,10 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
// In theory we shouldn't get a directed traffic light on a turn, as it indicates that
|
||||
// the traffic signal direction was potentially ambiguously annotated on the junction
|
||||
// node But we'll check anyway.
|
||||
const auto is_traffic_light = m_traffic_signals.HasSignal(from_node, intersection_node);
|
||||
const auto is_traffic_light = m_traffic_signals.Has(from_node, intersection_node);
|
||||
const auto is_stop_sign = m_stop_signs.Has(from_node, intersection_node);
|
||||
const auto is_give_way_sign = m_give_way_signs.Has(from_node, intersection_node);
|
||||
|
||||
const auto is_uturn =
|
||||
guidance::getTurnDirection(turn_angle) == guidance::DirectionModifier::UTurn;
|
||||
|
||||
@ -639,6 +645,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
road_legs_on_the_right.size() + road_legs_on_the_left.size() + 2 - is_uturn,
|
||||
is_uturn,
|
||||
is_traffic_light,
|
||||
is_stop_sign,
|
||||
is_give_way_sign,
|
||||
m_edge_based_node_container.GetAnnotation(edge_data1.annotation_data)
|
||||
.is_left_hand_driving,
|
||||
// source info
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "extractor/name_table.hpp"
|
||||
#include "extractor/restriction.hpp"
|
||||
#include "extractor/serialization.hpp"
|
||||
#include "extractor/traffic_flow_control_nodes.hpp"
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
#include "util/integer_range.hpp"
|
||||
|
||||
@ -412,12 +413,17 @@ void ExtractionContainers::PrepareData(ScriptingEnvironment &scripting_environme
|
||||
{
|
||||
const auto restriction_ways = IdentifyRestrictionWays();
|
||||
const auto maneuver_override_ways = IdentifyManeuverOverrideWays();
|
||||
const auto traffic_signals = IdentifyTrafficSignals();
|
||||
const auto traffic_signals = IdentifyTrafficFlowControlNodes(external_traffic_signals);
|
||||
const auto stop_signs = IdentifyTrafficFlowControlNodes(external_stop_signs);
|
||||
const auto give_ways = IdentifyTrafficFlowControlNodes(external_give_ways);
|
||||
|
||||
PrepareNodes();
|
||||
PrepareEdges(scripting_environment);
|
||||
|
||||
PrepareTrafficSignals(traffic_signals);
|
||||
PrepareTrafficFlowControlNodes(traffic_signals, internal_traffic_signals);
|
||||
PrepareTrafficFlowControlNodes(stop_signs, internal_stop_signs);
|
||||
PrepareTrafficFlowControlNodes(give_ways, internal_give_way_signs);
|
||||
|
||||
PrepareManeuverOverrides(maneuver_override_ways);
|
||||
PrepareRestrictions(restriction_ways);
|
||||
WriteCharData(name_file_name);
|
||||
@ -935,23 +941,23 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyManeuverOverr
|
||||
return maneuver_override_ways;
|
||||
}
|
||||
|
||||
void ExtractionContainers::PrepareTrafficSignals(
|
||||
const ExtractionContainers::ReferencedTrafficSignals &referenced_traffic_signals)
|
||||
void ExtractionContainers::PrepareTrafficFlowControlNodes(
|
||||
const ReferencedTrafficFlowControlNodes &referenced_traffic_control_nodes,
|
||||
TrafficFlowControlNodes &internal_traffic_control_nodes)
|
||||
{
|
||||
const auto &bidirectional_signal_nodes = referenced_traffic_signals.first;
|
||||
const auto &unidirectional_signal_segments = referenced_traffic_signals.second;
|
||||
const auto &bidirectional_traffic_control_nodes = referenced_traffic_control_nodes.first;
|
||||
const auto &unidirectional_node_segments = referenced_traffic_control_nodes.second;
|
||||
|
||||
util::UnbufferedLog log;
|
||||
log << "Preparing traffic light signals for " << bidirectional_signal_nodes.size()
|
||||
<< " bidirectional, " << unidirectional_signal_segments.size()
|
||||
<< " unidirectional nodes ...";
|
||||
log << "Preparing traffic control nodes for " << bidirectional_traffic_control_nodes.size()
|
||||
<< " bidirectional, " << unidirectional_node_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)
|
||||
for (const auto &osm_node : bidirectional_traffic_control_nodes)
|
||||
{
|
||||
const auto node_id = mapExternalToInternalNodeID(
|
||||
used_node_id_list.begin(), used_node_id_list.end(), osm_node);
|
||||
@ -960,7 +966,7 @@ void ExtractionContainers::PrepareTrafficSignals(
|
||||
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(
|
||||
used_node_id_list.begin(), used_node_id_list.end(), to_from.first);
|
||||
@ -972,8 +978,8 @@ void ExtractionContainers::PrepareTrafficSignals(
|
||||
}
|
||||
}
|
||||
|
||||
internal_traffic_signals.bidirectional_nodes = std::move(bidirectional);
|
||||
internal_traffic_signals.unidirectional_segments = std::move(unidirectional);
|
||||
internal_traffic_control_nodes.bidirectional_nodes = std::move(bidirectional);
|
||||
internal_traffic_control_nodes.unidirectional_segments = std::move(unidirectional);
|
||||
|
||||
TIMER_STOP(prepare_traffic_signals);
|
||||
log << "ok, after " << TIMER_SEC(prepare_traffic_signals) << "s";
|
||||
@ -1159,37 +1165,39 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyRestrictionWa
|
||||
return restriction_ways;
|
||||
}
|
||||
|
||||
ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTrafficSignals()
|
||||
ExtractionContainers::ReferencedTrafficFlowControlNodes
|
||||
ExtractionContainers::IdentifyTrafficFlowControlNodes(
|
||||
const std::vector<InputTrafficFlowControlNode> &external_nodes)
|
||||
{
|
||||
util::UnbufferedLog log;
|
||||
log << "Collecting traffic signal information on " << external_traffic_signals.size()
|
||||
<< " signals...";
|
||||
TIMER_START(identify_traffic_signals);
|
||||
log << "Collecting traffic nodes information on " << external_nodes.size() << " nodes...";
|
||||
TIMER_START(identify_traffic_flow_control_nodes);
|
||||
|
||||
// Temporary store for nodes containing a unidirectional signal.
|
||||
std::unordered_map<OSMNodeID, TrafficLightClass::Direction> unidirectional_signals;
|
||||
std::unordered_map<OSMNodeID, TrafficFlowControlNodeDirection> unidirectional_traffic_nodes;
|
||||
|
||||
// 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_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) {
|
||||
if (traffic_signal.second == TrafficLightClass::DIRECTION_FORWARD ||
|
||||
traffic_signal.second == TrafficLightClass::DIRECTION_REVERSE)
|
||||
const auto mark_traffic_nodes = [&](auto const &traffic_control_node) {
|
||||
if (traffic_control_node.second == TrafficFlowControlNodeDirection::FORWARD ||
|
||||
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
|
||||
{
|
||||
BOOST_ASSERT(traffic_signal.second == TrafficLightClass::DIRECTION_ALL);
|
||||
bidirectional_signals.insert(traffic_signal.first);
|
||||
BOOST_ASSERT(traffic_control_node.second == TrafficFlowControlNodeDirection::ALL);
|
||||
bidirectional_traffic_nodes.insert(traffic_control_node.first);
|
||||
}
|
||||
};
|
||||
std::for_each(external_traffic_signals.begin(), external_traffic_signals.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 flow control nodes.
|
||||
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];
|
||||
@ -1198,24 +1206,24 @@ ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTra
|
||||
|
||||
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())
|
||||
const auto sig = unidirectional_traffic_nodes.find(*node_it);
|
||||
if (sig != unidirectional_traffic_nodes.end())
|
||||
{
|
||||
if (sig->second == TrafficLightClass::DIRECTION_FORWARD)
|
||||
if (sig->second == TrafficFlowControlNodeDirection::FORWARD)
|
||||
{
|
||||
if (node_it != node_start_offset)
|
||||
{
|
||||
// Previous node leads to signal
|
||||
signal_segments.insert({*node_it, *(node_it - 1)});
|
||||
node_segments.insert({*node_it, *(node_it - 1)});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(sig->second == TrafficLightClass::DIRECTION_REVERSE);
|
||||
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)});
|
||||
node_segments.insert({*node_it, *(node_it + 1)});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1224,7 +1232,7 @@ 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) {
|
||||
node_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.
|
||||
@ -1240,10 +1248,10 @@ ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTra
|
||||
}
|
||||
});
|
||||
|
||||
TIMER_STOP(identify_traffic_signals);
|
||||
log << "ok, after " << TIMER_SEC(identify_traffic_signals) << "s";
|
||||
TIMER_STOP(identify_traffic_flow_control_nodes);
|
||||
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)};
|
||||
}
|
||||
|
||||
void ExtractionContainers::PrepareRestrictions(const ReferencedWays &restriction_ways)
|
||||
|
@ -226,6 +226,8 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
|
||||
parsed_osm_data.turn_restrictions,
|
||||
parsed_osm_data.unresolved_maneuver_overrides,
|
||||
parsed_osm_data.traffic_signals,
|
||||
parsed_osm_data.stop_signs,
|
||||
parsed_osm_data.give_way_signs,
|
||||
std::move(parsed_osm_data.barriers),
|
||||
std::move(parsed_osm_data.osm_coordinates),
|
||||
std::move(parsed_osm_data.osm_node_ids),
|
||||
@ -283,6 +285,8 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
|
||||
node_based_graph_factory.GetCompressedEdges(),
|
||||
barrier_nodes,
|
||||
parsed_osm_data.traffic_signals,
|
||||
parsed_osm_data.stop_signs,
|
||||
parsed_osm_data.give_way_signs,
|
||||
restriction_graph,
|
||||
segregated_edges,
|
||||
name_table,
|
||||
@ -649,6 +653,8 @@ Extractor::ParsedOSMData Extractor::ParseOSMData(ScriptingEnvironment &scripting
|
||||
std::move(extraction_containers.turn_restrictions),
|
||||
std::move(extraction_containers.internal_maneuver_overrides),
|
||||
std::move(extraction_containers.internal_traffic_signals),
|
||||
std::move(extraction_containers.internal_stop_signs),
|
||||
std::move(extraction_containers.internal_give_way_signs),
|
||||
std::move(extraction_containers.used_barrier_nodes),
|
||||
std::move(osm_coordinates),
|
||||
std::move(osm_node_ids),
|
||||
@ -724,7 +730,9 @@ EdgeID Extractor::BuildEdgeExpandedGraph(
|
||||
const std::vector<util::Coordinate> &coordinates,
|
||||
const CompressedEdgeContainer &compressed_edge_container,
|
||||
const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const TrafficSignals &traffic_signals,
|
||||
const TrafficFlowControlNodes &traffic_signals,
|
||||
const TrafficFlowControlNodes &stop_signs,
|
||||
const TrafficFlowControlNodes &give_way_signs,
|
||||
const RestrictionGraph &restriction_graph,
|
||||
const std::unordered_set<EdgeID> &segregated_edges,
|
||||
const NameTable &name_table,
|
||||
@ -746,6 +754,8 @@ EdgeID Extractor::BuildEdgeExpandedGraph(
|
||||
compressed_edge_container,
|
||||
barrier_nodes,
|
||||
traffic_signals,
|
||||
stop_signs,
|
||||
give_way_signs,
|
||||
coordinates,
|
||||
name_table,
|
||||
segregated_edges,
|
||||
|
@ -78,10 +78,23 @@ void ExtractorCallbacks::ProcessNode(const osmium::Node &input_node,
|
||||
{
|
||||
external_memory.barrier_nodes.push_back(id);
|
||||
}
|
||||
if (result_node.traffic_lights != TrafficLightClass::NONE)
|
||||
if (result_node.traffic_lights != TrafficFlowControlNodeDirection::NONE)
|
||||
{
|
||||
external_memory.external_traffic_signals.push_back({id, result_node.traffic_lights});
|
||||
}
|
||||
// TODO: we ignore `ALL` for both stop signs and give way signs, because we cannot understand
|
||||
// direction of the way they should be applied yet see:
|
||||
// https://wiki.openstreetmap.org/wiki/Tag:highway%3Dstop#Direction
|
||||
if (result_node.give_way != TrafficFlowControlNodeDirection::NONE &&
|
||||
result_node.give_way != TrafficFlowControlNodeDirection::ALL)
|
||||
{
|
||||
external_memory.external_give_ways.push_back({id, result_node.give_way});
|
||||
}
|
||||
if (result_node.stop_sign != TrafficFlowControlNodeDirection::NONE &&
|
||||
result_node.stop_sign != TrafficFlowControlNodeDirection::ALL)
|
||||
{
|
||||
external_memory.external_stop_signs.push_back({id, result_node.stop_sign});
|
||||
}
|
||||
}
|
||||
|
||||
void ExtractorCallbacks::ProcessRestriction(const InputTurnRestriction &restriction)
|
||||
|
@ -22,7 +22,9 @@ namespace extractor
|
||||
static constexpr int SECOND_TO_DECISECOND = 10;
|
||||
|
||||
void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const TrafficSignals &traffic_signals,
|
||||
const TrafficFlowControlNodes &traffic_signals,
|
||||
const TrafficFlowControlNodes &stop_signs,
|
||||
const TrafficFlowControlNodes &give_way_signs,
|
||||
ScriptingEnvironment &scripting_environment,
|
||||
std::vector<TurnRestriction> &turn_restrictions,
|
||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
||||
@ -208,15 +210,22 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
graph.GetEdgeData(reverse_e2).annotation_data = selectAnnotation(
|
||||
rev_edge_data2.annotation_data, rev_edge_data1.annotation_data);
|
||||
|
||||
// Add node penalty when compress edge crosses a traffic signal
|
||||
const bool has_forward_signal = traffic_signals.HasSignal(node_u, node_v);
|
||||
const bool has_reverse_signal = traffic_signals.HasSignal(node_w, node_v);
|
||||
// Add node penalty when compress edge crosses a traffic signal/stop sign/give way
|
||||
const bool has_forward_signal = traffic_signals.Has(node_u, node_v);
|
||||
const bool has_reverse_signal = traffic_signals.Has(node_w, 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_forward_give_way_sign = give_way_signs.Has(node_u, node_v);
|
||||
const bool has_reverse_give_way_sign = give_way_signs.Has(node_w, node_v);
|
||||
|
||||
EdgeDuration forward_node_duration_penalty = MAXIMAL_EDGE_DURATION;
|
||||
EdgeWeight forward_node_weight_penalty = INVALID_EDGE_WEIGHT;
|
||||
EdgeDuration reverse_node_duration_penalty = MAXIMAL_EDGE_DURATION;
|
||||
EdgeWeight reverse_node_weight_penalty = INVALID_EDGE_WEIGHT;
|
||||
if (has_forward_signal || has_reverse_signal)
|
||||
if (has_forward_signal || has_reverse_signal || has_forward_stop_sign ||
|
||||
has_reverse_stop_sign || has_forward_give_way_sign || has_reverse_give_way_sign)
|
||||
{
|
||||
// we cannot handle this as node penalty, if it depends on turn direction
|
||||
if (fwd_edge_data1.flags.restricted != fwd_edge_data2.flags.restricted)
|
||||
@ -228,7 +237,10 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
ExtractionTurn extraction_turn(0,
|
||||
2,
|
||||
false,
|
||||
true,
|
||||
has_forward_signal || has_reverse_signal,
|
||||
has_forward_stop_sign || has_reverse_stop_sign,
|
||||
has_forward_give_way_sign ||
|
||||
has_reverse_give_way_sign,
|
||||
false,
|
||||
false,
|
||||
TRAVEL_MODE_DRIVING,
|
||||
@ -253,10 +265,10 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
scripting_environment.ProcessTurn(extraction_turn);
|
||||
|
||||
auto update_direction_penalty = [&extraction_turn, weight_multiplier](
|
||||
bool signal,
|
||||
bool has_traffic_control_node,
|
||||
EdgeDuration &duration_penalty,
|
||||
EdgeWeight &weight_penalty) {
|
||||
if (signal)
|
||||
if (has_traffic_control_node)
|
||||
{
|
||||
duration_penalty = to_alias<EdgeDuration>(extraction_turn.duration *
|
||||
SECOND_TO_DECISECOND);
|
||||
@ -265,10 +277,12 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
}
|
||||
};
|
||||
|
||||
update_direction_penalty(has_forward_signal,
|
||||
update_direction_penalty(has_forward_signal || has_forward_stop_sign ||
|
||||
has_forward_give_way_sign,
|
||||
forward_node_duration_penalty,
|
||||
forward_node_weight_penalty);
|
||||
update_direction_penalty(has_reverse_signal,
|
||||
update_direction_penalty(has_reverse_signal || has_reverse_stop_sign ||
|
||||
has_reverse_give_way_sign,
|
||||
reverse_node_duration_penalty,
|
||||
reverse_node_weight_penalty);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "extractor/node_based_graph_factory.hpp"
|
||||
#include "extractor/files.hpp"
|
||||
#include "extractor/graph_compressor.hpp"
|
||||
#include "extractor/traffic_flow_control_nodes.hpp"
|
||||
#include "storage/io.hpp"
|
||||
|
||||
#include "util/log.hpp"
|
||||
@ -19,7 +20,9 @@ NodeBasedGraphFactory::NodeBasedGraphFactory(
|
||||
ScriptingEnvironment &scripting_environment,
|
||||
std::vector<TurnRestriction> &turn_restrictions,
|
||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
||||
const TrafficSignals &traffic_signals,
|
||||
const TrafficFlowControlNodes &traffic_signals,
|
||||
const TrafficFlowControlNodes &stop_signs,
|
||||
const TrafficFlowControlNodes &give_way_signs,
|
||||
std::unordered_set<NodeID> &&barriers,
|
||||
std::vector<util::Coordinate> &&coordinates,
|
||||
extractor::PackedOSMIDs &&osm_node_ids,
|
||||
@ -29,7 +32,12 @@ NodeBasedGraphFactory::NodeBasedGraphFactory(
|
||||
coordinates(std::move(coordinates)), osm_node_ids(std::move(osm_node_ids))
|
||||
{
|
||||
BuildCompressedOutputGraph(edge_list);
|
||||
Compress(scripting_environment, turn_restrictions, maneuver_overrides, traffic_signals);
|
||||
Compress(scripting_environment,
|
||||
turn_restrictions,
|
||||
maneuver_overrides,
|
||||
traffic_signals,
|
||||
stop_signs,
|
||||
give_way_signs);
|
||||
CompressGeometry();
|
||||
CompressAnnotationData();
|
||||
}
|
||||
@ -74,11 +82,15 @@ void NodeBasedGraphFactory::BuildCompressedOutputGraph(const std::vector<NodeBas
|
||||
void NodeBasedGraphFactory::Compress(ScriptingEnvironment &scripting_environment,
|
||||
std::vector<TurnRestriction> &turn_restrictions,
|
||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
||||
const TrafficSignals &traffic_signals)
|
||||
const TrafficFlowControlNodes &traffic_signals,
|
||||
const TrafficFlowControlNodes &stop_signs,
|
||||
const TrafficFlowControlNodes &give_way_signs)
|
||||
{
|
||||
GraphCompressor graph_compressor;
|
||||
graph_compressor.Compress(barriers,
|
||||
traffic_signals,
|
||||
stop_signs,
|
||||
give_way_signs,
|
||||
scripting_environment,
|
||||
turn_restrictions,
|
||||
maneuver_overrides,
|
||||
|
@ -284,17 +284,26 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
[&context, &get_location_tag](const osmium::Node &node, const char *key) {
|
||||
return get_location_tag(context, node.location(), key);
|
||||
});
|
||||
|
||||
// just for backward compatibility
|
||||
// TODO: remove in v6
|
||||
context.state.new_enum("traffic_lights",
|
||||
"none",
|
||||
extractor::TrafficLightClass::NONE,
|
||||
extractor::TrafficFlowControlNodeDirection::NONE,
|
||||
"direction_all",
|
||||
extractor::TrafficLightClass::DIRECTION_ALL,
|
||||
extractor::TrafficFlowControlNodeDirection::ALL,
|
||||
"direction_forward",
|
||||
extractor::TrafficLightClass::DIRECTION_FORWARD,
|
||||
extractor::TrafficFlowControlNodeDirection::FORWARD,
|
||||
"direction_reverse",
|
||||
extractor::TrafficLightClass::DIRECTION_REVERSE);
|
||||
|
||||
extractor::TrafficFlowControlNodeDirection::REVERSE);
|
||||
context.state.new_enum("traffic_flow_control_direction",
|
||||
"none",
|
||||
extractor::TrafficFlowControlNodeDirection::NONE,
|
||||
"direction_all",
|
||||
extractor::TrafficFlowControlNodeDirection::ALL,
|
||||
"direction_forward",
|
||||
extractor::TrafficFlowControlNodeDirection::FORWARD,
|
||||
"direction_reverse",
|
||||
extractor::TrafficFlowControlNodeDirection::REVERSE);
|
||||
context.state.new_usertype<ExtractionNode>(
|
||||
"ResultNode",
|
||||
"traffic_lights",
|
||||
@ -306,18 +315,30 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
// state to the node is converted to the class enum
|
||||
// TODO: Make a breaking API change and remove this option.
|
||||
bool val = obj.as<bool>();
|
||||
node.traffic_lights = (val) ? TrafficLightClass::DIRECTION_ALL
|
||||
: TrafficLightClass::NONE;
|
||||
node.traffic_lights = (val) ? TrafficFlowControlNodeDirection::ALL
|
||||
: TrafficFlowControlNodeDirection::NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
BOOST_ASSERT(obj.is<TrafficLightClass::Direction>());
|
||||
BOOST_ASSERT(obj.is<TrafficFlowControlNodeDirection>());
|
||||
{
|
||||
TrafficLightClass::Direction val =
|
||||
obj.as<TrafficLightClass::Direction>();
|
||||
TrafficFlowControlNodeDirection val =
|
||||
obj.as<TrafficFlowControlNodeDirection>();
|
||||
node.traffic_lights = val;
|
||||
}
|
||||
}),
|
||||
"stop_sign",
|
||||
sol::property([](const ExtractionNode &node) { return node.stop_sign; },
|
||||
[](ExtractionNode &node, const sol::object &obj) {
|
||||
BOOST_ASSERT(obj.is<TrafficFlowControlNodeDirection>());
|
||||
node.stop_sign = obj.as<TrafficFlowControlNodeDirection>();
|
||||
}),
|
||||
"give_way",
|
||||
sol::property([](const ExtractionNode &node) { return node.give_way; },
|
||||
[](ExtractionNode &node, const sol::object &obj) {
|
||||
BOOST_ASSERT(obj.is<TrafficFlowControlNodeDirection>());
|
||||
node.give_way = obj.as<TrafficFlowControlNodeDirection>();
|
||||
}),
|
||||
"barrier",
|
||||
&ExtractionNode::barrier);
|
||||
|
||||
@ -763,9 +784,12 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
&ExtractionTurn::is_u_turn,
|
||||
"has_traffic_light",
|
||||
&ExtractionTurn::has_traffic_light,
|
||||
"has_stop_sign",
|
||||
&ExtractionTurn::has_stop_sign,
|
||||
"has_give_way_sign",
|
||||
&ExtractionTurn::has_give_way_sign,
|
||||
"is_left_hand_driving",
|
||||
&ExtractionTurn::is_left_hand_driving,
|
||||
|
||||
"source_restricted",
|
||||
&ExtractionTurn::source_restricted,
|
||||
"source_mode",
|
||||
@ -1130,10 +1154,15 @@ void Sol2ScriptingEnvironment::ProcessTurn(ExtractionTurn &turn)
|
||||
// Turn weight falls back to the duration value in deciseconds
|
||||
// or uses the extracted unit-less weight value
|
||||
if (context.properties.fallback_to_duration)
|
||||
{
|
||||
turn.weight = turn.duration;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// cap turn weight to max turn weight, which depend on weight precision
|
||||
turn.weight = std::min(turn.weight, context.properties.GetMaxTurnWeight());
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -125,6 +125,8 @@
|
||||
{"key": "side_road", "value": "rotary", "description": "gets speed penalty"},
|
||||
{"key": "route", "object_types": ["way"]},
|
||||
{"key": "highway", "value": "traffic_signals", "object_types": ["node"]},
|
||||
{"key": "highway", "value": "stop", "object_types": ["node"]},
|
||||
{"key": "highway", "value": "give_way", "object_types": ["node"]},
|
||||
{"key": "highway", "value": "crossing", "object_types": ["node"]},
|
||||
{"key": "access", "value": "yes"},
|
||||
{"key": "access", "value": "motorcar"},
|
||||
|
@ -65,7 +65,9 @@ BOOST_AUTO_TEST_CASE(long_road_test)
|
||||
GraphCompressor compressor;
|
||||
|
||||
std::unordered_set<NodeID> barrier_nodes;
|
||||
TrafficSignals traffic_lights;
|
||||
TrafficFlowControlNodes traffic_lights;
|
||||
TrafficFlowControlNodes stop_signs;
|
||||
TrafficFlowControlNodes give_way_signs;
|
||||
std::vector<TurnRestriction> restrictions;
|
||||
std::vector<NodeBasedEdgeAnnotation> annotations(1);
|
||||
CompressedEdgeContainer container;
|
||||
@ -88,6 +90,8 @@ BOOST_AUTO_TEST_CASE(long_road_test)
|
||||
|
||||
compressor.Compress(barrier_nodes,
|
||||
traffic_lights,
|
||||
stop_signs,
|
||||
give_way_signs,
|
||||
scripting_environment,
|
||||
restrictions,
|
||||
maneuver_overrides,
|
||||
@ -111,7 +115,9 @@ BOOST_AUTO_TEST_CASE(loop_test)
|
||||
GraphCompressor compressor;
|
||||
|
||||
std::unordered_set<NodeID> barrier_nodes;
|
||||
TrafficSignals traffic_lights;
|
||||
TrafficFlowControlNodes traffic_lights;
|
||||
TrafficFlowControlNodes stop_signs;
|
||||
TrafficFlowControlNodes give_way_signs;
|
||||
std::vector<TurnRestriction> restrictions;
|
||||
CompressedEdgeContainer container;
|
||||
std::vector<NodeBasedEdgeAnnotation> annotations(1);
|
||||
@ -148,6 +154,8 @@ BOOST_AUTO_TEST_CASE(loop_test)
|
||||
|
||||
compressor.Compress(barrier_nodes,
|
||||
traffic_lights,
|
||||
stop_signs,
|
||||
give_way_signs,
|
||||
scripting_environment,
|
||||
restrictions,
|
||||
maneuver_overrides,
|
||||
@ -174,7 +182,9 @@ BOOST_AUTO_TEST_CASE(t_intersection)
|
||||
GraphCompressor compressor;
|
||||
|
||||
std::unordered_set<NodeID> barrier_nodes;
|
||||
TrafficSignals traffic_lights;
|
||||
TrafficFlowControlNodes traffic_lights;
|
||||
TrafficFlowControlNodes stop_signs;
|
||||
TrafficFlowControlNodes give_way_signs;
|
||||
std::vector<NodeBasedEdgeAnnotation> annotations(1);
|
||||
std::vector<TurnRestriction> restrictions;
|
||||
CompressedEdgeContainer container;
|
||||
@ -197,6 +207,8 @@ BOOST_AUTO_TEST_CASE(t_intersection)
|
||||
|
||||
compressor.Compress(barrier_nodes,
|
||||
traffic_lights,
|
||||
stop_signs,
|
||||
give_way_signs,
|
||||
scripting_environment,
|
||||
restrictions,
|
||||
maneuver_overrides,
|
||||
@ -217,7 +229,9 @@ BOOST_AUTO_TEST_CASE(street_name_changes)
|
||||
GraphCompressor compressor;
|
||||
|
||||
std::unordered_set<NodeID> barrier_nodes;
|
||||
TrafficSignals traffic_lights;
|
||||
TrafficFlowControlNodes traffic_lights;
|
||||
TrafficFlowControlNodes stop_signs;
|
||||
TrafficFlowControlNodes give_way_signs;
|
||||
std::vector<NodeBasedEdgeAnnotation> annotations(2);
|
||||
std::vector<TurnRestriction> restrictions;
|
||||
CompressedEdgeContainer container;
|
||||
@ -236,6 +250,8 @@ BOOST_AUTO_TEST_CASE(street_name_changes)
|
||||
|
||||
compressor.Compress(barrier_nodes,
|
||||
traffic_lights,
|
||||
stop_signs,
|
||||
give_way_signs,
|
||||
scripting_environment,
|
||||
restrictions,
|
||||
maneuver_overrides,
|
||||
@ -255,7 +271,9 @@ BOOST_AUTO_TEST_CASE(direction_changes)
|
||||
GraphCompressor compressor;
|
||||
|
||||
std::unordered_set<NodeID> barrier_nodes;
|
||||
TrafficSignals traffic_lights;
|
||||
TrafficFlowControlNodes traffic_lights;
|
||||
TrafficFlowControlNodes stop_signs;
|
||||
TrafficFlowControlNodes give_way_signs;
|
||||
std::vector<NodeBasedEdgeAnnotation> annotations(1);
|
||||
std::vector<TurnRestriction> restrictions;
|
||||
CompressedEdgeContainer container;
|
||||
@ -270,6 +288,8 @@ BOOST_AUTO_TEST_CASE(direction_changes)
|
||||
Graph graph(5, edges);
|
||||
compressor.Compress(barrier_nodes,
|
||||
traffic_lights,
|
||||
stop_signs,
|
||||
give_way_signs,
|
||||
scripting_environment,
|
||||
restrictions,
|
||||
maneuver_overrides,
|
||||
|
@ -19,7 +19,10 @@ using Graph = util::NodeBasedDynamicGraph;
|
||||
BOOST_AUTO_TEST_CASE(simple_intersection_connectivity)
|
||||
{
|
||||
std::unordered_set<NodeID> barrier_nodes{6};
|
||||
TrafficSignals traffic_lights;
|
||||
TrafficFlowControlNodes traffic_lights;
|
||||
TrafficFlowControlNodes stop_signs;
|
||||
TrafficFlowControlNodes give_way_signs;
|
||||
|
||||
std::vector<NodeBasedEdgeAnnotation> annotations{
|
||||
{EMPTY_NAMEID, 0, INAVLID_CLASS_DATA, TRAVEL_MODE_DRIVING, false},
|
||||
{EMPTY_NAMEID, 1, INAVLID_CLASS_DATA, TRAVEL_MODE_DRIVING, false}};
|
||||
@ -87,6 +90,8 @@ BOOST_AUTO_TEST_CASE(simple_intersection_connectivity)
|
||||
|
||||
GraphCompressor().Compress(barrier_nodes,
|
||||
traffic_lights,
|
||||
stop_signs,
|
||||
give_way_signs,
|
||||
scripting_environment,
|
||||
restrictions,
|
||||
maneuver_overrides,
|
||||
@ -152,7 +157,9 @@ BOOST_AUTO_TEST_CASE(simple_intersection_connectivity)
|
||||
BOOST_AUTO_TEST_CASE(roundabout_intersection_connectivity)
|
||||
{
|
||||
std::unordered_set<NodeID> barrier_nodes;
|
||||
TrafficSignals traffic_lights;
|
||||
TrafficFlowControlNodes traffic_lights;
|
||||
TrafficFlowControlNodes stop_signs;
|
||||
TrafficFlowControlNodes give_way_signs;
|
||||
std::vector<NodeBasedEdgeAnnotation> annotations;
|
||||
std::vector<TurnRestriction> restrictions;
|
||||
CompressedEdgeContainer container;
|
||||
@ -210,6 +217,8 @@ BOOST_AUTO_TEST_CASE(roundabout_intersection_connectivity)
|
||||
|
||||
GraphCompressor().Compress(barrier_nodes,
|
||||
traffic_lights,
|
||||
stop_signs,
|
||||
give_way_signs,
|
||||
scripting_environment,
|
||||
restrictions,
|
||||
maneuver_overrides,
|
||||
@ -259,7 +268,9 @@ BOOST_AUTO_TEST_CASE(roundabout_intersection_connectivity)
|
||||
BOOST_AUTO_TEST_CASE(skip_degree_two_nodes)
|
||||
{
|
||||
std::unordered_set<NodeID> barrier_nodes{1};
|
||||
TrafficSignals traffic_lights = {{2}, {}};
|
||||
TrafficFlowControlNodes traffic_lights = {{2}, {}};
|
||||
TrafficFlowControlNodes stop_signs = {};
|
||||
TrafficFlowControlNodes give_way_signs = {};
|
||||
std::vector<NodeBasedEdgeAnnotation> annotations(1);
|
||||
std::vector<TurnRestriction> restrictions;
|
||||
CompressedEdgeContainer container;
|
||||
@ -309,6 +320,8 @@ BOOST_AUTO_TEST_CASE(skip_degree_two_nodes)
|
||||
|
||||
GraphCompressor().Compress(barrier_nodes,
|
||||
traffic_lights,
|
||||
stop_signs,
|
||||
give_way_signs,
|
||||
scripting_environment,
|
||||
restrictions,
|
||||
maneuver_overrides,
|
||||
|
Loading…
Reference in New Issue
Block a user