Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fe491bf92c | |||
| 7b432b34bb | |||
| 6983cd0de2 | |||
| fe8177077c | |||
| 5f339f4ed6 | |||
| 3c0b52c637 | |||
| 877fc5b42c | |||
| e28785e399 | |||
| 2c4a54ce05 | |||
| a8afc74590 | |||
| d195eee7c4 | |||
| 9b737230d6 | |||
| ecbd709535 | |||
| 060ec99678 | |||
| 3601d1d262 | |||
| 41ba20ca9a | |||
| 57e3f173d3 | |||
| 92c298c7cf | |||
| b25011ee60 | |||
| 0e017a6ce5 | |||
| 2431e15ffa | |||
| 396add1e9d | |||
| 86241a2793 | |||
| ee47afbe17 | |||
| 8831ca2f32 | |||
| abde215bc3 | |||
| 130d5298fc | |||
| 50cbba1620 |
+5
-4
@@ -13,6 +13,7 @@ notifications:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- "5.3"
|
||||
|
||||
cache:
|
||||
ccache: true
|
||||
@@ -24,6 +25,7 @@ env:
|
||||
global:
|
||||
- CCACHE_TEMPDIR=/tmp/.ccache-temp
|
||||
- CCACHE_COMPRESS=1
|
||||
- CASHER_TIME_OUT=1000
|
||||
- JOBS=4
|
||||
|
||||
matrix:
|
||||
@@ -75,10 +77,9 @@ matrix:
|
||||
compiler: "gcc-5-release-i686"
|
||||
env: TARGET_ARCH='i686' CCOMPILER='gcc-5' CXXCOMPILER='g++-5' BUILD_TYPE='Release'
|
||||
|
||||
# FIXME disabled until sourceforge fixes its packages for stxxl
|
||||
#- os: linux
|
||||
#- compiler: "gcc-4.8-release-armhf"
|
||||
#- env: TARGET_ARCH='armhf' CCOMPILER='arm-linux-gnueabihf-gcc-4.8' CXXCOMPILER='arm-linux-gnueabihf-g++-4.8' BUILD_TYPE='Release'
|
||||
- os: linux
|
||||
compiler: "gcc-4.8-release-armhf"
|
||||
env: TARGET_ARCH='armhf' CCOMPILER='arm-linux-gnueabihf-gcc-4.8' CXXCOMPILER='arm-linux-gnueabihf-g++-4.8' BUILD_TYPE='Release'
|
||||
|
||||
# Disabled because of CI slowness
|
||||
#- os: linux
|
||||
|
||||
@@ -1,3 +1,41 @@
|
||||
# 5.3.1
|
||||
Changes from 5.3.1
|
||||
- Bugfixes:
|
||||
- Disabled broken lane handling for complex uturn/oneway combinations for now (190 intersections affected on the planet)
|
||||
- Fixed a bug with overlaping geometries, which broke OSRM on recent Egypt extracts with data-modelling issues
|
||||
|
||||
# 5.3.0
|
||||
Changes from 5.3.0-rc.3
|
||||
- Guidance
|
||||
- Only announce `use lane` on required turns (not using all lanes to go straight)
|
||||
- Moved `lanes` to the intersection objects. This is BREAKING in relation to other Release Candidates but not with respect to other releases.
|
||||
- Bugfixes
|
||||
- Fix BREAKING: bug that could result in failure to load 'osrm.icd' files. This breaks the dataformat
|
||||
- Fix: bug that results in segfaults when `use lane` instructions are suppressed
|
||||
|
||||
Changes form 5.2.7
|
||||
- API
|
||||
- Introduces new `TurnType` in the form of `use lane`. The type indicates that you have to stick to a lane without turning
|
||||
- Introduces `lanes` to the `Intersection` object. The lane data contains both the markings at the intersection and a flag indicating if they can be chosen for the next turn
|
||||
- Removed unused `-s` from `osrm-datastore`
|
||||
- Guidance
|
||||
- Only announce `use lane` on required turns (not using all lanes to go straight)
|
||||
- Improved detection of obvious turns
|
||||
- Improved turn lane detection
|
||||
- Reduce the number of end-of-road instructions in obvious cases
|
||||
- Profile:
|
||||
- bicycle.lua: Surface speeds never increase the actual speed
|
||||
- Infrastructure
|
||||
- Add 32bit support
|
||||
- Add ARM NEON/VFP support
|
||||
- Fix Windows builds
|
||||
- Optimize speed file updates using mmap
|
||||
- Add option to disable LTO for older compilers
|
||||
- BREAKING: The new turn type changes the turn-type order. This breaks the **data format**.
|
||||
- BREAKING: Turn lane data introduces two new files (osrm.tld,osrm.tls). This breaks the fileformat for older versions.
|
||||
- Bugfixes:
|
||||
- Fix devide by zero on updating speed data using osrm-contract
|
||||
|
||||
# 5.3.0 RC3
|
||||
Changes from 5.3.0-rc.2
|
||||
- Guidance
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ endif()
|
||||
project(OSRM C CXX)
|
||||
set(OSRM_VERSION_MAJOR 5)
|
||||
set(OSRM_VERSION_MINOR 3)
|
||||
set(OSRM_VERSION_PATCH 0)
|
||||
set(OSRM_VERSION_PATCH 1)
|
||||
|
||||
# these two functions build up custom variables:
|
||||
# OSRM_INCLUDE_PATHS and OSRM_DEFINES
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
# User
|
||||
|
||||
Before you open a new issue, please search for older ones that cover the same issue.
|
||||
In general "me too" comments/issues are frowned upon.
|
||||
You can add a :+1: emoji to the issue if you want to express interest in this.
|
||||
|
||||
# Developer
|
||||
|
||||
We use `clang-format` version `3.8` to consistently format the code base. There is a helper script under `scripts/format.sh`.
|
||||
|
||||
In general changes that affect the API and/or increase the memory consumption need to be discussed first.
|
||||
Often we don't include changes that would increase the memory consumption a lot if they are not generally usable (e.g. elevation data is a good example).
|
||||
|
||||
## Pull Request
|
||||
|
||||
Every pull-request that changes the API needs to update the docs in `docs/http.md` and add an entry to `CHANGELOG.md`.
|
||||
Breaking changes need to have a BREAKING prefix. See the [releasing documentation](docs/releasing.md) on how this affects the version.
|
||||
|
||||
Early feedback is also important.
|
||||
You will see that a lot of the PR have tags like `[not ready]` or `[wip]`.
|
||||
We like to open PRs as soon as we are starting to work on something to make it visible to the rest of the team.
|
||||
If your work is going in entirely the wrong direction, there is a good chance someone will pick up on this before it is too late.
|
||||
Everyone is encouraged to read PRs of other people and give feedback.
|
||||
|
||||
For every significant code change we require a pull request review before it is merged.
|
||||
If your pull request modifies the API this need to be signed of by a team discussion.
|
||||
This means you will need to find another member of the team with commit access and request a review of your pull request.
|
||||
|
||||
Once your pull request is reviewed you can merge it! If you don't have commit access, ping someone that has commit access.
|
||||
If you do have commit access there are in general two accepted styles to merging:
|
||||
|
||||
1. Make sure the branch is up to date with `master`. Run `git rebase master` to find out.
|
||||
2. Once that is ensured you can either:
|
||||
- Click the nice green merge button (for a non-fast-forward merge)
|
||||
- Merge by hand using a fast-forward merge
|
||||
|
||||
Which merge you prefer is up to personal preference. In general it is recommended to use fast-forward merges because it creates a history that is sequential and easier to understand.
|
||||
|
||||
# Maintainer
|
||||
|
||||
## Doing a release
|
||||
|
||||
There is an in-depth guide around how to push out a release once it is ready [here](docs/releasing.md).
|
||||
|
||||
## The API
|
||||
|
||||
Changes to the API need to be discussed and signed off by the team. Breaking changes even more so than additive changes.
|
||||
|
||||
## Milestones
|
||||
|
||||
If a pull request or an issue is applicable for the current or next milestone, depends on the target version number.
|
||||
Since we use semantic versioning we restrict breaking changes to major releases.
|
||||
After a Release Candidate is released we usually don't change the API anymore if it is not critical.
|
||||
Bigger code changes after a RC was released should also be avoided.
|
||||
|
||||
@@ -46,7 +46,7 @@ osrm-routed data.osrm
|
||||
Running a query on your local server:
|
||||
|
||||
```
|
||||
curl http://127.0.0.1:5000/13.388860,52.517037;13.385983,52.496891?steps=true&alternatives=true
|
||||
curl http://127.0.0.1:5000/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true&alternatives=true
|
||||
```
|
||||
|
||||
### Running a request against the Demo Server
|
||||
@@ -56,7 +56,7 @@ First read the [API usage policy](https://github.com/Project-OSRM/osrm-backend/w
|
||||
Then run simple query with instructions and alternatives on Berlin:
|
||||
|
||||
```
|
||||
curl https://router.project-osrm.org/13.388860,52.517037;13.385983,52.496891?steps=true&alternatives=true
|
||||
curl https://router.project-osrm.org/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true&alternatives=true
|
||||
```
|
||||
|
||||
## References in publications
|
||||
|
||||
+4
-13
@@ -1,18 +1,9 @@
|
||||
FROM ubuntu:14.04
|
||||
|
||||
RUN apt-get update -y
|
||||
RUN apt-get install -y build-essential git-core python-pip python-software-properties software-properties-common
|
||||
|
||||
RUN apt-get -y install gcc-4.8 g++-4.8 libboost1.55-all-dev llvm-3.4
|
||||
RUN apt-get -y install libbz2-dev libstxxl-dev libstxxl1 libxml2-dev
|
||||
RUN apt-get -y install libzip-dev lua5.1 liblua5.1-0-dev libtbb-dev libgdal-dev
|
||||
RUN apt-get -y install curl cmake cmake-curses-gui
|
||||
|
||||
RUN pip install awscli
|
||||
|
||||
|
||||
# luabind
|
||||
RUN curl https://gist.githubusercontent.com/DennisOSRM/f2eb7b948e6fe1ae319e/raw/install-luabind.sh | sudo bash
|
||||
RUN apt-get update -y && apt-get install -y software-properties-common
|
||||
RUN add-apt-repository ppa:ubuntu-toolchain-r/test
|
||||
RUN apt-get update -y && apt-get install -y g++-5 libbz2-dev libstxxl-dev libstxxl1 libxml2-dev libzip-dev lua5.1 liblua5.1-0-dev libtbb-dev libgdal-dev libluabind-dev libboost-all-dev ccache
|
||||
RUN apt-get -y install curl cmake cmake-curses-gui git
|
||||
|
||||
WORKDIR /opt
|
||||
RUN git clone --depth 1 --branch v0.31.0 https://github.com/creationix/nvm.git
|
||||
|
||||
+2
-1
@@ -5,7 +5,8 @@ set -o pipefail
|
||||
|
||||
docker run \
|
||||
-i \
|
||||
-e "CXX=g++" \
|
||||
-e "CXX=g++-5" \
|
||||
-e "CC=gcc-5" \
|
||||
-v `pwd`:/home/mapbox/osrm-backend \
|
||||
-t mapbox/osrm:linux \
|
||||
/bin/bash -lc "osrm-backend/docker/test.sh"
|
||||
|
||||
+21
-12
@@ -453,24 +453,28 @@ step.
|
||||
"maneuver":{
|
||||
"type":"turn",
|
||||
"modifier":"right",
|
||||
"lanes":[
|
||||
{"indications":["left","straight"], "valid":"false"},
|
||||
{"indications":["right"], "valid":"true"}
|
||||
]},
|
||||
},
|
||||
"geometry":"{lu_IypwpAVrAvAdI",
|
||||
"mode":"driving",
|
||||
"intersections":[
|
||||
{"location":[13.39677,52.54366],
|
||||
"in":3,
|
||||
"out":1,
|
||||
"out":2,
|
||||
"bearings":[10,92,184,270],
|
||||
"entry":[false,"true","true"]},
|
||||
"entry":["true","true","true","false"],
|
||||
"lanes":[
|
||||
{"indications":["left","straight"], "valid":"false"},
|
||||
{"indications":["right"], "valid":"true"}
|
||||
]},
|
||||
{"location":[13.394718,52.543096],
|
||||
"in":0,
|
||||
"out":2,
|
||||
"bearings":[60,150,240,330],
|
||||
"entry":["false","true","true","true"]
|
||||
}
|
||||
"out":1,
|
||||
"bearings":[60,240,330],
|
||||
"entry":["false","true","true"]
|
||||
"lanes":[
|
||||
{"indications":["straight"], "valid":"true"},
|
||||
{"indications":["right"], "valid":"false"}
|
||||
]}
|
||||
]}
|
||||
```
|
||||
|
||||
@@ -536,8 +540,7 @@ step.
|
||||
|------------------------|---------------------------------------------------------------------------------------------------------------------------|
|
||||
| `roundabout` | Number of the roundabout exit to take. If exit is `undefined` the destination is on the roundabout. |
|
||||
| else | Indicates the number of intersections passed until the turn. Example instruction: `at the fourth intersection, turn left` |
|
||||
|
||||
- `lanes`: Array of `Lane` objects that denote the available turn lanes at the turn location
|
||||
|
||||
|
||||
New properties (potentially depending on `type`) may be introduced in the future without an API version change.
|
||||
|
||||
@@ -588,6 +591,7 @@ location of the StepManeuver. Further intersections are listed for every cross-w
|
||||
in the direction of driving, the bearing has to be rotated by a value of 180. The value is not supplied for `depart` maneuvers.
|
||||
- `out`: index into the bearings/entry array. Used to extract the bearing just after the turn. Namely, The clockwise angle from true north to the
|
||||
direction of travel immediately after the maneuver/passing the intersection. The value is not supplied for `arrive` maneuvers.
|
||||
- `lanes`: Array of `Lane` objects that denote the available turn lanes at the turn location
|
||||
|
||||
#### Example
|
||||
```
|
||||
@@ -597,6 +601,11 @@ location of the StepManeuver. Further intersections are listed for every cross-w
|
||||
"out":2,
|
||||
"bearings":[60,150,240,330],
|
||||
"entry":["false","true","true","true"]
|
||||
"lanes":{
|
||||
"indications": ["left", "straight"],
|
||||
"valid": "false"
|
||||
}
|
||||
]}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -135,9 +135,9 @@ Feature: Turn Lane Guidance
|
||||
| cj | | 1 | motorway_link | yes | xbcj |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,i | ab,xbcj,ci,ci | depart,merge slight left,turn slight right,arrive | ,,none:false slight right:true, |
|
||||
| a,j | ab,xbcj,xbcj,xbcj | depart,merge slight left,use lane straight,arrive | ,,none:true slight right:false, |
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,i | ab,xbcj,ci,ci | depart,merge slight left,turn slight right,arrive | ,,none:false slight right:true, |
|
||||
| a,j | ab,xbcj,xbcj | depart,merge slight left,arrive | ,, |
|
||||
|
||||
|
||||
@anticipate
|
||||
@@ -259,8 +259,8 @@ Feature: Turn Lane Guidance
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,f | abx,bcy,cdz,dew,ef,ef | depart,turn right,turn left,turn right,turn left,arrive | ,straight:false right:false right:true right:false,left:false left:true straight:false,straight:false right:true right:false,left:true straight:false, |
|
||||
|
||||
@anticipate
|
||||
Scenario: Anticipate with lanes in roundabout: roundabouts as the unit of anticipation
|
||||
@anticipate @todo @bug @2661
|
||||
Scenario: Anticipate with lanes in roundabout: roundabouts as the unit of anticipation
|
||||
Given the node map
|
||||
| | | e | | |
|
||||
| a | b | | d | f |
|
||||
@@ -365,6 +365,62 @@ Feature: Turn Lane Guidance
|
||||
| x,c | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,slight right:true slight right:true, |
|
||||
| x,a | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,slight right:true slight right:true, |
|
||||
|
||||
@anticipate
|
||||
Scenario: Departing or arriving inside a roundabout does not yet anticipate lanes (BIG version)
|
||||
Given the node map
|
||||
| | | a | | |
|
||||
| x | b | | d | y |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | c | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | highway | junction | name |
|
||||
| xb | slight_right\|slight_right | primary | | xb |
|
||||
| dy | | primary | | dy |
|
||||
| ab | | primary | roundabout | roundabout |
|
||||
| bc | | primary | roundabout | roundabout |
|
||||
| cd | left\|slight_right | primary | roundabout | roundabout |
|
||||
| da | | primary | roundabout | roundabout |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| x,y | xb,dy,dy | depart,roundabout-exit-1,arrive | ,slight right:false slight right:true, |
|
||||
| x,c | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,slight right:true slight right:true, |
|
||||
| x,a | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,slight right:true slight right:true, |
|
||||
|
||||
@anticipate
|
||||
Scenario: Anticipate Lanes for turns before and / or after roundabout
|
||||
Given the node map
|
||||
|
||||
@@ -128,3 +128,36 @@ Feature: End Of Road Instructions
|
||||
| a,c | aeb,bc,bc | depart,on ramp left,arrive |
|
||||
| a,d | aeb,bd,bd | depart,on ramp right,arrive |
|
||||
|
||||
# http://www.openstreetmap.org/#map=19/52.49907/13.41836
|
||||
@end-of-road @negative
|
||||
Scenario: Don't Handle Circles as End-Of-Road
|
||||
Given the node map
|
||||
| | r | | | | q | | | | | | |
|
||||
| | | | | | a | s | | | | | |
|
||||
| | | | b | | | | | | | | |
|
||||
| | | | | | | | j | | | | |
|
||||
| | | | | | | | | | | | |
|
||||
| l | | c | | | | | i | | | | k |
|
||||
| | | | | | | | | | | | |
|
||||
| | | | | | | | h | | | | |
|
||||
| m | | | | | | | | | | | |
|
||||
| | | d | | | | | | | | | n |
|
||||
| | | | e | | | g | | | | | |
|
||||
| | | | | f | | | | | | | |
|
||||
| | | | | o | | p | | | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | oneway |
|
||||
| abcdefghijsa | secondary | kotti | yes |
|
||||
| ki | secondary | skal | yes |
|
||||
| cl | secondary | skal | yes |
|
||||
| md | secondary | skal | yes |
|
||||
| gn | secondary | skal | yes |
|
||||
| qa | tertiary | adal | no |
|
||||
| br | residential | rei | yes |
|
||||
| fo | secondary | kstr | yes |
|
||||
| pg | secondary | kstr | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | # |
|
||||
| k,l | skal,kotti,skal,skal | depart,turn right,turn right,arrive | # could be a case to find better turn instructions for |
|
||||
|
||||
@@ -437,3 +437,42 @@ Feature: Basic Roundabout
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,k | massachusetts,massachusetts,massachusetts,massachusetts | depart,sheridan circle-exit-2,dupont circle-exit-1,arrive |
|
||||
|
||||
Scenario: Enter and Exit - Traffic Signals
|
||||
Given the node map
|
||||
| | | a | | |
|
||||
| | i | b | l | |
|
||||
| h | g | | c | d |
|
||||
| | j | e | k | |
|
||||
| | | f | | |
|
||||
|
||||
And the nodes
|
||||
| node | highway |
|
||||
| i | traffic_signals |
|
||||
| j | traffic_signals |
|
||||
| k | traffic_signals |
|
||||
| l | traffic_signals |
|
||||
|
||||
And the ways
|
||||
| nodes | junction |
|
||||
| ab | |
|
||||
| cd | |
|
||||
| ef | |
|
||||
| gh | |
|
||||
| bigjekclb | roundabout |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,d | ab,cd,cd | depart,roundabout-exit-3,arrive |
|
||||
| a,f | ab,ef,ef | depart,roundabout-exit-2,arrive |
|
||||
| a,h | ab,gh,gh | depart,roundabout-exit-1,arrive |
|
||||
| d,f | cd,ef,ef | depart,roundabout-exit-3,arrive |
|
||||
| d,h | cd,gh,gh | depart,roundabout-exit-2,arrive |
|
||||
| d,a | cd,ab,ab | depart,roundabout-exit-1,arrive |
|
||||
| f,h | ef,gh,gh | depart,roundabout-exit-3,arrive |
|
||||
| f,a | ef,ab,ab | depart,roundabout-exit-2,arrive |
|
||||
| f,d | ef,cd,cd | depart,roundabout-exit-1,arrive |
|
||||
| h,a | gh,ab,ab | depart,roundabout-exit-3,arrive |
|
||||
| h,d | gh,cd,cd | depart,roundabout-exit-2,arrive |
|
||||
| h,f | gh,ef,ef | depart,roundabout-exit-1,arrive |
|
||||
|
||||
|
||||
@@ -87,7 +87,6 @@ Feature: Turn Lane Guidance
|
||||
|
||||
|
||||
#this next test requires decision on how to announce lanes for going straight if there is no turn
|
||||
@TODO
|
||||
Scenario: Turn with Bus-Lane
|
||||
Given the node map
|
||||
| a | | b | | c |
|
||||
@@ -101,9 +100,9 @@ Feature: Turn Lane Guidance
|
||||
| bd | turn | | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | road,turn,turn | depart,turn right,arrive | ,straight:false right:true, |
|
||||
| a,c | road,road,road | depart,use lane straight,arrive | ,straight:true right:false, |
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | road,turn,turn | depart,turn right,arrive | ,straight:false right:true, |
|
||||
| a,c | road,road | depart,arrive | , |
|
||||
|
||||
@PROFILE @LANES
|
||||
Scenario: Turn with Bus-Lane but without lanes
|
||||
@@ -194,13 +193,13 @@ Feature: Turn Lane Guidance
|
||||
| fl | cross | | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,j | road,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true, |
|
||||
| k,d | cross,road,road | depart,turn right,arrive | ,left:false straight;right:true, |
|
||||
| e,l | road,cross,cross | depart,turn right,arrive | ,none:false straight:false straight;right:true, |
|
||||
| i,h | cross,road,road | depart,turn right,arrive | ,, |
|
||||
| i,j | cross,cross,cross | depart,use lane straight,arrive | ,left:false straight:true, |
|
||||
| i,l | cross,cross,cross | depart,continue uturn,arrive | ,left:true straight:false, |
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,j | road,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true, |
|
||||
| k,d | cross,road,road | depart,turn right,arrive | ,left:false straight;right:true, |
|
||||
| e,l | road,cross,cross | depart,turn right,arrive | ,none:false straight:false straight;right:true, |
|
||||
| i,h | cross,road,road | depart,turn right,arrive | ,, |
|
||||
| i,j | cross,cross | depart,arrive | , |
|
||||
| i,l | cross,cross,cross | depart,continue uturn,arrive | ,left:true straight:false, |
|
||||
|
||||
Scenario: Turn Lanes at Segregated Road
|
||||
Given the node map
|
||||
@@ -238,9 +237,9 @@ Feature: Turn Lane Guidance
|
||||
| ce | turn | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | road,turn,turn | depart,turn right,arrive | ,none:false right:true, |
|
||||
| a,d | road,road,road | depart,use lane straight,arrive | ,none:true right:false, |
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | road,turn,turn | depart,turn right,arrive | ,none:false right:true, |
|
||||
| a,d | road,road | depart,arrive | , |
|
||||
|
||||
Scenario: Turn Lanes Given earlier than actual turn
|
||||
Given the node map
|
||||
@@ -258,11 +257,11 @@ Feature: Turn Lane Guidance
|
||||
| hk | second-turn | | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,k | road,second-turn,second-turn | depart,turn right,arrive | ,none:false right:true, |
|
||||
| a,i | road,road,road | depart,use lane straight,arrive | ,none:true right:false, |
|
||||
| i,j | road,first-turn,first-turn | depart,turn left,arrive | ,left:true none:false, |
|
||||
| i,a | road,road,road | depart,use lane straight,arrive | ,left:false none:true, |
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,k | road,second-turn,second-turn | depart,turn right,arrive | ,none:false right:true, |
|
||||
| a,i | road,road | depart,arrive | , |
|
||||
| i,j | road,first-turn,first-turn | depart,turn left,arrive | ,left:true none:false, |
|
||||
| i,a | road,road | depart,arrive | , |
|
||||
|
||||
Scenario: Passing a one-way street
|
||||
Given the node map
|
||||
@@ -358,9 +357,9 @@ Feature: Turn Lane Guidance
|
||||
| ce | turn | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | road,road,road | depart,use lane straight,arrive | ,straight:true right:false, |
|
||||
| a,e | road,turn,turn | depart,turn right,arrive | ,straight:false right:true, |
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | road,road | depart,arrive | , |
|
||||
| a,e | road,turn,turn | depart,turn right,arrive | ,straight:false right:true, |
|
||||
|
||||
@bug @todo
|
||||
Scenario: Theodor Heuss Platz
|
||||
@@ -422,9 +421,9 @@ Feature: Turn Lane Guidance
|
||||
| restriction | bc | fdcg | c | no_right_turn |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,g | road,cross,cross | depart,turn left,arrive | ,left:true left:true straight:false straight:false, |
|
||||
| a,e | road,road,road | depart,use lane straight,arrive | ,left:false left:false straight:true straight:true, |
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,g | road,cross,cross | depart,turn left,arrive | ,left:true left:true straight:false straight:false, |
|
||||
| a,e | road,road | depart,arrive | , |
|
||||
|
||||
Scenario: U-Turn Road at Intersection
|
||||
Given the node map
|
||||
@@ -445,11 +444,11 @@ Feature: Turn Lane Guidance
|
||||
| gdeh | cross | | no | primary |
|
||||
|
||||
When I route I should get
|
||||
| from | to | bearings | route | turns | lanes |
|
||||
| a | g | 180,180 180,180 | road,cross,cross | depart,turn right,arrive | ,none:false straight:false right:true, |
|
||||
| a | h | 180,180 180,180 | road,cross,cross | depart,turn left,arrive | ,none:true straight:false right:false, |
|
||||
| a | i | 180,180 180,180 | road,road,road | depart,use lane straight,arrive | ,none:true straight:true right:false, |
|
||||
| b | a | 90,2 270,2 | road,road,road | depart,continue uturn,arrive | ,none:true straight:false right:false, |
|
||||
| from | to | bearings | route | turns | lanes |
|
||||
| a | g | 180,180 180,180 | road,cross,cross | depart,turn right,arrive | ,none:false straight:false right:true, |
|
||||
| a | h | 180,180 180,180 | road,cross,cross | depart,turn left,arrive | ,none:true straight:false right:false, |
|
||||
| a | i | 180,180 180,180 | road,road | depart,arrive | , |
|
||||
| b | a | 90,2 270,2 | road,road,road | depart,continue uturn,arrive | ,none:true straight:false right:false, |
|
||||
|
||||
Scenario: Segregated Intersection Merges With Lanes
|
||||
Given the node map
|
||||
@@ -519,7 +518,7 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | road,road,road | depart,use lane straight,arrive | ,straight:true straight:true straight;slight right:true slight right:false, |
|
||||
| a,d | road,road | depart,arrive | , |
|
||||
| a,e | road,cross,cross | depart,turn slight right,arrive | ,straight:false straight:false straight;slight right:true slight right:true, |
|
||||
|
||||
Scenario: Highway Ramp
|
||||
@@ -535,7 +534,7 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | hwy,hwy,hwy | depart,use lane straight,arrive | ,straight:true straight:true straight;slight right:true slight right:false, |
|
||||
| a,d | hwy,hwy | depart,arrive | , |
|
||||
| a,e | hwy,ramp,ramp | depart,off ramp slight right,arrive | ,straight:false straight:false straight;slight right:true slight right:true, |
|
||||
|
||||
@bug @todo
|
||||
@@ -575,7 +574,7 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,c | hwy,hwy,hwy | depart,use lane slight left,arrive | ,straight:true straight:true slight right:false, |
|
||||
| a,c | hwy,hwy | depart,arrive | , |
|
||||
| a,d | hwy,ramp,ramp | depart,off ramp slight right,arrive | ,straight:false straight:false slight right:true, |
|
||||
|
||||
Scenario: Reverse Lane in Segregated Road
|
||||
@@ -681,6 +680,169 @@ Feature: Turn Lane Guidance
|
||||
| ab | on | motorway_link | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,j | on,xbcj,xbcj,xbcj | depart,merge slight left,use lane straight,arrive | ,,none:true slight right:false, |
|
||||
| a,i | on,xbcj,off,off | depart,merge slight left,turn slight right,arrive | ,,none:false slight right:true, |
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,j | on,xbcj,xbcj | depart,merge slight left,arrive | ,, |
|
||||
| a,i | on,xbcj,off,off | depart,merge slight left,turn slight right,arrive | ,,none:false slight right:true, |
|
||||
|
||||
#http://www.openstreetmap.org/#map=17/52.47414/13.35712
|
||||
@todo @ramp @2645
|
||||
Scenario: Kreuz Schoeneberg - Continue on ramp, don't merge
|
||||
Given the node map
|
||||
| i | | | | | j | | | | | | | | | | | |
|
||||
| | | | | k | | | | | | | | | | | | |
|
||||
| h | g | | l | | | f | | | | | | | | | | e |
|
||||
| d | | | | | | | | c | | | | | b | | | a |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | oneway | lanes | turn:lanes |
|
||||
| ab | motorway | A 100 | yes | 3 | |
|
||||
| bc | motorway | A 100 | yes | 4 | \|\|\|slight_right |
|
||||
| cd | motorway | A 100 | yes | 3 | |
|
||||
| eb | motorway_link | | yes | 1 | |
|
||||
| cf | motorway_link | | yes | 1 | |
|
||||
| fj | motorway_link | | yes | 1 | |
|
||||
| fl | motorway_link | | yes | 1 | |
|
||||
| kl | motorway_link | | yes | 1 | |
|
||||
| lg | motorway_link | | yes | 2 | through\|slight_right |
|
||||
| gi | motorway_link | | yes | 1 | |
|
||||
| gh | motorway_link | | yes | 1 | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | A 100,A 100 | depart,arrive | |
|
||||
| a,i | A 100,,,, | depart,off ramp slight right,fork slight left,turn right,arrive | ,none:false none:false none:false slight right:true,,straight:false slight right:true, |
|
||||
| e,j | ,,, | depart,off ramp slight right,fork slight right,arrive | ,none:false none:false none:false slight right:true,,, |
|
||||
| e,i | ,,,, | depart,off ramp right,fork slight left,use lane straight,arrive | ,none:false none:false none:false slight right:true,,straight:false slight right:true, |
|
||||
| e,d | ,A 100,A 100 | depart,merge slight left,arrive | ,, |
|
||||
| e,h | ,,,, | depart,off ramp right,fork left,use lane straight,arrive | ,none:false none:false none:false slight right:true,,straight:true slight right:false, |
|
||||
|
||||
@collapse @use-lane
|
||||
Scenario: Collapse Multiple Use Lanes
|
||||
Given the node map
|
||||
| x | a | | b | | | c | | | d |
|
||||
| | | | e | | | f | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | highway | turn:lanes:forward |
|
||||
| ab | road | primary | through,right |
|
||||
| bc | road | primary | through,right |
|
||||
| cd | road | primary | |
|
||||
| xa | road | primary | |
|
||||
| be | turn | primary | |
|
||||
| cf | turn | primary | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| x,d | road,road | depart,arrive | , |
|
||||
|
||||
|
||||
Scenario: Lane Parsing Issue #2694
|
||||
Given the node map
|
||||
| | c |
|
||||
| a | b |
|
||||
| | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | turn:lanes:forward |
|
||||
| ab | primary | left;left\|right |
|
||||
| bc | primary | |
|
||||
| bd | primary | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,c | ab,bc,bc | depart,turn left,arrive | ,left:true right:false, |
|
||||
|
||||
# http://www.openstreetmap.org/#map=19/47.97685/7.82933&layers=D
|
||||
@bug @todo
|
||||
Scenario: Lane Parsing Issue #2706: None Assignments I
|
||||
Given the node map
|
||||
| | f | | | j | |
|
||||
| | | | | | |
|
||||
| a | b | c | | d | e |
|
||||
| | | | | | |
|
||||
| | | | | i | |
|
||||
| | g | | | h | |
|
||||
|
||||
And the nodes
|
||||
| node | highway |
|
||||
| a | traffic_signals |
|
||||
| i | traffic_signals |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | oneway | turn:lanes:forward |
|
||||
| ab | secondary | Wiesentalstr | | through;left\|right |
|
||||
| bc | secondary | Wiesentalstr | | none\|left;through |
|
||||
| cd | secondary | Wiesentalstr | | none\|left;through |
|
||||
| de | residential | Wippertstr | | |
|
||||
| fb | secondary | Merzhauser Str | yes | through\|through\|right |
|
||||
| bg | secondary | Merzhauser Str | yes | |
|
||||
| hi | secondary | Merzhauser Str | yes | left;reverse\|none\|none |
|
||||
| ic | secondary_link | Merzhauser Str | yes | |
|
||||
| id | secondary | Merzhauser Str | yes | through;right\|none |
|
||||
| dj | secondary | Merzhauser Str | yes | |
|
||||
|
||||
And the relations
|
||||
| type | way:from | way:to | node:via | restriction |
|
||||
| restriction | fb | fb | b | no_left_turn |
|
||||
| restriction | ic | cb | c | only_left_turn |
|
||||
| restriction | id | dc | d | no_left_turn |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| h,a ||||
|
||||
# Note: at the moment we don't care about routes, we care about the extract process triggering assertions
|
||||
|
||||
# https://www.openstreetmap.org/#map=19/47.99257/7.83276&layers=D
|
||||
@bug @todo
|
||||
Scenario: Lane Parsing Issue #2706: None Assignments II
|
||||
Given the node map
|
||||
| | k | l | |
|
||||
| j | a | b | f |
|
||||
| i | c | d | e |
|
||||
| | h | g | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | oneway | turn:lanes |
|
||||
| ka | secondary | Eschholzstr | yes | left;reverse\|through\|through\|none |
|
||||
| kj | unclassified | kj | yes | |
|
||||
| ac | secondary | Eschholzstr | yes | left;reverse\|none\|none\|none |
|
||||
| ch | secondary | Eschholzstr | yes | |
|
||||
| gd | secondary | Eschholzstr | yes | left;reverse\|through\|through\|none |
|
||||
| db | secondary | Eschholzstr | yes | left;reverse\|through\|through\|none |
|
||||
| bl | secondary | Eschholzstr | yes | |
|
||||
| fb | residential | Haslacher Str | yes | left;reverse\|left;through\|right |
|
||||
| ba | secondary_link | Haslacher Str | yes | left;reverse\|left;through |
|
||||
| aj | unclassified | Haslacher Str | yes | |
|
||||
| ic | unclassified | Haslacher Str | yes | left;reverse\|left\|through |
|
||||
| cd | secondary_link | Haslacher Str | yes | left;reverse\|left\|through |
|
||||
| de | residential | Haslacher Str | yes | |
|
||||
|
||||
And the relations
|
||||
| type | way:from | way:to | node:via | restriction |
|
||||
| restriction | ka | ac | a | only_straight_on |
|
||||
| restriction | ic | cd | c | only_straight_on |
|
||||
| restriction | gd | db | d | only_straight_on |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| i,e ||||
|
||||
# Note: at the moment we don't care about routes, we care about the extract process triggering assertions
|
||||
|
||||
@bug @todo
|
||||
Scenario: Lane Parsing Issue #2706: None Assignments III - Minimal reproduction recipe
|
||||
Given the node map
|
||||
| | | l | |
|
||||
| | a | b | |
|
||||
| | | d | |
|
||||
| | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | oneway | turn:lanes |
|
||||
| db | secondary | Eschholzstr | yes | left;reverse\|through\|through\|none |
|
||||
| bl | secondary | Eschholzstr | yes | |
|
||||
| ba | secondary_link | Haslacher Str | yes | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| d,a ||||
|
||||
# Note: at the moment we don't care about routes, we care about the extract process triggering assertions
|
||||
|
||||
@@ -170,9 +170,9 @@ module.exports = function () {
|
||||
|
||||
this.lanesList = (instructions) => {
|
||||
return this.extractInstructionList(instructions, instruction => {
|
||||
if( 'lanes' in instruction.maneuver )
|
||||
if( 'lanes' in instruction.intersections[0] )
|
||||
{
|
||||
return instruction.maneuver.lanes.map( p => { return (p.indications).join(';') + ':' + p.valid; } ).join(' ');
|
||||
return instruction.intersections[0].lanes.map( p => { return (p.indications).join(';') + ':' + p.valid; } ).join(' ');
|
||||
} else
|
||||
{
|
||||
return '';
|
||||
|
||||
@@ -151,6 +151,7 @@ class RouteAPI : public BaseAPI
|
||||
phantoms.source_phantom,
|
||||
phantoms.target_phantom);
|
||||
leg.steps = guidance::anticipateLaneChange(std::move(leg.steps));
|
||||
leg.steps = guidance::collapseUseLane(std::move(leg.steps));
|
||||
leg_geometry = guidance::resyncGeometry(std::move(leg_geometry), leg.steps);
|
||||
}
|
||||
|
||||
|
||||
@@ -360,7 +360,7 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
std::vector<util::guidance::BearingClass> bearing_classes;
|
||||
// and the actual bearing values
|
||||
std::uint64_t num_bearings;
|
||||
intersection_stream >> num_bearings;
|
||||
intersection_stream.read(reinterpret_cast<char*>(&num_bearings),sizeof(num_bearings));
|
||||
m_bearing_values_table.resize(num_bearings);
|
||||
intersection_stream.read(reinterpret_cast<char *>(&m_bearing_values_table[0]),
|
||||
sizeof(m_bearing_values_table[0]) * num_bearings);
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#define ENGINE_GUIDANCE_ASSEMBLE_STEPS_HPP_
|
||||
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
#include "engine/guidance/leg_geometry.hpp"
|
||||
#include "engine/guidance/route_step.hpp"
|
||||
@@ -72,14 +72,15 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
bearings.second,
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
WaypointType::Depart,
|
||||
0,
|
||||
util::guidance::LaneTupel(),
|
||||
{}};
|
||||
0};
|
||||
|
||||
Intersection intersection{source_node.location,
|
||||
std::vector<short>({bearings.second}),
|
||||
std::vector<bool>({true}),
|
||||
Intersection::NO_INDEX,
|
||||
0};
|
||||
0,
|
||||
util::guidance::LaneTupel(),
|
||||
{}};
|
||||
|
||||
if (leg_data.size() > 0)
|
||||
{
|
||||
@@ -138,6 +139,11 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
intersection.location = facade.GetCoordinateOfNode(path_point.turn_via_node);
|
||||
intersection.bearings.clear();
|
||||
intersection.bearings.reserve(bearing_class.getAvailableBearings().size());
|
||||
intersection.lanes = path_point.lane_data.first;
|
||||
intersection.lane_description =
|
||||
path_point.lane_data.second != INVALID_LANE_DESCRIPTIONID
|
||||
? facade.GetTurnDescription(path_point.lane_data.second)
|
||||
: extractor::guidance::TurnLaneDescription();
|
||||
std::copy(bearing_class.getAvailableBearings().begin(),
|
||||
bearing_class.getAvailableBearings().end(),
|
||||
std::back_inserter(intersection.bearings));
|
||||
@@ -151,11 +157,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
bearings.second,
|
||||
path_point.turn_instruction,
|
||||
WaypointType::None,
|
||||
0,
|
||||
path_point.lane_data.first,
|
||||
(path_point.lane_data.second != INVALID_LANE_DESCRIPTIONID
|
||||
? facade.GetTurnDescription(path_point.lane_data.second)
|
||||
: extractor::guidance::TurnLaneDescription())};
|
||||
0};
|
||||
segment_index++;
|
||||
segment_duration = 0;
|
||||
}
|
||||
@@ -210,15 +212,16 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
bearings.second,
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
WaypointType::Arrive,
|
||||
0,
|
||||
util::guidance::LaneTupel(),
|
||||
{}};
|
||||
0};
|
||||
|
||||
intersection = {
|
||||
target_node.location,
|
||||
std::vector<short>({static_cast<short>(util::bearing::reverseBearing(bearings.first))}),
|
||||
std::vector<bool>({true}),
|
||||
0,
|
||||
Intersection::NO_INDEX};
|
||||
Intersection::NO_INDEX,
|
||||
util::guidance::LaneTupel(),
|
||||
{}};
|
||||
|
||||
BOOST_ASSERT(!leg_geometry.locations.empty());
|
||||
steps.push_back(RouteStep{target_node.name_id,
|
||||
@@ -243,9 +246,9 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
BOOST_ASSERT(steps.back().intersections.front().bearings.size() == 1);
|
||||
BOOST_ASSERT(steps.back().intersections.front().entry.size() == 1);
|
||||
BOOST_ASSERT(steps.back().maneuver.waypoint_type == WaypointType::Arrive);
|
||||
BOOST_ASSERT(steps.back().maneuver.lanes.lanes_in_turn == 0);
|
||||
BOOST_ASSERT(steps.back().maneuver.lanes.first_lane_from_the_right == INVALID_LANEID);
|
||||
BOOST_ASSERT(steps.back().maneuver.lane_description.empty());
|
||||
BOOST_ASSERT(steps.back().intersections.front().lanes.lanes_in_turn == 0);
|
||||
BOOST_ASSERT(steps.back().intersections.front().lanes.first_lane_from_the_right == INVALID_LANEID);
|
||||
BOOST_ASSERT(steps.back().intersections.front().lane_description.empty());
|
||||
return steps;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,10 @@ namespace guidance
|
||||
// Constrains lanes for multi-hop situations where lane changes depend on earlier ones.
|
||||
// Instead of forcing users to change lanes rapidly in a short amount of time,
|
||||
// we anticipate lane changes emitting only matching lanes early on.
|
||||
std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps);
|
||||
// the second parameter describes the duration that we feel two segments need to be apart to count
|
||||
// as separate maneuvers.
|
||||
std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
|
||||
const double min_duration_needed_for_lane_change = 15);
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace engine
|
||||
|
||||
@@ -43,6 +43,15 @@ std::vector<RouteStep> buildIntersections(std::vector<RouteStep> steps);
|
||||
// remove steps invalidated by post-processing
|
||||
std::vector<RouteStep> removeNoTurnInstructions(std::vector<RouteStep> steps);
|
||||
|
||||
// remove use lane information that is not actually a turn. For post-processing, we need to
|
||||
// associate lanes with every turn. Some of these use-lane instructions are not required after lane
|
||||
// anticipation anymore. This function removes all use lane instructions that are not actually used
|
||||
// anymore since all lanes going straight are used anyhow.
|
||||
// FIXME this is currently only a heuristic. We need knowledge on which lanes actually might become
|
||||
// turn lanes. If a straight lane becomes a turn lane, this might be something to consider. Right
|
||||
// now we bet on lane-anticipation to catch this.
|
||||
std::vector<RouteStep> collapseUseLane(std::vector<RouteStep> steps);
|
||||
|
||||
// postProcess will break the connection between the leg geometry
|
||||
// for which a segment is supposed to represent exactly the coordinates
|
||||
// between routing maneuvers and the route steps itself.
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
#include "util/guidance/bearing_class.hpp"
|
||||
#include "util/guidance/entry_class.hpp"
|
||||
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <string>
|
||||
@@ -34,6 +37,10 @@ struct Intersection
|
||||
std::vector<bool> entry;
|
||||
std::size_t in;
|
||||
std::size_t out;
|
||||
|
||||
// turn lane information
|
||||
util::guidance::LaneTupel lanes;
|
||||
extractor::guidance::TurnLaneDescription lane_description;
|
||||
};
|
||||
|
||||
inline Intersection getInvalidIntersection()
|
||||
@@ -42,7 +49,9 @@ inline Intersection getInvalidIntersection()
|
||||
{},
|
||||
{},
|
||||
Intersection::NO_INDEX,
|
||||
Intersection::NO_INDEX};
|
||||
Intersection::NO_INDEX,
|
||||
util::guidance::LaneTupel(),
|
||||
{}};
|
||||
}
|
||||
|
||||
struct RouteStep
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
#define ENGINE_GUIDANCE_STEP_MANEUVER_HPP
|
||||
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
@@ -33,9 +31,6 @@ struct StepManeuver
|
||||
|
||||
WaypointType waypoint_type;
|
||||
unsigned exit;
|
||||
|
||||
util::guidance::LaneTupel lanes;
|
||||
extractor::guidance::TurnLaneDescription lane_description;
|
||||
};
|
||||
|
||||
inline StepManeuver getInvalidStepManeuver()
|
||||
@@ -45,9 +40,7 @@ inline StepManeuver getInvalidStepManeuver()
|
||||
0,
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
WaypointType::None,
|
||||
0,
|
||||
util::guidance::LaneTupel(),
|
||||
{}};
|
||||
0};
|
||||
}
|
||||
|
||||
} // namespace guidance
|
||||
|
||||
@@ -62,6 +62,13 @@ class EntryClass
|
||||
friend std::size_t std::hash<EntryClass>::operator()(const EntryClass &) const;
|
||||
};
|
||||
|
||||
#if not defined __GNUC__ or __GNUC__ > 4
|
||||
static_assert(std::is_trivially_copyable<EntryClass>::value,
|
||||
"Class is serialized trivially in "
|
||||
"the datafacades. Bytewise writing "
|
||||
"requires trivially copyable type");
|
||||
#endif
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace utilr
|
||||
} // namespace osrm
|
||||
|
||||
@@ -60,7 +60,6 @@ class LaneTupel
|
||||
|
||||
bool operator==(const LaneTupel other) const;
|
||||
bool operator!=(const LaneTupel other) const;
|
||||
bool operator<(const LaneTupel other) const;
|
||||
|
||||
LaneID lanes_in_turn;
|
||||
LaneID first_lane_from_the_right;
|
||||
|
||||
@@ -72,6 +72,15 @@ namespace osrm
|
||||
namespace contractor
|
||||
{
|
||||
|
||||
// Returns duration in deci-seconds
|
||||
inline EdgeWeight distanceAndSpeedToWeight(double distance_in_meters, double speed_in_kmh)
|
||||
{
|
||||
BOOST_ASSERT(speed_in_kmh > 0);
|
||||
const double speed_in_ms = speed_in_kmh / 3.6;
|
||||
const double duration = distance_in_meters / speed_in_ms;
|
||||
return std::max<EdgeWeight>(1, static_cast<EdgeWeight>(std::round(duration * 10)));
|
||||
}
|
||||
|
||||
int Contractor::Run()
|
||||
{
|
||||
#ifdef WIN32
|
||||
@@ -573,12 +582,11 @@ EdgeID Contractor::LoadEdgeExpandedGraph(
|
||||
find(segment_speed_lookup, Segment{u->node_id, v->node_id});
|
||||
if (forward_speed_iter != segment_speed_lookup.end())
|
||||
{
|
||||
int new_segment_weight =
|
||||
std::max(1,
|
||||
static_cast<int>(std::floor(
|
||||
(segment_length * 10.) /
|
||||
(forward_speed_iter->speed_source.speed / 3.6) +
|
||||
.5)));
|
||||
auto new_segment_weight =
|
||||
(forward_speed_iter->speed_source.speed > 0)
|
||||
? distanceAndSpeedToWeight(segment_length,
|
||||
forward_speed_iter->speed_source.speed)
|
||||
: INVALID_EDGE_WEIGHT;
|
||||
m_geometry_list[forward_begin + leaf_object.fwd_segment_position].weight =
|
||||
new_segment_weight;
|
||||
m_geometry_datasource[forward_begin + leaf_object.fwd_segment_position] =
|
||||
@@ -624,12 +632,11 @@ EdgeID Contractor::LoadEdgeExpandedGraph(
|
||||
find(segment_speed_lookup, Segment{u->node_id, v->node_id});
|
||||
if (reverse_speed_iter != segment_speed_lookup.end())
|
||||
{
|
||||
int new_segment_weight =
|
||||
std::max(1,
|
||||
static_cast<int>(std::floor(
|
||||
(segment_length * 10.) /
|
||||
(reverse_speed_iter->speed_source.speed / 3.6) +
|
||||
.5)));
|
||||
auto new_segment_weight =
|
||||
(reverse_speed_iter->speed_source.speed > 0)
|
||||
? distanceAndSpeedToWeight(segment_length,
|
||||
reverse_speed_iter->speed_source.speed)
|
||||
: INVALID_EDGE_WEIGHT;
|
||||
m_geometry_list[reverse_begin + rev_segment_position].weight =
|
||||
new_segment_weight;
|
||||
m_geometry_datasource[reverse_begin + rev_segment_position] =
|
||||
@@ -763,21 +770,22 @@ EdgeID Contractor::LoadEdgeExpandedGraph(
|
||||
const auto num_segments = header->num_osm_nodes - 1;
|
||||
for (auto i : util::irange<std::size_t>(0, num_segments))
|
||||
{
|
||||
|
||||
auto speed_iter =
|
||||
find(segment_speed_lookup,
|
||||
Segment{previous_osm_node_id, segmentblocks[i].this_osm_node_id});
|
||||
if (speed_iter != segment_speed_lookup.end())
|
||||
{
|
||||
// This sets the segment weight using the same formula as the
|
||||
// EdgeBasedGraphFactory for consistency. The *why* of this formula
|
||||
// is lost in the annals of time.
|
||||
int new_segment_weight = std::max(
|
||||
1,
|
||||
static_cast<int>(std::floor((segmentblocks[i].segment_length * 10.) /
|
||||
(speed_iter->speed_source.speed / 3.6) +
|
||||
.5)));
|
||||
new_weight += new_segment_weight;
|
||||
if (speed_iter->speed_source.speed > 0)
|
||||
{
|
||||
auto new_segment_weight = distanceAndSpeedToWeight(segmentblocks[i].segment_length, speed_iter->speed_source.speed);
|
||||
new_weight += new_segment_weight;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This edge is blocked, we don't need to continue updating
|
||||
new_weight = INVALID_EDGE_WEIGHT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -61,9 +61,9 @@ inline bool isValidModifier(const guidance::StepManeuver maneuver)
|
||||
maneuver.instruction.direction_modifier != DirectionModifier::UTurn);
|
||||
}
|
||||
|
||||
inline bool hasValidLanes(const guidance::StepManeuver maneuver)
|
||||
inline bool hasValidLanes(const guidance::Intersection &intersection)
|
||||
{
|
||||
return maneuver.lanes.lanes_in_turn > 0;
|
||||
return intersection.lanes.lanes_in_turn > 0;
|
||||
}
|
||||
|
||||
std::string instructionTypeToString(const TurnType::Enum type)
|
||||
@@ -71,19 +71,19 @@ std::string instructionTypeToString(const TurnType::Enum type)
|
||||
return turn_type_names[static_cast<std::size_t>(type)];
|
||||
}
|
||||
|
||||
util::json::Array lanesFromManeuver(const guidance::StepManeuver &maneuver)
|
||||
util::json::Array lanesFromIntersection(const guidance::Intersection &intersection)
|
||||
{
|
||||
BOOST_ASSERT(maneuver.lanes.lanes_in_turn >= 1);
|
||||
BOOST_ASSERT(intersection.lanes.lanes_in_turn >= 1);
|
||||
util::json::Array result;
|
||||
LaneID lane_id = maneuver.lane_description.size();
|
||||
LaneID lane_id = intersection.lane_description.size();
|
||||
|
||||
for (const auto &lane_desc : maneuver.lane_description)
|
||||
for (const auto &lane_desc : intersection.lane_description)
|
||||
{
|
||||
--lane_id;
|
||||
util::json::Object lane;
|
||||
lane.values["indications"] = extractor::guidance::TurnLaneType::toJsonArray(lane_desc);
|
||||
if (lane_id >= maneuver.lanes.first_lane_from_the_right &&
|
||||
lane_id < maneuver.lanes.first_lane_from_the_right + maneuver.lanes.lanes_in_turn)
|
||||
if (lane_id >= intersection.lanes.first_lane_from_the_right &&
|
||||
lane_id < intersection.lanes.first_lane_from_the_right + intersection.lanes.lanes_in_turn)
|
||||
lane.values["valid"] = util::json::True();
|
||||
else
|
||||
lane.values["valid"] = util::json::False();
|
||||
@@ -175,9 +175,6 @@ util::json::Object makeStepManeuver(const guidance::StepManeuver &maneuver)
|
||||
step_maneuver.values["modifier"] =
|
||||
detail::instructionModifierToString(maneuver.instruction.direction_modifier);
|
||||
|
||||
if (detail::hasValidLanes(maneuver))
|
||||
step_maneuver.values["lanes"] = detail::lanesFromManeuver(maneuver);
|
||||
|
||||
step_maneuver.values["location"] = detail::coordinateToLonLat(maneuver.location);
|
||||
step_maneuver.values["bearing_before"] = std::round(maneuver.bearing_before);
|
||||
step_maneuver.values["bearing_after"] = std::round(maneuver.bearing_after);
|
||||
@@ -217,6 +214,9 @@ util::json::Object makeIntersection(const guidance::Intersection &intersection)
|
||||
if (intersection.out != guidance::Intersection::NO_INDEX)
|
||||
result.values["out"] = intersection.out;
|
||||
|
||||
if (detail::hasValidLanes(intersection))
|
||||
result.values["lanes"] = detail::lanesFromIntersection(intersection);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,18 +20,17 @@ namespace engine
|
||||
namespace guidance
|
||||
{
|
||||
|
||||
std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps)
|
||||
std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
|
||||
const double min_duration_needed_for_lane_change)
|
||||
{
|
||||
const constexpr auto MIN_DURATION_NEEDED_FOR_LANE_CHANGE = 15.;
|
||||
|
||||
// Postprocessing does not strictly guarantee for only turns
|
||||
const auto is_turn = [](const RouteStep &step) {
|
||||
return step.maneuver.instruction.type != TurnType::NewName &&
|
||||
step.maneuver.instruction.type != TurnType::Notification;
|
||||
};
|
||||
|
||||
const auto is_quick = [MIN_DURATION_NEEDED_FOR_LANE_CHANGE](const RouteStep &step) {
|
||||
return step.duration < MIN_DURATION_NEEDED_FOR_LANE_CHANGE;
|
||||
const auto is_quick = [min_duration_needed_for_lane_change](const RouteStep &step) {
|
||||
return step.duration < min_duration_needed_for_lane_change;
|
||||
};
|
||||
|
||||
const auto is_quick_turn = [&](const RouteStep &step) {
|
||||
@@ -61,10 +60,10 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps)
|
||||
// the current turn lanes constrain the lanes we have to take in the previous turn.
|
||||
util::for_each_pair(rev_first, rev_last, [](RouteStep ¤t, RouteStep &previous) {
|
||||
const auto current_inst = current.maneuver.instruction;
|
||||
const auto current_lanes = current.maneuver.lanes;
|
||||
const auto current_lanes = current.intersections.front().lanes;
|
||||
|
||||
// Constrain the previous turn's lanes
|
||||
auto &previous_lanes = previous.maneuver.lanes;
|
||||
auto &previous_lanes = previous.intersections.front().lanes;
|
||||
// Lane mapping (N:M) from previous lanes (N) to current lanes (M), with:
|
||||
// N > M, N > 1 fan-in situation, constrain N lanes to min(N,M) shared lanes
|
||||
// otherwise nothing to constrain
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "engine/guidance/post_processing.hpp"
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "engine/guidance/post_processing.hpp"
|
||||
|
||||
#include "engine/guidance/assemble_steps.hpp"
|
||||
#include "engine/guidance/lane_processing.hpp"
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
#include <boost/range/algorithm_ext/erase.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -524,7 +525,10 @@ std::vector<RouteStep> anticipateLaneChangeForRoundabouts(std::vector<RouteStep>
|
||||
enter.maneuver.instruction.direction_modifier =
|
||||
mirrorDirectionModifier(enter_direction);
|
||||
|
||||
auto enterAndLeave = anticipateLaneChange({enter, leave});
|
||||
// a roundabout is a continuous maneuver. We don't switch lanes within a roundabout, as long
|
||||
// as it can be avoided.
|
||||
auto enterAndLeave =
|
||||
anticipateLaneChange({enter, leave}, std::numeric_limits<double>::max());
|
||||
|
||||
// Undo flipping direction on a right turn in a right-sided counter-clockwise roundabout.
|
||||
// FIXME: assumes right-side driving (counter-clockwise roundabout flow)
|
||||
@@ -535,7 +539,6 @@ std::vector<RouteStep> anticipateLaneChangeForRoundabouts(std::vector<RouteStep>
|
||||
};
|
||||
|
||||
forEachRoundabout(begin(steps), end(steps), anticipate_lanes_in_roundabout);
|
||||
|
||||
return steps;
|
||||
}
|
||||
} // namespace
|
||||
@@ -628,6 +631,10 @@ std::vector<RouteStep> postProcess(std::vector<RouteStep> steps)
|
||||
has_entered_roundabout = false;
|
||||
on_roundabout = false;
|
||||
}
|
||||
else if (on_roundabout && step_index + 1 < steps.size())
|
||||
{
|
||||
steps[step_index + 1].maneuver.exit = step.maneuver.exit;
|
||||
}
|
||||
}
|
||||
|
||||
// unterminated roundabout
|
||||
@@ -906,8 +913,8 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
|
||||
designated_depart.maneuver.instruction = TurnInstruction::NO_TURN();
|
||||
// we need to make this conform with the intersection format for the first intersection
|
||||
auto &first_intersection = designated_depart.intersections.front();
|
||||
designated_depart.maneuver.lanes = util::guidance::LaneTupel();
|
||||
designated_depart.maneuver.lane_description.clear();
|
||||
designated_depart.intersections.front().lanes = util::guidance::LaneTupel();
|
||||
designated_depart.intersections.front().lane_description.clear();
|
||||
first_intersection.bearings = {first_intersection.bearings[first_intersection.out]};
|
||||
first_intersection.entry = {true};
|
||||
first_intersection.in = Intersection::NO_INDEX;
|
||||
@@ -974,8 +981,8 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
|
||||
next_to_last_step.maneuver.waypoint_type = WaypointType::Arrive;
|
||||
next_to_last_step.maneuver.instruction = TurnInstruction::NO_TURN();
|
||||
next_to_last_step.maneuver.bearing_after = 0;
|
||||
next_to_last_step.maneuver.lanes = util::guidance::LaneTupel();
|
||||
next_to_last_step.maneuver.lane_description.clear();
|
||||
next_to_last_step.intersections.front().lanes = util::guidance::LaneTupel();
|
||||
next_to_last_step.intersections.front().lane_description.clear();
|
||||
BOOST_ASSERT(next_to_last_step.intersections.size() == 1);
|
||||
auto &last_intersection = next_to_last_step.intersections.back();
|
||||
last_intersection.bearings = {last_intersection.bearings[last_intersection.in]};
|
||||
@@ -1143,6 +1150,60 @@ std::vector<RouteStep> buildIntersections(std::vector<RouteStep> steps)
|
||||
return removeNoTurnInstructions(std::move(steps));
|
||||
}
|
||||
|
||||
std::vector<RouteStep> collapseUseLane(std::vector<RouteStep> steps)
|
||||
{
|
||||
const auto containsTag = [](const extractor::guidance::TurnLaneType::Mask mask,
|
||||
const extractor::guidance::TurnLaneType::Mask tag) {
|
||||
return (mask & tag) != extractor::guidance::TurnLaneType::empty;
|
||||
};
|
||||
|
||||
const auto getPreviousIndex = [&steps](std::size_t index) {
|
||||
BOOST_ASSERT(index > 0);
|
||||
BOOST_ASSERT(index < steps.size());
|
||||
--index;
|
||||
while (index > 0 && steps[index].maneuver.instruction.type == TurnType::NoTurn)
|
||||
--index;
|
||||
|
||||
return index;
|
||||
};
|
||||
|
||||
const auto canCollapeUseLane =
|
||||
[containsTag](const util::guidance::LaneTupel lanes,
|
||||
extractor::guidance::TurnLaneDescription lane_description) {
|
||||
// the lane description is given left to right, lanes are counted from the right.
|
||||
// Therefore we access the lane description yousing the reverse iterator
|
||||
if (lanes.first_lane_from_the_right > 0 &&
|
||||
containsTag(*(lane_description.rbegin() + (lanes.first_lane_from_the_right - 1)),
|
||||
(extractor::guidance::TurnLaneType::straight |
|
||||
extractor::guidance::TurnLaneType::none)))
|
||||
return false;
|
||||
|
||||
const auto lane_to_the_right = lanes.first_lane_from_the_right + lanes.lanes_in_turn;
|
||||
if (lane_to_the_right < boost::numeric_cast<int>(lane_description.size()) &&
|
||||
containsTag(*(lane_description.rbegin() + lane_to_the_right),
|
||||
(extractor::guidance::TurnLaneType::straight |
|
||||
extractor::guidance::TurnLaneType::none)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
for (std::size_t step_index = 1; step_index < steps.size(); ++step_index)
|
||||
{
|
||||
const auto &step = steps[step_index];
|
||||
if (step.maneuver.instruction.type == TurnType::UseLane &&
|
||||
canCollapeUseLane(step.intersections.front().lanes,
|
||||
step.intersections.front().lane_description))
|
||||
{
|
||||
const auto previous = getPreviousIndex(step_index);
|
||||
steps[previous] = elongate(steps[previous], steps[step_index]);
|
||||
//elongate(steps[step_index-1], steps[step_index]);
|
||||
invalidateStep(steps[step_index]);
|
||||
}
|
||||
}
|
||||
return removeNoTurnInstructions(std::move(steps));
|
||||
}
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace engine
|
||||
} // namespace osrm
|
||||
|
||||
@@ -507,8 +507,8 @@ Extractor::BuildEdgeExpandedGraph(lua_State *lua_state,
|
||||
|
||||
std::vector<std::uint32_t> turn_lane_offsets;
|
||||
std::vector<guidance::TurnLaneType::Mask> turn_lane_masks;
|
||||
if( !util::deserializeAdjacencyArray(
|
||||
config.turn_lane_descriptions_file_name, turn_lane_offsets, turn_lane_masks) )
|
||||
if (!util::deserializeAdjacencyArray(
|
||||
config.turn_lane_descriptions_file_name, turn_lane_offsets, turn_lane_masks))
|
||||
{
|
||||
util::SimpleLogger().Write(logWARNING) << "Reading Turn Lane Masks failed.";
|
||||
}
|
||||
@@ -673,7 +673,7 @@ void Extractor::WriteIntersectionClassificationData(
|
||||
util::RangeTable<> bearing_class_range_table(bearing_counts);
|
||||
file_out_stream << bearing_class_range_table;
|
||||
|
||||
file_out_stream << total_bearings;
|
||||
file_out_stream.write(reinterpret_cast<const char *>(&total_bearings), sizeof(total_bearings));
|
||||
for (const auto &bearing_class : bearing_classes)
|
||||
{
|
||||
const auto &bearings = bearing_class.getAvailableBearings();
|
||||
@@ -681,17 +681,18 @@ void Extractor::WriteIntersectionClassificationData(
|
||||
sizeof(bearings[0]) * bearings.size());
|
||||
}
|
||||
|
||||
// FIXME
|
||||
// This should be here, but g++4.8 does not have it...
|
||||
// static_assert(std::is_trivially_copyable<util::guidance::EntryClass>::value,
|
||||
// "EntryClass Serialization requires trivial copyable entry classes");
|
||||
if (!static_cast<bool>(file_out_stream))
|
||||
{
|
||||
throw util::exception("Failed to write to " + output_file_name + ".");
|
||||
}
|
||||
|
||||
util::serializeVector(file_out_stream, entry_classes);
|
||||
TIMER_STOP(write_edges);
|
||||
util::SimpleLogger().Write() << "ok, after " << TIMER_SEC(write_edges) << "s for "
|
||||
<< node_based_intersection_classes.size() << " Indices into "
|
||||
<< bearing_classes.size() << " bearing classes and "
|
||||
<< entry_classes.size() << " entry classes";
|
||||
<< entry_classes.size() << " entry classes and " << total_bearings
|
||||
<< " bearing values." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,7 +193,8 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
for (auto token_itr = inner_tokens.begin(); token_itr != inner_tokens.end();
|
||||
++token_itr)
|
||||
{
|
||||
auto position = std::find(osm_lane_strings, osm_lane_strings + num_osm_tags, *token_itr);
|
||||
auto position =
|
||||
std::find(osm_lane_strings, osm_lane_strings + num_osm_tags, *token_itr);
|
||||
const auto translated_mask =
|
||||
masks_by_osm_string[std::distance(osm_lane_strings, position)];
|
||||
if (translated_mask == TurnLaneType::empty)
|
||||
@@ -203,7 +204,10 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
<< *token_itr << "\"";
|
||||
return {};
|
||||
}
|
||||
BOOST_ASSERT((lane_mask & translated_mask) == 0); // make sure the mask is valid
|
||||
|
||||
// In case of multiple times the same lane indicators withn a lane, as in
|
||||
// "left;left|.." or-ing the masks generates a single "left" enum.
|
||||
// Which is fine since this is data issue and we can't represent it anyway.
|
||||
lane_mask |= translated_mask;
|
||||
}
|
||||
// add the lane to the description
|
||||
@@ -265,8 +269,8 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
// name_offsets already has an offset of a new name, take the offset index as the name id
|
||||
name_id = external_memory.name_offsets.size() - 1;
|
||||
|
||||
external_memory.name_char_data.reserve(external_memory.name_char_data.size() + name_length
|
||||
+ destinations_length + pronunciation_length);
|
||||
external_memory.name_char_data.reserve(external_memory.name_char_data.size() + name_length +
|
||||
destinations_length + pronunciation_length);
|
||||
|
||||
std::copy(parsed_way.name.c_str(),
|
||||
parsed_way.name.c_str() + name_length,
|
||||
@@ -306,7 +310,9 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
std::transform(input_way.nodes().begin(),
|
||||
input_way.nodes().end(),
|
||||
std::back_inserter(external_memory.used_node_id_list),
|
||||
[](const osmium::NodeRef &ref) { return OSMNodeID{static_cast<std::uint64_t>(ref.ref())}; });
|
||||
[](const osmium::NodeRef &ref) {
|
||||
return OSMNodeID{static_cast<std::uint64_t>(ref.ref())};
|
||||
});
|
||||
|
||||
const bool is_opposite_way = TRAVEL_MODE_INACCESSIBLE == parsed_way.forward_travel_mode;
|
||||
|
||||
@@ -338,7 +344,8 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
external_memory.way_start_end_id_list.push_back(
|
||||
{OSMWayID{static_cast<std::uint32_t>(input_way.id())},
|
||||
OSMNodeID{static_cast<std::uint64_t>(input_way.nodes().back().ref())},
|
||||
OSMNodeID{static_cast<std::uint64_t>(input_way.nodes()[input_way.nodes().size() - 2].ref())},
|
||||
OSMNodeID{
|
||||
static_cast<std::uint64_t>(input_way.nodes()[input_way.nodes().size() - 2].ref())},
|
||||
OSMNodeID{static_cast<std::uint64_t>(input_way.nodes()[1].ref())},
|
||||
OSMNodeID{static_cast<std::uint64_t>(input_way.nodes()[0].ref())}});
|
||||
}
|
||||
@@ -372,27 +379,28 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
input_way.nodes().cbegin(),
|
||||
input_way.nodes().cend(),
|
||||
[&](const osmium::NodeRef &first_node, const osmium::NodeRef &last_node) {
|
||||
external_memory.all_edges_list.push_back(
|
||||
InternalExtractorEdge(OSMNodeID{static_cast<std::uint64_t>(first_node.ref())},
|
||||
OSMNodeID{static_cast<std::uint64_t>(last_node.ref())},
|
||||
name_id,
|
||||
backward_weight_data,
|
||||
false,
|
||||
true,
|
||||
parsed_way.roundabout,
|
||||
parsed_way.is_access_restricted,
|
||||
parsed_way.is_startpoint,
|
||||
parsed_way.backward_travel_mode,
|
||||
true,
|
||||
turn_lane_id_backward,
|
||||
road_classification));
|
||||
external_memory.all_edges_list.push_back(InternalExtractorEdge(
|
||||
OSMNodeID{static_cast<std::uint64_t>(first_node.ref())},
|
||||
OSMNodeID{static_cast<std::uint64_t>(last_node.ref())},
|
||||
name_id,
|
||||
backward_weight_data,
|
||||
false,
|
||||
true,
|
||||
parsed_way.roundabout,
|
||||
parsed_way.is_access_restricted,
|
||||
parsed_way.is_startpoint,
|
||||
parsed_way.backward_travel_mode,
|
||||
true,
|
||||
turn_lane_id_backward,
|
||||
road_classification));
|
||||
});
|
||||
}
|
||||
|
||||
external_memory.way_start_end_id_list.push_back(
|
||||
{OSMWayID{static_cast<std::uint32_t>(input_way.id())},
|
||||
OSMNodeID{static_cast<std::uint64_t>(input_way.nodes().back().ref())},
|
||||
OSMNodeID{static_cast<std::uint64_t>(input_way.nodes()[input_way.nodes().size() - 2].ref())},
|
||||
OSMNodeID{
|
||||
static_cast<std::uint64_t>(input_way.nodes()[input_way.nodes().size() - 2].ref())},
|
||||
OSMNodeID{static_cast<std::uint64_t>(input_way.nodes()[1].ref())},
|
||||
OSMNodeID{static_cast<std::uint64_t>(input_way.nodes()[0].ref())}});
|
||||
}
|
||||
|
||||
@@ -143,7 +143,20 @@ Intersection IntersectionGenerator::getConnectedRoads(const NodeID from_node,
|
||||
const auto valid_count =
|
||||
boost::count_if(intersection, [](const ConnectedRoad &road) { return road.entry_allowed; });
|
||||
if (0 == valid_count && uturn_could_be_valid)
|
||||
intersection[0].entry_allowed = true;
|
||||
{
|
||||
// after intersections sorting by angles, find the u-turn with (from_node == to_node)
|
||||
// that was inserted together with setting uturn_could_be_valid flag
|
||||
std::size_t self_u_turn = 0;
|
||||
while (self_u_turn < intersection.size()
|
||||
&& intersection[self_u_turn].turn.angle < std::numeric_limits<double>::epsilon()
|
||||
&& from_node != node_based_graph.GetTarget(intersection[self_u_turn].turn.eid))
|
||||
{
|
||||
++self_u_turn;
|
||||
}
|
||||
|
||||
BOOST_ASSERT(from_node == node_based_graph.GetTarget(intersection[self_u_turn].turn.eid));
|
||||
intersection[self_u_turn].entry_allowed = true;
|
||||
}
|
||||
|
||||
return mergeSegregatedRoads(std::move(intersection));
|
||||
}
|
||||
|
||||
@@ -282,7 +282,14 @@ LaneDataVector handleNoneValueAtSimpleTurn(LaneDataVector lane_data,
|
||||
// a pgerequisite is simple turns. Larger differences should not end up here
|
||||
// an additional line at the side is only reasonable if it is targeting public
|
||||
// service vehicles. Otherwise, we should not have it
|
||||
BOOST_ASSERT(connection_count + 1 == lane_data.size());
|
||||
//
|
||||
// TODO(mokob): #2730 have a look please
|
||||
// BOOST_ASSERT(connection_count + 1 == lane_data.size());
|
||||
//
|
||||
if (connection_count + 1 != lane_data.size())
|
||||
{
|
||||
goto these_intersections_are_clearly_broken_at_the_moment;
|
||||
}
|
||||
|
||||
lane_data = mergeNoneTag(none_index, std::move(lane_data));
|
||||
}
|
||||
@@ -292,6 +299,9 @@ LaneDataVector handleNoneValueAtSimpleTurn(LaneDataVector lane_data,
|
||||
{
|
||||
lane_data = handleRenamingSituations(none_index, std::move(lane_data), intersection);
|
||||
}
|
||||
|
||||
these_intersections_are_clearly_broken_at_the_moment:
|
||||
|
||||
// finally make sure we are still sorted
|
||||
std::sort(lane_data.begin(), lane_data.end());
|
||||
return lane_data;
|
||||
|
||||
@@ -351,8 +351,14 @@ bool TurnLaneHandler::isSimpleIntersection(const LaneDataVector &lane_data,
|
||||
if (lane_data.back().tag == TurnLaneType::uturn)
|
||||
return findBestMatchForReverse(lane_data[lane_data.size() - 2].tag, intersection);
|
||||
|
||||
BOOST_ASSERT(lane_data.front().tag == TurnLaneType::uturn);
|
||||
return findBestMatchForReverse(lane_data[1].tag, intersection);
|
||||
// TODO(mokob): #2730 have a look please
|
||||
// BOOST_ASSERT(lane_data.front().tag == TurnLaneType::uturn);
|
||||
// return findBestMatchForReverse(lane_data[1].tag, intersection);
|
||||
//
|
||||
if (lane_data.front().tag == TurnLaneType::uturn)
|
||||
return findBestMatchForReverse(lane_data[1].tag, intersection);
|
||||
|
||||
return findBestMatch(data.tag, intersection);
|
||||
}();
|
||||
std::size_t match_index = std::distance(intersection.begin(), best_match);
|
||||
all_simple &= (matched_indices.count(match_index) == 0);
|
||||
|
||||
@@ -375,7 +375,7 @@ int Storage::Run()
|
||||
}
|
||||
|
||||
std::uint64_t num_bearings;
|
||||
intersection_stream >> num_bearings;
|
||||
intersection_stream.read(reinterpret_cast<char*>(&num_bearings),sizeof(num_bearings));
|
||||
|
||||
std::vector<DiscreteBearing> bearing_class_table(num_bearings);
|
||||
intersection_stream.read(reinterpret_cast<char *>(&bearing_class_table[0]),
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <tuple>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
@@ -24,23 +25,12 @@ LaneTupel::LaneTupel(const LaneID lanes_in_turn, const LaneID first_lane_from_th
|
||||
// comparation based on interpretation as unsigned 32bit integer
|
||||
bool LaneTupel::operator==(const LaneTupel other) const
|
||||
{
|
||||
static_assert(sizeof(LaneTupel) == sizeof(std::uint16_t),
|
||||
"Comparation requires LaneTupel to be the of size 16Bit");
|
||||
return *reinterpret_cast<const std::uint16_t *>(this) ==
|
||||
*reinterpret_cast<const std::uint16_t *>(&other);
|
||||
return std::tie(lanes_in_turn, first_lane_from_the_right) ==
|
||||
std::tie(other.lanes_in_turn, other.first_lane_from_the_right);
|
||||
}
|
||||
|
||||
bool LaneTupel::operator!=(const LaneTupel other) const { return !(*this == other); }
|
||||
|
||||
// comparation based on interpretation as unsigned 32bit integer
|
||||
bool LaneTupel::operator<(const LaneTupel other) const
|
||||
{
|
||||
static_assert(sizeof(LaneTupel) == sizeof(std::uint16_t),
|
||||
"Comparation requires LaneTupel to be the of size 16Bit");
|
||||
return *reinterpret_cast<const std::uint16_t *>(this) <
|
||||
*reinterpret_cast<const std::uint16_t *>(&other);
|
||||
}
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace util
|
||||
} // namespace osrm
|
||||
|
||||
Reference in New Issue
Block a user