add support for junction=circular, allowing named circular junctions to be treated as rotaries
This commit is contained in:
parent
4636aaabfe
commit
12d58ace10
@ -547,7 +547,7 @@ step.
|
|||||||
| `use lane` | going straight on a specific lane |
|
| `use lane` | going straight on a specific lane |
|
||||||
| `continue` | Turn in direction of `modifier` to stay on the same road |
|
| `continue` | Turn in direction of `modifier` to stay on the same road |
|
||||||
| `roundabout` | traverse roundabout, has additional field `exit` with NR if the roundabout is left. `the modifier specifies the direction of entering the roundabout` |
|
| `roundabout` | traverse roundabout, has additional field `exit` with NR if the roundabout is left. `the modifier specifies the direction of entering the roundabout` |
|
||||||
| `rotary` | a larger version of a roundabout, can offer `rotary_name/rotary_pronunciation` in addition to the `exit` parameter. |
|
| `rotary` | a traffic circle. While very similar to a larger version of a roundabout, it does not necessarily follow roundabout rules for right of way. It can offer `rotary_name/rotary_pronunciation` in addition to the `exit` parameter. |
|
||||||
| `roundabout turn`| Describes a turn at a small roundabout that should be treated as normal turn. The `modifier` indicates the turn direciton. Example instruction: `At the roundabout turn left`. |
|
| `roundabout turn`| Describes a turn at a small roundabout that should be treated as normal turn. The `modifier` indicates the turn direciton. Example instruction: `At the roundabout turn left`. |
|
||||||
| `notification` | not an actual turn but a change in the driving conditions. For example the travel mode. If the road takes a turn itself, the `modifier` describes the direction |
|
| `notification` | not an actual turn but a change in the driving conditions. For example the travel mode. If the road takes a turn itself, the `modifier` describes the direction |
|
||||||
|
|
||||||
|
282
features/guidance/circular.feature
Normal file
282
features/guidance/circular.feature
Normal file
@ -0,0 +1,282 @@
|
|||||||
|
@routing @guidance
|
||||||
|
Feature: Rotary
|
||||||
|
|
||||||
|
Background:
|
||||||
|
Given the profile "car"
|
||||||
|
Given a grid size of 30 meters
|
||||||
|
|
||||||
|
Scenario: Enter and Exit
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a
|
||||||
|
b
|
||||||
|
h g c d
|
||||||
|
e
|
||||||
|
f
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | junction |
|
||||||
|
| ab | |
|
||||||
|
| cd | |
|
||||||
|
| ef | |
|
||||||
|
| gh | |
|
||||||
|
| bgecb | circular |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | ab,cd,cd | depart,bgecb-exit-3,arrive |
|
||||||
|
| a,f | ab,ef,ef | depart,bgecb-exit-2,arrive |
|
||||||
|
| a,h | ab,gh,gh | depart,bgecb-exit-1,arrive |
|
||||||
|
| d,f | cd,ef,ef | depart,bgecb-exit-3,arrive |
|
||||||
|
| d,h | cd,gh,gh | depart,bgecb-exit-2,arrive |
|
||||||
|
| d,a | cd,ab,ab | depart,bgecb-exit-1,arrive |
|
||||||
|
| f,h | ef,gh,gh | depart,bgecb-exit-3,arrive |
|
||||||
|
| f,a | ef,ab,ab | depart,bgecb-exit-2,arrive |
|
||||||
|
| f,d | ef,cd,cd | depart,bgecb-exit-1,arrive |
|
||||||
|
| h,a | gh,ab,ab | depart,bgecb-exit-3,arrive |
|
||||||
|
| h,d | gh,cd,cd | depart,bgecb-exit-2,arrive |
|
||||||
|
| h,f | gh,ef,ef | depart,bgecb-exit-1,arrive |
|
||||||
|
|
||||||
|
Scenario: Only Enter
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a
|
||||||
|
b
|
||||||
|
d c g h
|
||||||
|
e
|
||||||
|
f
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | junction |
|
||||||
|
| ab | |
|
||||||
|
| cd | |
|
||||||
|
| ef | |
|
||||||
|
| gh | |
|
||||||
|
| bcegb | circular |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,c | ab,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
|
||||||
|
| a,e | ab,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
|
||||||
|
| a,g | ab,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
|
||||||
|
| d,e | cd,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
|
||||||
|
| d,g | cd,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
|
||||||
|
| d,b | cd,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
|
||||||
|
| f,g | ef,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
|
||||||
|
| f,b | ef,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
|
||||||
|
| f,c | ef,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
|
||||||
|
| h,b | gh,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
|
||||||
|
| h,c | gh,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
|
||||||
|
| h,e | gh,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
|
||||||
|
|
||||||
|
Scenario: Only Exit
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a
|
||||||
|
b
|
||||||
|
d c g h
|
||||||
|
e
|
||||||
|
f
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | junction |
|
||||||
|
| ab | |
|
||||||
|
| cd | |
|
||||||
|
| ef | |
|
||||||
|
| gh | |
|
||||||
|
| bcegb | circular |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| b,d | bcegb,cd,cd | depart,bcegb-exit-1,arrive |
|
||||||
|
| b,f | bcegb,ef,ef | depart,bcegb-exit-2,arrive |
|
||||||
|
| b,h | bcegb,gh,gh | depart,bcegb-exit-3,arrive |
|
||||||
|
| c,f | bcegb,ef,ef | depart,bcegb-exit-1,arrive |
|
||||||
|
| c,h | bcegb,gh,gh | depart,bcegb-exit-2,arrive |
|
||||||
|
| c,a | bcegb,ab,ab | depart,bcegb-exit-3,arrive |
|
||||||
|
| e,h | bcegb,gh,gh | depart,bcegb-exit-1,arrive |
|
||||||
|
| e,a | bcegb,ab,ab | depart,bcegb-exit-2,arrive |
|
||||||
|
| e,d | bcegb,cd,cd | depart,bcegb-exit-3,arrive |
|
||||||
|
| g,a | bcegb,ab,ab | depart,bcegb-exit-1,arrive |
|
||||||
|
| g,d | bcegb,cd,cd | depart,bcegb-exit-2,arrive |
|
||||||
|
| g,f | bcegb,ef,ef | depart,bcegb-exit-3,arrive |
|
||||||
|
#phantom node snapping can result in a full round-trip here, therefore we cannot test b->a and the other direct exits
|
||||||
|
|
||||||
|
Scenario: Drive Around
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a
|
||||||
|
b
|
||||||
|
d c g h
|
||||||
|
e
|
||||||
|
f
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | junction |
|
||||||
|
| ab | |
|
||||||
|
| cd | |
|
||||||
|
| ef | |
|
||||||
|
| gh | |
|
||||||
|
| bcegb | circular |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| b,c | bcegb,bcegb | depart,arrive |
|
||||||
|
| b,e | bcegb,bcegb | depart,arrive |
|
||||||
|
| b,g | bcegb,bcegb | depart,arrive |
|
||||||
|
| c,e | bcegb,bcegb | depart,arrive |
|
||||||
|
| c,g | bcegb,bcegb | depart,arrive |
|
||||||
|
| c,b | bcegb,bcegb | depart,arrive |
|
||||||
|
| e,g | bcegb,bcegb | depart,arrive |
|
||||||
|
| e,b | bcegb,bcegb | depart,arrive |
|
||||||
|
| e,c | bcegb,bcegb | depart,arrive |
|
||||||
|
| g,b | bcegb,bcegb | depart,arrive |
|
||||||
|
| g,c | bcegb,bcegb | depart,arrive |
|
||||||
|
| g,e | bcegb,bcegb | depart,arrive |
|
||||||
|
|
||||||
|
#needs to be adjusted when name-discovery works for entrys
|
||||||
|
Scenario: Mixed Entry and Exit
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
c a
|
||||||
|
j b f
|
||||||
|
k e
|
||||||
|
l h d
|
||||||
|
g i
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | junction | oneway |
|
||||||
|
| abc | | yes |
|
||||||
|
| def | | yes |
|
||||||
|
| ghi | | yes |
|
||||||
|
| jkl | | yes |
|
||||||
|
| bkheb | circular | yes |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,c | abc,abc,abc | depart,rotary-exit-1,arrive |
|
||||||
|
| a,l | abc,jkl,jkl | depart,bkheb-exit-2,arrive |
|
||||||
|
| a,i | abc,ghi,ghi | depart,bkheb-exit-3,arrive |
|
||||||
|
| a,f | abc,def,def | depart,bkheb-exit-4,arrive |
|
||||||
|
| d,f | def,def,def | depart,rotary-exit-1,arrive |
|
||||||
|
| d,c | def,abc,abc | depart,bkheb-exit-2,arrive |
|
||||||
|
| d,l | def,jkl,jkl | depart,bkheb-exit-3,arrive |
|
||||||
|
| d,i | def,ghi,ghi | depart,bkheb-exit-4,arrive |
|
||||||
|
| g,i | ghi,ghi,ghi | depart,rotary-exit-1,arrive |
|
||||||
|
| g,f | ghi,def,def | depart,bkheb-exit-2,arrive |
|
||||||
|
| g,c | ghi,abc,abc | depart,bkheb-exit-3,arrive |
|
||||||
|
| g,l | ghi,jkl,jkl | depart,bkheb-exit-4,arrive |
|
||||||
|
| j,l | jkl,jkl,jkl | depart,rotary-exit-1,arrive |
|
||||||
|
| j,i | jkl,ghi,ghi | depart,bkheb-exit-2,arrive |
|
||||||
|
| j,f | jkl,def,def | depart,bkheb-exit-3,arrive |
|
||||||
|
| j,c | jkl,abc,abc | depart,bkheb-exit-4,arrive |
|
||||||
|
|
||||||
|
Scenario: Collinear in X,Y
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a
|
||||||
|
b
|
||||||
|
c d f
|
||||||
|
e
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | junction |
|
||||||
|
| ab | |
|
||||||
|
| bcdb | circular |
|
||||||
|
| ce | |
|
||||||
|
| df | |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,e | ab,ce,ce | depart,bcdb-exit-1,arrive |
|
||||||
|
| a,f | ab,df,df | depart,bcdb-exit-2,arrive |
|
||||||
|
|
||||||
|
Scenario: Collinear in X,Y
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a
|
||||||
|
d
|
||||||
|
b c f
|
||||||
|
e
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | junction |
|
||||||
|
| ad | |
|
||||||
|
| bcdb | circular |
|
||||||
|
| be | |
|
||||||
|
| cf | |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,e | ad,be,be | depart,bcdb-exit-1,arrive |
|
||||||
|
| a,f | ad,cf,cf | depart,bcdb-exit-2,arrive |
|
||||||
|
|
||||||
|
Scenario: Collinear in X,Y
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a
|
||||||
|
c
|
||||||
|
d b f
|
||||||
|
e
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | junction |
|
||||||
|
| ac | |
|
||||||
|
| bcdb | circular |
|
||||||
|
| de | |
|
||||||
|
| bf | |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,e | ac,de,de | depart,bcdb-exit-1,arrive |
|
||||||
|
| a,f | ac,bf,bf | depart,bcdb-exit-2,arrive |
|
||||||
|
|
||||||
|
Scenario: Collinear in X,Y
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
f
|
||||||
|
d c e
|
||||||
|
b
|
||||||
|
a
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | junction |
|
||||||
|
| ab | |
|
||||||
|
| bcdb | circular |
|
||||||
|
| ce | |
|
||||||
|
| df | |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,e | ab,ce,ce | depart,bcdb-exit-1,arrive |
|
||||||
|
| a,f | ab,df,df | depart,bcdb-exit-2,arrive |
|
||||||
|
|
||||||
|
Scenario: Collinear in X,Y
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
f
|
||||||
|
d c e
|
||||||
|
b
|
||||||
|
a
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | junction |
|
||||||
|
| ab | |
|
||||||
|
| bcdb | circular |
|
||||||
|
| ce | |
|
||||||
|
| df | |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,e | ab,ce,ce | depart,bcdb-exit-1,arrive |
|
||||||
|
| a,f | ab,df,df | depart,bcdb-exit-2,arrive |
|
@ -45,6 +45,7 @@ struct ExtractionWay
|
|||||||
backward_speed = -1;
|
backward_speed = -1;
|
||||||
duration = -1;
|
duration = -1;
|
||||||
roundabout = false;
|
roundabout = false;
|
||||||
|
circular = false;
|
||||||
is_startpoint = true;
|
is_startpoint = true;
|
||||||
is_access_restricted = false;
|
is_access_restricted = false;
|
||||||
name.clear();
|
name.clear();
|
||||||
@ -89,6 +90,7 @@ struct ExtractionWay
|
|||||||
std::string turn_lanes_forward;
|
std::string turn_lanes_forward;
|
||||||
std::string turn_lanes_backward;
|
std::string turn_lanes_backward;
|
||||||
bool roundabout;
|
bool roundabout;
|
||||||
|
bool circular;
|
||||||
bool is_access_restricted;
|
bool is_access_restricted;
|
||||||
bool is_startpoint;
|
bool is_startpoint;
|
||||||
TravelMode forward_travel_mode : 4;
|
TravelMode forward_travel_mode : 4;
|
||||||
|
@ -43,11 +43,12 @@ struct InternalExtractorEdge
|
|||||||
MIN_OSM_NODEID,
|
MIN_OSM_NODEID,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
false,
|
false, // forward
|
||||||
false,
|
false, // backward
|
||||||
false,
|
false, // roundabout
|
||||||
false,
|
false, // circular
|
||||||
true,
|
false, // access restricted
|
||||||
|
true, // can be startpoint
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
false,
|
false,
|
||||||
guidance::TurnLaneType::empty,
|
guidance::TurnLaneType::empty,
|
||||||
@ -62,6 +63,7 @@ struct InternalExtractorEdge
|
|||||||
bool forward,
|
bool forward,
|
||||||
bool backward,
|
bool backward,
|
||||||
bool roundabout,
|
bool roundabout,
|
||||||
|
bool circular,
|
||||||
bool access_restricted,
|
bool access_restricted,
|
||||||
bool startpoint,
|
bool startpoint,
|
||||||
TravelMode travel_mode,
|
TravelMode travel_mode,
|
||||||
@ -75,6 +77,7 @@ struct InternalExtractorEdge
|
|||||||
forward,
|
forward,
|
||||||
backward,
|
backward,
|
||||||
roundabout,
|
roundabout,
|
||||||
|
circular,
|
||||||
access_restricted,
|
access_restricted,
|
||||||
startpoint,
|
startpoint,
|
||||||
travel_mode,
|
travel_mode,
|
||||||
@ -99,11 +102,12 @@ struct InternalExtractorEdge
|
|||||||
MIN_OSM_NODEID,
|
MIN_OSM_NODEID,
|
||||||
0,
|
0,
|
||||||
WeightData(),
|
WeightData(),
|
||||||
false,
|
false, // forward
|
||||||
false,
|
false, // backward
|
||||||
false,
|
false, // roundabout
|
||||||
false,
|
false, // circular
|
||||||
true,
|
false, // access restricted
|
||||||
|
true, // can be startpoint
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
false,
|
false,
|
||||||
INVALID_LANE_DESCRIPTIONID,
|
INVALID_LANE_DESCRIPTIONID,
|
||||||
@ -115,11 +119,12 @@ struct InternalExtractorEdge
|
|||||||
MAX_OSM_NODEID,
|
MAX_OSM_NODEID,
|
||||||
SPECIAL_NODEID,
|
SPECIAL_NODEID,
|
||||||
WeightData(),
|
WeightData(),
|
||||||
false,
|
false, // forward
|
||||||
false,
|
false, // backward
|
||||||
false,
|
false, // roundabout
|
||||||
false,
|
false, // circular
|
||||||
true,
|
false, // access restricted
|
||||||
|
true, // can be startpoint
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
false,
|
false,
|
||||||
INVALID_LANE_DESCRIPTIONID,
|
INVALID_LANE_DESCRIPTIONID,
|
||||||
|
@ -22,6 +22,7 @@ struct NodeBasedEdge
|
|||||||
bool forward,
|
bool forward,
|
||||||
bool backward,
|
bool backward,
|
||||||
bool roundabout,
|
bool roundabout,
|
||||||
|
bool circular,
|
||||||
bool access_restricted,
|
bool access_restricted,
|
||||||
bool startpoint,
|
bool startpoint,
|
||||||
TravelMode travel_mode,
|
TravelMode travel_mode,
|
||||||
@ -38,6 +39,7 @@ struct NodeBasedEdge
|
|||||||
bool forward : 1;
|
bool forward : 1;
|
||||||
bool backward : 1;
|
bool backward : 1;
|
||||||
bool roundabout : 1;
|
bool roundabout : 1;
|
||||||
|
bool circular : 1;
|
||||||
bool access_restricted : 1;
|
bool access_restricted : 1;
|
||||||
bool startpoint : 1;
|
bool startpoint : 1;
|
||||||
bool is_split : 1;
|
bool is_split : 1;
|
||||||
@ -55,6 +57,7 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge
|
|||||||
bool forward,
|
bool forward,
|
||||||
bool backward,
|
bool backward,
|
||||||
bool roundabout,
|
bool roundabout,
|
||||||
|
bool circular,
|
||||||
bool access_restricted,
|
bool access_restricted,
|
||||||
bool startpoint,
|
bool startpoint,
|
||||||
TravelMode travel_mode,
|
TravelMode travel_mode,
|
||||||
@ -70,7 +73,7 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge
|
|||||||
|
|
||||||
inline NodeBasedEdge::NodeBasedEdge()
|
inline NodeBasedEdge::NodeBasedEdge()
|
||||||
: source(SPECIAL_NODEID), target(SPECIAL_NODEID), name_id(0), weight(0), forward(false),
|
: source(SPECIAL_NODEID), target(SPECIAL_NODEID), name_id(0), weight(0), forward(false),
|
||||||
backward(false), roundabout(false), access_restricted(false), startpoint(true),
|
backward(false), roundabout(false), circular(false), access_restricted(false), startpoint(true),
|
||||||
is_split(false), travel_mode(false), lane_description_id(INVALID_LANE_DESCRIPTIONID)
|
is_split(false), travel_mode(false), lane_description_id(INVALID_LANE_DESCRIPTIONID)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -82,6 +85,7 @@ inline NodeBasedEdge::NodeBasedEdge(NodeID source,
|
|||||||
bool forward,
|
bool forward,
|
||||||
bool backward,
|
bool backward,
|
||||||
bool roundabout,
|
bool roundabout,
|
||||||
|
bool circular,
|
||||||
bool access_restricted,
|
bool access_restricted,
|
||||||
bool startpoint,
|
bool startpoint,
|
||||||
TravelMode travel_mode,
|
TravelMode travel_mode,
|
||||||
@ -89,7 +93,7 @@ inline NodeBasedEdge::NodeBasedEdge(NodeID source,
|
|||||||
const LaneDescriptionID lane_description_id,
|
const LaneDescriptionID lane_description_id,
|
||||||
guidance::RoadClassification road_classification)
|
guidance::RoadClassification road_classification)
|
||||||
: source(source), target(target), name_id(name_id), weight(weight), forward(forward),
|
: source(source), target(target), name_id(name_id), weight(weight), forward(forward),
|
||||||
backward(backward), roundabout(roundabout), access_restricted(access_restricted),
|
backward(backward), roundabout(roundabout), circular(circular), access_restricted(access_restricted),
|
||||||
startpoint(startpoint), is_split(is_split), travel_mode(travel_mode),
|
startpoint(startpoint), is_split(is_split), travel_mode(travel_mode),
|
||||||
lane_description_id(lane_description_id), road_classification(std::move(road_classification))
|
lane_description_id(lane_description_id), road_classification(std::move(road_classification))
|
||||||
{
|
{
|
||||||
@ -119,6 +123,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(OSMNodeID source,
|
|||||||
bool forward,
|
bool forward,
|
||||||
bool backward,
|
bool backward,
|
||||||
bool roundabout,
|
bool roundabout,
|
||||||
|
bool circular,
|
||||||
bool access_restricted,
|
bool access_restricted,
|
||||||
bool startpoint,
|
bool startpoint,
|
||||||
TravelMode travel_mode,
|
TravelMode travel_mode,
|
||||||
@ -132,6 +137,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(OSMNodeID source,
|
|||||||
forward,
|
forward,
|
||||||
backward,
|
backward,
|
||||||
roundabout,
|
roundabout,
|
||||||
|
circular,
|
||||||
access_restricted,
|
access_restricted,
|
||||||
startpoint,
|
startpoint,
|
||||||
travel_mode,
|
travel_mode,
|
||||||
|
@ -20,7 +20,7 @@ struct NodeBasedEdgeData
|
|||||||
NodeBasedEdgeData()
|
NodeBasedEdgeData()
|
||||||
: distance(INVALID_EDGE_WEIGHT), edge_id(SPECIAL_NODEID),
|
: distance(INVALID_EDGE_WEIGHT), edge_id(SPECIAL_NODEID),
|
||||||
name_id(std::numeric_limits<unsigned>::max()), access_restricted(false), reversed(false),
|
name_id(std::numeric_limits<unsigned>::max()), access_restricted(false), reversed(false),
|
||||||
roundabout(false), travel_mode(TRAVEL_MODE_INACCESSIBLE),
|
roundabout(false), circular(false), travel_mode(TRAVEL_MODE_INACCESSIBLE),
|
||||||
lane_description_id(INVALID_LANE_DESCRIPTIONID)
|
lane_description_id(INVALID_LANE_DESCRIPTIONID)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -31,12 +31,14 @@ struct NodeBasedEdgeData
|
|||||||
bool access_restricted,
|
bool access_restricted,
|
||||||
bool reversed,
|
bool reversed,
|
||||||
bool roundabout,
|
bool roundabout,
|
||||||
|
bool circular,
|
||||||
bool startpoint,
|
bool startpoint,
|
||||||
extractor::TravelMode travel_mode,
|
extractor::TravelMode travel_mode,
|
||||||
const LaneDescriptionID lane_description_id)
|
const LaneDescriptionID lane_description_id)
|
||||||
: distance(distance), edge_id(edge_id), name_id(name_id),
|
: distance(distance), edge_id(edge_id), name_id(name_id),
|
||||||
access_restricted(access_restricted), reversed(reversed), roundabout(roundabout),
|
access_restricted(access_restricted), reversed(reversed), roundabout(roundabout),
|
||||||
startpoint(startpoint), travel_mode(travel_mode), lane_description_id(lane_description_id)
|
circular(circular), startpoint(startpoint), travel_mode(travel_mode),
|
||||||
|
lane_description_id(lane_description_id)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,6 +48,7 @@ struct NodeBasedEdgeData
|
|||||||
bool access_restricted : 1;
|
bool access_restricted : 1;
|
||||||
bool reversed : 1;
|
bool reversed : 1;
|
||||||
bool roundabout : 1;
|
bool roundabout : 1;
|
||||||
|
bool circular : 1;
|
||||||
bool startpoint : 1;
|
bool startpoint : 1;
|
||||||
extractor::TravelMode travel_mode : 4;
|
extractor::TravelMode travel_mode : 4;
|
||||||
LaneDescriptionID lane_description_id;
|
LaneDescriptionID lane_description_id;
|
||||||
@ -54,7 +57,8 @@ struct NodeBasedEdgeData
|
|||||||
bool IsCompatibleTo(const NodeBasedEdgeData &other) const
|
bool IsCompatibleTo(const NodeBasedEdgeData &other) const
|
||||||
{
|
{
|
||||||
return (reversed == other.reversed) && (roundabout == other.roundabout) &&
|
return (reversed == other.reversed) && (roundabout == other.roundabout) &&
|
||||||
(startpoint == other.startpoint) && (access_restricted == other.access_restricted) &&
|
(circular == other.circular) && (startpoint == other.startpoint) &&
|
||||||
|
(access_restricted == other.access_restricted) &&
|
||||||
(travel_mode == other.travel_mode) &&
|
(travel_mode == other.travel_mode) &&
|
||||||
(road_classification == other.road_classification);
|
(road_classification == other.road_classification);
|
||||||
}
|
}
|
||||||
@ -82,6 +86,7 @@ NodeBasedDynamicGraphFromEdges(NodeID number_of_nodes,
|
|||||||
BOOST_ASSERT(output_edge.data.distance > 0);
|
BOOST_ASSERT(output_edge.data.distance > 0);
|
||||||
|
|
||||||
output_edge.data.roundabout = input_edge.roundabout;
|
output_edge.data.roundabout = input_edge.roundabout;
|
||||||
|
output_edge.data.circular = input_edge.circular;
|
||||||
output_edge.data.name_id = input_edge.name_id;
|
output_edge.data.name_id = input_edge.name_id;
|
||||||
output_edge.data.access_restricted = input_edge.access_restricted;
|
output_edge.data.access_restricted = input_edge.access_restricted;
|
||||||
output_edge.data.travel_mode = input_edge.travel_mode;
|
output_edge.data.travel_mode = input_edge.travel_mode;
|
||||||
|
@ -554,6 +554,9 @@ function handle_roundabouts(way,result)
|
|||||||
if way:get_value_by_key("junction") == "roundabout" then
|
if way:get_value_by_key("junction") == "roundabout" then
|
||||||
result.roundabout = true
|
result.roundabout = true
|
||||||
end
|
end
|
||||||
|
if way:get_value_by_key("junction") == "circular" then
|
||||||
|
result.circular = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Set access restriction flag if access is allowed under certain restrictions only
|
-- Set access restriction flag if access is allowed under certain restrictions only
|
||||||
@ -638,6 +641,7 @@ function handle_oneway(way,result)
|
|||||||
oneway == "1" or
|
oneway == "1" or
|
||||||
oneway == "true" or
|
oneway == "true" or
|
||||||
way:get_value_by_key("junction") == "roundabout" or
|
way:get_value_by_key("junction") == "roundabout" or
|
||||||
|
way:get_value_by_key("junction") == "circular" or
|
||||||
(way:get_value_by_key("highway") == "motorway" and oneway ~= "no") then
|
(way:get_value_by_key("highway") == "motorway" and oneway ~= "no") then
|
||||||
|
|
||||||
result.backward_mode = mode.inaccessible
|
result.backward_mode = mode.inaccessible
|
||||||
|
@ -327,6 +327,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
|||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
parsed_way.roundabout,
|
parsed_way.roundabout,
|
||||||
|
parsed_way.circular,
|
||||||
parsed_way.is_access_restricted,
|
parsed_way.is_access_restricted,
|
||||||
parsed_way.is_startpoint,
|
parsed_way.is_startpoint,
|
||||||
parsed_way.backward_travel_mode,
|
parsed_way.backward_travel_mode,
|
||||||
@ -359,6 +360,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
|||||||
true,
|
true,
|
||||||
!forward_only,
|
!forward_only,
|
||||||
parsed_way.roundabout,
|
parsed_way.roundabout,
|
||||||
|
parsed_way.circular,
|
||||||
parsed_way.is_access_restricted,
|
parsed_way.is_access_restricted,
|
||||||
parsed_way.is_startpoint,
|
parsed_way.is_startpoint,
|
||||||
parsed_way.forward_travel_mode,
|
parsed_way.forward_travel_mode,
|
||||||
@ -381,6 +383,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
parsed_way.roundabout,
|
parsed_way.roundabout,
|
||||||
|
parsed_way.circular,
|
||||||
parsed_way.is_access_restricted,
|
parsed_way.is_access_restricted,
|
||||||
parsed_way.is_startpoint,
|
parsed_way.is_startpoint,
|
||||||
parsed_way.backward_travel_mode,
|
parsed_way.backward_travel_mode,
|
||||||
|
@ -88,7 +88,7 @@ CoordinateExtractor::GetCoordinateAlongRoad(const NodeID intersection_node,
|
|||||||
const auto &turn_edge_data = node_based_graph.GetEdgeData(turn_edge);
|
const auto &turn_edge_data = node_based_graph.GetEdgeData(turn_edge);
|
||||||
|
|
||||||
// roundabouts, check early to avoid other costly checks
|
// roundabouts, check early to avoid other costly checks
|
||||||
if (turn_edge_data.roundabout)
|
if (turn_edge_data.roundabout || turn_edge_data.circular )
|
||||||
return TrimCoordinatesToLength(std::move(coordinates),
|
return TrimCoordinatesToLength(std::move(coordinates),
|
||||||
distance_to_skip_over_due_to_coordinate_inaccuracies)
|
distance_to_skip_over_due_to_coordinate_inaccuracies)
|
||||||
.back();
|
.back();
|
||||||
|
@ -56,7 +56,8 @@ bool IntersectionNormalizer::CanMerge(const NodeID node_at_intersection,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// may not be on a roundabout
|
// may not be on a roundabout
|
||||||
if (first_data.roundabout || second_data.roundabout)
|
if (first_data.roundabout || second_data.roundabout || first_data.circular ||
|
||||||
|
second_data.circular)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// exactly one of them has to be reversed
|
// exactly one of them has to be reversed
|
||||||
@ -237,7 +238,8 @@ Intersection IntersectionNormalizer::MergeSegregatedRoads(const NodeID intersect
|
|||||||
const bool is_connected_to_roundabout = [this, &intersection]() {
|
const bool is_connected_to_roundabout = [this, &intersection]() {
|
||||||
for (const auto &road : intersection)
|
for (const auto &road : intersection)
|
||||||
{
|
{
|
||||||
if (node_based_graph.GetEdgeData(road.eid).roundabout)
|
if (node_based_graph.GetEdgeData(road.eid).roundabout ||
|
||||||
|
node_based_graph.GetEdgeData(road.eid).circular)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -67,7 +67,7 @@ detail::RoundaboutFlags RoundaboutHandler::getRoundaboutFlags(
|
|||||||
const NodeID from_nid, const EdgeID via_eid, const Intersection &intersection) const
|
const NodeID from_nid, const EdgeID via_eid, const Intersection &intersection) const
|
||||||
{
|
{
|
||||||
const auto &in_edge_data = node_based_graph.GetEdgeData(via_eid);
|
const auto &in_edge_data = node_based_graph.GetEdgeData(via_eid);
|
||||||
bool on_roundabout = in_edge_data.roundabout;
|
bool on_roundabout = in_edge_data.roundabout || in_edge_data.circular;
|
||||||
bool can_enter_roundabout = false;
|
bool can_enter_roundabout = false;
|
||||||
bool can_exit_roundabout_separately = false;
|
bool can_exit_roundabout_separately = false;
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ detail::RoundaboutFlags RoundaboutHandler::getRoundaboutFlags(
|
|||||||
if (edge_data.reversed || !road.entry_allowed)
|
if (edge_data.reversed || !road.entry_allowed)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (edge_data.roundabout)
|
if (edge_data.roundabout || edge_data.circular)
|
||||||
{
|
{
|
||||||
can_enter_roundabout = true;
|
can_enter_roundabout = true;
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ void RoundaboutHandler::invalidateExitAgainstDirection(const NodeID from_nid,
|
|||||||
Intersection &intersection) const
|
Intersection &intersection) const
|
||||||
{
|
{
|
||||||
const auto &in_edge_data = node_based_graph.GetEdgeData(via_eid);
|
const auto &in_edge_data = node_based_graph.GetEdgeData(via_eid);
|
||||||
if (in_edge_data.roundabout)
|
if (in_edge_data.roundabout || in_edge_data.circular)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool past_roundabout_angle = false;
|
bool past_roundabout_angle = false;
|
||||||
@ -121,7 +121,7 @@ void RoundaboutHandler::invalidateExitAgainstDirection(const NodeID from_nid,
|
|||||||
if (edge_data.reversed)
|
if (edge_data.reversed)
|
||||||
{
|
{
|
||||||
// remember whether we have seen the roundabout in-part
|
// remember whether we have seen the roundabout in-part
|
||||||
if (edge_data.roundabout)
|
if (edge_data.roundabout || edge_data.circular)
|
||||||
past_roundabout_angle = true;
|
past_roundabout_angle = true;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@ -131,8 +131,8 @@ void RoundaboutHandler::invalidateExitAgainstDirection(const NodeID from_nid,
|
|||||||
// This workaround handles cases in which an exit precedes and entry. The resulting
|
// This workaround handles cases in which an exit precedes and entry. The resulting
|
||||||
// u-turn against the roundabout direction is invalidated.
|
// u-turn against the roundabout direction is invalidated.
|
||||||
// The sorting of the angles represents a problem for left-sided driving, though.
|
// The sorting of the angles represents a problem for left-sided driving, though.
|
||||||
if (!edge_data.roundabout && node_based_graph.GetTarget(road.eid) != from_nid &&
|
if (!edge_data.roundabout && !edge_data.circular &&
|
||||||
past_roundabout_angle)
|
node_based_graph.GetTarget(road.eid) != from_nid && past_roundabout_angle)
|
||||||
{
|
{
|
||||||
road.entry_allowed = false;
|
road.entry_allowed = false;
|
||||||
}
|
}
|
||||||
@ -176,7 +176,7 @@ bool RoundaboutHandler::qualifiesAsRoundaboutIntersection(
|
|||||||
for (const auto edge : node_based_graph.GetAdjacentEdgeRange(node))
|
for (const auto edge : node_based_graph.GetAdjacentEdgeRange(node))
|
||||||
{
|
{
|
||||||
const auto edge_data = node_based_graph.GetEdgeData(edge);
|
const auto edge_data = node_based_graph.GetEdgeData(edge);
|
||||||
if (edge_data.roundabout)
|
if (edge_data.roundabout || edge_data.circular)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// there is a single non-roundabout edge
|
// there is a single non-roundabout edge
|
||||||
@ -224,12 +224,14 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
|
|||||||
std::unordered_set<unsigned> connected_names;
|
std::unordered_set<unsigned> connected_names;
|
||||||
|
|
||||||
const auto getNextOnRoundabout = [this, &roundabout_name_ids, &connected_names](
|
const auto getNextOnRoundabout = [this, &roundabout_name_ids, &connected_names](
|
||||||
const NodeID node) {
|
const NodeID node, const bool roundabout, const bool circular) {
|
||||||
|
BOOST_ASSERT(roundabout != circular);
|
||||||
EdgeID continue_edge = SPECIAL_EDGEID;
|
EdgeID continue_edge = SPECIAL_EDGEID;
|
||||||
for (const auto edge : node_based_graph.GetAdjacentEdgeRange(node))
|
for (const auto edge : node_based_graph.GetAdjacentEdgeRange(node))
|
||||||
{
|
{
|
||||||
const auto &edge_data = node_based_graph.GetEdgeData(edge);
|
const auto &edge_data = node_based_graph.GetEdgeData(edge);
|
||||||
if (!edge_data.reversed && edge_data.roundabout)
|
if (!edge_data.reversed && (edge_data.circular == circular) &&
|
||||||
|
(edge_data.roundabout == roundabout))
|
||||||
{
|
{
|
||||||
if (SPECIAL_EDGEID != continue_edge)
|
if (SPECIAL_EDGEID != continue_edge)
|
||||||
{
|
{
|
||||||
@ -251,7 +253,7 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
|
|||||||
|
|
||||||
continue_edge = edge;
|
continue_edge = edge;
|
||||||
}
|
}
|
||||||
else if (!edge_data.roundabout)
|
else if (!edge_data.roundabout && !edge_data.circular)
|
||||||
{
|
{
|
||||||
// remember all connected road names
|
// remember all connected road names
|
||||||
connected_names.insert(edge_data.name_id);
|
connected_names.insert(edge_data.name_id);
|
||||||
@ -268,7 +270,7 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
|
|||||||
for (const auto edge : node_based_graph.GetAdjacentEdgeRange(at_node))
|
for (const auto edge : node_based_graph.GetAdjacentEdgeRange(at_node))
|
||||||
{
|
{
|
||||||
const auto &edge_data = node_based_graph.GetEdgeData(edge);
|
const auto &edge_data = node_based_graph.GetEdgeData(edge);
|
||||||
if (edge_data.roundabout)
|
if (edge_data.roundabout || edge_data.circular)
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
@ -294,6 +296,19 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
|
|||||||
double roundabout_length = 0.;
|
double roundabout_length = 0.;
|
||||||
|
|
||||||
NodeID last_node = nid;
|
NodeID last_node = nid;
|
||||||
|
|
||||||
|
// cannot be find_if, as long as adjacent edge range does not work.
|
||||||
|
bool roundabout = false, circular = false;
|
||||||
|
for (const auto eid : node_based_graph.GetAdjacentEdgeRange(nid))
|
||||||
|
{
|
||||||
|
const auto data = node_based_graph.GetEdgeData(eid);
|
||||||
|
roundabout |= data.roundabout;
|
||||||
|
circular |= data.circular;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (roundabout == circular)
|
||||||
|
return RoundaboutType::None;
|
||||||
|
|
||||||
while (0 == roundabout_nodes.count(last_node))
|
while (0 == roundabout_nodes.count(last_node))
|
||||||
{
|
{
|
||||||
// only count exits/entry locations
|
// only count exits/entry locations
|
||||||
@ -304,7 +319,7 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
|
|||||||
if (countRoundaboutFlags(last_node) != 2)
|
if (countRoundaboutFlags(last_node) != 2)
|
||||||
return RoundaboutType::None;
|
return RoundaboutType::None;
|
||||||
|
|
||||||
const auto eid = getNextOnRoundabout(last_node);
|
const auto eid = getNextOnRoundabout(last_node, roundabout, circular);
|
||||||
|
|
||||||
if (eid == SPECIAL_EDGEID)
|
if (eid == SPECIAL_EDGEID)
|
||||||
{
|
{
|
||||||
@ -324,7 +339,7 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
|
|||||||
return RoundaboutType::None;
|
return RoundaboutType::None;
|
||||||
|
|
||||||
// More a traffic loop than anything else, currently treated as roundabout turn
|
// More a traffic loop than anything else, currently treated as roundabout turn
|
||||||
if (roundabout_nodes.size() == 1)
|
if (roundabout_nodes.size() == 1 && roundabout)
|
||||||
{
|
{
|
||||||
return RoundaboutType::RoundaboutIntersection;
|
return RoundaboutType::RoundaboutIntersection;
|
||||||
}
|
}
|
||||||
@ -336,13 +351,18 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
|
|||||||
// This function can theoretically fail if the roundabout name is partly
|
// This function can theoretically fail if the roundabout name is partly
|
||||||
// used with a reference and without. This will be fixed automatically
|
// used with a reference and without. This will be fixed automatically
|
||||||
// when we handle references separately or if the useage is more consistent
|
// when we handle references separately or if the useage is more consistent
|
||||||
const auto is_rotary = 1 == roundabout_name_ids.size() && //
|
const auto is_rotary = (1 == roundabout_name_ids.size()) &&
|
||||||
0 == connected_names.count(*roundabout_name_ids.begin()) && //
|
(circular || //
|
||||||
radius > MAX_ROUNDABOUT_RADIUS;
|
((0 == connected_names.count(*roundabout_name_ids.begin())) && //
|
||||||
|
(radius > MAX_ROUNDABOUT_RADIUS)));
|
||||||
|
|
||||||
if (is_rotary)
|
if (is_rotary)
|
||||||
return RoundaboutType::Rotary;
|
return RoundaboutType::Rotary;
|
||||||
|
|
||||||
|
// circular intersections need to be rotaries
|
||||||
|
if (circular)
|
||||||
|
return RoundaboutType::None;
|
||||||
|
|
||||||
// Looks like an intersection: four ways and turn angles are easy to distinguish
|
// Looks like an intersection: four ways and turn angles are easy to distinguish
|
||||||
const auto is_roundabout_intersection = qualifiesAsRoundaboutIntersection(roundabout_nodes) &&
|
const auto is_roundabout_intersection = qualifiesAsRoundaboutIntersection(roundabout_nodes) &&
|
||||||
radius < MAX_ROUNDABOUT_INTERSECTION_RADIUS;
|
radius < MAX_ROUNDABOUT_INTERSECTION_RADIUS;
|
||||||
@ -376,7 +396,7 @@ Intersection RoundaboutHandler::handleRoundabouts(const RoundaboutType roundabou
|
|||||||
auto &road = intersection[idx];
|
auto &road = intersection[idx];
|
||||||
auto &turn = road;
|
auto &turn = road;
|
||||||
const auto &out_data = node_based_graph.GetEdgeData(road.eid);
|
const auto &out_data = node_based_graph.GetEdgeData(road.eid);
|
||||||
if (out_data.roundabout)
|
if (out_data.roundabout || out_data.circular)
|
||||||
{
|
{
|
||||||
// TODO can forks happen in roundabouts? E.g. required lane changes
|
// TODO can forks happen in roundabouts? E.g. required lane changes
|
||||||
if (1 == node_based_graph.GetDirectedOutDegree(node_at_center_of_intersection))
|
if (1 == node_based_graph.GetDirectedOutDegree(node_at_center_of_intersection))
|
||||||
@ -401,6 +421,7 @@ Intersection RoundaboutHandler::handleRoundabouts(const RoundaboutType roundabou
|
|||||||
const auto &data_of_leaving_edge = node_based_graph.GetEdgeData(eid);
|
const auto &data_of_leaving_edge = node_based_graph.GetEdgeData(eid);
|
||||||
if (!data_of_leaving_edge.reversed &&
|
if (!data_of_leaving_edge.reversed &&
|
||||||
!data_of_leaving_edge.roundabout &&
|
!data_of_leaving_edge.roundabout &&
|
||||||
|
!data_of_leaving_edge.circular &&
|
||||||
!data_of_leaving_edge.road_classification.IsLowPriorityRoadClass())
|
!data_of_leaving_edge.road_classification.IsLowPriorityRoadClass())
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -433,7 +454,7 @@ Intersection RoundaboutHandler::handleRoundabouts(const RoundaboutType roundabou
|
|||||||
continue;
|
continue;
|
||||||
auto &turn = road;
|
auto &turn = road;
|
||||||
const auto &out_data = node_based_graph.GetEdgeData(turn.eid);
|
const auto &out_data = node_based_graph.GetEdgeData(turn.eid);
|
||||||
if (out_data.roundabout)
|
if (out_data.roundabout || out_data.circular)
|
||||||
{
|
{
|
||||||
if (can_exit_roundabout_separately)
|
if (can_exit_roundabout_separately)
|
||||||
turn.instruction = TurnInstruction::ENTER_ROUNDABOUT_AT_EXIT(
|
turn.instruction = TurnInstruction::ENTER_ROUNDABOUT_AT_EXIT(
|
||||||
|
@ -220,6 +220,7 @@ void LuaScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
|||||||
&ExtractionWay::GetTurnLanesBackward,
|
&ExtractionWay::GetTurnLanesBackward,
|
||||||
&ExtractionWay::SetTurnLanesBackward)
|
&ExtractionWay::SetTurnLanesBackward)
|
||||||
.def_readwrite("roundabout", &ExtractionWay::roundabout)
|
.def_readwrite("roundabout", &ExtractionWay::roundabout)
|
||||||
|
.def_readwrite("circular", &ExtractionWay::circular)
|
||||||
.def_readwrite("is_access_restricted", &ExtractionWay::is_access_restricted)
|
.def_readwrite("is_access_restricted", &ExtractionWay::is_access_restricted)
|
||||||
.def_readwrite("is_startpoint", &ExtractionWay::is_startpoint)
|
.def_readwrite("is_startpoint", &ExtractionWay::is_startpoint)
|
||||||
.def_readwrite("duration", &ExtractionWay::duration)
|
.def_readwrite("duration", &ExtractionWay::duration)
|
||||||
|
@ -350,6 +350,11 @@
|
|||||||
"object_types": [ "way" ],
|
"object_types": [ "way" ],
|
||||||
"value": "roundabout"
|
"value": "roundabout"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key": "junction",
|
||||||
|
"object_types": [ "way" ],
|
||||||
|
"value": "circular"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key": "type",
|
"key": "type",
|
||||||
"value": "restriction",
|
"value": "restriction",
|
||||||
|
@ -16,6 +16,30 @@ using namespace osrm::extractor;
|
|||||||
using InputEdge = util::NodeBasedDynamicGraph::InputEdge;
|
using InputEdge = util::NodeBasedDynamicGraph::InputEdge;
|
||||||
using Graph = util::NodeBasedDynamicGraph;
|
using Graph = util::NodeBasedDynamicGraph;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
// creates a default edge of unit weight
|
||||||
|
inline InputEdge MakeUnitEdge(const NodeID from, const NodeID to)
|
||||||
|
{
|
||||||
|
// src, tgt, dist, edge_id, name_id, access_restricted, fwd, bkwd, roundabout, circular
|
||||||
|
// travel_mode
|
||||||
|
return {from,
|
||||||
|
to,
|
||||||
|
1,
|
||||||
|
SPECIAL_EDGEID,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
|
INVALID_LANE_DESCRIPTIONID};
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(long_road_test)
|
BOOST_AUTO_TEST_CASE(long_road_test)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@ -28,96 +52,14 @@ BOOST_AUTO_TEST_CASE(long_road_test)
|
|||||||
RestrictionMap map;
|
RestrictionMap map;
|
||||||
CompressedEdgeContainer container;
|
CompressedEdgeContainer container;
|
||||||
|
|
||||||
std::vector<InputEdge> edges = {
|
std::vector<InputEdge> edges = {MakeUnitEdge(0, 1),
|
||||||
// src, tgt, dist, edge_id, name_id, access_restricted, fwd, bkwd, roundabout, travel_mode
|
MakeUnitEdge(1, 0),
|
||||||
{0,
|
MakeUnitEdge(1, 2),
|
||||||
1,
|
MakeUnitEdge(2, 1),
|
||||||
1,
|
MakeUnitEdge(2, 3),
|
||||||
SPECIAL_EDGEID,
|
MakeUnitEdge(3, 2),
|
||||||
0,
|
MakeUnitEdge(3, 4),
|
||||||
false,
|
MakeUnitEdge(4, 3)};
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{1,
|
|
||||||
2,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{2,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{2,
|
|
||||||
3,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{3,
|
|
||||||
2,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{3,
|
|
||||||
4,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{4,
|
|
||||||
3,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID}};
|
|
||||||
|
|
||||||
BOOST_ASSERT(edges[0].data.IsCompatibleTo(edges[2].data));
|
BOOST_ASSERT(edges[0].data.IsCompatibleTo(edges[2].data));
|
||||||
BOOST_ASSERT(edges[2].data.IsCompatibleTo(edges[4].data));
|
BOOST_ASSERT(edges[2].data.IsCompatibleTo(edges[4].data));
|
||||||
@ -147,141 +89,18 @@ BOOST_AUTO_TEST_CASE(loop_test)
|
|||||||
RestrictionMap map;
|
RestrictionMap map;
|
||||||
CompressedEdgeContainer container;
|
CompressedEdgeContainer container;
|
||||||
|
|
||||||
std::vector<InputEdge> edges = {
|
std::vector<InputEdge> edges = {MakeUnitEdge(0, 1),
|
||||||
// src, tgt, dist, edge_id, name_id, access_restricted, fwd, bkwd, roundabout, travel_mode
|
MakeUnitEdge(0, 5),
|
||||||
{0,
|
MakeUnitEdge(1, 0),
|
||||||
1,
|
MakeUnitEdge(1, 2),
|
||||||
1,
|
MakeUnitEdge(2, 1),
|
||||||
SPECIAL_EDGEID,
|
MakeUnitEdge(2, 3),
|
||||||
0,
|
MakeUnitEdge(3, 2),
|
||||||
false,
|
MakeUnitEdge(3, 4),
|
||||||
false,
|
MakeUnitEdge(4, 3),
|
||||||
false,
|
MakeUnitEdge(4, 5),
|
||||||
true,
|
MakeUnitEdge(5, 0),
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
MakeUnitEdge(5, 4)};
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{0,
|
|
||||||
5,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{1,
|
|
||||||
2,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{2,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{2,
|
|
||||||
3,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{3,
|
|
||||||
2,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{3,
|
|
||||||
4,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{4,
|
|
||||||
3,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{4,
|
|
||||||
5,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{5,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{5,
|
|
||||||
4,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
};
|
|
||||||
|
|
||||||
BOOST_ASSERT(edges.size() == 12);
|
BOOST_ASSERT(edges.size() == 12);
|
||||||
BOOST_ASSERT(edges[0].data.IsCompatibleTo(edges[1].data));
|
BOOST_ASSERT(edges[0].data.IsCompatibleTo(edges[1].data));
|
||||||
@ -322,75 +141,12 @@ BOOST_AUTO_TEST_CASE(t_intersection)
|
|||||||
RestrictionMap map;
|
RestrictionMap map;
|
||||||
CompressedEdgeContainer container;
|
CompressedEdgeContainer container;
|
||||||
|
|
||||||
std::vector<InputEdge> edges = {
|
std::vector<InputEdge> edges = {MakeUnitEdge(0, 1),
|
||||||
// src, tgt, dist, edge_id, name_id, access_restricted, fwd, bkwd, roundabout, travel_mode
|
MakeUnitEdge(1, 0),
|
||||||
{0,
|
MakeUnitEdge(1, 2),
|
||||||
1,
|
MakeUnitEdge(1, 3),
|
||||||
1,
|
MakeUnitEdge(2, 1),
|
||||||
SPECIAL_EDGEID,
|
MakeUnitEdge(3, 1)};
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{1,
|
|
||||||
2,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{1,
|
|
||||||
3,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{2,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{3,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
};
|
|
||||||
|
|
||||||
BOOST_ASSERT(edges[0].data.IsCompatibleTo(edges[1].data));
|
BOOST_ASSERT(edges[0].data.IsCompatibleTo(edges[1].data));
|
||||||
BOOST_ASSERT(edges[1].data.IsCompatibleTo(edges[2].data));
|
BOOST_ASSERT(edges[1].data.IsCompatibleTo(edges[2].data));
|
||||||
@ -419,52 +175,8 @@ BOOST_AUTO_TEST_CASE(street_name_changes)
|
|||||||
CompressedEdgeContainer container;
|
CompressedEdgeContainer container;
|
||||||
|
|
||||||
std::vector<InputEdge> edges = {
|
std::vector<InputEdge> edges = {
|
||||||
// src, tgt, dist, edge_id, name_id, access_restricted, fwd, bkwd, roundabout, travel_mode
|
MakeUnitEdge(0, 1), MakeUnitEdge(1, 0), MakeUnitEdge(1, 2), MakeUnitEdge(2, 1)};
|
||||||
{0,
|
edges[2].data.name_id = edges[3].data.name_id = 1;
|
||||||
1,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{1,
|
|
||||||
2,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
1,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{2,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
1,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
};
|
|
||||||
|
|
||||||
BOOST_ASSERT(edges[0].data.IsCompatibleTo(edges[1].data));
|
BOOST_ASSERT(edges[0].data.IsCompatibleTo(edges[1].data));
|
||||||
BOOST_ASSERT(edges[2].data.IsCompatibleTo(edges[3].data));
|
BOOST_ASSERT(edges[2].data.IsCompatibleTo(edges[3].data));
|
||||||
@ -489,52 +201,9 @@ BOOST_AUTO_TEST_CASE(direction_changes)
|
|||||||
CompressedEdgeContainer container;
|
CompressedEdgeContainer container;
|
||||||
|
|
||||||
std::vector<InputEdge> edges = {
|
std::vector<InputEdge> edges = {
|
||||||
// src, tgt, dist, edge_id, name_id, access_restricted, fwd, bkwd, roundabout, travel_mode
|
MakeUnitEdge(0, 1), MakeUnitEdge(1, 0), MakeUnitEdge(1, 2), MakeUnitEdge(2, 1)};
|
||||||
{0,
|
// make first edge point forward
|
||||||
1,
|
edges[1].data.reversed = true;
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{1,
|
|
||||||
2,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
{2,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
SPECIAL_EDGEID,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
|
||||||
INVALID_LANE_DESCRIPTIONID},
|
|
||||||
};
|
|
||||||
|
|
||||||
Graph graph(5, edges);
|
Graph graph(5, edges);
|
||||||
compressor.Compress(barrier_nodes, traffic_lights, map, graph, container);
|
compressor.Compress(barrier_nodes, traffic_lights, map, graph, container);
|
||||||
|
Loading…
Reference in New Issue
Block a user