Compare commits

..

7 Commits

Author SHA1 Message Date
Patrick Niklaus 97c7bcd9c8 Add assetion fix to changelog 2016-04-27 23:35:59 +02:00
Patrick Niklaus c511b5a133 Try to kick start travis again 2016-04-27 23:25:14 +02:00
Daniel J. Hofmann e7ab764714 Enable Travis builds for this branch 2016-04-27 18:50:49 +02:00
Daniel J. Hofmann cbc2283b58 Add Hotfixes to Changelog 2016-04-27 17:25:00 +02:00
Moritz Kobitzsch 598d5fbb67 fix post-processing for local paths, fixes #2310 2016-04-27 17:16:05 +02:00
Moritz Kobitzsch 823dcbf511 remove invalid assertion 2016-04-27 17:15:54 +02:00
Moritz Kobitzsch 1933c5e8f4 Fix local path looping, fixes #2309 2016-04-26 00:53:49 +02:00
211 changed files with 4414 additions and 7431 deletions
-1
View File
@@ -80,7 +80,6 @@ stxxl.errlog
/test/profile.lua
/test/cache
/test/speeds.csv
/test/penalties.csv
/test/data/monaco.*
node_modules
+70 -83
View File
@@ -1,7 +1,7 @@
language: cpp
#language: cpp
# This makes travis use the thin image which boots faster
language: generic
git:
depth: 10
# sudo:required is needed for trusty images
sudo: required
@@ -13,109 +13,101 @@ notifications:
branches:
only:
- master
cache:
ccache: true
apt: true
env:
global:
- CCACHE_TEMPDIR=/tmp/.ccache-temp
- CCACHE_COMPRESS=1
- JOBS=4
- "5.0"
matrix:
fast_finish: true
# We override the compiler names here to yield better ccache behavior, which uses this as key
include:
# Debug Builds
- os: linux
compiler: "gcc-5-debug"
compiler: gcc
addons: &gcc5
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['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']
packages: ['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', 'pip']
env: CCOMPILER='gcc-5' CXXCOMPILER='g++-5' BUILD_TYPE='Debug' COVERAGE=ON
- os: linux
compiler: "gcc-4.8-debug"
compiler: gcc
addons: &gcc48
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.8', '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']
packages: ['g++-4.8', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev']
env: CCOMPILER='gcc-4.8' CXXCOMPILER='g++-4.8' BUILD_TYPE='Debug'
- os: linux
compiler: "clang-3.8-debug"
compiler: clang
addons: &clang38
apt:
sources: ['llvm-toolchain-precise-3.8', 'ubuntu-toolchain-r-test']
packages: ['clang-3.8', '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']
packages: ['clang-3.8', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev']
env: CCOMPILER='clang-3.8' CXXCOMPILER='clang++-3.8' BUILD_TYPE='Debug' RUN_CLANG_FORMAT=ON
- os: osx
osx_image: xcode7.3
compiler: clang
env: CCOMPILER='clang' CXXCOMPILER='clang++' BUILD_TYPE='Debug' JOBS=1 CUCUMBER_TIMEOUT=60000
env: CCOMPILER='clang' CXXCOMPILER='clang++' BUILD_TYPE='Debug'
# Release Builds
- os: linux
compiler: "gcc-5-release"
compiler: gcc
addons: &gcc5
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['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']
packages: ['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']
env: CCOMPILER='gcc-5' CXXCOMPILER='g++-5' BUILD_TYPE='Release'
# Disabled because of CI slowness
#- os: linux
#- compiler: gcc
#- addons: &gcc48
#- apt:
#- sources: ['ubuntu-toolchain-r-test']
#- packages: ['g++-4.8', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev']
#- env: CCOMPILER='gcc-4.8' CXXCOMPILER='g++-4.8' BUILD_TYPE='Release'
- os: linux
compiler: gcc
addons: &gcc48
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.8', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev']
env: CCOMPILER='gcc-4.8' CXXCOMPILER='g++-4.8' BUILD_TYPE='Release'
# Disabled because of CI slowness
#- os: linux
#- compiler: clang
#- addons: &clang38
#- apt:
#- sources: ['llvm-toolchain-precise-3.8', 'ubuntu-toolchain-r-test']
#- packages: ['clang-3.8', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev']
#- env: CCOMPILER='clang-3.8' CXXCOMPILER='clang++-3.8' BUILD_TYPE='Release'
- os: linux
compiler: clang
addons: &clang38
apt:
sources: ['llvm-toolchain-precise-3.8', 'ubuntu-toolchain-r-test']
packages: ['clang-3.8', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev']
env: CCOMPILER='clang-3.8' CXXCOMPILER='clang++-3.8' BUILD_TYPE='Release'
# Disabled because of CI slowness
#- os: osx
#- osx_image: xcode7.3
#- compiler: clang
#- env: CCOMPILER='clang' CXXCOMPILER='clang++' BUILD_TYPE='Release'
- os: osx
osx_image: xcode7.3
compiler: clang
env: CCOMPILER='clang' CXXCOMPILER='clang++' BUILD_TYPE='Release'
# Shared Library
- os: linux
compiler: "gcc-5-release-shared"
compiler: gcc
addons: &gcc5
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['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']
packages: ['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']
env: CCOMPILER='gcc-5' CXXCOMPILER='g++-5' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
# Disabled because CI slowness
#- os: linux
#- compiler: clang
#- addons: &clang38
#- apt:
#- sources: ['llvm-toolchain-precise-3.8', 'ubuntu-toolchain-r-test']
#- packages: ['clang-3.8', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev']
#- env: CCOMPILER='clang-3.8' CXXCOMPILER='clang++-3.8' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
- os: linux
compiler: clang
addons: &clang38
apt:
sources: ['llvm-toolchain-precise-3.8', 'ubuntu-toolchain-r-test']
packages: ['clang-3.8', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev']
env: CCOMPILER='clang-3.8' CXXCOMPILER='clang++-3.8' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
before_install:
- source ./scripts/install_node.sh 4
install:
- npm install
- DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
- mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR}
- |
if [[ -n "${COVERAGE}" ]]; then
pip install --user cpp-coveralls
fi
- |
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
CMAKE_URL="http://www.cmake.org/files/v3.5/cmake-3.5.1-Linux-x86_64.tar.gz"
@@ -123,10 +115,10 @@ before_install:
export PATH=${DEPS_DIR}/cmake/bin:${PATH}
elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
# implicit deps, but seem to be installed by default with recent images: libxml2 GDAL boost
brew install cmake libzip libstxxl lua51 luabind tbb md5sha1sum ccache
brew install cmake libzip libstxxl lua51 luabind tbb md5sha1sum
fi
install:
before_script:
- cd ${TRAVIS_BUILD_DIR}
- |
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
@@ -134,46 +126,41 @@ install:
fi
- mkdir build && pushd build
- export CC=${CCOMPILER} CXX=${CXXCOMPILER}
- cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS:-OFF} -DCOVERAGE=${COVERAGE:-OFF} -DBUILD_TOOLS=1 -DENABLE_CCACHE=ON
- echo "travis_fold:start:MAKE"
- make osrm-extract --jobs=3
- make --jobs=${JOBS}
- make tests --jobs=${JOBS}
- make benchmarks --jobs=${JOBS}
- echo "travis_fold:end:MAKE"
- ccache -s
- export OSRM_PORT=5000 OSRM_TIMEOUT=6000
- cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS:-OFF} -DCOVERAGE=${COVERAGE:-OFF} -DBUILD_TOOLS=1 -DENABLE_CCACHE=0
script:
- make --jobs=2
- make tests --jobs=2
- make benchmarks
- sudo make install
- |
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
sudo ldconfig
fi
- popd
- mkdir example/build && pushd example/build
- cmake ..
- make
- popd
script:
- echo "travis_fold:start:BENCHMARK"
- make -C test/data benchmark
- echo "travis_fold:end:BENCHMARK"
- ./example/build/osrm-example test/data/monaco.osrm
# All tests assume to be run from the build directory
- pushd build
- ./unit_tests/library-tests ../test/data/monaco.osrm
- echo "travis_fold:start:UNIT_TESTS"
- ./unit_tests/extractor-tests
- ./unit_tests/engine-tests
- ./unit_tests/util-tests
- ./unit_tests/server-tests
- echo "travis_fold:end:UNIT_TESTS"
- popd
- echo "travis_fold:start:CUCUMBER"
- npm test
- echo "travis_fold:end:CUCUMBER"
- echo "travis_fold:start:BENCHMARK"
- make -C test/data benchmark
- echo "travis_fold:end:BENCHMARK"
- ./build/unit_tests/library-tests test/data/monaco.osrm
- mkdir example/build && pushd example/build
- cmake ..
- make
- ./osrm-example ../../test/data/monaco.osrm
- popd
after_success:
- |
if [ -n "${RUN_CLANG_FORMAT}" ]; then
if [ -n "$RUN_CLANG_FORMAT" ]; then
./scripts/format.sh || true # we don't want to fail just yet
fi
- |
if [ -n "${COVERAGE}" ]; then
bash <(curl -s https://codecov.io/bash)
fi
- coveralls --build-root build --exclude unit_tests --exclude third_party --exclude node_modules --gcov-options '\-lp'
+4 -55
View File
@@ -1,59 +1,8 @@
# 5.2.0 RC1
Changes from 5.1.0
- API:
- new parameter `annotate` for `route` and `match` requests. Returns additional data about each
coordinate along the selected/matched route line.
- Introducing Intersections for Route Steps. This changes the API format in multiple ways.
- `bearing_before`/`bearing_after` of `StepManeuver` are now deprecated and will be removed in the next major release
- `location` of `StepManeuvers` is now deprecated and will be removed in the next major release
- every `RouteStep` now has property `intersections` containing a list of `Intersection` objects.
- Profile changes:
- duration parser now accepts P[n]DT[n]H[n]M[n]S, P[n]W, PTHHMMSS and PTHH:MM:SS ISO8601 formats.
- Infrastructure:
- Better support for osrm-routed binary upgrade on the fly [UNIX specific]:
- Open sockets with SO_REUSEPORT to allow multiple osrm-routed processes serving requests from the same port.
- Add SIGNAL_PARENT_WHEN_READY environment variable to enable osrm-routed signal its parent with USR1 when it's running and waiting for requests.
- BREAKING: Intersection Classification adds a new file to the mix (osrm.icd). This breaks the fileformat for older versions.
- Disable http access logging via DISABLE_ACCESS_LOGGING environment
variable.
- Guidance:
- improved detection of turning streets, not reporting new-name in wrong situations
# 5.1.0
Changes with regard to 5.0.0
- API:
- added StepManeuver type `roundabout turn`. The type indicates a small roundabout that is treated as an intersection
(turn right at the roundabout for first exit, go straight at the roundabout...)
- added StepManeuver type `on ramp` and `off ramp` to distinguish between ramps that enter and exit a highway.
- reduced new name instructions for trivial changes
- combined multiple turns into a single instruction at segregated roads`
- Profile Changes:
- introduced a suffix_list / get_name_suffix_list to specify name suffices to be suppressed in name change announcements
- street names are now consistently assembled for the car, bike and walk profile as: "Name (Ref)" as in "Berlin (A5)"
- new `car.lua` dependency `lib/destination.lua`
- register a way's .nodes() function for use in the profile's way_function.
- Infrastructure
- BREAKING: reordered internal instruction types. This breaks the **data format**
- BREAKING: Changed the on-disk encoding of the StaticRTree for better performance. This breaks the **data format**
# 5.0.1
- Fixes:
- Issue #2310: post-processing for local paths, fixes #2310
- Issue #2309: local path looping, fixes #2309
- Issue #2356: Make hint values optional
- Issue #2349: Segmentation fault in some requests
- Issue #2335: map matching was using shortest path with uturns disabled
- Issue #2193: Fix syntax error position indicators in parameters queries
- Fix search with u-turn
- PhantomNode packing in MSVC now the same on other platforms
- Summary is now not malformed when including unnamed roads
- Emit new-name on when changing fron unanmed road to named road
- Issue #2309: Fixes local path looping, same coordinates crash
- Issue #2311: Fixes invalid assertion in loop unpacking
- Issue #2310: Local paths could falsely end up trying to remove the start step
# 5.0.0
Changes with regard 5.0.0 RC2:
+6 -7
View File
@@ -8,7 +8,7 @@ endif()
project(OSRM C CXX)
set(OSRM_VERSION_MAJOR 5)
set(OSRM_VERSION_MINOR 2)
set(OSRM_VERSION_MINOR 0)
set(OSRM_VERSION_PATCH 0)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
@@ -25,14 +25,14 @@ else()
message(WARNING "Building on a 32 bit system is unsupported")
endif()
if(WIN32 AND MSVC_VERSION LESS 1900)
message(FATAL_ERROR "Building with Microsoft compiler needs Latest Visual Studio 2015 (Community or better)")
if(WIN32 AND MSVC_VERSION LESS 1800)
message(FATAL_ERROR "Building with Microsoft compiler needs Visual Studio 2013 or later (Express version works too)")
endif()
option(ENABLE_CCACHE "Speed up incremental rebuilds via ccache" ON)
option(ENABLE_JSON_LOGGING "Adds additional JSON debug logging to the response" OFF)
option(BUILD_TOOLS "Build OSRM tools" OFF)
option(BUILD_COMPONENTS "Build osrm-components" OFF)
option(BUILD_COMPONENTS "Build osrm-components" ON)
option(ENABLE_ASSERTIONS OFF)
option(COVERAGE OFF)
option(SANITIZER OFF)
@@ -54,7 +54,7 @@ configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/include/util/version.hpp.in
${CMAKE_CURRENT_BINARY_DIR}/include/util/version.hpp
)
file(GLOB UtilGlob src/util/*.cpp src/util/*/*.cpp)
file(GLOB UtilGlob src/util/*.cpp)
file(GLOB ExtractorGlob src/extractor/*.cpp src/extractor/*/*.cpp)
file(GLOB ContractorGlob src/contractor/*.cpp)
file(GLOB StorageGlob src/storage/*.cpp)
@@ -140,7 +140,6 @@ if (COVERAGE)
if (NOT CMAKE_BUILD_TYPE MATCHES "Debug")
message(ERROR "COVERAGE=ON only make sense with a Debug build")
endif()
message(INFO "Enabling coverage")
set(MAYBE_COVERAGE_LIBRARIES "gcov")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftest-coverage -fprofile-arcs")
endif()
@@ -233,7 +232,7 @@ include_directories(SYSTEM ${OSMIUM_INCLUDE_DIRS})
find_package(Boost 1.49.0 REQUIRED COMPONENTS ${BOOST_COMPONENTS})
if(NOT WIN32 AND NOT Boost_USE_STATIC_LIBS)
if(NOT WIN32)
add_definitions(-DBOOST_TEST_DYN_LINK)
endif()
add_definitions(-DBOOST_SPIRIT_USE_PHOENIX_V3)
+8 -45
View File
@@ -4,11 +4,13 @@ The Open Source Routing Machine is a high performance routing engine written in
## Current build status
| build config | status |
|:-------------|:-------|
| Linux | [![Build Status](https://travis-ci.org/Project-OSRM/osrm-backend.png?branch=master)](https://travis-ci.org/Project-OSRM/osrm-backend) |
| Windows | [![Build status](https://ci.appveyor.com/api/projects/status/4iuo3s9gxprmcjjh)](https://ci.appveyor.com/project/DennisOSRM/osrm-backend) |
| Coverage | [![codecov](https://codecov.io/gh/Project-OSRM/osrm-backend/branch/master/graph/badge.svg)](https://codecov.io/gh/Project-OSRM/osrm-backend) |
| build config | branch | status |
|:-------------|:--------|:------------|
| Linux | master | [![Build Status](https://travis-ci.org/Project-OSRM/osrm-backend.png?branch=master)](https://travis-ci.org/Project-OSRM/osrm-backend) |
| Linux | develop | [![Build Status](https://travis-ci.org/Project-OSRM/osrm-backend.png?branch=develop)](https://travis-ci.org/Project-OSRM/osrm-backend) |
| Windows | master/develop | [![Build status](https://ci.appveyor.com/api/projects/status/4iuo3s9gxprmcjjh)](https://ci.appveyor.com/project/DennisOSRM/osrm-backend) |
| LUAbind fork | master | [![Build Status](https://travis-ci.org/DennisOSRM/luabind.png?branch=master)](https://travis-ci.org/DennisOSRM/luabind) |
| Coverage | develop | [![Coverage Status](https://coveralls.io/repos/github/Project-OSRM/osrm-backend/badge.svg?branch=develop)](https://coveralls.io/github/Project-OSRM/osrm-backend?branch=develop) |
## Building
@@ -18,46 +20,7 @@ To quickly try OSRM use our [free and daily updated online service](http://map.p
## Documentation
### Full documentation
- [osrm-routed HTTP API documentation](docs/http.md)
- [libosrm API documentation](docs/libosrm.md)
### Quick start
Building OSRM assuming all dependencies are installed:
```
mkdir -p build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build .
sudo cmake --build . --target install
```
Loading preparing a dataset and starting the server:
```
osrm-extract data.osm.pbf -p profiles/car.lua
osrm-contract data.osrm
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
```
### Running a request against the Demo Server
First read the [API usage policy](https://github.com/Project-OSRM/osrm-backend/wiki/Api-usage-policy).
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
```
See the Wiki's [server API documentation](https://github.com/Project-OSRM/osrm-backend/wiki/Server-api) as well as the [library API documentation](https://github.com/Project-OSRM/osrm-backend/wiki/Library-api)
## References in publications
+1 -1
View File
@@ -129,7 +129,7 @@ ECHO running server-tests.exe ...
unit_tests\%Configuration%\server-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
IF NOT "%APPVEYOR_REPO_BRANCH%"=="master" GOTO DONE
IF NOT "%APPVEYOR_REPO_BRANCH%"=="develop" GOTO DONE
ECHO ========= CREATING PACKAGES ==========
CD %PROJECT_DIR%\build\%Configuration%
+1
View File
@@ -28,6 +28,7 @@ artifacts:
branches:
only:
- master
- develop
deploy:
provider: FTP
-7
View File
@@ -1,7 +0,0 @@
coverage:
ignore:
- unit_tests/.*
- third_party/.*
comment: off
+1 -9
View File
@@ -5,23 +5,15 @@ RUN apt-get install -y build-essential git-core python-pip python-software-prope
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 libzip-dev lua5.1 liblua5.1-0-dev libtbb-dev libgdal-dev ruby1.9
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
WORKDIR /opt
RUN git clone --depth 1 --branch v0.31.0 https://github.com/creationix/nvm.git
RUN /bin/bash -c "source /opt/nvm/nvm.sh && nvm install v4"
RUN useradd -ms /bin/bash mapbox
USER mapbox
ENV HOME /home/mapbox
WORKDIR /home/mapbox
RUN echo "source /opt/nvm/nvm.sh" > .bashrc
RUN echo "source /home/mapbox/.bashrc" > .profile
+1 -1
View File
@@ -8,4 +8,4 @@ docker run \
-e "CXX=clang++" \
-v `pwd`:/home/mapbox/osrm-backend \
-t mapbox/osrm:linux \
/bin/bash -lc "osrm-backend/docker/test.sh"
osrm-backend/docker/test.sh
+1 -1
View File
@@ -8,4 +8,4 @@ docker run \
-e "CXX=g++" \
-v `pwd`:/home/mapbox/osrm-backend \
-t mapbox/osrm:linux \
/bin/bash -lc "osrm-backend/docker/test.sh"
osrm-backend/docker/test.sh
+6 -5
View File
@@ -4,8 +4,11 @@ set -e
set -o pipefail
export CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Release"
export PATH=$PATH:/home/mapbox/.gem/ruby/1.9.1/bin:/home/mapbox/osrm-backend/vendor/bundle/ruby/1.9.1/bin
cd /home/mapbox/osrm-backend
gem install --user-install bundler
bundle install --path vendor/bundle
[ -d build ] && rm -rf build
mkdir -p build
cd build
@@ -13,9 +16,7 @@ cmake .. $CMAKEOPTIONS -DBUILD_TOOLS=1
make -j`nproc`
make tests -j`nproc`
#./unit_tests/server-tests
#./unit_tests/library-tests
#./unit_tests/extractor-tests
#./unit_tests/util-tests
./datastructure-tests
./algorithm-tests
cd ..
npm test
bundle exec cucumber -p verify
-592
View File
@@ -1,592 +0,0 @@
## Environent Variables
### SIGNAL_PARENT_WHEN_READY
If the SIGNAL_PARENT_WHEN_READY environment variable is set osrm-routed will
send the USR1 signal to its parent when it will be running and waiting for
requests. This could be used to upgrade osrm-routed to a new binary on the fly
without any service downtime - no incoming requests will be lost.
### DISABLE_ACCESS_LOGGING
If the DISABLE_ACCESS_LOGGING environment variable is set osrm-routed will
**not** log any http requests to standard output. This can be useful in high
traffic setup.
## HTTP API
`osrm-routed` supports only `GET` requests of the form. If you your response size
exceeds the limits of a simple URL encoding, consider using our [NodeJS bindings](https://github.com/Project-OSRM/node-osrm)
or using the [C++ library directly](libosrm.md).
### Request
```
http://{server}/{service}/{version}/{profile}/{coordinates}[.{format}]?option=value&option=value
```
- `server`: location of the server. Example: `127.0.0.1:5000` (default)
- `service`: Name of the service to be used. Support are the following services:
| Service | Description |
|-------------|-----------------------------------------------------------|
| [`route`](#service-route) | shortest path between given coordinates |
| [`nearest`](#service-nearest) | returns the nearest street segment for a given coordinate |
| [`table`](#service-table) | computes distance tables for given coordinates |
| [`match`](#service-match) | matches given coordinates to the road network |
| [`trip`](#service-trip) | Compute the shortest round trip between given coordinates |
| [`tile`](#service-tile) | Return vector tiles containing debugging info |
- `version`: Version of the protocol implemented by the service.
- `profile`: Mode of transportation, is determined by the profile that is used to prepare the data
- `coordinates`: String of format `{longitude},{latitude};{longitude},{latitude}[;{longitude},{latitude} ...]` or `polyline({polyline})`.
- `format`: Only `json` is supportest at the moment. This parameter is optional and defaults to `json`.
Passing any `option=value` is optional. `polyline` follows Google's polyline format with precision 5 and can be generated using [this package](https://www.npmjs.com/package/polyline).
To pass parameters to each location some options support an array like encoding:
```
{option}={element};{element}[;{element} ... ]
```
The number of elements must match exactly the number of locations. If you don't want to pass a value but instead use the default you can pass an empty `element`.
Example: 2nd location use the default value for `option`:
```
{option}={element};;{element}
```
## General options
| Option | Values | Description |
|------------|--------------------------------------------------------|--------------------------------------------------|
|bearings |`{bearing};{bearing}[;{bearing} ...]` |Limits the search to segments with given bearing in degrees towards true north in clockwise direction. |
|radiuses |`{radius};{radius}[;{radius} ...]` |Limits the search to given radius in meters. |
|hints |`{hint};{hint}[;{hint} ...]` |Hint to derive position in street network. |
Where the elements follow the following format:
| Element | Values |
|------------|--------------------------------------------------------|
|bearing |`{value},{range}` `integer 0 .. 360,integer 0 .. 180` |
|radius |`double >= 0` or `unlimited` (default) |
|hint |Base64 `string` |
#### Examples
Query on Berlin with three coordinates:
```
http://router.project-osrm.org/route/v1/driving/13.388860,52.517037;13.397634,52.529407;13.428555,52.523219?overview=false
```
Using polyline:
```
http://router.project-osrm.org/route/v1/driving/polyline(ofp_Ik_vpAilAyu@te@g`E)?overview=false
```
### Response
Every response object has a `code` field.
```json
{
"code": {code},
"message": {message}
}
```
Where `code` is on one of the strings below or service dependent:
| Type | Description |
|-------------------|----------------------------------------------------------------------------------|
| `Ok` | Request could be processed as expected. |
| `InvalidUrl` | URL string is invalid. |
| `InvalidService` | Service name is invalid. |
| `InvalidVersion` | Version is not found. |
| `InvalidOptions` | Options are invalid. |
| `NoSegment` | One of the supplied input coordinates could not snap to street segment. |
| `TooBig` | The request size violates one of the service specific request size restrictions. |
`message` is a **optional** human-readable error message. All other status types are service dependent.
In case of an error the HTTP status code will be `400`. Otherwise the HTTP status code will be `200` and `code` will be `Ok`.
## Service `nearest`
Snaps a coordinate to the street network and returns the nearest n matches.
### Request
```
http://{server}/nearest/v1/{profile}/{coordinates}.json?number={number}
```
Where `coordinates` only supports a single `{longitude},{latitude}` entry.
In addition to the [general options](#general-options) the following options are supported for this service:
|Option |Values |Description |
|------------|------------------------------|----------------------------------------------------|
|number |`integer >= 1` (default `1`) |Number of nearest segments that should be returned. |
### Response
- `code` if the request was successful `Ok` otherwise see the service dependent and general status codes.
- `waypoints` array of `Waypoint` objects sorted by distance to the input coordinate. Each object has at least the following additional properties:
- `distance`: Distance in meters to the supplied input coordinate.
### Examples
Querying nearest three snapped locations of `13.388860,52.517037` with a bearing between `20° - 340°`.
```
http://router.project-osrm.org/nearest/v1/driving/13.388860,52.517037?number=3&bearings=0,20
```
## Service `route`
### Request
```
http://{server}/route/v1/{profile}/{coordinates}?alternatives={true|false}&steps={true|false}&geometries={polyline|geojson}&overview={full|simplified|false}
```
In addition to the [general options](#general-options) the following options are supported for this service:
|Option |Values |Description |
|------------|------------------------------------------|-------------------------------------------------------------------------------|
|alternatives|`true`, `false` (default) |Search for alternative routes and return as well.\* |
|steps |`true`, `false` (default) |Return route steps for each route leg |
|annotate |`true`, `false` (default) |Returns additional metadata for each coordinate along the route geometry. |
|geometries |`polyline` (default), `geojson` |Returned route geometry format (influences overview and per step) |
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
|continue_straight |`default` (default), `true`, `false`|Forces the route to keep going straight at waypoints and don't do a uturn even if it would be faster. Default value depends on the profile. |
\* Please note that even if an alternative route is requested, a result cannot be guaranteed.
### Response
- `code` if the request was successful `Ok` otherwise see the service dependent and general status codes.
- `waypoints`: Array of `Waypoint` objects representing all waypoints in order:
- `routes`: An array of `Route` objects, ordered by descending recommendation rank.
In case of error the following `code`s are supported in addition to the general ones:
| Type | Description |
|-------------------|-----------------|
| `NoRoute` | No route found. |
All other fields might be undefined.
## Service `table`
### Request
```
http://{server}/table/v1/{profile}/{coordinates}?{sources}=[{elem}...];&destinations=[{elem}...]`
```
This computes duration tables for the given locations. Allows for both symmetric and asymmetric tables.
### Coordinates
In addition to the [general options](#general-options) the following options are supported for this service:
|Option |Values |Description |
|------------|--------------------------------------------------|---------------------------------------------|
|sources |`{index};{index}[;{index} ...]` or `all` (default)|Use location with given index as source. |
|destinations|`{index};{index}[;{index} ...]` or `all` (default)|Use location with given index as destination.|
Unlike other array encoded options, the length of `sources` and `destinations` can be **smaller or equal**
to number of input locations;
Example:
```
sources=0;5;7&destinations=5;1;4;2;3;6
```
|Element |Values |
|------------|-----------------------------|
|index |`0 <= integer < #locations` |
### Response
- `code` if the request was successful `Ok` otherwise see the service dependent and general status codes.
- `durations` array of arrays that stores the matrix in row-major order. `durations[i][j]` gives the travel time from
the i-th waypoint to the j-th waypoint. Values are given in seconds.
- `sources` array of `Waypoint` objects describing all sources in order
- `destinations` array of `Waypoint` objects describing all destinations in order
In case of error the following `code`s are supported in addition to the general ones:
| Type | Description |
|-------------------|-----------------|
| `NoTable` | No route found. |
All other fields might be undefined.
#### Examples
Returns a `3x3` matrix:
```
http://router.project-osrm.org/table/v1/driving/13.388860,52.517037;13.397634,52.529407;13.428555,52.523219
```
Returns a `1x3` matrix:
```
http://router.project-osrm.org/table/v1/driving/13.388860,52.517037;13.397634,52.529407;13.428555,52.523219?sources=0
```
Returns a asymmetric 3x2 matrix with from the polyline encoded locations `qikdcB}~dpXkkHz`:
```
http://router.project-osrm.org/table/v1/driving/qikdcB}~dpXkkHz?sources=0;1;3&destinations=2;4
```
## Service `match`
Map matching matches given GPS points to the road network in the most plausible way.
Please note the request might result multiple sub-traces. Large jumps in the timestamps (>60s) or improbable transitions lead to trace splits if a complete matching could not be found.
The algorithm might not be able to match all points. Outliers are removed if they can not be matched successfully.
### Request
```
http://{server}/match/v1/{profile}/{coordinates}?steps={true|false}&geometries={polyline|geojson}&overview={simplified|full|false}
```
In addition to the [general options](#general-options) the following options are supported for this service:
|Option |Values |Description |
|------------|------------------------------------------------|------------------------------------------------------------------------------------------|
|steps |`true`, `false` (default) |Return route steps for each route |
|geometries |`polyline` (default), `geojson` |Returned route geometry format (influences overview and per step) |
|annotate |`true`, `false` (default) |Returns additional metadata for each coordinate along the route geometry. |
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
|timestamps |`{timestamp};{timestamp}[;{timestamp} ...]` |Timestamp of the input location. |
|radiuses |`{radius};{radius}[;{radius} ...]` |Standard deviation of GPS precision used for map matching. If applicable use GPS accuracy.|
|Parameter |Values |
|------------|------------------------------|
|timestamp |`integer` UNIX-like timestamp |
|radius |`double >= 0` (default 5m) |
### Response
- `code` if the request was successful `Ok` otherwise see the service dependent and general status codes.
- `tracepoints`: Array of `Ẁaypoint` objects representing all points of the trace in order.
If the trace point was ommited by map matching because it is an outlier, the entry will be `null`.
Each `Waypoint` object has the following additional properties:
- `matchings_index`: Index to the `Route` object in `matchings` the sub-trace was matched to.
- `waypoint_index`: Index of the waypoint inside the matched route.
- `matchings`: An array of `Route` objects that assemble the trace. Each `Route` object has the following additional properties:
- `confidence`: Confidence of the matching. `float` value between 0 and 1. 1 is very confident that the matching is correct.
In case of error the following `code`s are supported in addition to the general ones:
| Type | Description |
|-------------------|---------------------|
| `NoMatch` | No matchings found. |
All other fields might be undefined.
## Service `trip`
The trip plugin solves the Traveling Salesman Problem using a greedy heuristic (farthest-insertion algorithm).
The returned path does not have to be the shortest path, as TSP is NP-hard it is only an approximation.
Note that if the input coordinates can not be joined by a single trip (e.g. the coordinates are on several disconnected islands)
multiple trips for each connected component are returned.
### Request
```
http://{server}/trip/v1/{profile}/{coordinates}?steps={true|false}&geometries={polyline|geojson}&overview={simplified|full|false}
```
In addition to the [general options](#general-options) the following options are supported for this service:
|Option |Values |Description |
|------------|------------------------------------------------|---------------------------------------------------------------------------|
|steps |`true`, `false` (default) |Return route instructions for each trip |
|annotate |`true`, `false` (default) |Returns additional metadata for each coordinate along the route geometry. |
|geometries |`polyline` (default), `geojson` |Returned route geometry format (influences overview and per step) |
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
### Response
- `code` if the request was successful `Ok` otherwise see the service dependent and general status codes.
- `waypoints`: Array of `Waypoint` objects representing all waypoints in input order. Each `Waypoint` object has the following additional properties:
- `trips_index`: Index to `trips` of the sub-trip the point was matched to.
- `waypoint_index`: Index of the point in the trip.
- `trips`: An array of `Route` objects that assemble the trace.
In case of error the following `code`s are supported in addition to the general ones:
| Type | Description |
|-------------------|---------------------|
| `NoTrips` | No trips found. |
All other fields might be undefined.
## Result objects
### Route
Represents a route through (potentially multiple) waypoints.
#### Properties
- `distance`: The distance traveled by the route, in `float` meters.
- `duration`: The estimated travel time, in `float` number of seconds.
- `geometry`: The whole geometry of the route value depending on `overview` parameter, format depending on the `geometries` parameter. See `RouteStep`'s `geometry` field for a parameter documentation.
| overview | Description |
|------------|-----------------------------|
| simplified | Geometry is simplified according to the highest zoom level it can still be displayed on full. |
| full | Geometry is not simplified. |
| false | Geometry is not added. |
- `legs`: The legs between the given waypoints, an array of `RouteLeg` objects.
#### Example
Three input coordinates, `geometry=geojson`, `steps=false`:
```json
{
"distance": 90.0,
"duration": 300.0,
"geometry": {"type": "LineString", "coordinates": [[120., 10.], [120.1, 10.], [120.2, 10.], [120.3, 10.]]},
"legs": [
{
"distance": 30.0,
"duration": 100.0,
"steps": []
},
{
"distance": 60.0,
"duration": 200.0,
"steps": []
}
]
}
```
### RouteLeg
Represents a route between two waypoints.
#### Properties
- `distance`: The distance traveled by this route leg, in `float` meters.
- `duration`: The estimated travel time, in `float` number of seconds.
- `summary`: Summary of the route taken as `string`. Depends on the `steps` parameter:
| steps | |
|--------------|-----------------------------------------------------------------------|
| true | Names of the two major roads used. Can be empty if route is too short.|
| false | empty `string` |
- `steps`: Depends on the `steps` parameter.
| steps | |
|--------------|-----------------------------------------------------------------------|
| true | array of `RouteStep` objects describing the turn-by-turn instructions |
| false | empty array |
- `annotation`: Additional details about each coordinate along the route geometry:
| annotate | |
|--------------|-----------------------------------------------------------------------|
| true | returns distance and durations of each coordinate along the route |
| false | will not exist |
#### Example
With `steps=false` and `annotate=true`:
```json
{
"distance": 30.0,
"duration": 100.0,
"steps": []
"annotation": {
"distance": [5,5,10,5,5],
"duration": [15,15,40,15,15]
}
}
```
### RouteStep
A step consists of a maneuver such as a turn or merge, followed
by a distance of travel along a single way to the subsequent
step.
#### Properties
- `distance`: The distance of travel from the maneuver to the subsequent step, in `float` meters.
- `duration`: The estimated travel time, in `float` number of seconds.
- `geometry`: The unsimplified geometry of the route segment, depending on the `geometries` parameter.
| geometries | |
|------------|--------------------------------------------------------------------|
| polyline | [polyline](https://www.npmjs.com/package/polyline) with precision 5 in [latitude,longitude] encoding |
| geojson | [GeoJSON `LineString`](http://geojson.org/geojson-spec.html#linestring) or [GeoJSON `Point`](http://geojson.org/geojson-spec.html#point) if it is only one coordinate (not wrapped by a GeoJSON feature)|
- `name`: The name of the way along which travel proceeds.
- `mode`: A string signifying the mode of transportation.
- `maneuver`: A `StepManeuver` object representing the maneuver.
- `intersections`: A list of `Intersections` that are passed along the segment, the very first belonging to the StepManeuver
#### Example
```
{
"distance":152.3,
"duration":15.6,
"name":"Lortzingstraße",
"maneuver":{
"type":"depart",
"modifier":"left"
},
"geometry":"{lu_IypwpAVrAvAdI",
"mode":"driving",
"intersections":[
{"location":[13.39677,52.54366],
"out":1,
"bearings":[66,246],
"entry":["true","true"]},
{"location":[13.394718,52.543096],
"in":0,
"out":2,
"bearings":[60,150,240,330],
"entry":["false","true","true","true"]
}
]}
```
### StepManeuver
#### Properties
- `location`: A `[longitude, latitude]` pair describing the location of the turn.
- `bearing_before`: The clockwise angle from true north to the
direction of travel immediately before the maneuver.
- `bearing_after`: The clockwise angle from true north to the
direction of travel immediately after the maneuver.
- `type` A string indicating the type of maneuver. **new identifiers might be introduced without API change**
Types unknown to the client should be handled like the `turn` type, the existance of correct `modifier` values is guranteed.
| `type` | Description |
|-------------------|--------------------------------------------------------------|
| turn | a basic turn into direction of the `modifier` |
| new name | no turn is taken, but the road name changes. The Road can take a turn itself, following `modifier` |
| depart | indicates the departure of the leg |
| arrive | indicates the destination of the leg |
| merge | merge onto a street (e.g. getting on the highway from a ramp, the `modifier specifies the direction of the merge`) |
| ramp | **Deprecated**. Replaced by `on_ramp` and `off_ramp`. |
| on ramp | take a ramp to enter a highway (direction given my `modifier`) |
| off ramp | take a ramp to exit a highway (direction given my `modifier`) |
| fork | take the left/right side at a fork depending on `modifier` |
| end of road | road ends in a T intersection turn in direction of `modifier`|
| 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` |
| rotary | a larger version of a roundabout, can offer `rotary_name` 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`. |
| 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 |
Please note that even though there are `new name` and `notification` instructions, the `mode` and `name` can change
between all instructions. They only offer a fallback in case nothing else is to report.
- `modifier` An optional `string` indicating the direction change of the maneuver.
| `modifier` | Description |
|-------------------|-------------------------------------------|
| uturn | indicates reversal of direction |
| sharp right | a sharp right turn |
| right | a normal turn to the right |
| slight right | a slight turn to the right |
| straight | no relevant change in direction |
| slight left | a slight turn to the left |
| left | a normal turn to the left |
| sharp left | a sharp turn to the left |
The list of turns without a modifier is limited to: `depart/arrive`. If the source/target location is close enough to the `depart/arrive` location, no modifier will be given.
The meaning depends on the `type` field.
| `type` | Description |
|------------------------|---------------------------------------------------------------------------------------------------------------------------|
| `turn` | `modifier` indicates the change in direction accomplished through the turn |
| `depart`/`arrive` | `modifier` indicates the position of departure point and arrival point in relation to the current direction of travel |
- `exit` An optional `integer` indicating number of the exit to take. The field exists for the following `type` field:
| `type` | Description |
|------------------------|---------------------------------------------------------------------------------------------------------------------------|
| `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` |
New properties (potentially depending on `type`) may be introduced in the future without an API version change.
### Intersections
An intersection gives a full representation of any cross-way the path passes bay. For every step, the very first intersection (`intersections[0]`) corresponds to the
location of the StepManeuver. Further intersections are listed for every cross-way until the next turn instruction.
#### Properties
- `location`: A `[longitude, latitude]` pair describing the location of the turn.
- `bearings`: A list of bearing values (e.g. [0,90,180,270]) that are available at the intersection. The bearings describe all available roads at the intersection.
- `entry`: A list of entry flags, corresponding in a 1:1 relationship to the bearings. A value of `true` indicates that the respective road could be entered on a valid route.
`false` indicates that the turn onto the respective road would violate a restriction.
- `in`: index into bearings/entry array. Used to calculate the bearing just before the turn. Namely, the clockwise angle from true north to the
direction of travel immediately before the maneuver/passing the intersection. Bearings are given relative to the intersection. To get the bearing
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.
#### Example
```
{
"location":[13.394718,52.543096],
"in":0,
"out":2,
"bearings":[60,150,240,330],
"entry":["false","true","true","true"]
}
```
### Waypoint
Object used to describe waypoint on a route.
#### Properties
- `name` Name of the street the coordinate snapped to
- `location` Array that contains the `[longitude, latitude]` pair of the snapped coordinate
- `hint` Unique internal identifier of the segment (ephemeral, not constant over data updates)
This can be used on subsequent request to significantly speed up the query and to connect multiple services.
E.g. you can use the `hint` value obtained by the `nearest` query as `hint` values for `route` inputs.
## Service `tile`
This generates [Mapbox Vector Tiles](https://www.mapbox.com/developers/vector-tiles/) that can be viewed with a vector-tile capable slippy-map viewer. The tiles contain road geometries and metadata that can be used to examine the routing graph. The tiles are generated directly from the data in-memory, so are in sync with actual routing results, and let you examine which roads are actually routable, and what weights they have applied.
### Request
```
http://{server}/tile/v1/{profile}/tile({x},{y},{zoom}).mvt
```
The `x`, `y`, and `zoom` values are the same as described at https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames, and are supported by vector tile viewers like [Mapbox GL JS](https://www.mapbox.com/mapbox-gl-js/api/).
### Response
The response object is either a binary encoded blob with a `Content-Type` of `application/x-protobuf`, or a `404` error. Note that OSRM is hard-coded to only return tiles from zoom level 12 and higher (to avoid accidentally returning extremely large vector tiles).
Vector tiles contain just a single layer named `speeds`. Within that layer, features can have `speed` (int) and `is_small` (boolean) attributes.
-26
View File
@@ -1,26 +0,0 @@
OSRM can be used as a library (libosrm) via C++ instead of using it through the HTTP interface and `osrm-routed`. This allows for fine-tuning OSRM and has much less overhead. Here is a quick introduction into how to use `libosrm` in the upcoming v5 release.
Take a look at the example code that lives in the [example directory](https://github.com/Project-OSRM/osrm-backend/tree/master/example). Here is all you ever wanted to know about `libosrm`, that is a short description of what the types do and where to find documentation on it:
- [`EngineConfig`](https://github.com/Project-OSRM/osrm-backend/blob/master/include/engine/engine_config.hpp) - for initializing an OSRM instance we can configure certain properties and constraints. E.g. the storage config is the base path such as `france.osm.osrm` from which we derive and load `france.osm.osrm.*` auxiliary files. This also lets you set constraints such as the maximum number of locations allowed for specific services.
- [`OSRM`](https://github.com/Project-OSRM/osrm-backend/blob/master/include/osrm/osrm.hpp) - this is the main Routing Machine type with functions such as `Route` and `Table`. You initialize it with a `EngineConfig`. It does all the heavy lifting for you. Each function takes its own parameters, e.g. the `Route` function takes `RouteParameters`, and a out-reference to a JSON result that gets filled. The return value is a `Status`, indicating error or success.
- [`Status`](https://github.com/Project-OSRM/osrm-backend/blob/master/include/engine/status.hpp) - this is a type wrapping `Error` or `Ok` for indicating error or success, respectively.
- [`TableParameters`](https://github.com/Project-OSRM/osrm-backend/blob/master/include/engine/api/table_parameters.hpp) - this is an example of parameter types the Routing Machine functions expect. In this case `Table` expects its own parameters as `TableParameters`. You can see it wrapping two vectors, sources and destinations --- these are indices into your coordinates for the table service to construct a matrix from (empty sources or destinations means: use all of them). If you ask yourself where coordinates come from, you can see `TableParameters` inheriting from `BaseParameters`.
- [`BaseParameter`](https://github.com/Project-OSRM/osrm-backend/blob/master/include/engine/api/base_parameters.hpp) - this most importantly holds coordinates (and a few other optional properties that you don't need for basic usage); the specific parameter types inherit from `BaseParameters` to get these member attributes. That means your `TableParameters` type has `coordinates`, `sources` and `destination` member attributes (and a few other that we ignore for now).
- [`Coordinate`](https://github.com/Project-OSRM/osrm-backend/blob/master/include/util/coordinate.hpp) - this is a wrapper around a (longitude, latitude) pair. We really don't care about (lon,lat) vs (lat, lon) but we don't want you to accidentally mix them up, so both latitude and longitude are strictly typed wrappers around integers (fixed notation such as `13423240`) and floating points (floating notation such as `13.42324`).
- [Parameters for other services](https://github.com/Project-OSRM/osrm-backend/tree/master/include/engine/api) - here are all other `*Parameters` you need for other Routing Machine services.
- [JSON](https://github.com/Project-OSRM/osrm-backend/blob/master/include/util/json_container.hpp) - this is a sum type resembling JSON. The Routing Machine service functions take a out-ref to a JSON result and fill it accordingly. It is currently implemented using [mapbox/variant](https://github.com/mapbox/variant) which is similar to [Boost.Variant](http://www.boost.org/doc/libs/1_55_0/doc/html/variant.html) (Boost documentation is great). There are two ways to work with this sum type: either provide a visitor that acts on each type on visitation or use the `get` function in case you're sure about the structure. The JSON structure is written down in the [[v5 server API|Server-API-v5,-current]].
------------------------------------------------------------------------------------------------------------------
To summarize:
- create an `OSRM` instance initialized with a `EngineConfig`
- call the service function on the `OSRM` object providing service specific `*Parameters`
- check the return code and use the JSON result
-34
View File
@@ -1,34 +0,0 @@
OSRM supports "profiles". Configurations representing different routing behaviours for (typically) different transport modes. A profile describes whether or not we route along a particular type of way, or over a particular node in the OpenStreetMap data, and also how quickly we'll be travelling when we do. This feeds into the way the routing graph is created and thus influences the output routes.
## Available profiles
Out-of-the-box OSRM comes with several different profiles, including car, bicycle and foot.
Profile configuration files have a 'lua' extension, and are found under the 'profiles' subdirectory.
Alternatively commands will take a lua profile specified with an explicit -p param, for example:
`osrm-extract -p ../profiles/car.lua planet-latest.osm.pbf`
And then **you will need to extract and contract again** (A change to the profile will typically affect the extract step as well as the contract step. See [Processing Flow](https://github.com/Project-OSRM/osrm-backend/wiki/Processing-Flow))
## lua scripts?
Profiles are not just configuration files. They are scripts written in the "lua" scripting language ( http://www.lua.org ) The reason for this, is that OpenStreetMap data is not sufficiently straightforward, to simply define tag mappings. Lua scripting offers a powerful way of coping with the complexity of different node,way,relation,tag combinations found within OpenStreetMap data.
## Basic structure of a profile
You can understand these lua scripts enough to make interesting modifications, without needing to get to grips with how they work completely.
Towards the top of the file, a profile (such as [car.lua](../profiles/car.lua)) will typically define various configurations as global variables. A lot of these are look-up hashes of one sort or another.
As you scroll down the file you'll see local variables, and then local functions, and finally...
`way_function` and `node_function` are the important functions which are called when extracting OpenStreetMap data with `osrm-extract`.
## way_function
Given an OpenStreetMap way, the way_function will either return nothing (meaning we are not going to route over this way at all), or it will set up a result hash to be returned. The most important thing it will do is set the value of `result.forward_speed` and `result.backward_speed` as a suitable integer value representing the speed for traversing the way.
All other calculations stem from that, including the returned timings in driving directions, but also, less directly, it feeds into the actual routing decisions the engine will take (a way with a slow traversal speed, may be less favoured than a way with fast traversal speed, but it depends how long it is, and... what it connects to in the rest of the network graph)
Using the power of the scripting language you wouldn't typically see something as simple as a `result.forward_speed = 20` line within the way_function. Instead a way_function will examine the tagging (e.g. `way:get_value_by_key("highway")` and many others), process this information in various ways, calling other local functions, referencing the global variables and look-up hashes, before arriving at the result.
-50
View File
@@ -1,50 +0,0 @@
# Releasing a new OSRM version
Do decide if this is a major or minor version bump use: http://semver.org/
What we guarantee on major version changes:
- Breaking changes will be in the changelog
- If we break an HTTP API we bump the version
What we guarantee on minor version changes:
- HTTP API does not include breaking changes
- C++ library API does not include breaking changes
- node-osrm API does not include breaking changes
What we DO NOT guarantee on minor version changes:
- file format comp ability. Breakage will be listed in the changelog.
- new turn types and fields may be introduced. How to handle this see [the HTTP API docs](http.md).
What we guarantee on patch version changes:
- HTTP API does not include breaking changes
- C++ library API does not include breaking changes
- node-osrm API does not include breaking changes
- full file format compatibility
## Major or Minor release x.y
1. Make sure all tests are passing (e.g. Travis CI gives you a :thumbs_up:)
2. Make sure `CHANGELOG.md` is up to date.
3. Make sure the OSRM version in `CMakeLists.txt` is up to date
4. Use an annotated tag to mark the release: `git tag vx.y.0 -a` Body of the tag description should be the changelog entries.
5. Push tags and commits: `git push; git push --tags`
6. Branch of the `vx.y.0` tag to create a release branch `x.y`:
`git branch x.y. vx.y.0; git push -u x.y:origin/x.y`
7. Modify `.travis.yml` to allow builds for the `x.y` branch.
8. Write a mailing-list post to osrm-talk@openstreetmap.org to announce the release
## Patch release x.y.z
1. Check out the appropriate release branch x.y
2. Make sure all fixes are listed in the changelog and included in the branch
3. Make sure all tests are passing (e.g. Travis CI gives you a :thumbs_up:)
4. Make sure the OSRM version in `CMakeLists.txt` is up to date
5. Use an annotated tag to mark the release: `git tag vx.y.z -a` Body of the tag description should be the changelog entries.
6. Push tags and commits: `git push; git push --tags`
7. Proceede with the `node-osrm` release as outlined in the repository.
8. Write a mailing-list post to osrm-talk@openstreetmap.org to announce the release
+3 -3
View File
@@ -19,14 +19,14 @@ else()
message(WARNING "Building on a 32 bit system is unsupported")
endif()
if(WIN32 AND MSVC_VERSION LESS 1900)
message(FATAL_ERROR "Building with Microsoft compiler needs Latest Visual Studio 2015 (Community or better)")
if(WIN32 AND MSVC_VERSION LESS 1800)
message(FATAL_ERROR "Building with Microsoft compiler needs Visual Studio 2013 or later (Express version works too)")
endif()
add_executable(osrm-example example.cpp)
find_package(LibOSRM REQUIRED)
find_package(Boost 1.49.0 COMPONENTS filesystem system thread iostreams REQUIRED)
find_package(Boost 1.49.0 COMPONENTS filesystem system thread REQUIRED)
target_link_libraries(osrm-example ${LibOSRM_LIBRARIES} ${Boost_LIBRARIES})
include_directories(SYSTEM ${LibOSRM_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
+5 -5
View File
@@ -10,13 +10,13 @@ Feature: Bike - Street names in instructions
| | c |
And the ways
| nodes | name | ref |
| ab | My Way | A6 |
| bc | Your Way | A7 |
| nodes | name |
| ab | My Way |
| bc | Your Way |
When I route I should get
| from | to | route |
| a | c | My Way (A6),Your Way (A7),Your Way (A7) |
| from | to | route |
| a | c | My Way,Your Way,Your Way |
@unnamed
Scenario: Bike - Use way type to describe unnamed ways
+1 -1
View File
@@ -14,7 +14,7 @@ Feature: Bike - Way ref
When I route I should get
| from | to | route |
| a | b | Utopia Drive (E7),Utopia Drive (E7) |
| a | b | Utopia Drive / E7,Utopia Drive / E7 |
Scenario: Bike - Way with only ref
Given the node map
@@ -31,7 +31,7 @@ Feature: Traffic - speeds
4,1,27
"""
Scenario: Weighting based on speed file
Scenario: Weighting not based on raster sources
Given the profile "testbot"
Given the extract extra arguments "--generate-edge-lookup"
Given the contract extra arguments "--segment-speed-file speeds.csv"
@@ -1,97 +0,0 @@
@routing @speed @traffic
Feature: Traffic - turn penalties
Background: Evenly spaced grid with multiple intersections
Given the node map
| | a:1 | | b:2 | |
| c:3 | d:4 | e:5 | f:6 | g:7 |
| | h:8 | | i:9 | |
| j:10 | k:11 | l:12 | m:13 | n:14 |
| | o:15 | | p:16 | |
And the ways
| nodes | highway |
| ad | primary |
| cd | primary |
| de | primary |
| dhk | primary |
| bf | primary |
| ef | primary |
| fg | primary |
| fim | primary |
| jk | primary |
| kl | primary |
| ko | primary |
| lm | primary |
| mn | primary |
| mp | primary |
And the profile "car"
And the extract extra arguments "--generate-edge-lookup"
Scenario: Weighting not based on turn penalty file
When I route I should get
| from | to | route | speed | time |
| a | h | ad,dhk,dhk | 63 km/h | 11.5s +-1 |
# straight
| i | g | fim,fg,fg | 59 km/h | 12s +-1 |
# right
| a | e | ad,de,de | 57 km/h | 12.5s +-1 |
# left
| c | g | cd,de,ef,fg,fg | 63 km/h | 23s +-1 |
# double straight
| p | g | mp,fim,fg,fg | 61 km/h | 23.5s +-1 |
# straight-right
| a | l | ad,dhk,kl,kl | 60 km/h | 24s +-1 |
# straight-left
| l | e | kl,dhk,de,de | 59 km/h | 24.5s +-1 |
# double right
| g | n | fg,fim,mn,mn | 57 km/h | 25s +-1 |
# double left
Scenario: Weighting based on turn penalty file
Given the turn penalty file
"""
9,6,7,1.8
9,13,14,24.5
8,4,3,26
12,11,8,9
8,11,12,13
1,4,5,-0.2
"""
And the contract extra arguments "--turn-penalty-file penalties.csv"
When I route I should get
| from | to | route | speed | time |
| a | h | ad,dhk,dhk | 63 km/h | 11.5s +-1 |
# straight
| i | g | fim,fg,fg | 55 km/h | 13s +-1 |
# right - ifg penalty
| a | e | ad,de,de | 64 km/h | 11s +-1 |
# left - faster because of negative ade penalty
| c | g | cd,de,ef,fg,fg | 63 km/h | 23s +-1 |
# double straight
| p | g | mp,fim,fg,fg | 59 km/h | 24.5s +-1 |
# straight-right - ifg penalty
| a | l | ad,de,ef,fim,lm,lm | 61 km/h | 35.5s +-1 |
# was straight-left - forced around by hkl penalty
| l | e | lm,fim,ef,ef | 57 km/h | 25s +-1 |
# double right - forced left by lkh penalty
| g | n | fg,fim,mn,mn | 30 km/h | 47.5s +-1 |
# double left - imn penalty
| j | c | jk,kl,lm,fim,ef,de,cd,cd | 60 km/h | 48s +-1 |
# double left - hdc penalty ever so slightly higher than imn; forces all the way around
Scenario: Too-negative penalty clamps, but does not fail
Given the contract extra arguments "--turn-penalty-file penalties.csv"
And the profile "testbot"
And the turn penalty file
"""
1,4,5,-10
"""
When I route I should get
| from | to | route | time |
| a | d | ad,ad | 10s +-1 |
| a | e | ad,de,de | 10s +-1 |
| b | f | bf,bf | 10s +-1 |
| b | g | bf,fg,fg | 20s +-1 |
+5 -5
View File
@@ -10,13 +10,13 @@ Feature: Foot - Street names in instructions
| | c |
And the ways
| nodes | name | ref |
| ab | My Way | A6 |
| bc | Your Way | B7 |
| nodes | name |
| ab | My Way |
| bc | Your Way |
When I route I should get
| from | to | route |
| a | c | My Way (A6),Your Way (B7),Your Way (B7) |
| from | to | route |
| a | c | My Way,Your Way,Your Way |
@unnamed
Scenario: Foot - Use way type to describe unnamed ways
+1 -1
View File
@@ -14,7 +14,7 @@ Feature: Foot - Way ref
When I route I should get
| from | to | route |
| a | b | Utopia Drive (E7),Utopia Drive (E7) |
| a | b | Utopia Drive / E7,Utopia Drive / E7 |
Scenario: Foot - Way with only ref
Given the node map
@@ -1,120 +0,0 @@
@routing @car @bridge @tunnel @guidance
Feature: Car - Guidance - Bridges and Tunnels
Background:
Given the profile "car"
And a grid size of 100 meters
Scenario: Simple Bridge
Given the node map
| a | b | c | d |
And the ways
| nodes | highway | bridge | name |
| ab | primary | | Hauptstraße |
| bc | primary | yes | Hauptstraßenbrücke |
| cd | primary | | Hauptstraße |
When I route I should get
| from | to | route | turns |
| a | d | Hauptstraße,Hauptstraße | depart,arrive |
Scenario: Bridge with Immediate Turn
Given the node map
| | | | d |
| a | | b | c |
| | | | e |
And the ways
| nodes | highway | bridge | name |
| ab | primary | | Hauptstraße |
| bc | primary | yes | Hauptstraßenbrücke |
| dce | primary | | Nebenstraße |
When I route I should get
| from | to | route | turns |
| a | d | Hauptstraße,Nebenstraße,Nebenstraße | depart,end of road left,arrive |
| a | e | Hauptstraße,Nebenstraße,Nebenstraße | depart,end of road right,arrive |
| e | a | Nebenstraße,Hauptstraßenbrücke,Hauptstraße | depart,turn left,arrive |
| d | a | Nebenstraße,Hauptstraßenbrücke,Hauptstraße | depart,turn right,arrive |
Scenario: Bridge with Immediate Turn Front and Back
Given the node map
| f | | | d |
| a | | b | c |
| g | | | e |
And the ways
| nodes | highway | bridge | name |
| ab | primary | | Hauptstraße |
| bc | primary | yes | Hauptstraßenbrücke |
| dce | primary | | Nebenstraße |
| gaf | primary | | Anderestraße |
When I route I should get
| from | to | route | turns |
| f | d | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn left,end of road left,arrive |
| f | e | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn left,end of road right,arrive |
| g | d | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn right,end of road left,arrive |
| g | e | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn right,end of road right,arrive |
| e | f | Nebenstraße,Hauptstraßenbrücke,Anderestraße,Anderestraße | depart,turn left,end of road right,arrive |
| e | g | Nebenstraße,Hauptstraßenbrücke,Anderestraße,Anderestraße | depart,turn left,end of road left,arrive |
| d | f | Nebenstraße,Hauptstraßenbrücke,Anderestraße,Anderestraße | depart,turn right,end of road right,arrive |
| d | g | Nebenstraße,Hauptstraßenbrücke,Anderestraße,Anderestraße | depart,turn right,end of road left,arrive |
Scenario: Simple Tunnel
Given the node map
| a | b | c | d |
And the ways
| nodes | highway | tunnel | name |
| ab | primary | | Hauptstraße |
| bc | primary | yes | Hauptstraßentunnel |
| cd | primary | | Hauptstraße |
When I route I should get
| from | to | route | turns |
| a | d | Hauptstraße,Hauptstraße | depart,arrive |
Scenario: Tunnel with Immediate Turn
Given the node map
| | | | d |
| a | | b | c |
| | | | e |
And the ways
| nodes | highway | tunnel | name |
| ab | primary | | Hauptstraße |
| bc | primary | yes | Hauptstraßentunnel |
| dce | primary | | Nebenstraße |
When I route I should get
| from | to | route | turns |
| a | d | Hauptstraße,Nebenstraße,Nebenstraße | depart,end of road left,arrive |
| a | e | Hauptstraße,Nebenstraße,Nebenstraße | depart,end of road right,arrive |
| e | a | Nebenstraße,Hauptstraßentunnel,Hauptstraße | depart,turn left,arrive |
| d | a | Nebenstraße,Hauptstraßentunnel,Hauptstraße | depart,turn right,arrive |
Scenario: Tunnel with Immediate Turn Front and Back
Given the node map
| f | | | d |
| a | | b | c |
| g | | | e |
And the ways
| nodes | highway | bridge | name |
| ab | primary | | Hauptstraße |
| bc | primary | yes | Hauptstraßentunnel |
| dce | primary | | Nebenstraße |
| gaf | primary | | Anderestraße |
When I route I should get
| from | to | route | turns |
| f | d | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn left,end of road left,arrive |
| f | e | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn left,end of road right,arrive |
| g | d | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn right,end of road left,arrive |
| g | e | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn right,end of road right,arrive |
| e | f | Nebenstraße,Hauptstraßentunnel,Anderestraße,Anderestraße | depart,turn left,end of road right,arrive |
| e | g | Nebenstraße,Hauptstraßentunnel,Anderestraße,Anderestraße | depart,turn left,end of road left,arrive |
| d | f | Nebenstraße,Hauptstraßentunnel,Anderestraße,Anderestraße | depart,turn right,end of road right,arrive |
| d | g | Nebenstraße,Hauptstraßentunnel,Anderestraße,Anderestraße | depart,turn right,end of road left,arrive |
-347
View File
@@ -1,347 +0,0 @@
@routing @guidance @collapsing
Feature: Collapse
Background:
Given the profile "car"
Given a grid size of 20 meters
Scenario: Segregated Intersection, Cross Belonging to Single Street
Given the node map
| | | i | l | | |
| | | | | | |
| d | | c | b | | a |
| e | | f | g | | h |
| | | | | | |
| | | j | k | | |
And the ways
| nodes | highway | name | oneway |
| ab | primary | first | yes |
| bc | primary | first | yes |
| cd | primary | first | yes |
| ef | primary | first | yes |
| fg | primary | first | yes |
| gh | primary | first | yes |
| ic | primary | second | yes |
| bl | primary | second | yes |
| kg | primary | second | yes |
| fj | primary | second | yes |
| cf | primary | first | yes |
| gb | primary | first | yes |
When I route I should get
| waypoints | route | turns |
| a,l | first,second,second | depart,turn right,arrive |
| a,d | first,first | depart,arrive |
| a,j | first,second,second | depart,turn left,arrive |
| a,h | first,first,first | depart,continue uturn,arrive |
| e,j | first,second,second | depart,turn right,arrive |
| e,h | first,first | depart,arrive |
| e,l | first,second,second | depart,turn left,arrive |
| e,d | first,first,first | depart,continue uturn,arrive |
| k,h | second,first,first | depart,turn right,arrive |
| k,l | second,second | depart,arrive |
| k,d | second,first,first | depart,turn left,arrive |
| k,j | second,second,second | depart,continue uturn,arrive |
| i,d | second,first,first | depart,turn right,arrive |
| i,j | second,second | depart,arrive |
| i,h | second,first,first | depart,turn left,arrive |
| i,l | second,second,second | depart,continue uturn,arrive |
Scenario: Segregated Intersection, Cross Belonging to Correct Street
Given the node map
| | | i | l | | |
| | | | | | |
| d | | c | b | | a |
| e | | f | g | | h |
| | | | | | |
| | | j | k | | |
And the ways
| nodes | highway | name | oneway |
| ab | primary | first | yes |
| bc | primary | first | yes |
| cd | primary | first | yes |
| ef | primary | first | yes |
| fg | primary | first | yes |
| gh | primary | first | yes |
| ic | primary | second | yes |
| bl | primary | second | yes |
| kg | primary | second | yes |
| fj | primary | second | yes |
| cf | primary | second | yes |
| gb | primary | second | yes |
When I route I should get
| waypoints | route | turns |
| a,l | first,second,second | depart,turn right,arrive |
| a,d | first,first | depart,arrive |
| a,j | first,second,second | depart,turn left,arrive |
| a,h | first,first,first | depart,continue uturn,arrive |
| e,j | first,second,second | depart,turn right,arrive |
| e,h | first,first | depart,arrive |
| e,l | first,second,second | depart,turn left,arrive |
| e,d | first,first,first | depart,continue uturn,arrive |
| k,h | second,first,first | depart,turn right,arrive |
| k,l | second,second | depart,arrive |
| k,d | second,first,first | depart,turn left,arrive |
| k,j | second,second,second | depart,continue uturn,arrive |
| i,d | second,first,first | depart,turn right,arrive |
| i,j | second,second | depart,arrive |
| i,h | second,first,first | depart,turn left,arrive |
| i,l | second,second,second | depart,continue uturn,arrive |
Scenario: Segregated Intersection, Cross Belonging to Mixed Streets
Given the node map
| | | i | l | | |
| | | | | | |
| d | | c | b | | a |
| e | | f | g | | h |
| | | | | | |
| | | j | k | | |
And the ways
| nodes | highway | name | oneway |
| ab | primary | first | yes |
| bc | primary | second | yes |
| cd | primary | first | yes |
| ef | primary | first | yes |
| fg | primary | first | yes |
| gh | primary | first | yes |
| ic | primary | second | yes |
| bl | primary | second | yes |
| kg | primary | second | yes |
| fj | primary | second | yes |
| cf | primary | second | yes |
| gb | primary | first | yes |
When I route I should get
| waypoints | route | turns |
| a,l | first,second,second | depart,turn right,arrive |
| a,d | first,first | depart,arrive |
| a,j | first,second,second | depart,turn left,arrive |
| a,h | first,first,first | depart,continue uturn,arrive |
| e,j | first,second,second | depart,turn right,arrive |
| e,h | first,first | depart,arrive |
| e,l | first,second,second | depart,turn left,arrive |
| e,d | first,first,first | depart,continue uturn,arrive |
| k,h | second,first,first | depart,turn right,arrive |
| k,l | second,second | depart,arrive |
| k,d | second,first,first | depart,turn left,arrive |
| k,j | second,second,second | depart,continue uturn,arrive |
| i,d | second,first,first | depart,turn right,arrive |
| i,j | second,second | depart,arrive |
| i,h | second,first,first | depart,turn left,arrive |
| i,l | second,second,second | depart,continue uturn,arrive |
Scenario: Partly Segregated Intersection, Two Segregated Roads
Given the node map
| | g | | h | |
| | | | | |
| | | | | |
| c | | b | | a |
| d | | e | | f |
| | | | | |
| | | | | |
| | j | | i | |
And the ways
| nodes | highway | name | oneway |
| ab | primary | first | yes |
| bc | primary | first | yes |
| de | primary | first | yes |
| ef | primary | first | yes |
| be | primary | first | no |
| gbh | primary | second | yes |
| iej | primary | second | yes |
When I route I should get
| waypoints | route | turns |
| a,h | first,second,second | depart,turn right,arrive |
| a,c | first,first | depart,arrive |
| a,j | first,second,second | depart,turn left,arrive |
| a,f | first,first,first | depart,continue uturn,arrive |
| d,j | first,second,second | depart,turn right,arrive |
| d,f | first,first | depart,arrive |
| d,h | first,second,second | depart,turn left,arrive |
| d,c | first,first,first | depart,continue uturn,arrive |
| g,c | second,first,first | depart,turn right,arrive |
| g,j | second,second | depart,arrive |
| g,f | second,first,first | depart,turn left,arrive |
| g,h | second,second,second | depart,continue uturn,arrive |
| i,f | second,first,first | depart,turn right,arrive |
| i,h | second,second | depart,arrive |
| i,c | second,first,first | depart,turn left,arrive |
| i,j | second,second,second | depart,continue uturn,arrive |
Scenario: Partly Segregated Intersection, Two Segregated Roads, Intersection belongs to Second
Given the node map
| | g | | h | |
| | | | | |
| | | | | |
| c | | b | | a |
| d | | e | | f |
| | | | | |
| | | | | |
| | j | | i | |
And the ways
| nodes | highway | name | oneway |
| ab | primary | first | yes |
| bc | primary | first | yes |
| de | primary | first | yes |
| ef | primary | first | yes |
| be | primary | second | no |
| gbh | primary | second | yes |
| iej | primary | second | yes |
When I route I should get
| waypoints | route | turns |
| a,h | first,second,second | depart,turn right,arrive |
| a,c | first,first | depart,arrive |
| a,j | first,second,second | depart,turn left,arrive |
| a,f | first,first,first | depart,continue uturn,arrive |
| d,j | first,second,second | depart,turn right,arrive |
| d,f | first,first | depart,arrive |
| d,h | first,second,second | depart,turn left,arrive |
| d,c | first,first,first | depart,continue uturn,arrive |
| g,c | second,first,first | depart,turn right,arrive |
| g,j | second,second | depart,arrive |
| g,f | second,first,first | depart,turn left,arrive |
| g,h | second,second,second | depart,continue uturn,arrive |
| i,f | second,first,first | depart,turn right,arrive |
| i,h | second,second | depart,arrive |
| i,c | second,first,first | depart,turn left,arrive |
| i,j | second,second,second | depart,continue uturn,arrive |
Scenario: Segregated Intersection, Cross Belonging to Mixed Streets - Slight Angles
Given the node map
| | | i | l | | |
| | | | | | a |
| | | c | b | | h |
| d | | f | g | | |
| e | | | | | |
| | | j | k | | |
And the ways
| nodes | highway | name | oneway |
| ab | primary | first | yes |
| bc | primary | second | yes |
| cd | primary | first | yes |
| ef | primary | first | yes |
| fg | primary | first | yes |
| gh | primary | first | yes |
| ic | primary | second | yes |
| bl | primary | second | yes |
| kg | primary | second | yes |
| fj | primary | second | yes |
| cf | primary | second | yes |
| gb | primary | first | yes |
When I route I should get
| waypoints | route | turns |
| a,l | first,second,second | depart,turn right,arrive |
| a,d | first,first | depart,arrive |
| a,j | first,second,second | depart,turn left,arrive |
| a,h | first,first,first | depart,continue uturn,arrive |
| e,j | first,second,second | depart,turn right,arrive |
| e,h | first,first | depart,arrive |
| e,l | first,second,second | depart,turn left,arrive |
| e,d | first,first,first | depart,continue uturn,arrive |
| k,h | second,first,first | depart,turn right,arrive |
| k,l | second,second | depart,arrive |
| k,d | second,first,first | depart,turn left,arrive |
| k,j | second,second,second | depart,continue uturn,arrive |
| i,d | second,first,first | depart,turn right,arrive |
| i,j | second,second | depart,arrive |
| i,h | second,first,first | depart,turn left,arrive |
| i,l | second,second,second | depart,continue uturn,arrive |
Scenario: Segregated Intersection, Cross Belonging to Mixed Streets - Slight Angles (2)
Given the node map
| | | i | l | | |
| | | | | | |
| | | c | b | | |
| d | | f | g | | a |
| e | | | | | h |
| | | j | k | | |
And the ways
| nodes | highway | name | oneway |
| ab | primary | first | yes |
| bc | primary | second | yes |
| cd | primary | first | yes |
| ef | primary | first | yes |
| fg | primary | first | yes |
| gh | primary | first | yes |
| ic | primary | second | yes |
| bl | primary | second | yes |
| kg | primary | second | yes |
| fj | primary | second | yes |
| cf | primary | second | yes |
| gb | primary | first | yes |
When I route I should get
| waypoints | route | turns |
| a,l | first,second,second | depart,turn right,arrive |
| a,d | first,first | depart,arrive |
| a,j | first,second,second | depart,turn left,arrive |
| a,h | first,first,first | depart,continue uturn,arrive |
| e,j | first,second,second | depart,turn right,arrive |
| e,h | first,first | depart,arrive |
| e,l | first,second,second | depart,turn left,arrive |
| e,d | first,first,first | depart,continue uturn,arrive |
| k,h | second,first,first | depart,turn right,arrive |
| k,l | second,second | depart,arrive |
| k,d | second,first,first | depart,turn left,arrive |
| k,j | second,second,second | depart,continue uturn,arrive |
| i,d | second,first,first | depart,turn right,arrive |
| i,j | second,second | depart,arrive |
| i,h | second,first,first | depart,turn left,arrive |
| i,l | second,second,second | depart,continue uturn,arrive |
Scenario: Entering a segregated road
Given the node map
| | a | f | | |
| | | | | g |
| | b | e | | |
| | | | | |
| | | | | |
| c | d | | | |
And the ways
| nodes | highway | name | oneway |
| abc | primary | first | yes |
| def | primary | first | yes |
| be | primary | first | no |
| ge | primary | second | no |
When I route I should get
| waypoints | route | turns |
| d,c | first,first,first | depart,continue uturn,arrive |
| a,f | first,first,first | depart,continue uturn,arrive |
| a,g | first,second,second | depart,turn left,arrive |
| d,g | first,second,second | depart,turn right,arrive |
| g,f | second,first,first | depart,turn right,arrive |
| g,c | second,first,first | depart,end of road left,arrive |
Scenario: Do not collapse turning roads
Given the node map
| | | e | | |
| | | c | | d |
| a | | b | f | |
And the ways
| nodes | highway | name |
| ab | primary | first |
| bc | primary | first |
| cd | primary | first |
| ce | primary | second |
| bf | primary | third |
When I route I should get
| waypoints | route | turns |
| a,d | first,first,first,first | depart,continue left,continue right,arrive |
| a,e | first,second,second | depart,turn left,arrive |
| a,f | first,third,third | depart,turn straight,arrive |
+6 -39
View File
@@ -16,42 +16,9 @@ Feature: Continue Instructions
| bd | primary |
When I route I should get
| waypoints | route | turns |
| a,c | abc,abc,abc | depart,continue left,arrive |
| a,d | abc,bd,bd | depart,turn straight,arrive |
Scenario: Road turning left and straight
Given the node map
| | | c | |
| a | | b | d |
And the ways
| nodes | highway | name |
| abc | primary | road |
| bd | primary | road |
When I route I should get
| waypoints | route | turns |
| a,c | road,road,road | depart,continue left,arrive |
| a,d | road,road | depart,arrive |
Scenario: Road turning left and straight
Given the node map
| | | c | |
| a | | b | d |
| | | e | |
And the ways
| nodes | highway | name |
| abc | primary | road |
| bd | primary | road |
| be | primary | road |
When I route I should get
| waypoints | route | turns |
| a,c | road,road,road | depart,continue left,arrive |
| a,d | road,road | depart,arrive |
| a,e | road,road,road | depart,continue right,arrive |
| waypoints | route | turns |
| a,c | abc,abc,abc | depart,continue left,arrive |
| a,d | abc,bd,bd | depart,new name straight,arrive |
Scenario: Road turning right
Given the node map
@@ -64,9 +31,9 @@ Feature: Continue Instructions
| bd | primary |
When I route I should get
| waypoints | route | turns |
| a,c | abc,abc,abc | depart,continue right,arrive |
| a,d | abc,bd,bd | depart,turn straight,arrive |
| waypoints | route | turns |
| a,c | abc,abc,abc | depart,continue right,arrive |
| a,d | abc,bd,bd | depart,new name straight,arrive |
Scenario: Road turning slight left
Given the node map
@@ -1,41 +0,0 @@
@routing @guidance
Feature: Destination Signs
Background:
Given the profile "car"
Scenario: Car - route name assembly with destination signs
Given the node map
| a | b |
| c | d |
| e | f |
| g | h |
| i | j |
| k | l |
| m | n |
| o | p |
| q | r |
And the ways
| nodes | name | ref | destination | destination:ref | oneway | # |
| ab | AB | E1 | | | yes | |
| cd | CD | | Berlin | | yes | |
| ef | EF | | Berlin | A1 | yes | |
| gh | | | Berlin | A1 | yes | |
| ij | | | Berlin | | yes | |
| kl | KL | E1 | Berlin | A1 | yes | |
| mn | MN | | Berlin;Hamburg | A1;A2 | yes | |
| op | OP | | Berlin;Hamburg | A1;A2 | no | mis-tagged destination: not a oneway |
| qr | QR | | | A1;A2 | yes | |
When I route I should get
| from | to | route | # |
| a | b | AB (E1),AB (E1) | |
| c | d | CD (Berlin),CD (Berlin) | |
| e | f | EF (A1: Berlin),EF (A1: Berlin) | |
| g | h | , | |
| i | j | , | |
| k | l | KL (E1),KL (E1) | |
| m | n | MN (A1, A2: Berlin, Hamburg),MN (A1, A2: Berlin, Hamburg) | |
| o | p | OP,OP | guard against mis-tagging |
| q | r | QR (A1, A2),QR (A1, A2) | |
+3 -3
View File
@@ -117,7 +117,7 @@ Feature: End Of Road Instructions
| bd | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,c | ab,bc,bc | depart,on ramp left,arrive |
| a,d | ab,bd,bd | depart,on ramp right,arrive |
| waypoints | route | turns |
| a,c | ab,bc,bc | depart,ramp left,arrive |
| a,d | ab,bd,bd | depart,ramp right,arrive |
+1
View File
@@ -245,6 +245,7 @@ Feature: Fork Instructions
| a,c | abd,bc,bc | depart,turn slight left,arrive |
| a,d | abd,abd | depart,arrive |
@pr2275 @bug
Scenario: Tripple fork
Given the node map
| | | | | | | | | c |
-153
View File
@@ -1,153 +0,0 @@
@routing @guidance @intersections
Feature: Intersections Data
Background:
Given the profile "car"
Given a grid size of 10 meters
Scenario: Passing Three Way South
Given the node map
| a | | b | | c |
| | | d | | |
And the ways
| nodes | name |
| ab | through |
| bc | through |
| bd | corner |
When I route I should get
| waypoints | route | turns | intersections |
| a,c | through,through | depart,arrive | true:90,true:90 true:180 false:270;true:270 |
Scenario: Passing Three Way North
Given the node map
| | | d | | |
| a | | b | | c |
And the ways
| nodes | name |
| ab | through |
| bc | through |
| bd | corner |
When I route I should get
| waypoints | route | turns | intersections |
| a,c | through,through | depart,arrive | true:90,true:0 true:90 false:270;true:270 |
Scenario: Passing Oneway Street In
Given the node map
| | | d | | |
| a | | b | | c |
And the ways
| nodes | name | oneway |
| ab | through | no |
| bc | through | no |
| db | corner | yes |
When I route I should get
| waypoints | route | turns | intersections |
| a,c | through,through | depart,arrive | true:90,false:0 true:90 false:270;true:270 |
Scenario: Passing Oneway Street Out
Given the node map
| | | d | | |
| a | | b | | c |
And the ways
| nodes | name | oneway |
| ab | through | no |
| bc | through | no |
| bd | corner | yes |
When I route I should get
| waypoints | route | turns | intersections |
| a,c | through,through | depart,arrive | true:90,true:0 true:90 false:270;true:270 |
Scenario: Passing Two Intersections
Given the node map
| | | e | | | | |
| a | | b | | c | | d |
| | | | | f | | |
And the ways
| nodes | name |
| ab | through |
| bc | through |
| cd | through |
| be | corner |
| cf | corner |
When I route I should get
| waypoints | route | turns | intersections |
| a,d | through,through | depart,arrive | true:90,true:0 true:90 false:270,true:90 true:180 false:270;true:270 |
Scenario: Regression test #2424
Given the node map
| | | e | | | | | | i | | | | |
| a | | b | | c | | d | | h | | k | | m |
| | | | | f | | | | | | l | | |
And the ways
| nodes | name |
| abcd | Fritz-Elsas-Straße |
| hkm | Fritz-Elsas-Straße |
| dhi | Martin-Luther-Straße |
| be | corner |
| kl | corner |
| cf | corner |
When I route I should get
| waypoints | route | turns |
| a,m | Fritz-Elsas-Straße,Fritz-Elsas-Straße| depart,arrive |
Scenario: Passing Two Intersections, Collapsing
Given the node map
| | | e | | | | |
| a | | b | | c | | d |
| | | | | f | | |
And the ways
| nodes | name |
| ab | through |
| bc | throughbridge |
| cd | through |
| be | corner |
| cf | corner |
When I route I should get
| waypoints | route | turns | intersections |
| a,d | through,through | depart,arrive | true:90,true:0 true:90 false:270,true:90 true:180 false:270;true:270 |
| f,a | corner,throughbridge,through | depart,end of road left,arrive | true:0;true:90 false:180 true:270,true:0 false:90 true:270;true:90 |
Scenario: Roundabouts
Given the node map
| | | | | e | | | | |
| | | | | | | | | |
| | | | | a | | | | |
| | | | 1 | | 4 | | | |
| | | | | | | | | |
| f | | b | | | | d | | h |
| | | | | | | | | |
| | | | 2 | | 3 | | | |
| | | | | c | | | | |
| | | | | | | | | |
| | | | | g | | | | |
And the ways
| nodes | junction |
| abcda | roundabout |
| ea | |
| fb | |
| gc | |
| hd | |
When I route I should get
| waypoints | route | turns | intersections |
| e,f | ea,fb,fb | depart,abcda-exit-1,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:90 |
| e,g | ea,gc,gc | depart,abcda-exit-2,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330;true:0|
| e,h | ea,hd,hd | depart,abcda-exit-3,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330,true:90 false:210 true:330;true:270 |
| e,2 | ea,abcda,abcda | depart,abcda-exit-undefined,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:327 +-1|
| 1,g | abcda,gc,gc | depart,abcda-exit-2,arrive | true:214;true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:0|
| 1,3 | abcda,abcda | depart,arrive | true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:214|
+28 -28
View File
@@ -16,9 +16,9 @@ Feature: Motorway Guidance
| bfg | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,e | abcde,abcde | depart,arrive |
| a,g | abcde,bfg,bfg | depart,off ramp slight right,arrive |
| waypoints | route | turns |
| a,e | abcde,abcde | depart,arrive |
| a,g | abcde,bfg,bfg | depart,ramp slight right,arrive |
Scenario: Ramp Exit Right Curved Right
Given the node map
@@ -32,9 +32,9 @@ Feature: Motorway Guidance
| bfg | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,e | abcde,abcde | depart,arrive |
| a,g | abcde,bfg,bfg | depart,off ramp right,arrive |
| waypoints | route | turns |
| a,e | abcde,abcde | depart,arrive |
| a,g | abcde,bfg,bfg | depart,ramp right,arrive |
Scenario: Ramp Exit Right Curved Left
Given the node map
@@ -49,9 +49,9 @@ Feature: Motorway Guidance
| cfg | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,e | abcde,abcde | depart,arrive |
| a,g | abcde,cfg,cfg | depart,off ramp slight right,arrive |
| waypoints | route | turns |
| a,e | abcde,abcde | depart,arrive |
| a,g | abcde,cfg,cfg | depart,ramp slight right,arrive |
Scenario: Ramp Exit Left
@@ -65,9 +65,9 @@ Feature: Motorway Guidance
| bfg | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,e | abcde,abcde | depart,arrive |
| a,g | abcde,bfg,bfg | depart,off ramp slight left,arrive |
| waypoints | route | turns |
| a,e | abcde,abcde | depart,arrive |
| a,g | abcde,bfg,bfg | depart,ramp slight left,arrive |
Scenario: Ramp Exit Left Curved Left
Given the node map
@@ -81,9 +81,9 @@ Feature: Motorway Guidance
| bfg | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,e | abcde,abcde | depart,arrive |
| a,g | abcde,bfg,bfg | depart,off ramp left,arrive |
| waypoints | route | turns |
| a,e | abcde,abcde | depart,arrive |
| a,g | abcde,bfg,bfg | depart,ramp left,arrive |
Scenario: Ramp Exit Left Curved Right
Given the node map
@@ -97,9 +97,9 @@ Feature: Motorway Guidance
| cfg | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,e | abcde,abcde | depart,arrive |
| a,g | abcde,cfg,cfg | depart,off ramp slight left,arrive |
| waypoints | route | turns |
| a,e | abcde,abcde | depart,arrive |
| a,g | abcde,cfg,cfg | depart,ramp slight left,arrive |
Scenario: On Ramp Right
Given the node map
@@ -176,11 +176,11 @@ Feature: Motorway Guidance
| chi | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,e | abcde,abcde | depart,arrive |
| f,e | fgc,abcde,abcde | depart,merge slight left,arrive |
| a,i | abcde,chi,chi | depart,off ramp slight right,arrive |
| f,i | fgc,chi,chi | depart,off ramp right,arrive |
| waypoints | route | turns |
| a,e | abcde,abcde | depart,arrive |
| f,e | fgc,abcde,abcde | depart,merge slight left,arrive |
| a,i | abcde,chi,chi | depart,ramp slight right,arrive |
| f,i | fgc,chi,chi | depart,ramp right,arrive |
Scenario: On And Off Ramp Left
Given the node map
@@ -194,11 +194,11 @@ Feature: Motorway Guidance
| chi | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,e | abcde,abcde | depart,arrive |
| f,e | fgc,abcde,abcde | depart,merge slight right,arrive |
| a,i | abcde,chi,chi | depart,off ramp slight left,arrive |
| f,i | fgc,chi,chi | depart,off ramp left,arrive |
| waypoints | route | turns |
| a,e | abcde,abcde | depart,arrive |
| f,e | fgc,abcde,abcde | depart,merge slight right,arrive |
| a,i | abcde,chi,chi | depart,ramp slight left,arrive |
| f,i | fgc,chi,chi | depart,ramp left,arrive |
Scenario: Merging Motorways
Given the node map
-31
View File
@@ -133,34 +133,3 @@ Feature: New-Name Instructions
When I route I should get
| waypoints | route | turns |
| a,c | ab,bc,bc | depart,new name slight right,arrive |
Scenario: Empty road names - Announce Change From, suppress Change To
Given the node map
| a | | b | | c | | d |
And the ways
| nodes | name |
| ab | ab |
| bc | |
| cd | cd |
When I route I should get
| waypoints | route | turns |
| a,d | ab,cd,cd | depart,new name straight,arrive |
| a,c | ab, | depart,arrive |
Scenario: Empty road names - Loose name shortly
Given the node map
| a | | b | | c | | d | | e |
And the ways
| nodes | name |
| ab | name |
| bc | with-name |
| cd | |
| de | with-name |
When I route I should get
| waypoints | route | turns |
| a,e | name,with-name,with-name | depart,new name straight,arrive |
| b,e | with-name,with-name | depart,arrive |
+32 -32
View File
@@ -16,8 +16,8 @@ Feature: Ramp Guidance
| bd | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,on ramp right,arrive |
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,ramp right,arrive |
Scenario: Ramp On Through Street Left
Given the node map
@@ -30,8 +30,8 @@ Feature: Ramp Guidance
| bd | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,on ramp left,arrive |
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,ramp left,arrive |
Scenario: Ramp On Through Street Left and Right
Given the node map
@@ -46,9 +46,9 @@ Feature: Ramp Guidance
| bd | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,on ramp right,arrive |
| a,e | abc,be,be | depart,on ramp left,arrive |
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,ramp right,arrive |
| a,e | abc,be,be | depart,ramp left,arrive |
Scenario: Ramp On Three Way Intersection Right
Given the node map
@@ -62,8 +62,8 @@ Feature: Ramp Guidance
| bd | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,d | ab,bd,bd | depart,on ramp right,arrive |
| waypoints | route | turns |
| a,d | ab,bd,bd | depart,ramp right,arrive |
Scenario: Ramp On Three Way Intersection Right
Given the node map
@@ -78,8 +78,8 @@ Feature: Ramp Guidance
| bd | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,d | ab,bd,bd | depart,on ramp right,arrive |
| waypoints | route | turns |
| a,d | ab,bd,bd | depart,ramp right,arrive |
Scenario: Ramp Off Though Street
Given the node map
@@ -93,9 +93,9 @@ Feature: Ramp Guidance
| bd | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,on ramp right,arrive |
| a,c | abc,abc | depart,arrive |
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,ramp right,arrive |
| a,c | abc,abc | depart,arrive |
Scenario: Straight Ramp Off Turning Though Street
Given the node map
@@ -108,9 +108,9 @@ Feature: Ramp Guidance
| bd | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,on ramp straight,arrive |
| a,c | abc,abc,abc | depart,continue left,arrive |
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,ramp straight,arrive |
| a,c | abc,abc,abc | depart,continue left,arrive |
Scenario: Fork Ramp Off Turning Though Street
Given the node map
@@ -124,9 +124,9 @@ Feature: Ramp Guidance
| bd | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,on ramp right,arrive |
| a,c | abc,abc,abc | depart,continue left,arrive |
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,ramp right,arrive |
| a,c | abc,abc,abc | depart,continue left,arrive |
Scenario: Fork Ramp
Given the node map
@@ -141,9 +141,9 @@ Feature: Ramp Guidance
| bd | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,d | ab,bd,bd | depart,on ramp right,arrive |
| a,c | ab,bc,bc | depart,turn left,arrive |
| waypoints | route | turns |
| a,d | ab,bd,bd | depart,ramp right,arrive |
| a,c | ab,bc,bc | depart,turn left,arrive |
Scenario: Fork Slight Ramp
Given the node map
@@ -158,9 +158,9 @@ Feature: Ramp Guidance
| bd | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,d | ab,bd,bd | depart,on ramp slight right,arrive |
| a,c | ab,bc,bc | depart,turn slight left,arrive |
| waypoints | route | turns |
| a,d | ab,bd,bd | depart,ramp slight right,arrive |
| a,c | ab,bc,bc | depart,turn slight left,arrive |
Scenario: Fork Slight Ramp on Through Street
Given the node map
@@ -174,9 +174,9 @@ Feature: Ramp Guidance
| bd | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,on ramp slight right,arrive |
| a,c | abc,abc,abc | depart,continue slight left,arrive |
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,ramp slight right,arrive |
| a,c | abc,abc,abc | depart,continue slight left,arrive |
Scenario: Fork Slight Ramp on Obvious Through Street
Given the node map
@@ -190,9 +190,9 @@ Feature: Ramp Guidance
| bd | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,on ramp slight right,arrive |
| a,c | abc,abc | depart,arrive |
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,ramp slight right,arrive |
| a,c | abc,abc | depart,arrive |
Scenario: Two Ramps Joining into common Motorway
Given the node map
+10 -10
View File
@@ -194,15 +194,15 @@ Feature: Rotary
And the ways
| nodes | junction |
| ad | |
| ab | |
| bcdb | roundabout |
| be | |
| cf | |
| ce | |
| df | |
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 |
| 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
@@ -213,15 +213,15 @@ Feature: Rotary
And the ways
| nodes | junction |
| ac | |
| ab | |
| bcdb | roundabout |
| de | |
| bf | |
| ce | |
| df | |
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 |
| 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
-369
View File
@@ -1,369 +0,0 @@
@routing @guidance
Feature: Basic Roundabout
Background:
Given the profile "car"
Given a grid size of 3 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 | roundabout |
When I route I should get
| waypoints | route | turns |
| a,d | ab,cd,cd | depart,roundabout turn left exit-3,arrive |
| a,f | ab,ef,ef | depart,roundabout turn straight exit-2,arrive |
| a,h | ab,gh,gh | depart,roundabout turn right exit-1,arrive |
| d,f | cd,ef,ef | depart,roundabout turn left exit-3,arrive |
| d,h | cd,gh,gh | depart,roundabout turn straight exit-2,arrive |
| d,a | cd,ab,ab | depart,roundabout turn right exit-1,arrive |
| f,h | ef,gh,gh | depart,roundabout turn left exit-3,arrive |
| f,a | ef,ab,ab | depart,roundabout turn straight exit-2,arrive |
| f,d | ef,cd,cd | depart,roundabout turn right exit-1,arrive |
| h,a | gh,ab,ab | depart,roundabout turn left exit-3,arrive |
| h,d | gh,cd,cd | depart,roundabout turn straight exit-2,arrive |
| h,f | gh,ef,ef | depart,roundabout turn right exit-1,arrive |
Scenario: Enter and Exit - Rotated
Given the node map
| a | | | d |
| | b | c | |
| | g | e | |
| h | | | f |
And the ways
| nodes | junction |
| ab | |
| cd | |
| ef | |
| gh | |
| bgecb | roundabout |
When I route I should get
| waypoints | route | turns |
| a,d | ab,cd,cd | depart,roundabout turn left exit-3,arrive |
| a,f | ab,ef,ef | depart,roundabout turn straight exit-2,arrive |
| a,h | ab,gh,gh | depart,roundabout turn right exit-1,arrive |
| d,f | cd,ef,ef | depart,roundabout turn left exit-3,arrive |
| d,h | cd,gh,gh | depart,roundabout turn straight exit-2,arrive |
| d,a | cd,ab,ab | depart,roundabout turn right exit-1,arrive |
| f,h | ef,gh,gh | depart,roundabout turn left exit-3,arrive |
| f,a | ef,ab,ab | depart,roundabout turn straight exit-2,arrive |
| f,d | ef,cd,cd | depart,roundabout turn right exit-1,arrive |
| h,a | gh,ab,ab | depart,roundabout turn left exit-3,arrive |
| h,d | gh,cd,cd | depart,roundabout turn straight exit-2,arrive |
| h,f | gh,ef,ef | depart,roundabout turn right 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 | roundabout |
When I route I should get
| waypoints | route | turns |
| a,c | ab,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| a,e | ab,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| a,g | ab,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| d,e | cd,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| d,g | cd,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| d,b | cd,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| f,g | ef,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| f,b | ef,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| f,c | ef,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| h,b | gh,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| h,c | gh,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| h,e | gh,bcegb,bcegb | depart,roundabout-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 | roundabout |
When I route I should get
| waypoints | route | turns |
| b,d | bcegb,cd,cd | depart,roundabout-exit-1,arrive |
| b,f | bcegb,ef,ef | depart,roundabout-exit-2,arrive |
| b,h | bcegb,gh,gh | depart,roundabout-exit-3,arrive |
| c,f | bcegb,ef,ef | depart,roundabout-exit-1,arrive |
| c,h | bcegb,gh,gh | depart,roundabout-exit-2,arrive |
| c,a | bcegb,ab,ab | depart,roundabout-exit-3,arrive |
| e,h | bcegb,gh,gh | depart,roundabout-exit-1,arrive |
| e,a | bcegb,ab,ab | depart,roundabout-exit-2,arrive |
| e,d | bcegb,cd,cd | depart,roundabout-exit-3,arrive |
| g,a | bcegb,ab,ab | depart,roundabout-exit-1,arrive |
| g,d | bcegb,cd,cd | depart,roundabout-exit-2,arrive |
| g,f | bcegb,ef,ef | depart,roundabout-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 | roundabout |
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 |
Scenario: Mixed Entry and Exit - Not an Intersection
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 | roundabout | yes |
When I route I should get
| waypoints | route | turns |
| a,c | abc,abc,abc | depart,roundabout-exit-1,arrive |
| a,l | abc,jkl,jkl | depart,roundabout-exit-2,arrive |
| a,i | abc,ghi,ghi | depart,roundabout-exit-3,arrive |
| a,f | abc,def,def | depart,roundabout-exit-4,arrive |
| d,f | def,def,def | depart,roundabout-exit-1,arrive |
| d,c | def,abc,abc | depart,roundabout-exit-2,arrive |
| d,l | def,jkl,jkl | depart,roundabout-exit-3,arrive |
| d,i | def,ghi,ghi | depart,roundabout-exit-4,arrive |
| g,i | ghi,ghi,ghi | depart,roundabout-exit-1,arrive |
| g,f | ghi,def,def | depart,roundabout-exit-2,arrive |
| g,c | ghi,abc,abc | depart,roundabout-exit-3,arrive |
| g,l | ghi,jkl,jkl | depart,roundabout-exit-4,arrive |
| j,l | jkl,jkl,jkl | depart,roundabout-exit-1,arrive |
| j,i | jkl,ghi,ghi | depart,roundabout-exit-2,arrive |
| j,f | jkl,def,def | depart,roundabout-exit-3,arrive |
| j,c | jkl,abc,abc | depart,roundabout-exit-4,arrive |
Scenario: Segregated roads - Not an intersection
Given the node map
| | a | | c | |
| l | | b | | d |
| | k | | e | |
| j | | h | | f |
| | i | | g | |
And the ways
| nodes | junction | oneway |
| abc | | yes |
| def | | yes |
| ghi | | yes |
| jkl | | yes |
| bkheb | roundabout | yes |
When I route I should get
| waypoints | route | turns |
| a,c | abc,abc,abc | depart,roundabout-exit-4,arrive |
| a,l | abc,jkl,jkl | depart,roundabout-exit-1,arrive |
| a,i | abc,ghi,ghi | depart,roundabout-exit-2,arrive |
| a,f | abc,def,def | depart,roundabout-exit-3,arrive |
| d,f | def,def,def | depart,roundabout-exit-4,arrive |
| d,c | def,abc,abc | depart,roundabout-exit-1,arrive |
| d,l | def,jkl,jkl | depart,roundabout-exit-2,arrive |
| d,i | def,ghi,ghi | depart,roundabout-exit-3,arrive |
| g,i | ghi,ghi,ghi | depart,roundabout-exit-4,arrive |
| g,f | ghi,def,def | depart,roundabout-exit-1,arrive |
| g,c | ghi,abc,abc | depart,roundabout-exit-2,arrive |
| g,l | ghi,jkl,jkl | depart,roundabout-exit-3,arrive |
| j,l | jkl,jkl,jkl | depart,roundabout-exit-4,arrive |
| j,i | jkl,ghi,ghi | depart,roundabout-exit-1,arrive |
| j,f | jkl,def,def | depart,roundabout-exit-2,arrive |
| j,c | jkl,abc,abc | depart,roundabout-exit-3,arrive |
Scenario: Collinear in X
Given the node map
| a | b | c | d | f |
| | | e | | |
And the ways
| nodes | junction |
| ab | |
| bcdb | roundabout |
| ce | |
| df | |
When I route I should get
| waypoints | route | turns |
| a,e | ab,ce,ce | depart,roundabout-exit-1,arrive |
| a,f | ab,df,df | depart,roundabout-exit-2,arrive |
Scenario: Collinear in X,Y
Given the node map
| a | | |
| b | | |
| c | d | f |
| e | | |
And the ways
| nodes | junction |
| ab | |
| bcdb | roundabout |
| ce | |
| df | |
When I route I should get
| waypoints | route | turns |
| a,e | ab,ce,ce | depart,roundabout turn straight exit-1,arrive |
| a,f | ab,df,df | depart,roundabout turn left 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 | roundabout |
| be | |
| cf | |
When I route I should get
| waypoints | route | turns |
| a,e | ad,be,be | depart,roundabout turn straight exit-1,arrive |
| a,f | ad,cf,cf | depart,roundabout turn left 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 | roundabout |
| de | |
| bf | |
When I route I should get
| waypoints | route | turns |
| a,e | ac,de,de | depart,roundabout turn straight exit-1,arrive |
| a,f | ac,bf,bf | depart,roundabout turn left exit-2,arrive |
Scenario: Enter and Exit -- too complex
Given the node map
| j | | a | | |
| | i | b | | |
| | g | | c | d |
| h | | e | | |
| | | f | | |
And the ways
| nodes | junction |
| ab | |
| ij | |
| cd | |
| ef | |
| gh | |
| bigecb | roundabout |
When I route I should get
| waypoints | route | turns |
| a,d | ab,cd,cd | depart,roundabout-exit-4,arrive |
| a,f | ab,ef,ef | depart,roundabout-exit-3,arrive |
| a,h | ab,gh,gh | depart,roundabout-exit-2,arrive |
| d,f | cd,ef,ef | depart,roundabout-exit-4,arrive |
| d,h | cd,gh,gh | depart,roundabout-exit-3,arrive |
| d,a | cd,ab,ab | depart,roundabout-exit-1,arrive |
| f,h | ef,gh,gh | depart,roundabout-exit-4,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 |
Scenario: Enter and Exit -- Non-Distinct
Given the node map
| | | a | | |
| | | b | | |
| | g | | c | d |
| | | e | | |
| h | | f | | |
And the ways
| nodes | junction |
| ab | |
| cd | |
| ef | |
| gh | |
| bgecb | 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 |
+15 -93
View File
@@ -165,84 +165,6 @@ Feature: Basic Roundabout
| j,f | jkl,def,def | depart,roundabout-exit-3,arrive |
| j,c | jkl,abc,abc | depart,roundabout-exit-4,arrive |
Scenario: Mixed Entry and Exit - segregated roads
Given the node map
| | | a | | c | | |
| | | | | | | |
| l | | | b | | | d |
| | | k | | e | | |
| j | | | h | | | f |
| | | | | | | |
| | | i | | g | | |
And the ways
| nodes | junction | oneway |
| abc | | yes |
| def | | yes |
| ghi | | yes |
| jkl | | yes |
| bkheb | roundabout | yes |
When I route I should get
| waypoints | route | turns |
| a,c | abc,abc,abc | depart,roundabout-exit-4,arrive |
| a,l | abc,jkl,jkl | depart,roundabout-exit-1,arrive |
| a,i | abc,ghi,ghi | depart,roundabout-exit-2,arrive |
| a,f | abc,def,def | depart,roundabout-exit-3,arrive |
| d,f | def,def,def | depart,roundabout-exit-4,arrive |
| d,c | def,abc,abc | depart,roundabout-exit-1,arrive |
| d,l | def,jkl,jkl | depart,roundabout-exit-2,arrive |
| d,i | def,ghi,ghi | depart,roundabout-exit-3,arrive |
| g,i | ghi,ghi,ghi | depart,roundabout-exit-4,arrive |
| g,f | ghi,def,def | depart,roundabout-exit-1,arrive |
| g,c | ghi,abc,abc | depart,roundabout-exit-2,arrive |
| g,l | ghi,jkl,jkl | depart,roundabout-exit-3,arrive |
| j,l | jkl,jkl,jkl | depart,roundabout-exit-4,arrive |
| j,i | jkl,ghi,ghi | depart,roundabout-exit-1,arrive |
| j,f | jkl,def,def | depart,roundabout-exit-2,arrive |
| j,c | jkl,abc,abc | depart,roundabout-exit-3,arrive |
Scenario: Mixed Entry and Exit - segregated roads, different names
Given the node map
| | | a | | c | | |
| | | | | | | |
| l | | | b | | | d |
| | | k | | e | | |
| j | | | h | | | f |
| | | | | | | |
| | | i | | g | | |
And the ways
| nodes | junction | oneway |
| ab | | yes |
| bc | | yes |
| de | | yes |
| ef | | yes |
| gh | | yes |
| hi | | yes |
| jk | | yes |
| kl | | yes |
| bkheb | roundabout | yes |
When I route I should get
| waypoints | route | turns |
| a,c | ab,bc,bc | depart,roundabout-exit-4,arrive |
| a,l | ab,kl,kl | depart,roundabout-exit-1,arrive |
| a,i | ab,hi,hi | depart,roundabout-exit-2,arrive |
| a,f | ab,ef,ef | depart,roundabout-exit-3,arrive |
| d,f | de,ef,ef | depart,roundabout-exit-4,arrive |
| d,c | de,bc,bc | depart,roundabout-exit-1,arrive |
| d,l | de,kl,kl | depart,roundabout-exit-2,arrive |
| d,i | de,hi,hi | depart,roundabout-exit-3,arrive |
| g,i | gh,hi,hi | depart,roundabout-exit-4,arrive |
| g,f | gh,ef,ef | depart,roundabout-exit-1,arrive |
| g,c | gh,bc,bc | depart,roundabout-exit-2,arrive |
| g,l | gh,kl,kl | depart,roundabout-exit-3,arrive |
| j,l | jk,kl,kl | depart,roundabout-exit-4,arrive |
| j,i | jk,hi,hi | depart,roundabout-exit-1,arrive |
| j,f | jk,ef,ef | depart,roundabout-exit-2,arrive |
| j,c | jk,bc,bc | depart,roundabout-exit-3,arrive |
Scenario: Collinear in X
Given the node map
| a | b | c | d | f |
@@ -262,11 +184,11 @@ Feature: Basic Roundabout
Scenario: Collinear in Y
Given the node map
| | a |
| | b |
| e | c |
| | d |
| | f |
| a | |
| b | |
| c | e |
| d | |
| f | |
And the ways
| nodes | junction |
@@ -308,15 +230,15 @@ Feature: Basic Roundabout
And the ways
| nodes | junction |
| ad | |
| ab | |
| bcdb | roundabout |
| be | |
| cf | |
| ce | |
| df | |
When I route I should get
| waypoints | route | turns |
| a,e | ad,be,be | depart,roundabout-exit-1,arrive |
| a,f | ad,cf,cf | depart,roundabout-exit-2,arrive |
| a,e | ab,ce,ce | depart,roundabout-exit-1,arrive |
| a,f | ab,df,df | depart,roundabout-exit-2,arrive |
Scenario: Collinear in X,Y
Given the node map
@@ -327,13 +249,13 @@ Feature: Basic Roundabout
And the ways
| nodes | junction |
| ac | |
| ab | |
| bcdb | roundabout |
| de | |
| bf | |
| ce | |
| df | |
When I route I should get
| waypoints | route | turns |
| a,e | ac,de,de | depart,roundabout-exit-1,arrive |
| a,f | ac,bf,bf | depart,roundabout-exit-2,arrive |
| a,e | ab,ce,ce | depart,roundabout-exit-1,arrive |
| a,f | ab,df,df | depart,roundabout-exit-2,arrive |
-101
View File
@@ -1,101 +0,0 @@
@routing @guidance
Feature: Suppress New Names on dedicated Suffices
Background:
Given the profile "car"
Given a grid size of 10 meters
Scenario: Suffix To Suffix
Given the node map
| a | | b | | c |
And the ways
| nodes | name |
| ab | 42 N |
| bc | 42 S |
When I route I should get
| waypoints | route | turns |
| a,c | 42 N,42 S | depart,arrive |
Scenario: Suffix To Suffix Ref
Given the node map
| a | | b | | c |
And the ways
| nodes | name | ref |
| ab | 42 N | |
| bc | 42 S | 101 |
When I route I should get
| waypoints | route | turns |
| a,c | 42 N,42 S (101) | depart,arrive |
Scenario: Prefix Change
Given the node map
| a | | b | | c |
And the ways
| nodes | name |
| ab | West 42 |
| bc | East 42 |
When I route I should get
| waypoints | route | turns |
| a,c | West 42,East 42 | depart,arrive |
Scenario: Prefix Change and Reference
Given the node map
| a | | b | | c |
And the ways
| nodes | name | ref |
| ab | West 42 | 101 |
| bc | East 42 | |
When I route I should get
| waypoints | route | turns |
| a,c | West 42 (101),East 42 | depart,arrive |
Scenario: Suffix To Suffix - Turn
Given the node map
| a | | b | | c |
| | | d | | |
And the ways
| nodes | name |
| ab | 42 N |
| bc | 42 S |
| bd | 42 E |
When I route I should get
| waypoints | route | turns |
| a,c | 42 N,42 S | depart,arrive |
| a,d | 42 N,42 E,42 E | depart,turn right,arrive |
Scenario: Suffix To No Suffix
Given the node map
| a | | b | | c |
And the ways
| nodes | name |
| ab | 42 N |
| bc | 42 |
When I route I should get
| waypoints | route | turns |
| a,c | 42 N,42 | depart,arrive |
Scenario: No Suffix To Suffix
Given the node map
| a | | b | | c |
And the ways
| nodes | name |
| ab | 42 |
| bc | 42 S |
When I route I should get
| waypoints | route | turns |
| a,c | 42,42 S | depart,arrive |
+6 -1
View File
@@ -389,6 +389,7 @@ Feature: Simple Turns
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,turn left,arrive |
@bug @pr2275
Scenario: Left Turn Assignment (6)
Given the node map
| d | | | | |
@@ -510,6 +511,7 @@ Feature: Simple Turns
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,turn right,arrive |
@bug @pr2275
Scenario: Right Turn Assignment (6)
Given the node map
| | | e | | |
@@ -567,7 +569,7 @@ Feature: Simple Turns
Scenario: Right Turn Assignment Two Turns (2)
Given the node map
| | | f | | c |
| | | f | c | |
| a | | b | | |
| | | | | e |
| | | | d | |
@@ -665,6 +667,7 @@ Feature: Simple Turns
| d,e | dbe,dbe | depart,arrive |
| e,d | dbe,dbe | depart,arrive |
@bug @pr2275
Scenario: Slight Turn involving Oneways
Given the node map
| | | | a | |
@@ -726,6 +729,7 @@ Feature: Simple Turns
| a,e | abc,eb,eb | depart,turn right,arrive |
| a,f | abc,fb,fb | depart,turn slight right,arrive |
@bug @pr2275
Scenario: Right Turn Assignment Three Conflicting Turns with invalid - 2
Given the node map
| | | g | | |
@@ -786,6 +790,7 @@ Feature: Simple Turns
| a,e | abc,be,be | depart,turn right,arrive |
| a,f | abc,bf,bf | depart,turn sharp right,arrive |
@bug @pr2275
Scenario: Conflicting Turns with well distinguished turn (back)
Given the node map
| a | | | b | | | c |
+15 -26
View File
@@ -10,11 +10,13 @@ module.exports = function () {
});
this.Given(/^the extract extra arguments "(.*?)"$/, (args, callback) => {
this.setExtractArgs(args, callback);
this.setExtractArgs(args);
callback();
});
this.Given(/^the contract extra arguments "(.*?)"$/, (args, callback) => {
this.setContractArgs(args, callback);
this.setContractArgs(args);
callback();
});
this.Given(/^a grid size of (\d+) meters$/, (meters, callback) => {
@@ -47,27 +49,18 @@ module.exports = function () {
var addNode = (name, ri, ci, cb) => {
if (name) {
var nodeWithID = name.match(/([a-z])\:([0-9]*)/);
if (nodeWithID) {
var nodeName = nodeWithID[1],
nodeID = nodeWithID[2];
if (this.nameNodeHash[nodeName]) throw new Error(util.format('*** duplicate node %s', name));
lonLat = this.tableCoordToLonLat(ci, ri);
this.addOSMNode(nodeName, lonLat[0], lonLat[1], nodeID);
} else {
if (name.length !== 1) throw new Error(util.format('*** node invalid name %s, must be single characters', name));
if (!name.match(/[a-z0-9]/)) throw new Error(util.format('*** invalid node name %s, must me alphanumeric', name));
if (name.length !== 1) throw new Error(util.format('*** node invalid name %s, must be single characters', name));
if (!name.match(/[a-z0-9]/)) throw new Error(util.format('*** invalid node name %s, must me alphanumeric', name));
var lonLat;
if (name.match(/[a-z]/)) {
if (this.nameNodeHash[name]) throw new Error(util.format('*** duplicate node %s', name));
lonLat = this.tableCoordToLonLat(ci, ri);
this.addOSMNode(name, lonLat[0], lonLat[1], null);
} else {
if (this.locationHash[name]) throw new Error(util.format('*** duplicate node %s'), name);
lonLat = this.tableCoordToLonLat(ci, ri);
this.addLocation(name, lonLat[0], lonLat[1], null);
}
var lonLat;
if (name.match(/[a-z]/)) {
if (this.nameNodeHash[name]) throw new Error(util.format('*** duplicate node %s', name));
lonLat = this.tableCoordToLonLat(ci, ri);
this.addOSMNode(name, lonLat[0], lonLat[1], null);
} else {
if (this.locationHash[name]) throw new Error(util.format('*** duplicate node %s'), name);
lonLat = this.tableCoordToLonLat(ci, ri);
this.addLocation(name, lonLat[0], lonLat[1], null);
}
cb();
@@ -235,10 +228,6 @@ module.exports = function () {
fs.writeFile(path.resolve(this.TEST_FOLDER, 'speeds.csv'), data, callback);
});
this.Given(/^the turn penalty file$/, (data, callback) => {
fs.writeFile(path.resolve(this.TEST_FOLDER, 'penalties.csv'), data, callback);
});
this.Given(/^the data has been saved to disk$/, (callback) => {
try {
this.reprocess(callback);
+1 -13
View File
@@ -33,9 +33,7 @@ module.exports = function () {
var subMatchings = [],
turns = '',
route = '',
duration = '',
annotation = '';
duration = '';
if (res.statusCode === 200) {
if (headers.has('matchings')) {
@@ -56,11 +54,6 @@ module.exports = function () {
if (json.matchings.length != 1) throw new Error('*** Checking duration only supported for matchings with one subtrace');
duration = json.matchings[0].duration;
}
if (headers.has('annotation')) {
if (json.matchings.length != 1) throw new Error('*** Checking annotation only supported for matchings with one subtrace');
annotation = this.annotationList(json.matchings[0]);
}
}
if (headers.has('turns')) {
@@ -75,10 +68,6 @@ module.exports = function () {
got.duration = duration.toString();
}
if (headers.has('annotation')) {
got.annotation = annotation.toString();
}
var ok = true;
var encodedResult = '',
extendedTarget = '';
@@ -145,7 +134,6 @@ module.exports = function () {
this.requestUrl(row.request, afterRequest);
} else {
var params = this.queryParams;
params['annotate'] = 'true';
got = {};
for (var k in row) {
var match = k.match(/param:(.*)/);
+1 -1
View File
@@ -1,7 +1,7 @@
var assert = require('assert');
module.exports = function () {
this.When(/^I run "osrm\-routed\s?(.*?)"$/, { timeout: this.TIMEOUT }, (options, callback) => {
this.When(/^I run "osrm\-routed\s?(.*?)"$/, { timeout: this.SHUTDOWN_TIMEOUT }, (options, callback) => {
this.runBin('osrm-routed', options, () => {
callback();
});
-1
View File
@@ -71,7 +71,6 @@ module.exports = function () {
r.status = res.statusCode === 200 ? 'x' : null;
if (r.status) {
r.route = this.wayList(r.json.routes[0]);
r.summary = r.json.routes[0].legs.map(l => l.summary).join(',');
if (r.route.split(',')[0] === util.format('w%d', i)) {
r.time = r.json.routes[0].duration;
+2 -1
View File
@@ -3,7 +3,8 @@ var d3 = require('d3-queue');
module.exports = function () {
this.When(/^I route I should get$/, this.WhenIRouteIShouldGet);
this.When(/^I route (\d+) times I should get$/, { timeout: 100 * this.TIMEOUT }, (n, table, callback) => {
// This is used to route 100 times; timeout for entire step is therefore set to 100 * STRESS_TIMEOUT
this.When(/^I route (\d+) times I should get$/, { timeout: 30000 }, (n, table, callback) => {
var q = d3.queue(1);
for (var i=0; i<n; i++) {
+2 -2
View File
@@ -46,8 +46,8 @@ module.exports = function () {
if (headers.has('trips')) {
subTrips = json.trips.filter(t => !!t).map(t => t.legs).map(tl => Array.prototype.concat.apply([], tl.map((sl, i) => {
var toAdd = [];
if (i === 0) toAdd.push(sl.steps[0].intersections[0].location);
toAdd.push(sl.steps[sl.steps.length-1].intersections[0].location);
if (i === 0) toAdd.push(sl.steps[0].maneuver.location);
toAdd.push(sl.steps[sl.steps.length-1].maneuver.location);
return toAdd;
})));
}
+4 -7
View File
@@ -19,6 +19,8 @@ module.exports = function () {
this.osmData = new classes.osmData(this);
this.STRESS_TIMEOUT = 300;
this.OSRMLoader = this._OSRMLoader();
this.PREPROCESS_LOG_FILE = path.resolve(this.TEST_FOLDER, 'preprocessing.log');
@@ -103,16 +105,11 @@ module.exports = function () {
} else cb();
};
this.setExtractArgs = (args, callback) => {
this.setExtractArgs = (args) => {
this.extractArgs = args;
this.forceExtract = true;
this.forceContract = true;
callback();
};
this.setContractArgs = (args, callback) => {
this.setContractArgs = (args) => {
this.contractArgs = args;
this.forceContract = true;
callback();
};
};
+4 -6
View File
@@ -222,7 +222,7 @@ module.exports = function () {
});
};
['osrm','osrm.names','osrm.restrictions','osrm.ebg','osrm.enw','osrm.edges','osrm.fileIndex','osrm.geometry','osrm.nodes','osrm.ramIndex','osrm.properties','osrm.icd'].forEach(file => {
['osrm','osrm.names','osrm.restrictions','osrm.ebg','osrm.enw','osrm.edges','osrm.fileIndex','osrm.geometry','osrm.nodes','osrm.ramIndex','osrm.properties'].forEach(file => {
q.defer(rename, file);
});
@@ -273,7 +273,7 @@ module.exports = function () {
var q = d3.queue();
['osrm.hsgr','osrm.fileIndex','osrm.geometry','osrm.nodes','osrm.ramIndex','osrm.core','osrm.edges','osrm.datasource_indexes','osrm.datasource_names','osrm.level','osrm.icd'].forEach((file) => {
['osrm.hsgr','osrm.fileIndex','osrm.geometry','osrm.nodes','osrm.ramIndex','osrm.core','osrm.edges','osrm.datasource_indexes','osrm.datasource_names','osrm.level'].forEach((file) => {
q.defer(rename, file);
});
@@ -295,10 +295,9 @@ module.exports = function () {
this.writeAndExtract((e) => {
if (e) return callback(e);
this.isContracted((isContracted) => {
var contractFn = (isContracted && !this.forceContract) ? noop : this.contractData;
var contractFn = isContracted ? noop : this.contractData;
if (isContracted) this.log('Already contracted ' + this.osmData.contractedFile, 'preprocess');
contractFn((e) => {
this.forceContract = false;
if (e) return callback(e);
this.logPreprocessDone();
callback();
@@ -312,10 +311,9 @@ module.exports = function () {
this.writeInputData((e) => {
if (e) return callback(e);
this.isExtracted((isExtracted) => {
var extractFn = (isExtracted && !this.forceExtract) ? noop : this.extractData;
var extractFn = isExtracted ? noop : this.extractData;
if (isExtracted) this.log('Already extracted ' + this.osmData.extractedFile, 'preprocess');
extractFn((e) => {
this.forceExtract = false;
callback(e);
});
});
+6 -73
View File
@@ -52,91 +52,24 @@ module.exports = {
match (got, want) {
var matchPercent = want.match(/(.*)\s+~(.+)%$/),
matchAbs = want.match(/(.*)\s+\+\-(.+)$/),
matchRe = want.match(/^\/(.*)\/$/),
// we use this for matching before/after bearing
matchBearingListAbs = want.match(/^((\d+)->(\d+))(,(\d+)->(\d+))*\s+\+\-(.+)$/),
matchIntersectionListAbs = want.match(/^(((((true|false):\d+)\s{0,1})+,{0,1})+;{0,1})+\s+\+\-(.+)$/);
function inRange(margin, got, want) {
var fromR = parseFloat(want) - margin,
toR = parseFloat(want) + margin;
return parseFloat(got) >= fromR && parseFloat(got) <= toR;
}
function parseIntersectionString(str) {
return str.split(';')
.map((turn_intersections) => turn_intersections
.split(',')
.map((intersection) => intersection
.split(' ')
.map((entry_bearing_pair) => entry_bearing_pair
.split(':'))));
}
matchRe = want.match(/^\/(.*)\/$/);
if (got === want) {
return true;
} else if (matchBearingListAbs) {
let want_and_margin = want.split('+-'),
margin = parseFloat(want_and_margin[1].trim()),
want_pairs = want_and_margin[0].trim().split(',').map((pair) => pair.split('->')),
got_pairs = got.split(',').map((pair) => pair.split('->'));
if (want_pairs.length != got_pairs.length)
{
return false;
}
for (var i = 0; i < want_pairs.length; ++i)
{
if (!inRange(margin, got_pairs[i][0], want_pairs[i][0]) ||
!inRange(margin, got_pairs[i][1], want_pairs[i][1]))
{
return false;
}
}
return true;
} else if (matchIntersectionListAbs) {
let margin = parseFloat(want.split('+-')[1]),
want_intersections = parseIntersectionString(want.split('+-')[0].trim()),
got_intersections = parseIntersectionString(got);
if (want_intersections.length != got_intersections.length)
{
return false;
}
for (let step_idx = 0; step_idx < want_intersections.length; ++step_idx)
{
if (want_intersections[step_idx].length != got_intersections[step_idx].length)
{
return false;
}
for (let intersection_idx = 0; intersection_idx < want_intersections[step_idx].length; ++intersection_idx)
{
if (want_intersections[step_idx][intersection_idx].length != got_intersections[step_idx][intersection_idx].length)
{
return false;
}
for (let pair_idx = 0; pair_idx < want_intersections[step_idx][intersection_idx].length; ++pair_idx)
{
let want_pair = want_intersections[step_idx][intersection_idx][pair_idx],
got_pair = got_intersections[step_idx][intersection_idx][pair_idx];
if (got_pair[0] != want_pair[0] ||
!inRange(margin, got_pair[1], want_pair[1]))
{
return false;
}
}
}
}
return true;
} else if (matchPercent) { // percentage range: 100 ~ 5%
var target = parseFloat(matchPercent[1]),
percentage = parseFloat(matchPercent[2]);
if (target === 0) {
return true;
} else {
let ratio = Math.abs(1 - parseFloat(got) / target);
var ratio = Math.abs(1 - parseFloat(got) / target);
return 100 * ratio < percentage;
}
} else if (matchAbs) { // absolute range: 100 +-5
let margin = parseFloat(matchAbs[2]);
return inRange(margin, got, matchAbs[1]);
var margin = parseFloat(matchAbs[2]),
fromR = parseFloat(matchAbs[1]) - margin,
toR = parseFloat(matchAbs[1]) + margin;
return parseFloat(got) >= fromR && parseFloat(got) <= toR;
} else if (matchRe) { // regex: /a,b,.*/
return got.match(matchRe[1]);
} else {
+26 -3
View File
@@ -6,9 +6,10 @@ var d3 = require('d3-queue');
module.exports = function () {
this.initializeEnv = (callback) => {
this.OSRM_PORT = process.env.OSRM_PORT && parseInt(process.env.OSRM_PORT) || 5000;
this.TIMEOUT = process.env.CUCUMBER_TIMEOUT && parseInt(process.env.CUCUMBER_TIMEOUT) || 3000;
this.setDefaultTimeout(this.TIMEOUT);
this.DEFAULT_PORT = 5000;
// OSX builds on Travis hit a timeout of ~2000 from time to time
this.DEFAULT_TIMEOUT = 5000;
this.setDefaultTimeout(this.DEFAULT_TIMEOUT);
this.ROOT_FOLDER = process.cwd();
this.OSM_USER = 'osrm';
this.OSM_GENERATOR = 'osrm-test';
@@ -24,6 +25,8 @@ module.exports = function () {
this.BIN_PATH = path.resolve(this.ROOT_FOLDER, 'build');
this.DEFAULT_INPUT_FORMAT = 'osm';
this.DEFAULT_ORIGIN = [1,1];
this.LAUNCH_TIMEOUT = 1000;
this.SHUTDOWN_TIMEOUT = 10000;
this.DEFAULT_LOAD_METHOD = 'datastore';
this.OSRM_ROUTED_LOG_FILE = path.resolve(this.TEST_FOLDER, 'osrm-routed.log');
this.ERROR_LOG_FILE = path.resolve(this.TEST_FOLDER, 'error.log');
@@ -48,6 +51,26 @@ module.exports = function () {
console.info(util.format('Node Version', process.version));
if (parseInt(process.version.match(/v(\d)/)[1]) < 4) throw new Error('*** PLease upgrade to Node 4.+ to run OSRM cucumber tests');
if (process.env.OSRM_PORT) {
this.OSRM_PORT = parseInt(process.env.OSRM_PORT);
// eslint-disable-next-line no-console
console.info(util.format('Port set to %d', this.OSRM_PORT));
} else {
this.OSRM_PORT = this.DEFAULT_PORT;
// eslint-disable-next-line no-console
console.info(util.format('Using default port %d', this.OSRM_PORT));
}
if (process.env.OSRM_TIMEOUT) {
this.OSRM_TIMEOUT = parseInt(process.env.OSRM_TIMEOUT);
// eslint-disable-next-line no-console
console.info(util.format('Timeout set to %d', this.OSRM_TIMEOUT));
} else {
this.OSRM_TIMEOUT = this.DEFAULT_TIMEOUT;
// eslint-disable-next-line no-console
console.info(util.format('Using default timeout %d', this.OSRM_TIMEOUT));
}
fs.exists(this.TEST_FOLDER, (exists) => {
if (!exists) throw new Error(util.format('*** Test folder %s doesn\'t exist.', this.TEST_FOLDER));
callback();
+4 -6
View File
@@ -24,12 +24,10 @@ module.exports = function () {
});
this.After((scenario, callback) => {
this.setExtractArgs('', () => {
this.setContractArgs('', () => {
if (this.loadMethod === 'directly' && !!this.OSRMLoader.loader) this.OSRMLoader.shutdown(callback);
else callback();
});
});
this.setExtractArgs('');
this.setContractArgs('');
if (this.loadMethod === 'directly' && !!this.OSRMLoader.loader) this.OSRMLoader.shutdown(callback);
else callback();
});
this.Around('@stress', (scenario, callback) => {
+1 -1
View File
@@ -20,7 +20,7 @@ module.exports = function () {
};
this.sendRequest = (baseUri, parameters, callback) => {
var limit = Timeout(this.TIMEOUT, { err: { statusCode: 408 } });
var limit = Timeout(this.OSRM_TIMEOUT, { err: { statusCode: 408 } });
var runRequest = (cb) => {
var params = this.paramsToString(parameters);
+2 -2
View File
@@ -12,7 +12,7 @@ var OSRMBaseLoader = class {
}
launch (callback) {
var limit = Timeout(this.scope.TIMEOUT, { err: this.scope.RoutedError('Launching osrm-routed timed out.') });
var limit = Timeout(this.scope.LAUNCH_TIMEOUT, { err: this.scope.RoutedError('Launching osrm-routed timed out.') });
var runLaunch = (cb) => {
this.osrmUp(() => {
@@ -24,7 +24,7 @@ var OSRMBaseLoader = class {
}
shutdown (callback) {
var limit = Timeout(this.scope.TIMEOUT, { err: this.scope.RoutedError('Shutting down osrm-routed timed out.')});
var limit = Timeout(this.scope.SHUTDOWN_TIMEOUT, { err: this.scope.RoutedError('Shutting down osrm-routed timed out.')});
var runShutdown = (cb) => {
this.osrmDown(cb);
+2 -36
View File
@@ -15,7 +15,7 @@ module.exports = function () {
this.requestUrl = (path, callback) => {
var uri = this.query = [this.HOST, path].join('/'),
limit = Timeout(this.TIMEOUT, { err: { statusCode: 408 } });
limit = Timeout(this.OSRM_TIMEOUT, { err: { statusCode: 408 } });
function runRequest (cb) {
request(uri, cb);
@@ -127,28 +127,12 @@ module.exports = function () {
}
};
this.summary = (instructions) => {
if (instructions) {
return instructions.legs.map(l => l.summary).join(',');
}
};
this.wayList = (instructions) => {
return this.extractInstructionList(instructions, s => s.name);
};
this.bearingList = (instructions) => {
return this.extractInstructionList(instructions, s => s.maneuver.bearing_before + '->' + s.maneuver.bearing_after);
};
this.annotationList = (instructions) => {
// Pull out all the distinct segment distances, skipping the arrive
// instructions, and the leading 0 on all timestamps arrays.
var pairs = [];
for (var i in instructions.annotation.duration) {
pairs.push(instructions.annotation.duration[i]+':'+instructions.annotation.distance[i]);
}
return pairs.join(',');
return this.extractInstructionList(instructions, s => s.maneuver.bearing_after);
};
this.turnList = (instructions) => {
@@ -158,9 +142,6 @@ module.exports = function () {
case 'depart':
case 'arrive':
return v.maneuver.type;
case 'on ramp':
case 'off ramp':
return v.maneuver.type + ' ' + v.maneuver.modifier;
case 'roundabout':
return 'roundabout-exit-' + v.maneuver.exit;
case 'rotary':
@@ -168,8 +149,6 @@ module.exports = function () {
return v.rotary_name + '-exit-' + v.maneuver.exit;
else
return 'rotary-exit-' + v.maneuver.exit;
case 'roundabout turn':
return v.maneuver.type + ' ' + v.maneuver.modifier + ' exit-' + v.maneuver.exit;
// FIXME this is a little bit over-simplistic for merge/fork instructions
default:
return v.maneuver.type + ' ' + v.maneuver.modifier;
@@ -178,19 +157,6 @@ module.exports = function () {
.join(',');
};
this.intersectionList = (instructions) => {
return instructions.legs.reduce((m, v) => m.concat(v.steps), [])
.map( v => {
return v.intersections
.map( intersection => {
var string = intersection.entry[0]+':'+intersection.bearings[0], i;
for( i = 1; i < intersection.bearings.length; ++i )
string = string + ' ' + intersection.entry[i]+':'+intersection.bearings[i];
return string;
}).join(',');
}).join(';');
};
this.modeList = (instructions) => {
return this.extractInstructionList(instructions, s => s.mode);
};
+1 -11
View File
@@ -31,7 +31,7 @@ module.exports = function () {
var afterRequest = (err, res, body) => {
if (err) return cb(err);
if (body && body.length) {
var instructions, bearings, turns, modes, times, distances, summary, intersections;
var instructions, bearings, turns, modes, times, distances;
var json = JSON.parse(body);
@@ -41,11 +41,9 @@ module.exports = function () {
instructions = this.wayList(json.routes[0]);
bearings = this.bearingList(json.routes[0]);
turns = this.turnList(json.routes[0]);
intersections = this.intersectionList(json.routes[0]);
modes = this.modeList(json.routes[0]);
times = this.timeList(json.routes[0]);
distances = this.distanceList(json.routes[0]);
summary = this.summary(json.routes[0]);
}
if (headers.has('status')) {
@@ -68,10 +66,6 @@ module.exports = function () {
if (headers.has('route')) {
got.route = (instructions || '').trim();
if (headers.has('summary')) {
got.summary = (summary || '').trim();
}
if (headers.has('alternative')) {
// TODO examine more than first alternative?
got.alternative ='';
@@ -109,10 +103,6 @@ module.exports = function () {
}
}
if (headers.has('intersections')) {
got.intersections = (intersections || '').trim();
}
var putValue = (key, value) => {
if (headers.has(key)) got[key] = instructions ? value : '';
};
+73 -73
View File
@@ -14,8 +14,8 @@ Feature: Compass bearing
| ab |
When I route I should get
| from | to | route | bearing |
| a | b | ab,ab | 0->315,315->0|
| from | to | route | bearing |
| a | b | ab,ab | 315,0 |
Scenario: Bearing when going west
Given the node map
@@ -26,8 +26,8 @@ Feature: Compass bearing
| ab |
When I route I should get
| from | to | route | bearing |
| a | b | ab,ab | 0->270,270->0|
| from | to | route | bearing |
| a | b | ab,ab | 270,0 |
Scenario: Bearing af 45 degree intervals
Given the node map
@@ -48,14 +48,14 @@ Feature: Compass bearing
When I route I should get
| from | to | route | bearing |
| x | a | xa,xa | 0->0,0->0|
| x | b | xb,xb | 0->315,315->0|
| x | c | xc,xc | 0->270,270->0|
| x | d | xd,xd | 0->225,225->0|
| x | e | xe,xe | 0->180,180->0|
| x | f | xf,xf | 0->135,135->0|
| x | g | xg,xg | 0->90,90->0|
| x | h | xh,xh | 0->45,45->0|
| x | a | xa,xa | 0,0 |
| x | b | xb,xb | 315,0 |
| x | c | xc,xc | 270,0 |
| x | d | xd,xd | 225,0 |
| x | e | xe,xe | 180,0 |
| x | f | xf,xf | 135,0 |
| x | g | xg,xg | 90,0 |
| x | h | xh,xh | 45,0 |
Scenario: Bearing in a roundabout
Given the node map
@@ -76,9 +76,9 @@ Feature: Compass bearing
| ha | yes |
When I route I should get
| from | to | route | bearing |
| c | b | cd,de,ef,fg,gh,ha,ab,ab | 0->270,270->225,225->180,180->135,135->90,90->45,45->0,0->0 |
| g | f | gh,ha,ab,bc,cd,de,ef,ef | 0->90,90->45,45->0,0->315,315->270,270->225,225->180,180->0 |
| from | to | route | bearing |
| c | b | cd,de,ef,fg,gh,ha,ab,ab | 270,225,180,135,90,45,0,0 |
| g | f | gh,ha,ab,bc,cd,de,ef,ef | 90,45,0,315,270,225,180,0 |
Scenario: Bearing should stay constant when zig-zagging
Given the node map
@@ -97,7 +97,7 @@ Feature: Compass bearing
When I route I should get
| from | to | route | bearing |
| a | h | ab,bc,cd,de,ef,fg,gh,gh | 0->0,0->135,135->0,0->135,135->0,0->135,135->0,0->0 |
| a | h | ab,bc,cd,de,ef,fg,gh,gh | 0,135,0,135,0,135,0,0 |
Scenario: Bearings on an east-west way.
Given the node map
@@ -108,37 +108,37 @@ Feature: Compass bearing
| abcdef |
When I route I should get
| from | to | route | bearing |
| a | b | abcdef,abcdef | 0->90,90->0 |
| a | c | abcdef,abcdef | 0->90,90->0 |
| a | d | abcdef,abcdef | 0->90,90->0 |
| a | e | abcdef,abcdef | 0->90,90->0 |
| a | f | abcdef,abcdef | 0->90,90->0 |
| b | a | abcdef,abcdef | 0->270,270->0 |
| b | c | abcdef,abcdef | 0->90,90->0 |
| b | d | abcdef,abcdef | 0->90,90->0 |
| b | e | abcdef,abcdef | 0->90,90->0 |
| b | f | abcdef,abcdef | 0->90,90->0 |
| c | a | abcdef,abcdef | 0->270,270->0 |
| c | b | abcdef,abcdef | 0->270,270->0 |
| c | d | abcdef,abcdef | 0->90,90->0 |
| c | e | abcdef,abcdef | 0->90,90->0 |
| c | f | abcdef,abcdef | 0->90,90->0 |
| d | a | abcdef,abcdef | 0->270,270->0 |
| d | b | abcdef,abcdef | 0->270,270->0 |
| d | c | abcdef,abcdef | 0->270,270->0 |
| d | e | abcdef,abcdef | 0->90,90->0 |
| d | f | abcdef,abcdef | 0->90,90->0 |
| e | a | abcdef,abcdef | 0->270,270->0 |
| e | b | abcdef,abcdef | 0->270,270->0 |
| e | c | abcdef,abcdef | 0->270,270->0 |
| e | d | abcdef,abcdef | 0->270,270->0 |
| e | f | abcdef,abcdef | 0->90,90->0 |
| f | a | abcdef,abcdef | 0->270,270->0 |
| f | b | abcdef,abcdef | 0->270,270->0 |
| f | c | abcdef,abcdef | 0->270,270->0 |
| f | d | abcdef,abcdef | 0->270,270->0 |
| f | e | abcdef,abcdef | 0->270,270->0 |
| from | to | route | bearing |
| a | b | abcdef,abcdef | 90,0 |
| a | c | abcdef,abcdef | 90,0 |
| a | d | abcdef,abcdef | 90,0 |
| a | e | abcdef,abcdef | 90,0 |
| a | f | abcdef,abcdef | 90,0 |
| b | a | abcdef,abcdef | 270,0 |
| b | c | abcdef,abcdef | 90,0 |
| b | d | abcdef,abcdef | 90,0 |
| b | e | abcdef,abcdef | 90,0 |
| b | f | abcdef,abcdef | 90,0 |
| c | a | abcdef,abcdef | 270,0 |
| c | b | abcdef,abcdef | 270,0 |
| c | d | abcdef,abcdef | 90,0 |
| c | e | abcdef,abcdef | 90,0 |
| c | f | abcdef,abcdef | 90,0 |
| d | a | abcdef,abcdef | 270,0 |
| d | b | abcdef,abcdef | 270,0 |
| d | c | abcdef,abcdef | 270,0 |
| d | e | abcdef,abcdef | 90,0 |
| d | f | abcdef,abcdef | 90,0 |
| e | a | abcdef,abcdef | 270,0 |
| e | b | abcdef,abcdef | 270,0 |
| e | c | abcdef,abcdef | 270,0 |
| e | d | abcdef,abcdef | 270,0 |
| e | f | abcdef,abcdef | 90,0 |
| f | a | abcdef,abcdef | 270,0 |
| f | b | abcdef,abcdef | 270,0 |
| f | c | abcdef,abcdef | 270,0 |
| f | d | abcdef,abcdef | 270,0 |
| f | e | abcdef,abcdef | 270,0 |
Scenario: Bearings at high latitudes
# The coordinas below was calculated using http://www.movable-type.co.uk/scripts/latlong.html,
@@ -161,19 +161,19 @@ Feature: Compass bearing
| bd |
When I route I should get
| from | to | route | bearing |
| a | b | ab,ab | 0->0,0->0 |
| b | c | bc,bc | 0->90,90->0 |
| c | d | cd,cd | 0->180,180->0 |
| d | a | da,da | 0->270,270->0 |
| b | a | ab,ab | 0->180,180->0 |
| c | b | bc,bc | 0->270,270->0 |
| d | c | cd,cd | 0->0,0->0 |
| a | d | da,da | 0->90,90->0 |
| a | c | ac,ac | 0->45,45->0 |
| c | a | ac,ac | 0->225,225->0 |
| b | d | bd,bd | 0->135,135->0 |
| d | b | bd,bd | 0->315,315->0 |
| from | to | route | bearing |
| a | b | ab,ab | 0,0 |
| b | c | bc,bc | 90,0 |
| c | d | cd,cd | 180,0 |
| d | a | da,da | 270,0 |
| b | a | ab,ab | 180,0 |
| c | b | bc,bc | 270,0 |
| d | c | cd,cd | 0,0 |
| a | d | da,da | 90,0 |
| a | c | ac,ac | 45,0 |
| c | a | ac,ac | 225,0 |
| b | d | bd,bd | 135,0 |
| d | b | bd,bd | 315,0 |
Scenario: Bearings at high negative latitudes
# The coordinas below was calculated using http://www.movable-type.co.uk/scripts/latlong.html,
@@ -196,16 +196,16 @@ Feature: Compass bearing
| bd |
When I route I should get
| from | to | route | bearing |
| a | b | ab,ab | 0->180,180->0 |
| b | c | bc,bc | 0->90,90->0 |
| c | d | cd,cd | 0->0,0->0 |
| d | a | da,da | 0->270,270->0 |
| b | a | ab,ab | 0->0,0->0 |
| c | b | bc,bc | 0->270,270->0 |
| d | c | cd,cd | 0->180,180->0 |
| a | d | da,da | 0->90,90->0 |
| a | c | ac,ac | 0->135,135->0 |
| c | a | ac,ac | 0->315,315->0 |
| b | d | bd,bd | 0->45,45->0 |
| d | b | bd,bd | 0->225,225->0 |
| from | to | route | bearing |
| a | b | ab,ab | 180,0 |
| b | c | bc,bc | 90,0 |
| c | d | cd,cd | 0,0 |
| d | a | da,da | 270,0 |
| b | a | ab,ab | 0,0 |
| c | b | bc,bc | 270,0 |
| d | c | cd,cd | 180,0 |
| a | d | da,da | 90,0 |
| a | c | ac,ac | 135,0 |
| c | a | ac,ac | 315,0 |
| b | d | bd,bd | 45,0 |
| d | b | bd,bd | 225,0 |
+20 -20
View File
@@ -15,11 +15,11 @@ Feature: Bearing parameter
When I route I should get
| from | to | bearings | route | bearing |
| b | c | 90 90 | ad,ad | 0->90,90->0|
| b | c | 90 90 | ad,ad | 90,0 |
| b | c | 180 90 | | |
| b | c | 80 100 | ad,ad | 0->90,90->0|
| b | c | 80 100 | ad,ad | 90,0 |
| b | c | 79 100 | | |
| b | c | 79,11 100 | ad,ad | 0->90,90->0|
| b | c | 79,11 100 | ad,ad | 90,0 |
Scenario: Testbot - Intial bearing in simple case
Given the node map
@@ -35,10 +35,10 @@ Feature: Bearing parameter
When I route I should get
| from | to | bearings | route | bearing |
| 0 | c | 0 0 | | |
| 0 | c | 45 45 | bc,bc | 0->44,44->0 +- 1|
| 0 | c | 45 45 | bc,bc | 45 ~3% |
| 0 | c | 85 85 | | |
| 0 | c | 95 95 | | |
| 0 | c | 135 135 | ac,ac | 0->135,135->0 +- 1|
| 0 | c | 135 135 | ac,ac | 135 ~1% |
| 0 | c | 180 180 | | |
Scenario: Testbot - Initial bearing on split way
@@ -55,19 +55,19 @@ Feature: Bearing parameter
When I route I should get
| from | to | bearings | route | bearing |
| 0 | b | 10 10 | bc,bc | 0->0,0->0 |
| 0 | b | 90 90 | ab,ab | 0->90,90->0 |
| 0 | b | 10 10 | bc,bc | 0,0 |
| 0 | b | 90 90 | ab,ab | 90,0 |
# The returned bearing is wrong here, it's based on the snapped
# coordinates, not the acutal edge bearing. This should be
# fixed one day, but it's only a problem when we snap two vias
# to the same point - DP
#| 0 | b | 170 170 | da | 180 |
#| 0 | b | 189 189 | da | 180 |
| 0 | 1 | 90 270 | ab,bc,cd,cd | 0->90,90->0,0->270,270->0 |
| 1 | d | 10 10 | bc,bc | 0->0,0->0 |
| 1 | d | 90 90 | ab,bc,cd,da,da | 0->90,90->0,0->270,270->180,180->0 |
| 1 | 0 | 189 189 | da,da | 0->180,180->0 |
| 1 | d | 270 270 | cd,cd | 0->270,270->0 |
| 0 | 1 | 90 270 | ab,bc,cd,cd | 90,0,270,0 |
| 1 | d | 10 10 | bc,bc | 0,0 |
| 1 | d | 90 90 | ab,bc,cd,da,da | 90,0,270,180,0 |
| 1 | 0 | 189 189 | da,da | 180,0 |
| 1 | d | 270 270 | cd,cd | 270,0 |
| 1 | d | 349 349 | | |
Scenario: Testbot - Initial bearing in all direction
@@ -101,11 +101,11 @@ Feature: Bearing parameter
When I route I should get
| from | to | bearings | route | bearing |
| 0 | q | 0 90 | ia,ab,bc,cd,de,ef,fg,gh,ha,ha | 0->0,0->90,90->180,180->180,180->270,270->270,270->0,0->0,0->90,90->0 |
| 0 | a | 45 90 | jb,bc,cd,de,ef,fg,gh,ha,ha | 0->45,45->180,180->180,180->270,270->270,270->0,0->0,0->90,90->0 |
| 0 | q | 90 90 | kc,cd,de,ef,fg,gh,ha,ha | 0->90,90->180,180->270,270->270,270->0,0->0,0->90,90->0 |
| 0 | a | 135 90 | ld,de,ef,fg,gh,ha,ha | 0->135,135->270,270->270,270->0,0->0,0->90,90->0 |
| 0 | a | 180 90 | me,ef,fg,gh,ha,ha | 0->180,180->270,270->0,0->0,0->90,90->0 |
| 0 | a | 225 90 | nf,fg,gh,ha,ha | 0->225,225->0,0->0,0->90,90->0 |
| 0 | a | 270 90 | og,gh,ha,ha | 0->270,270->0,0->90,90->0 |
| 0 | a | 315 90 | ph,ha,ha | 0->315,315->90,90->0 |
| 0 | q | 0 90 | ia,ab,bc,cd,de,ef,fg,gh,ha,ha | 0,90,180,180,270,270,0,0,90,0 |
| 0 | a | 45 90 | jb,bc,cd,de,ef,fg,gh,ha,ha | 45,180,180,270,270,0,0,90,0 |
| 0 | q | 90 90 | kc,cd,de,ef,fg,gh,ha,ha | 90,180,270,270,0,0,90,0 |
| 0 | a | 135 90 | ld,de,ef,fg,gh,ha,ha | 135,270,270,0,0,90,0 |
| 0 | a | 180 90 | me,ef,fg,gh,ha,ha | 180,270,0,0,90,0 |
| 0 | a | 225 90 | nf,fg,gh,ha,ha | 225,0,0,90,0 |
| 0 | a | 270 90 | og,gh,ha,ha | 270,0,90,0 |
| 0 | a | 315 90 | ph,ha,ha | 315,90,0 |
+2 -2
View File
@@ -18,5 +18,5 @@ Feature: Geometry Compression
When I route I should get
| from | to | route | distance | speed |
| b | e | abcdef,abcdef | 588.8m | 36 km/h |
| e | b | abcdef,abcdef | 588.8m | 36 km/h |
| b | e | abcdef,abcdef | 589m | 36 km/h |
| e | b | abcdef,abcdef | 589m | 36 km/h |
-15
View File
@@ -104,18 +104,3 @@ Feature: Basic Map Matching
| trace | matchings |
| dcba | hg,gf,fe |
| efgh | ab,bc,cd |
Scenario: Testbot - Duration details
Given the node map
| a | b | c | d | e | | g | h |
| | | i | | | | | |
And the ways
| nodes | oneway |
| abcdegh | no |
| ci | no |
When I match I should get
| trace | matchings | annotation |
| abeh | abcedgh | 1:9.897633,0:0,1:10.008842,1:10.008842,1:10.008842,0:0,2:20.017685,1:10.008842 |
| abci | abc,ci | 1:9.897633,0:0,1:10.008842,0:0.111209,1:10.010367 |
+6 -6
View File
@@ -24,12 +24,12 @@ Feature: Projection to nearest point on road
Scenario: Projection onto way at high latitudes, 1km distance
When I route I should get
| from | to | route | bearing | distance |
| b | a | abc,abc | 0->225,225->0 | 1000m +- 7 |
| b | c | abc,abc | 0->45,45->0 | 1000m +- 7 |
| a | d | abc,abc | 0->45,45->0 | 1000m +- 7 |
| d | a | abc,abc | 0->225,225->0 | 1000m +- 7 |
| c | d | abc,abc | 0->225,224->0 | 1000m +- 8 |
| d | c | abc,abc | 0->44,45->0 | 1000m +- 8 |
| b | a | abc,abc | 225,0 +-1 | 1000m +- 7 |
| b | c | abc,abc | 45,0 +-1 | 1000m +- 7 |
| a | d | abc,abc | 45,0 +-1 | 1000m +- 7 |
| d | a | abc,abc | 225,0 +-1 | 1000m +- 7 |
| c | d | abc,abc | 225,0 +-1 | 1000m +- 8 |
| d | c | abc,abc | 45 +-1 | 1000m +- 8 |
Scenario: Projection onto way at high latitudes, no distance
When I route I should get
+9 -9
View File
@@ -55,13 +55,13 @@ Feature: Status messages
| ? | 400 | URL string malformed close to position 1: "/?" |
| route/v1/driving | 400 | URL string malformed close to position 17: "ing" |
| route/v1/driving/ | 400 | URL string malformed close to position 18: "ng/" |
| route/v1/driving/1 | 400 | Query string malformed close to position 19 |
| route/v1/driving/1 | 400 | Query string malformed close to position 1 |
| route/v1/driving/1,1 | 400 | Number of coordinates needs to be at least two. |
| route/v1/driving/1,1,1 | 400 | Query string malformed close to position 21 |
| route/v1/driving/x | 400 | Query string malformed close to position 18 |
| route/v1/driving/x,y | 400 | Query string malformed close to position 18 |
| route/v1/driving/1,1; | 400 | Query string malformed close to position 21 |
| route/v1/driving/1,1;1 | 400 | Query string malformed close to position 23 |
| route/v1/driving/1,1;1,1,1 | 400 | Query string malformed close to position 25 |
| route/v1/driving/1,1;x | 400 | Query string malformed close to position 21 |
| route/v1/driving/1,1;x,y | 400 | Query string malformed close to position 21 |
| route/v1/driving/1,1,1 | 400 | Query string malformed close to position 3 |
| route/v1/driving/x | 400 | Query string malformed close to position 0 |
| route/v1/driving/x,y | 400 | Query string malformed close to position 0 |
| route/v1/driving/1,1; | 400 | Query string malformed close to position 3 |
| route/v1/driving/1,1;1 | 400 | Query string malformed close to position 5 |
| route/v1/driving/1,1;1,1,1 | 400 | Query string malformed close to position 7 |
| route/v1/driving/1,1;x | 400 | Query string malformed close to position 3 |
| route/v1/driving/1,1;x,y | 400 | Query string malformed close to position 3 |
-77
View File
@@ -1,77 +0,0 @@
@routing @basic @testbot
Feature: Basic Routing
Background:
Given the profile "testbot"
@smallest
Scenario: Checking
Given the node map
| a | b | | c | d | e |
And the ways
| nodes |
| ab |
| bc |
| cd |
| de |
When I route I should get
| from | to | route | summary |
| a | e | ab,bc,cd,de,de | ab, bc |
| e | a | de,cd,bc,ab,ab | de, bc |
| a | b | ab,ab | ab |
| b | d | bc,cd,cd | bc, cd |
@smallest
Scenario: Check handling empty values
Given the node map
| a | b | | c | | d | f |
| | | | | | e |
And the ways
| nodes | name |
| ab | ab |
| bc | bc |
| cd | |
| de | de |
| df | df |
When I route I should get
| from | to | route | summary |
| e | a | de,,bc,ab,ab | de, bc |
@smallest @todo
Scenario: Summaries when routing on a simple network
Given the node map
| a | b |
And the ways
| nodes |
| ab |
When I route I should get
| from | to | route | summary |
| a | b | ab,ab | ab |
| b | a | ab,ab | ab |
@repeated
Scenario: Check handling empty values
Given the node map
| f | | | x | | |
| b | c | d | e | 1 | g |
| a | | | y | | |
And the ways
| nodes | name | # |
| ab | first | |
| bc | first | |
| cd | first | |
| deg | second | |
| bf | third | |
| xey | cross |we need this because phantom node segments are not considered for the summary |
When I route I should get
| from | to | route | summary |
| a | 1 | first,first,second,second | first, second |
@@ -1,37 +0,0 @@
@routing @speed @traffic
Feature: Traffic - turn penalties applied to turn onto which a phantom node snaps
Background: Simple map with phantom nodes
Given the node map
| | 1 | | 2 | | 3 | |
| a:1 | | b:2 | | c:3 | | d:4 |
| | | | | | | |
| | | e:5 | | f:6 | | g:7 |
And the ways
| nodes | highway |
| ab | primary |
| bc | primary |
| cd | primary |
| be | primary |
| cf | primary |
| dg | primary |
And the profile "testbot"
# Since testbot doesn't have turn penalties, a penalty from file of 0 should produce a neutral effect
And the extract extra arguments "--generate-edge-lookup"
Scenario: Weighting based on turn penalty file, with an extreme negative value -- clamps and does not fail
Given the turn penalty file
"""
1,2,5,0
3,4,7,-20
"""
And the contract extra arguments "--turn-penalty-file penalties.csv"
When I route I should get
| from | to | route | speed | time |
| a | e | ab,be,be | 36 km/h | 40s +-1 |
| 1 | e | ab,be,be | 36 km/h | 30s +-1 |
| b | f | bc,cf,cf | 36 km/h | 40s +-1 |
| 2 | f | bc,cf,cf | 36 km/h | 30s +-1 |
| c | g | cd,dg,dg | 71 km/h | 20s +-1 |
| 3 | g | cd,dg,dg | 54 km/h | 20s +-1 |
-41
View File
@@ -148,47 +148,6 @@ Feature: Via points
| a,d,c | abc,bd,bd,bd,abc,abc |
| c,d,a | abc,bd,bd,bd,abc,abc |
# See issue #2349
Scenario: Via point at a dead end with oneway
Given the node map
| a | b | c |
| | d | |
| | e | |
And the ways
| nodes | oneway |
| abc | no |
| bd | no |
| ed | yes |
When I route I should get
| waypoints | route |
| a,d,c | abc,bd,bd,bd,abc,abc |
| c,d,a | abc,bd,bd,bd,abc,abc |
# See issue #2349
@bug
Scenario: Via point at a dead end with oneway
Given the node map
| a | b | c |
| | d | |
| | e | g |
| | f | |
And the ways
| nodes | oneway |
| abc | no |
| bd | no |
| ed | yes |
| dg | yes |
| ef | no |
| fg | yes |
When I route I should get
| waypoints | route |
| a,d,c | abc,bd,bd,bd,abc,abc |
| c,d,a | abc,bd,bd,bd,abc,abc |
# See issue #1896
Scenario: Via point at a dead end with barrier
Given the profile "car"
-1
View File
@@ -84,7 +84,6 @@ class Contractor
const std::string &edge_segment_lookup_path,
const std::string &edge_penalty_path,
const std::vector<std::string> &segment_speed_path,
const std::vector<std::string> &turn_penalty_path,
const std::string &nodes_filename,
const std::string &geometry_filename,
const std::string &datasource_names_filename,
-1
View File
@@ -81,7 +81,6 @@ struct ContractorConfig
double core_factor;
std::vector<std::string> segment_speed_lookup_paths;
std::vector<std::string> turn_penalty_lookup_paths;
std::string datasource_indexes_path;
std::string datasource_names_path;
};
+8 -8
View File
@@ -17,9 +17,9 @@ namespace contractor
class IteratorbasedCRC32
{
public:
bool UsingHardware() const { return use_hardware_implementation; }
bool using_hardware() const { return use_hardware_implementation; }
IteratorbasedCRC32() : crc(0) { use_hardware_implementation = DetectHardwareSupport(); }
IteratorbasedCRC32() : crc(0) { use_hardware_implementation = detect_hardware_support(); }
template <class Iterator> unsigned operator()(Iterator iter, const Iterator end)
{
@@ -31,11 +31,11 @@ class IteratorbasedCRC32
if (use_hardware_implementation)
{
crc = ComputeInHardware(data, sizeof(value_type));
crc = compute_in_hardware(data, sizeof(value_type));
}
else
{
crc = ComputeInSoftware(data, sizeof(value_type));
crc = compute_in_software(data, sizeof(value_type));
}
++iter;
}
@@ -43,7 +43,7 @@ class IteratorbasedCRC32
}
private:
bool DetectHardwareSupport() const
bool detect_hardware_support() const
{
static const int sse42_bit = 0x00100000;
const unsigned ecx = cpuid();
@@ -51,14 +51,14 @@ class IteratorbasedCRC32
return sse42_found;
}
unsigned ComputeInSoftware(const char *str, unsigned len)
unsigned compute_in_software(const char *str, unsigned len)
{
crc_processor.process_bytes(str, len);
return crc_processor.checksum();
}
// adapted from http://byteworm.com/2010/10/13/crc32/
unsigned ComputeInHardware(const char *str, unsigned len)
unsigned compute_in_hardware(const char *str, unsigned len)
{
#if defined(__x86_64__)
unsigned q = len / sizeof(unsigned);
@@ -114,7 +114,7 @@ struct RangebasedCRC32
return crc32(std::begin(iterable), std::end(iterable));
}
bool UsingHardware() const { return crc32.UsingHardware(); }
bool using_hardware() const { return crc32.using_hardware(); }
private:
IteratorbasedCRC32 crc32;
+15 -15
View File
@@ -115,7 +115,7 @@ class GraphContractor
{
explicit ThreadDataContainer(int number_of_nodes) : number_of_nodes(number_of_nodes) {}
inline ContractorThreadData *GetThreadData()
inline ContractorThreadData *getThreadData()
{
bool exists = false;
auto &ref = data.local(exists);
@@ -302,7 +302,7 @@ class GraphContractor
[this, &node_priorities, &node_depth,
&thread_data_list](const tbb::blocked_range<int> &range)
{
ContractorThreadData *data = thread_data_list.GetThreadData();
ContractorThreadData *data = thread_data_list.getThreadData();
for (int x = range.begin(), end = range.end(); x != end; ++x)
{
node_priorities[x] =
@@ -424,7 +424,7 @@ class GraphContractor
[this, &node_priorities, &remaining_nodes,
&thread_data_list](const tbb::blocked_range<std::size_t> &range)
{
ContractorThreadData *data = thread_data_list.GetThreadData();
ContractorThreadData *data = thread_data_list.getThreadData();
// determine independent node set
for (auto i = range.begin(), end = range.end(); i != end; ++i)
{
@@ -481,7 +481,7 @@ class GraphContractor
[this, &remaining_nodes,
&thread_data_list](const tbb::blocked_range<std::size_t> &range)
{
ContractorThreadData *data = thread_data_list.GetThreadData();
ContractorThreadData *data = thread_data_list.getThreadData();
for (int position = range.begin(), end = range.end();
position != end; ++position)
{
@@ -495,7 +495,7 @@ class GraphContractor
DeleteGrainSize),
[this, &remaining_nodes, &thread_data_list](const tbb::blocked_range<int> &range)
{
ContractorThreadData *data = thread_data_list.GetThreadData();
ContractorThreadData *data = thread_data_list.getThreadData();
for (int position = range.begin(), end = range.end(); position != end;
++position)
{
@@ -547,7 +547,7 @@ class GraphContractor
[this, &node_priorities, &remaining_nodes, &node_depth,
&thread_data_list](const tbb::blocked_range<int> &range)
{
ContractorThreadData *data = thread_data_list.GetThreadData();
ContractorThreadData *data = thread_data_list.getThreadData();
for (int position = range.begin(), end = range.end(); position != end;
++position)
{
@@ -561,7 +561,7 @@ class GraphContractor
number_of_contracted_nodes += end_independent_nodes_idx - begin_independent_nodes_idx;
remaining_nodes.resize(begin_independent_nodes_idx);
p.PrintStatus(number_of_contracted_nodes);
p.printStatus(number_of_contracted_nodes);
++current_level;
}
@@ -627,7 +627,7 @@ class GraphContractor
Edge new_edge;
for (const auto node : util::irange(0u, number_of_nodes))
{
p.PrintStatus(node);
p.printStatus(node);
for (auto edge : contractor_graph->GetAdjacentEdgeRange(node))
{
const NodeID target = contractor_graph->GetTarget(edge);
@@ -710,9 +710,9 @@ class GraphContractor
inline void Dijkstra(const int max_distance,
const unsigned number_of_targets,
const int max_nodes,
const int maxNodes,
ContractorThreadData &data,
const NodeID middle_node)
const NodeID middleNode)
{
ContractorHeap &heap = data.heap;
@@ -723,7 +723,7 @@ class GraphContractor
{
const NodeID node = heap.DeleteMin();
const auto distance = heap.GetKey(node);
if (++nodes > max_nodes)
if (++nodes > maxNodes)
{
return;
}
@@ -742,7 +742,7 @@ class GraphContractor
}
}
RelaxNode(node, middle_node, distance, heap);
RelaxNode(node, middleNode, distance, heap);
}
}
@@ -1032,7 +1032,7 @@ class GraphContractor
}
// tie breaking
if (std::abs(priority - target_priority) < std::numeric_limits<float>::epsilon() &&
Bias(node, target))
bias(node, target))
{
return false;
}
@@ -1061,7 +1061,7 @@ class GraphContractor
}
// tie breaking
if (std::abs(priority - target_priority) < std::numeric_limits<float>::epsilon() &&
Bias(node, target))
bias(node, target))
{
return false;
}
@@ -1071,7 +1071,7 @@ class GraphContractor
}
// This bias function takes up 22 assembly instructions in total on X86
inline bool Bias(const NodeID a, const NodeID b) const
inline bool bias(const NodeID a, const NodeID b) const
{
const unsigned short hasha = fast_hash(a);
const unsigned short hashb = fast_hash(b);
+2 -2
View File
@@ -33,8 +33,8 @@ namespace json
namespace detail
{
std::string instructionTypeToString(extractor::guidance::TurnType::Enum type);
std::string instructionModifierToString(extractor::guidance::DirectionModifier::Enum modifier);
std::string instructionTypeToString(extractor::guidance::TurnType type);
std::string instructionModifierToString(extractor::guidance::DirectionModifier modifier);
util::json::Array coordinateToLonLat(const util::Coordinate coordinate);
-1
View File
@@ -52,7 +52,6 @@ struct MatchParameters : public RouteParameters
{
MatchParameters()
: RouteParameters(false,
false,
false,
RouteParameters::GeometriesType::Polyline,
RouteParameters::OverviewType::Simplified,
+1 -26
View File
@@ -132,7 +132,6 @@ class RouteAPI : public BaseAPI
guidance::trimShortSegments(steps, leg_geometry);
leg.steps = guidance::postProcess(std::move(steps));
leg.steps = guidance::collapseTurns(std::move(leg.steps));
leg.steps = guidance::assignRelativeLocations(std::move(leg.steps), leg_geometry,
phantoms.source_phantom,
phantoms.target_phantom);
@@ -176,33 +175,9 @@ class RouteAPI : public BaseAPI
});
}
auto result = json::makeRoute(route,
return json::makeRoute(route,
json::makeRouteLegs(std::move(legs), std::move(step_geometries)),
std::move(json_overview));
if (parameters.annotation)
{
util::json::Array durations;
util::json::Array distances;
for (const auto idx : util::irange<std::size_t>(0UL, leg_geometries.size()))
{
auto &leg_geometry = leg_geometries[idx];
std::for_each(leg_geometry.annotations.begin(),
leg_geometry.annotations.end(),
[this, &durations, &distances](const guidance::LegGeometry::Annotation &step) {
durations.values.push_back(step.duration);
distances.values.push_back(step.distance);
});
}
util::json::Object details;
details.values["distance"] = std::move(distances);
details.values["duration"] = std::move(durations);
result.values["annotation"] = std::move(details);
}
return result;
}
const RouteParameters &parameters;
+1 -4
View File
@@ -72,20 +72,17 @@ struct RouteParameters : public BaseParameters
template <typename... Args>
RouteParameters(const bool steps_,
const bool alternatives_,
const bool annotation_,
const GeometriesType geometries_,
const OverviewType overview_,
const boost::optional<bool> continue_straight_,
Args... args_)
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
annotation{annotation_}, geometries{geometries_}, overview{overview_},
continue_straight{continue_straight_}
geometries{geometries_}, overview{overview_}, continue_straight{continue_straight_}
{
}
bool steps = false;
bool alternatives = false;
bool annotation = false;
GeometriesType geometries = GeometriesType::Polyline;
OverviewType overview = OverviewType::Simplified;
boost::optional<bool> continue_straight;
+3 -3
View File
@@ -15,9 +15,6 @@
#include <boost/algorithm/string/trim.hpp>
#include <boost/range/algorithm/copy.hpp>
namespace osrm
{
// RFC 4648 "The Base16, Base32, and Base64 Data Encodings"
// See: https://tools.ietf.org/html/rfc4648
@@ -39,6 +36,9 @@ using BinaryFromBase64 = boost::archive::iterators::transform_width<
6 // from a sequence of 6 bit
>;
} // ns detail
namespace osrm
{
namespace engine
{
+16 -27
View File
@@ -3,15 +3,13 @@
// Exposes all data access interfaces to the algorithms via base class ptr
#include "contractor/query_edge.hpp"
#include "engine/phantom_node.hpp"
#include "extractor/edge_based_node.hpp"
#include "extractor/external_memory_node.hpp"
#include "contractor/query_edge.hpp"
#include "engine/phantom_node.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "util/exception.hpp"
#include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp"
#include "util/integer_range.hpp"
#include "util/exception.hpp"
#include "util/string_util.hpp"
#include "util/typedefs.hpp"
@@ -19,9 +17,9 @@
#include <cstddef>
#include <string>
#include <utility>
#include <vector>
#include <utility>
#include <string>
namespace osrm
{
@@ -92,47 +90,47 @@ class BaseDataFacade
virtual extractor::TravelMode GetTravelModeForEdgeID(const unsigned id) const = 0;
virtual std::vector<RTreeLeaf> GetEdgesInBox(const util::Coordinate south_west,
const util::Coordinate north_east) const = 0;
const util::Coordinate north_east) = 0;
virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float max_distance,
const int bearing,
const int bearing_range) const = 0;
const int bearing_range) = 0;
virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float max_distance) const = 0;
const float max_distance) = 0;
virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results,
const double max_distance,
const int bearing,
const int bearing_range) const = 0;
const int bearing_range) = 0;
virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results,
const int bearing,
const int bearing_range) const = 0;
const int bearing_range) = 0;
virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, const unsigned max_results) const = 0;
NearestPhantomNodes(const util::Coordinate input_coordinate, const unsigned max_results) = 0;
virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results,
const double max_distance) const = 0;
const double max_distance) = 0;
virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate) const = 0;
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate) = 0;
virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance) const = 0;
const double max_distance) = 0;
virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance,
const int bearing,
const int bearing_range) const = 0;
const int bearing_range) = 0;
virtual std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
const util::Coordinate input_coordinate, const int bearing, const int bearing_range) const = 0;
const util::Coordinate input_coordinate, const int bearing, const int bearing_range) = 0;
virtual unsigned GetCheckSum() const = 0;
@@ -147,15 +145,6 @@ class BaseDataFacade
virtual std::string GetTimestamp() const = 0;
virtual bool GetContinueStraightDefault() const = 0;
virtual BearingClassID GetBearingClassID(const NodeID id) const = 0;
virtual util::guidance::BearingClass
GetBearingClass(const BearingClassID bearing_class_id) const = 0;
virtual EntryClassID GetEntryClassID(const EdgeID eid) const = 0;
virtual util::guidance::EntryClass GetEntryClass(const EntryClassID entry_class_id) const = 0;
};
}
}
+102 -158
View File
@@ -6,24 +6,20 @@
#include "engine/datafacade/datafacade_base.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp"
#include "engine/geospatial_query.hpp"
#include "extractor/compressed_edge_container.hpp"
#include "extractor/original_edge_data.hpp"
#include "extractor/profile_properties.hpp"
#include "extractor/query_node.hpp"
#include "storage/storage_config.hpp"
#include "util/graph_loader.hpp"
#include "util/io.hpp"
#include "util/range_table.hpp"
#include "util/rectangle.hpp"
#include "contractor/query_edge.hpp"
#include "util/shared_memory_vector_wrapper.hpp"
#include "util/simple_logger.hpp"
#include "util/static_graph.hpp"
#include "util/static_rtree.hpp"
#include "util/typedefs.hpp"
#include "util/range_table.hpp"
#include "util/graph_loader.hpp"
#include "util/simple_logger.hpp"
#include "util/rectangle.hpp"
#include "extractor/compressed_edge_container.hpp"
#include "osrm/coordinate.hpp"
@@ -59,8 +55,8 @@ class InternalDataFacade final : public BaseDataFacade
private:
using super = BaseDataFacade;
using QueryGraph = util::StaticGraph<typename super::EdgeData>;
using InputEdge = QueryGraph::InputEdge;
using RTreeLeaf = super::RTreeLeaf;
using InputEdge = typename QueryGraph::InputEdge;
using RTreeLeaf = typename super::RTreeLeaf;
using InternalRTree =
util::StaticRTree<RTreeLeaf, util::ShM<util::Coordinate, false>::vector, false>;
using InternalGeospatialQuery = GeospatialQuery<InternalRTree, BaseDataFacade>;
@@ -72,7 +68,7 @@ class InternalDataFacade final : public BaseDataFacade
std::unique_ptr<QueryGraph> m_query_graph;
std::string m_timestamp;
util::ShM<util::Coordinate, false>::vector m_coordinate_list;
std::shared_ptr<util::ShM<util::Coordinate, false>::vector> m_coordinate_list;
util::ShM<NodeID, false>::vector m_via_node_list;
util::ShM<unsigned, false>::vector m_name_ID_list;
util::ShM<extractor::guidance::TurnInstruction, false>::vector m_turn_instruction_list;
@@ -86,24 +82,12 @@ class InternalDataFacade final : public BaseDataFacade
util::ShM<std::string, false>::vector m_datasource_names;
extractor::ProfileProperties m_profile_properties;
std::unique_ptr<InternalRTree> m_static_rtree;
std::unique_ptr<InternalGeospatialQuery> m_geospatial_query;
boost::thread_specific_ptr<InternalRTree> m_static_rtree;
boost::thread_specific_ptr<InternalGeospatialQuery> m_geospatial_query;
boost::filesystem::path ram_index_path;
boost::filesystem::path file_index_path;
util::RangeTable<16, false> m_name_table;
// bearing classes by node based node
util::ShM<BearingClassID, false>::vector m_bearing_class_id_table;
// entry class IDs by edge based egde
util::ShM<EntryClassID, false>::vector m_entry_class_id_list;
// the look-up table for entry classes. An entry class lists the possibility of entry for all
// available turns. For every turn, there is an associated entry class.
util::ShM<util::guidance::EntryClass, false>::vector m_entry_class_table;
// the look-up table for distinct bearing classes. A bearing class lists the available bearings
// at an intersection
util::RangeTable<16, false> m_bearing_ranges_table;
util::ShM<DiscreteBearing, false>::vector m_bearing_values_table;
void LoadProfileProperties(const boost::filesystem::path &properties_path)
{
boost::filesystem::ifstream in_stream(properties_path);
@@ -112,8 +96,7 @@ class InternalDataFacade final : public BaseDataFacade
throw util::exception("Could not open " + properties_path.string() + " for reading.");
}
in_stream.read(reinterpret_cast<char *>(&m_profile_properties),
sizeof(m_profile_properties));
in_stream.read(reinterpret_cast<char*>(&m_profile_properties), sizeof(m_profile_properties));
}
void LoadTimestamp(const boost::filesystem::path &timestamp_path)
@@ -129,8 +112,8 @@ class InternalDataFacade final : public BaseDataFacade
void LoadGraph(const boost::filesystem::path &hsgr_path)
{
util::ShM<QueryGraph::NodeArrayEntry, false>::vector node_list;
util::ShM<QueryGraph::EdgeArrayEntry, false>::vector edge_list;
typename util::ShM<typename QueryGraph::NodeArrayEntry, false>::vector node_list;
typename util::ShM<typename QueryGraph::EdgeArrayEntry, false>::vector edge_list;
util::SimpleLogger().Write() << "loading graph from " << hsgr_path.string();
@@ -155,12 +138,12 @@ class InternalDataFacade final : public BaseDataFacade
extractor::QueryNode current_node;
unsigned number_of_coordinates = 0;
nodes_input_stream.read((char *)&number_of_coordinates, sizeof(unsigned));
m_coordinate_list.resize(number_of_coordinates);
m_coordinate_list = std::make_shared<std::vector<util::Coordinate>>(number_of_coordinates);
for (unsigned i = 0; i < number_of_coordinates; ++i)
{
nodes_input_stream.read((char *)&current_node, sizeof(extractor::QueryNode));
m_coordinate_list[i] = util::Coordinate(current_node.lon, current_node.lat);
BOOST_ASSERT(m_coordinate_list[i].IsValid());
m_coordinate_list->at(i) = util::Coordinate(current_node.lon, current_node.lat);
BOOST_ASSERT(m_coordinate_list->at(i).IsValid());
}
boost::filesystem::ifstream edges_input_stream(edges_file, std::ios::binary);
@@ -170,7 +153,6 @@ class InternalDataFacade final : public BaseDataFacade
m_name_ID_list.resize(number_of_edges);
m_turn_instruction_list.resize(number_of_edges);
m_travel_mode_list.resize(number_of_edges);
m_entry_class_id_list.resize(number_of_edges);
extractor::OriginalEdgeData current_edge_data;
for (unsigned i = 0; i < number_of_edges; ++i)
@@ -181,7 +163,6 @@ class InternalDataFacade final : public BaseDataFacade
m_name_ID_list[i] = current_edge_data.name_id;
m_turn_instruction_list[i] = current_edge_data.turn_instruction;
m_travel_mode_list[i] = current_edge_data.travel_mode;
m_entry_class_id_list[i] = current_edge_data.entry_classid;
}
}
@@ -242,8 +223,7 @@ class InternalDataFacade final : public BaseDataFacade
boost::filesystem::ifstream datasources_stream(datasource_indexes_file, std::ios::binary);
if (!datasources_stream)
{
throw util::exception("Could not open " + datasource_indexes_file.string() +
" for reading!");
throw util::exception("Could not open " + datasource_indexes_file.string() + " for reading!");
}
BOOST_ASSERT(datasources_stream);
@@ -260,8 +240,7 @@ class InternalDataFacade final : public BaseDataFacade
boost::filesystem::ifstream datasourcenames_stream(datasource_names_file, std::ios::binary);
if (!datasourcenames_stream)
{
throw util::exception("Could not open " + datasource_names_file.string() +
" for reading!");
throw util::exception("Could not open " + datasource_names_file.string() + " for reading!");
}
BOOST_ASSERT(datasourcenames_stream);
std::string name;
@@ -273,7 +252,7 @@ class InternalDataFacade final : public BaseDataFacade
void LoadRTree()
{
BOOST_ASSERT_MSG(!m_coordinate_list.empty(), "coordinates must be loaded before r-tree");
BOOST_ASSERT_MSG(!m_coordinate_list->empty(), "coordinates must be loaded before r-tree");
m_static_rtree.reset(new InternalRTree(ram_index_path, file_index_path, m_coordinate_list));
m_geospatial_query.reset(
@@ -297,52 +276,6 @@ class InternalDataFacade final : public BaseDataFacade
}
}
void LoadIntersectionClasses(const boost::filesystem::path &intersection_class_file)
{
std::ifstream intersection_stream(intersection_class_file.string(), std::ios::binary);
if (!intersection_stream)
throw util::exception("Could not open " + intersection_class_file.string() +
" for reading.");
if (!util::readAndCheckFingerprint(intersection_stream))
throw util::exception("Fingeprint does not match in " +
intersection_class_file.string());
{
util::SimpleLogger().Write(logINFO) << "Loading Bearing Class IDs";
std::vector<BearingClassID> bearing_class_id;
if (!util::deserializeVector(intersection_stream, bearing_class_id))
throw util::exception("Reading from " + intersection_class_file.string() + " failed.");
m_bearing_class_id_table.resize(bearing_class_id.size());
std::copy(bearing_class_id.begin(), bearing_class_id.end(),
&m_bearing_class_id_table[0]);
}
{
util::SimpleLogger().Write(logINFO) << "Loading Bearing Classes";
// read the range table
intersection_stream >> m_bearing_ranges_table;
std::vector<util::guidance::BearingClass> bearing_classes;
// and the actual bearing values
std::uint64_t num_bearings;
intersection_stream >> 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);
if (!static_cast<bool>(intersection_stream))
throw util::exception("Reading from " + intersection_class_file.string() + " failed.");
}
{
util::SimpleLogger().Write(logINFO) << "Loading Entry Classes";
std::vector<util::guidance::EntryClass> entry_classes;
if (!util::deserializeVector(intersection_stream, entry_classes))
throw util::exception("Reading from " + intersection_class_file.string() + " failed.");
m_entry_class_table.resize(entry_classes.size());
std::copy(entry_classes.begin(), entry_classes.end(), &m_entry_class_table[0]);
}
}
public:
virtual ~InternalDataFacade()
{
@@ -350,7 +283,7 @@ class InternalDataFacade final : public BaseDataFacade
m_geospatial_query.reset();
}
explicit InternalDataFacade(const storage::StorageConfig &config)
explicit InternalDataFacade(const storage::StorageConfig& config)
{
ram_index_path = config.ram_index_path;
file_index_path = config.file_index_path;
@@ -368,7 +301,8 @@ class InternalDataFacade final : public BaseDataFacade
LoadGeometries(config.geometries_path);
util::SimpleLogger().Write() << "loading datasource info";
LoadDatasourceInfo(config.datasource_names_path, config.datasource_indexes_path);
LoadDatasourceInfo(config.datasource_names_path,
config.datasource_indexes_path);
util::SimpleLogger().Write() << "loading timestamp";
LoadTimestamp(config.timestamp_path);
@@ -378,12 +312,6 @@ class InternalDataFacade final : public BaseDataFacade
util::SimpleLogger().Write() << "loading street names";
LoadStreetNames(config.names_data_path);
util::SimpleLogger().Write() << "loading rtree";
LoadRTree();
util::SimpleLogger().Write() << "loading intersection class data";
LoadIntersectionClasses(config.intersection_class_path);
}
// search graph access
@@ -432,7 +360,7 @@ class InternalDataFacade final : public BaseDataFacade
// node and edge information access
util::Coordinate GetCoordinateOfNode(const unsigned id) const override final
{
return m_coordinate_list[id];
return m_coordinate_list->at(id);
}
extractor::guidance::TurnInstruction
@@ -447,9 +375,13 @@ class InternalDataFacade final : public BaseDataFacade
}
std::vector<RTreeLeaf> GetEdgesInBox(const util::Coordinate south_west,
const util::Coordinate north_east) const override final
const util::Coordinate north_east) override final
{
BOOST_ASSERT(m_geospatial_query.get());
if (!m_static_rtree.get())
{
LoadRTree();
BOOST_ASSERT(m_geospatial_query.get());
}
const util::RectangleInt2D bbox{south_west.lon, north_east.lon, south_west.lat,
north_east.lat};
return m_geospatial_query->Search(bbox);
@@ -457,9 +389,13 @@ class InternalDataFacade final : public BaseDataFacade
std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float max_distance) const override final
const float max_distance) override final
{
BOOST_ASSERT(m_geospatial_query.get());
if (!m_static_rtree.get())
{
LoadRTree();
BOOST_ASSERT(m_geospatial_query.get());
}
return m_geospatial_query->NearestPhantomNodesInRange(input_coordinate, max_distance);
}
@@ -468,9 +404,13 @@ class InternalDataFacade final : public BaseDataFacade
NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float max_distance,
const int bearing,
const int bearing_range) const override final
const int bearing_range) override final
{
BOOST_ASSERT(m_geospatial_query.get());
if (!m_static_rtree.get())
{
LoadRTree();
BOOST_ASSERT(m_geospatial_query.get());
}
return m_geospatial_query->NearestPhantomNodesInRange(input_coordinate, max_distance,
bearing, bearing_range);
@@ -478,9 +418,13 @@ class InternalDataFacade final : public BaseDataFacade
std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results) const override final
const unsigned max_results) override final
{
BOOST_ASSERT(m_geospatial_query.get());
if (!m_static_rtree.get())
{
LoadRTree();
BOOST_ASSERT(m_geospatial_query.get());
}
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results);
}
@@ -488,9 +432,13 @@ class InternalDataFacade final : public BaseDataFacade
std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results,
const double max_distance) const override final
const double max_distance) override final
{
BOOST_ASSERT(m_geospatial_query.get());
if (!m_static_rtree.get())
{
LoadRTree();
BOOST_ASSERT(m_geospatial_query.get());
}
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, max_distance);
}
@@ -499,9 +447,13 @@ class InternalDataFacade final : public BaseDataFacade
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results,
const int bearing,
const int bearing_range) const override final
const int bearing_range) override final
{
BOOST_ASSERT(m_geospatial_query.get());
if (!m_static_rtree.get())
{
LoadRTree();
BOOST_ASSERT(m_geospatial_query.get());
}
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, bearing,
bearing_range);
@@ -512,27 +464,40 @@ class InternalDataFacade final : public BaseDataFacade
const unsigned max_results,
const double max_distance,
const int bearing,
const int bearing_range) const override final
const int bearing_range) override final
{
BOOST_ASSERT(m_geospatial_query.get());
if (!m_static_rtree.get())
{
LoadRTree();
BOOST_ASSERT(m_geospatial_query.get());
}
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, max_distance,
bearing, bearing_range);
}
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
const util::Coordinate input_coordinate, const double max_distance) const override final
std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance) override final
{
BOOST_ASSERT(m_geospatial_query.get());
if (!m_static_rtree.get())
{
LoadRTree();
BOOST_ASSERT(m_geospatial_query.get());
}
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, max_distance);
}
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
const util::Coordinate input_coordinate) const override final
const util::Coordinate input_coordinate) override final
{
BOOST_ASSERT(m_geospatial_query.get());
if (!m_static_rtree.get())
{
LoadRTree();
BOOST_ASSERT(m_geospatial_query.get());
}
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate);
@@ -542,9 +507,13 @@ class InternalDataFacade final : public BaseDataFacade
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance,
const int bearing,
const int bearing_range) const override final
const int bearing_range) override final
{
BOOST_ASSERT(m_geospatial_query.get());
if (!m_static_rtree.get())
{
LoadRTree();
BOOST_ASSERT(m_geospatial_query.get());
}
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, max_distance, bearing, bearing_range);
@@ -553,9 +522,13 @@ class InternalDataFacade final : public BaseDataFacade
std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const int bearing,
const int bearing_range) const override final
const int bearing_range) override final
{
BOOST_ASSERT(m_geospatial_query.get());
if (!m_static_rtree.get())
{
LoadRTree();
BOOST_ASSERT(m_geospatial_query.get());
}
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, bearing, bearing_range);
@@ -615,7 +588,8 @@ class InternalDataFacade final : public BaseDataFacade
result_nodes.clear();
result_nodes.reserve(end - begin);
std::for_each(m_geometry_list.begin() + begin, m_geometry_list.begin() + end,
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge) {
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge)
{
result_nodes.emplace_back(edge.node_id);
});
}
@@ -630,7 +604,8 @@ class InternalDataFacade final : public BaseDataFacade
result_weights.clear();
result_weights.reserve(end - begin);
std::for_each(m_geometry_list.begin() + begin, m_geometry_list.begin() + end,
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge) {
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge)
{
result_weights.emplace_back(edge.weight);
});
}
@@ -657,9 +632,11 @@ class InternalDataFacade final : public BaseDataFacade
}
else
{
std::for_each(
m_datasource_list.begin() + begin, m_datasource_list.begin() + end,
[&](const uint8_t &datasource_id) { result_datasources.push_back(datasource_id); });
std::for_each(m_datasource_list.begin() + begin, m_datasource_list.begin() + end,
[&](const uint8_t &datasource_id)
{
result_datasources.push_back(datasource_id);
});
}
}
@@ -672,40 +649,7 @@ class InternalDataFacade final : public BaseDataFacade
std::string GetTimestamp() const override final { return m_timestamp; }
bool GetContinueStraightDefault() const override final
{
return m_profile_properties.continue_straight_at_waypoint;
}
BearingClassID GetBearingClassID(const NodeID nid) const override final
{
return m_bearing_class_id_table.at(nid);
}
util::guidance::BearingClass
GetBearingClass(const BearingClassID bearing_class_id) const override final
{
BOOST_ASSERT(bearing_class_id != INVALID_BEARING_CLASSID);
auto range = m_bearing_ranges_table.GetRange(bearing_class_id);
util::guidance::BearingClass result;
for (auto itr = m_bearing_values_table.begin() + range.front();
itr != m_bearing_values_table.begin() + range.back() + 1; ++itr)
result.add(*itr);
return result;
}
EntryClassID GetEntryClassID(const EdgeID eid) const override final
{
return m_entry_class_id_list.at(eid);
}
util::guidance::EntryClass GetEntryClass(const EntryClassID entry_class_id) const override final
{
return m_entry_class_table.at(entry_class_id);
}
bool GetContinueStraightDefault() const override final { return m_profile_properties.continue_straight_at_waypoint; }
};
}
}
+132 -165
View File
@@ -7,20 +7,16 @@
#include "storage/shared_datatype.hpp"
#include "storage/shared_memory.hpp"
#include "extractor/compressed_edge_container.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "extractor/profile_properties.hpp"
#include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp"
#include "engine/geospatial_query.hpp"
#include "util/make_unique.hpp"
#include "util/range_table.hpp"
#include "util/rectangle.hpp"
#include "util/simple_logger.hpp"
#include "util/static_graph.hpp"
#include "util/static_rtree.hpp"
#include "util/typedefs.hpp"
#include "util/make_unique.hpp"
#include "util/simple_logger.hpp"
#include "util/rectangle.hpp"
#include <cstddef>
@@ -33,9 +29,9 @@
#include <vector>
#include <boost/assert.hpp>
#include <boost/thread/lock_guard.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/tss.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/lock_guard.hpp>
namespace osrm
{
@@ -50,15 +46,16 @@ class SharedDataFacade final : public BaseDataFacade
private:
using super = BaseDataFacade;
using QueryGraph = util::StaticGraph<EdgeData, true>;
using GraphNode = QueryGraph::NodeArrayEntry;
using GraphEdge = QueryGraph::EdgeArrayEntry;
using IndexBlock = util::RangeTable<16, true>::BlockT;
using InputEdge = QueryGraph::InputEdge;
using RTreeLeaf = super::RTreeLeaf;
using GraphNode = typename QueryGraph::NodeArrayEntry;
using GraphEdge = typename QueryGraph::EdgeArrayEntry;
using NameIndexBlock = typename util::RangeTable<16, true>::BlockT;
using InputEdge = typename QueryGraph::InputEdge;
using RTreeLeaf = typename super::RTreeLeaf;
using SharedRTree =
util::StaticRTree<RTreeLeaf, util::ShM<util::Coordinate, true>::vector, true>;
using SharedGeospatialQuery = GeospatialQuery<SharedRTree, BaseDataFacade>;
using RTreeNode = SharedRTree::TreeNode;
using TimeStampedRTreePair = std::pair<unsigned, std::shared_ptr<SharedRTree>>;
using RTreeNode = typename SharedRTree::TreeNode;
storage::SharedDataLayout *data_layout;
char *shared_memory;
@@ -73,9 +70,9 @@ class SharedDataFacade final : public BaseDataFacade
std::unique_ptr<storage::SharedMemory> m_layout_memory;
std::unique_ptr<storage::SharedMemory> m_large_memory;
std::string m_timestamp;
extractor::ProfileProperties *m_profile_properties;
extractor::ProfileProperties* m_profile_properties;
util::ShM<util::Coordinate, true>::vector m_coordinate_list;
std::shared_ptr<util::ShM<util::Coordinate, true>::vector> m_coordinate_list;
util::ShM<NodeID, true>::vector m_via_node_list;
util::ShM<unsigned, true>::vector m_name_ID_list;
util::ShM<extractor::guidance::TurnInstruction, true>::vector m_turn_instruction_list;
@@ -91,24 +88,12 @@ class SharedDataFacade final : public BaseDataFacade
util::ShM<std::size_t, true>::vector m_datasource_name_offsets;
util::ShM<std::size_t, true>::vector m_datasource_name_lengths;
std::unique_ptr<SharedRTree> m_static_rtree;
std::unique_ptr<SharedGeospatialQuery> m_geospatial_query;
boost::thread_specific_ptr<std::pair<unsigned, std::shared_ptr<SharedRTree>>> m_static_rtree;
boost::thread_specific_ptr<SharedGeospatialQuery> m_geospatial_query;
boost::filesystem::path file_index_path;
std::shared_ptr<util::RangeTable<16, true>> m_name_table;
// bearing classes by node based node
util::ShM<BearingClassID, true>::vector m_bearing_class_id_table;
// entry class IDs
util::ShM<EntryClassID, true>::vector m_entry_class_id_list;
// the look-up table for entry classes. An entry class lists the possibility of entry for all
// available turns. Such a class id is stored with every edge.
util::ShM<util::guidance::EntryClass, true>::vector m_entry_class_table;
// the look-up table for distinct bearing classes. A bearing class lists the available bearings
// at an intersection
std::shared_ptr<util::RangeTable<16, true>> m_bearing_ranges_table;
util::ShM<DiscreteBearing, true>::vector m_bearing_values_table;
void LoadChecksum()
{
m_check_sum = *data_layout->GetBlockPtr<unsigned>(shared_memory,
@@ -118,8 +103,8 @@ class SharedDataFacade final : public BaseDataFacade
void LoadProfileProperties()
{
m_profile_properties = data_layout->GetBlockPtr<extractor::ProfileProperties>(
shared_memory, storage::SharedDataLayout::PROPERTIES);
m_profile_properties =
data_layout->GetBlockPtr<extractor::ProfileProperties>(shared_memory, storage::SharedDataLayout::PROPERTIES);
}
void LoadTimestamp()
@@ -134,15 +119,17 @@ class SharedDataFacade final : public BaseDataFacade
void LoadRTree()
{
BOOST_ASSERT_MSG(!m_coordinate_list.empty(), "coordinates must be loaded before r-tree");
BOOST_ASSERT_MSG(!m_coordinate_list->empty(), "coordinates must be loaded before r-tree");
auto tree_ptr = data_layout->GetBlockPtr<RTreeNode>(
shared_memory, storage::SharedDataLayout::R_SEARCH_TREE);
m_static_rtree.reset(new SharedRTree(
tree_ptr, data_layout->num_entries[storage::SharedDataLayout::R_SEARCH_TREE],
file_index_path, m_coordinate_list));
m_static_rtree.reset(new TimeStampedRTreePair(
CURRENT_TIMESTAMP,
util::make_unique<SharedRTree>(
tree_ptr, data_layout->num_entries[storage::SharedDataLayout::R_SEARCH_TREE],
file_index_path, m_coordinate_list)));
m_geospatial_query.reset(
new SharedGeospatialQuery(*m_static_rtree, m_coordinate_list, *this));
new SharedGeospatialQuery(*m_static_rtree->second, m_coordinate_list, *this));
}
void LoadGraph()
@@ -153,9 +140,9 @@ class SharedDataFacade final : public BaseDataFacade
auto graph_edges_ptr = data_layout->GetBlockPtr<GraphEdge>(
shared_memory, storage::SharedDataLayout::GRAPH_EDGE_LIST);
util::ShM<GraphNode, true>::vector node_list(
typename util::ShM<GraphNode, true>::vector node_list(
graph_nodes_ptr, data_layout->num_entries[storage::SharedDataLayout::GRAPH_NODE_LIST]);
util::ShM<GraphEdge, true>::vector edge_list(
typename util::ShM<GraphEdge, true>::vector edge_list(
graph_edges_ptr, data_layout->num_entries[storage::SharedDataLayout::GRAPH_EDGE_LIST]);
m_query_graph.reset(new QueryGraph(node_list, edge_list));
}
@@ -164,42 +151,37 @@ class SharedDataFacade final : public BaseDataFacade
{
auto coordinate_list_ptr = data_layout->GetBlockPtr<util::Coordinate>(
shared_memory, storage::SharedDataLayout::COORDINATE_LIST);
m_coordinate_list.reset(coordinate_list_ptr,
m_coordinate_list = util::make_unique<util::ShM<util::Coordinate, true>::vector>(
coordinate_list_ptr,
data_layout->num_entries[storage::SharedDataLayout::COORDINATE_LIST]);
auto travel_mode_list_ptr = data_layout->GetBlockPtr<extractor::TravelMode>(
shared_memory, storage::SharedDataLayout::TRAVEL_MODE);
util::ShM<extractor::TravelMode, true>::vector travel_mode_list(
typename util::ShM<extractor::TravelMode, true>::vector travel_mode_list(
travel_mode_list_ptr, data_layout->num_entries[storage::SharedDataLayout::TRAVEL_MODE]);
m_travel_mode_list = std::move(travel_mode_list);
auto turn_instruction_list_ptr =
data_layout->GetBlockPtr<extractor::guidance::TurnInstruction>(
shared_memory, storage::SharedDataLayout::TURN_INSTRUCTION);
util::ShM<extractor::guidance::TurnInstruction, true>::vector turn_instruction_list(
turn_instruction_list_ptr,
data_layout->num_entries[storage::SharedDataLayout::TURN_INSTRUCTION]);
typename util::ShM<extractor::guidance::TurnInstruction, true>::vector
turn_instruction_list(
turn_instruction_list_ptr,
data_layout->num_entries[storage::SharedDataLayout::TURN_INSTRUCTION]);
m_turn_instruction_list = std::move(turn_instruction_list);
auto name_id_list_ptr = data_layout->GetBlockPtr<unsigned>(
shared_memory, storage::SharedDataLayout::NAME_ID_LIST);
util::ShM<unsigned, true>::vector name_id_list(
typename util::ShM<unsigned, true>::vector name_id_list(
name_id_list_ptr, data_layout->num_entries[storage::SharedDataLayout::NAME_ID_LIST]);
m_name_ID_list = std::move(name_id_list);
auto entry_class_id_list_ptr = data_layout->GetBlockPtr<EntryClassID>(
shared_memory, storage::SharedDataLayout::ENTRY_CLASSID);
typename util::ShM<EntryClassID, true>::vector entry_class_id_list(
entry_class_id_list_ptr,
data_layout->num_entries[storage::SharedDataLayout::ENTRY_CLASSID]);
m_entry_class_id_list = std::move(entry_class_id_list);
}
void LoadViaNodeList()
{
auto via_node_list_ptr = data_layout->GetBlockPtr<NodeID>(
shared_memory, storage::SharedDataLayout::VIA_NODE_LIST);
util::ShM<NodeID, true>::vector via_node_list(
typename util::ShM<NodeID, true>::vector via_node_list(
via_node_list_ptr, data_layout->num_entries[storage::SharedDataLayout::VIA_NODE_LIST]);
m_via_node_list = std::move(via_node_list);
}
@@ -208,16 +190,16 @@ class SharedDataFacade final : public BaseDataFacade
{
auto offsets_ptr = data_layout->GetBlockPtr<unsigned>(
shared_memory, storage::SharedDataLayout::NAME_OFFSETS);
auto blocks_ptr = data_layout->GetBlockPtr<IndexBlock>(
auto blocks_ptr = data_layout->GetBlockPtr<NameIndexBlock>(
shared_memory, storage::SharedDataLayout::NAME_BLOCKS);
util::ShM<unsigned, true>::vector name_offsets(
typename util::ShM<unsigned, true>::vector name_offsets(
offsets_ptr, data_layout->num_entries[storage::SharedDataLayout::NAME_OFFSETS]);
util::ShM<IndexBlock, true>::vector name_blocks(
typename util::ShM<NameIndexBlock, true>::vector name_blocks(
blocks_ptr, data_layout->num_entries[storage::SharedDataLayout::NAME_BLOCKS]);
auto names_list_ptr = data_layout->GetBlockPtr<char>(
shared_memory, storage::SharedDataLayout::NAME_CHAR_LIST);
util::ShM<char, true>::vector names_char_list(
typename util::ShM<char, true>::vector names_char_list(
names_list_ptr, data_layout->num_entries[storage::SharedDataLayout::NAME_CHAR_LIST]);
m_name_table = util::make_unique<util::RangeTable<16, true>>(
name_offsets, name_blocks, static_cast<unsigned>(names_char_list.size()));
@@ -234,7 +216,7 @@ class SharedDataFacade final : public BaseDataFacade
auto core_marker_ptr = data_layout->GetBlockPtr<unsigned>(
shared_memory, storage::SharedDataLayout::CORE_MARKER);
util::ShM<bool, true>::vector is_core_node(
typename util::ShM<bool, true>::vector is_core_node(
core_marker_ptr, data_layout->num_entries[storage::SharedDataLayout::CORE_MARKER]);
m_is_core_node = std::move(is_core_node);
}
@@ -243,7 +225,7 @@ class SharedDataFacade final : public BaseDataFacade
{
auto geometries_index_ptr = data_layout->GetBlockPtr<unsigned>(
shared_memory, storage::SharedDataLayout::GEOMETRIES_INDEX);
util::ShM<unsigned, true>::vector geometry_begin_indices(
typename util::ShM<unsigned, true>::vector geometry_begin_indices(
geometries_index_ptr,
data_layout->num_entries[storage::SharedDataLayout::GEOMETRIES_INDEX]);
m_geometry_indices = std::move(geometry_begin_indices);
@@ -251,74 +233,40 @@ class SharedDataFacade final : public BaseDataFacade
auto geometries_list_ptr =
data_layout->GetBlockPtr<extractor::CompressedEdgeContainer::CompressedEdge>(
shared_memory, storage::SharedDataLayout::GEOMETRIES_LIST);
util::ShM<extractor::CompressedEdgeContainer::CompressedEdge, true>::vector geometry_list(
geometries_list_ptr,
data_layout->num_entries[storage::SharedDataLayout::GEOMETRIES_LIST]);
typename util::ShM<extractor::CompressedEdgeContainer::CompressedEdge, true>::vector
geometry_list(geometries_list_ptr,
data_layout->num_entries[storage::SharedDataLayout::GEOMETRIES_LIST]);
m_geometry_list = std::move(geometry_list);
auto datasources_list_ptr = data_layout->GetBlockPtr<uint8_t>(
shared_memory, storage::SharedDataLayout::DATASOURCES_LIST);
util::ShM<uint8_t, true>::vector datasources_list(
typename util::ShM<uint8_t, true>::vector datasources_list(
datasources_list_ptr,
data_layout->num_entries[storage::SharedDataLayout::DATASOURCES_LIST]);
m_datasource_list = std::move(datasources_list);
auto datasource_name_data_ptr = data_layout->GetBlockPtr<char>(
shared_memory, storage::SharedDataLayout::DATASOURCE_NAME_DATA);
util::ShM<char, true>::vector datasource_name_data(
typename util::ShM<char, true>::vector datasource_name_data(
datasource_name_data_ptr,
data_layout->num_entries[storage::SharedDataLayout::DATASOURCE_NAME_DATA]);
m_datasource_name_data = std::move(datasource_name_data);
auto datasource_name_offsets_ptr = data_layout->GetBlockPtr<std::size_t>(
shared_memory, storage::SharedDataLayout::DATASOURCE_NAME_OFFSETS);
util::ShM<std::size_t, true>::vector datasource_name_offsets(
typename util::ShM<std::size_t, true>::vector datasource_name_offsets(
datasource_name_offsets_ptr,
data_layout->num_entries[storage::SharedDataLayout::DATASOURCE_NAME_OFFSETS]);
m_datasource_name_offsets = std::move(datasource_name_offsets);
auto datasource_name_lengths_ptr = data_layout->GetBlockPtr<std::size_t>(
shared_memory, storage::SharedDataLayout::DATASOURCE_NAME_LENGTHS);
util::ShM<std::size_t, true>::vector datasource_name_lengths(
typename util::ShM<std::size_t, true>::vector datasource_name_lengths(
datasource_name_lengths_ptr,
data_layout->num_entries[storage::SharedDataLayout::DATASOURCE_NAME_LENGTHS]);
m_datasource_name_lengths = std::move(datasource_name_lengths);
}
void LoadIntersectionClasses()
{
auto bearing_class_id_ptr = data_layout->GetBlockPtr<BearingClassID>(
shared_memory, storage::SharedDataLayout::BEARING_CLASSID);
typename util::ShM<BearingClassID, true>::vector bearing_class_id_table(
bearing_class_id_ptr,
data_layout->num_entries[storage::SharedDataLayout::BEARING_CLASSID]);
m_bearing_class_id_table = std::move(bearing_class_id_table);
auto bearing_class_ptr = data_layout->GetBlockPtr<DiscreteBearing>(
shared_memory, storage::SharedDataLayout::BEARING_VALUES);
typename util::ShM<DiscreteBearing, true>::vector bearing_class_table(
bearing_class_ptr, data_layout->num_entries[storage::SharedDataLayout::BEARING_VALUES]);
m_bearing_values_table = std::move(bearing_class_table);
auto offsets_ptr = data_layout->GetBlockPtr<unsigned>(
shared_memory, storage::SharedDataLayout::BEARING_OFFSETS);
auto blocks_ptr = data_layout->GetBlockPtr<IndexBlock>(
shared_memory, storage::SharedDataLayout::BEARING_BLOCKS);
util::ShM<unsigned, true>::vector bearing_offsets(
offsets_ptr, data_layout->num_entries[storage::SharedDataLayout::BEARING_OFFSETS]);
util::ShM<IndexBlock, true>::vector bearing_blocks(
blocks_ptr, data_layout->num_entries[storage::SharedDataLayout::BEARING_BLOCKS]);
m_bearing_ranges_table = util::make_unique<util::RangeTable<16, true>>(
bearing_offsets, bearing_blocks, static_cast<unsigned>(m_bearing_values_table.size()));
auto entry_class_ptr = data_layout->GetBlockPtr<util::guidance::EntryClass>(
shared_memory, storage::SharedDataLayout::ENTRY_CLASS);
typename util::ShM<util::guidance::EntryClass, true>::vector entry_class_table(
entry_class_ptr, data_layout->num_entries[storage::SharedDataLayout::ENTRY_CLASS]);
m_entry_class_table = std::move(entry_class_table);
}
public:
virtual ~SharedDataFacade() {}
@@ -405,14 +353,15 @@ class SharedDataFacade final : public BaseDataFacade
LoadNames();
LoadCoreInformation();
LoadProfileProperties();
LoadRTree();
LoadIntersectionClasses();
util::SimpleLogger().Write() << "number of geometries: "
<< m_coordinate_list.size();
for (unsigned i = 0; i < m_coordinate_list.size(); ++i)
<< m_coordinate_list->size();
for (unsigned i = 0; i < m_coordinate_list->size(); ++i)
{
BOOST_ASSERT(GetCoordinateOfNode(i).IsValid());
if (!GetCoordinateOfNode(i).IsValid())
{
util::SimpleLogger().Write() << "coordinate " << i << " not valid";
}
}
}
util::SimpleLogger().Write(logDEBUG) << "Releasing exclusive lock";
@@ -465,7 +414,7 @@ class SharedDataFacade final : public BaseDataFacade
// node and edge information access
util::Coordinate GetCoordinateOfNode(const NodeID id) const override final
{
return m_coordinate_list[id];
return m_coordinate_list->at(id);
}
virtual void GetUncompressedGeometry(const EdgeID id,
@@ -477,7 +426,8 @@ class SharedDataFacade final : public BaseDataFacade
result_nodes.clear();
result_nodes.reserve(end - begin);
std::for_each(m_geometry_list.begin() + begin, m_geometry_list.begin() + end,
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge) {
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge)
{
result_nodes.emplace_back(edge.node_id);
});
}
@@ -492,7 +442,8 @@ class SharedDataFacade final : public BaseDataFacade
result_weights.clear();
result_weights.reserve(end - begin);
std::for_each(m_geometry_list.begin() + begin, m_geometry_list.begin() + end,
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge) {
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge)
{
result_weights.emplace_back(edge.weight);
});
}
@@ -514,9 +465,13 @@ class SharedDataFacade final : public BaseDataFacade
}
std::vector<RTreeLeaf> GetEdgesInBox(const util::Coordinate south_west,
const util::Coordinate north_east) const override final
const util::Coordinate north_east) override final
{
BOOST_ASSERT(m_geospatial_query.get());
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
{
LoadRTree();
BOOST_ASSERT(m_geospatial_query.get());
}
const util::RectangleInt2D bbox{south_west.lon, north_east.lon, south_west.lat,
north_east.lat};
return m_geospatial_query->Search(bbox);
@@ -524,9 +479,13 @@ class SharedDataFacade final : public BaseDataFacade
std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float max_distance) const override final
const float max_distance) override final
{
BOOST_ASSERT(m_geospatial_query.get());
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
{
LoadRTree();
BOOST_ASSERT(m_geospatial_query.get());
}
return m_geospatial_query->NearestPhantomNodesInRange(input_coordinate, max_distance);
}
@@ -535,9 +494,13 @@ class SharedDataFacade final : public BaseDataFacade
NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float max_distance,
const int bearing,
const int bearing_range) const override final
const int bearing_range) override final
{
BOOST_ASSERT(m_geospatial_query.get());
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
{
LoadRTree();
BOOST_ASSERT(m_geospatial_query.get());
}
return m_geospatial_query->NearestPhantomNodesInRange(input_coordinate, max_distance,
bearing, bearing_range);
@@ -545,9 +508,13 @@ class SharedDataFacade final : public BaseDataFacade
std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results) const override final
const unsigned max_results) override final
{
BOOST_ASSERT(m_geospatial_query.get());
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
{
LoadRTree();
BOOST_ASSERT(m_geospatial_query.get());
}
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results);
}
@@ -555,9 +522,13 @@ class SharedDataFacade final : public BaseDataFacade
std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results,
const double max_distance) const override final
const double max_distance) override final
{
BOOST_ASSERT(m_geospatial_query.get());
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
{
LoadRTree();
BOOST_ASSERT(m_geospatial_query.get());
}
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, max_distance);
}
@@ -566,9 +537,13 @@ class SharedDataFacade final : public BaseDataFacade
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results,
const int bearing,
const int bearing_range) const override final
const int bearing_range) override final
{
BOOST_ASSERT(m_geospatial_query.get());
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
{
LoadRTree();
BOOST_ASSERT(m_geospatial_query.get());
}
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, bearing,
bearing_range);
@@ -579,18 +554,26 @@ class SharedDataFacade final : public BaseDataFacade
const unsigned max_results,
const double max_distance,
const int bearing,
const int bearing_range) const override final
const int bearing_range) override final
{
BOOST_ASSERT(m_geospatial_query.get());
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
{
LoadRTree();
BOOST_ASSERT(m_geospatial_query.get());
}
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, max_distance,
bearing, bearing_range);
}
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
const util::Coordinate input_coordinate) const override final
const util::Coordinate input_coordinate) override final
{
BOOST_ASSERT(m_geospatial_query.get());
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
{
LoadRTree();
BOOST_ASSERT(m_geospatial_query.get());
}
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate);
@@ -598,9 +581,13 @@ class SharedDataFacade final : public BaseDataFacade
std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance) const override final
const double max_distance) override final
{
BOOST_ASSERT(m_geospatial_query.get());
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
{
LoadRTree();
BOOST_ASSERT(m_geospatial_query.get());
}
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, max_distance);
@@ -610,9 +597,13 @@ class SharedDataFacade final : public BaseDataFacade
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance,
const int bearing,
const int bearing_range) const override final
const int bearing_range) override final
{
BOOST_ASSERT(m_geospatial_query.get());
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
{
LoadRTree();
BOOST_ASSERT(m_geospatial_query.get());
}
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, max_distance, bearing, bearing_range);
@@ -621,9 +612,13 @@ class SharedDataFacade final : public BaseDataFacade
std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const int bearing,
const int bearing_range) const override final
const int bearing_range) override final
{
BOOST_ASSERT(m_geospatial_query.get());
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
{
LoadRTree();
BOOST_ASSERT(m_geospatial_query.get());
}
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, bearing, bearing_range);
@@ -689,9 +684,11 @@ class SharedDataFacade final : public BaseDataFacade
}
else
{
std::for_each(
m_datasource_list.begin() + begin, m_datasource_list.begin() + end,
[&](const uint8_t &datasource_id) { result_datasources.push_back(datasource_id); });
std::for_each(m_datasource_list.begin() + begin, m_datasource_list.begin() + end,
[&](const uint8_t &datasource_id)
{
result_datasources.push_back(datasource_id);
});
}
}
@@ -712,37 +709,7 @@ class SharedDataFacade final : public BaseDataFacade
std::string GetTimestamp() const override final { return m_timestamp; }
bool GetContinueStraightDefault() const override final
{
return m_profile_properties->continue_straight_at_waypoint;
}
BearingClassID GetBearingClassID(const NodeID id) const override final
{
return m_bearing_class_id_table.at(id);
}
util::guidance::BearingClass
GetBearingClass(const BearingClassID bearing_class_id) const override final
{
BOOST_ASSERT(bearing_class_id != INVALID_BEARING_CLASSID);
auto range = m_bearing_ranges_table->GetRange(bearing_class_id);
util::guidance::BearingClass result;
for (auto itr = m_bearing_values_table.begin() + range.front();
itr != m_bearing_values_table.begin() + range.back() + 1; ++itr)
result.add(*itr);
return result;
}
EntryClassID GetEntryClassID(const EdgeID eid) const override final
{
return m_entry_class_id_list.at(eid);
}
util::guidance::EntryClass GetEntryClass(const EntryClassID entry_class_id) const override final
{
return m_entry_class_table.at(entry_class_id);
}
bool GetContinueStraightDefault() const override final { return m_profile_properties->continue_straight_at_waypoint; }
};
}
}
+32 -32
View File
@@ -22,7 +22,7 @@ namespace engine
// Implements complex queries on top of an RTree and builds PhantomNodes from it.
//
// Only holds a weak reference on the RTree and coordinates!
// Only holds a weak reference on the RTree!
template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
{
using EdgeData = typename RTreeT::EdgeData;
@@ -31,9 +31,9 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
public:
GeospatialQuery(RTreeT &rtree_,
const CoordinateList &coordinates_,
std::shared_ptr<CoordinateList> coordinates_,
DataFacadeT &datafacade_)
: rtree(rtree_), coordinates(coordinates_), datafacade(datafacade_)
: rtree(rtree_), coordinates(std::move(coordinates_)), datafacade(datafacade_)
{
}
@@ -45,7 +45,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// Returns nearest PhantomNodes in the given bearing range within max_distance.
// Does not filter by small/big component!
std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, const double max_distance) const
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, const double max_distance)
{
auto results =
rtree.Nearest(input_coordinate,
@@ -56,7 +56,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
[this, max_distance, input_coordinate](const std::size_t,
const CandidateSegment &segment)
{
return CheckSegmentDistance(input_coordinate, segment, max_distance);
return checkSegmentDistance(input_coordinate, segment, max_distance);
});
return MakePhantomNodes(input_coordinate, results);
@@ -68,18 +68,18 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const double max_distance,
const int bearing,
const int bearing_range) const
const int bearing_range)
{
auto results = rtree.Nearest(
input_coordinate,
[this, bearing, bearing_range, max_distance](const CandidateSegment &segment)
{
return CheckSegmentBearing(segment, bearing, bearing_range);
return checkSegmentBearing(segment, bearing, bearing_range);
},
[this, max_distance, input_coordinate](const std::size_t,
const CandidateSegment &segment)
{
return CheckSegmentDistance(input_coordinate, segment, max_distance);
return checkSegmentDistance(input_coordinate, segment, max_distance);
});
return MakePhantomNodes(input_coordinate, results);
@@ -91,13 +91,13 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results,
const int bearing,
const int bearing_range) const
const int bearing_range)
{
auto results =
rtree.Nearest(input_coordinate,
[this, bearing, bearing_range](const CandidateSegment &segment)
{
return CheckSegmentBearing(segment, bearing, bearing_range);
return checkSegmentBearing(segment, bearing, bearing_range);
},
[max_results](const std::size_t num_results, const CandidateSegment &)
{
@@ -115,19 +115,19 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
const unsigned max_results,
const double max_distance,
const int bearing,
const int bearing_range) const
const int bearing_range)
{
auto results =
rtree.Nearest(input_coordinate,
[this, bearing, bearing_range](const CandidateSegment &segment)
{
return CheckSegmentBearing(segment, bearing, bearing_range);
return checkSegmentBearing(segment, bearing, bearing_range);
},
[this, max_distance, max_results, input_coordinate](
const std::size_t num_results, const CandidateSegment &segment)
{
return num_results >= max_results ||
CheckSegmentDistance(input_coordinate, segment, max_distance);
checkSegmentDistance(input_coordinate, segment, max_distance);
});
return MakePhantomNodes(input_coordinate, results);
@@ -136,7 +136,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// Returns max_results nearest PhantomNodes.
// Does not filter by small/big component!
std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, const unsigned max_results) const
NearestPhantomNodes(const util::Coordinate input_coordinate, const unsigned max_results)
{
auto results =
rtree.Nearest(input_coordinate,
@@ -157,7 +157,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results,
const double max_distance) const
const double max_distance)
{
auto results =
rtree.Nearest(input_coordinate,
@@ -169,7 +169,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
const std::size_t num_results, const CandidateSegment &segment)
{
return num_results >= max_results ||
CheckSegmentDistance(input_coordinate, segment, max_distance);
checkSegmentDistance(input_coordinate, segment, max_distance);
});
return MakePhantomNodes(input_coordinate, results);
@@ -179,7 +179,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// a second phantom node is return that is the nearest coordinate in a big component.
std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance) const
const double max_distance)
{
bool has_small_component = false;
bool has_big_component = false;
@@ -200,7 +200,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
input_coordinate](const std::size_t num_results, const CandidateSegment &segment)
{
return (num_results > 0 && has_big_component) ||
CheckSegmentDistance(input_coordinate, segment, max_distance);
checkSegmentDistance(input_coordinate, segment, max_distance);
});
if (results.size() == 0)
@@ -216,7 +216,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// Returns the nearest phantom node. If this phantom node is not from a big component
// a second phantom node is return that is the nearest coordinate in a big component.
std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate) const
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate)
{
bool has_small_component = false;
bool has_big_component = false;
@@ -251,7 +251,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// Returns the nearest phantom node. If this phantom node is not from a big component
// a second phantom node is return that is the nearest coordinate in a big component.
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
const util::Coordinate input_coordinate, const int bearing, const int bearing_range) const
const util::Coordinate input_coordinate, const int bearing, const int bearing_range)
{
bool has_small_component = false;
bool has_big_component = false;
@@ -266,7 +266,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
if (use_segment)
{
use_directions = CheckSegmentBearing(segment, bearing, bearing_range);
use_directions = checkSegmentBearing(segment, bearing, bearing_range);
if (use_directions.first || use_directions.second)
{
has_big_component = has_big_component || !segment.data.component.is_tiny;
@@ -297,7 +297,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance,
const int bearing,
const int bearing_range) const
const int bearing_range)
{
bool has_small_component = false;
bool has_big_component = false;
@@ -312,7 +312,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
if (use_segment)
{
use_directions = CheckSegmentBearing(segment, bearing, bearing_range);
use_directions = checkSegmentBearing(segment, bearing, bearing_range);
if (use_directions.first || use_directions.second)
{
has_big_component = has_big_component || !segment.data.component.is_tiny;
@@ -326,7 +326,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
input_coordinate](const std::size_t num_results, const CandidateSegment &segment)
{
return (num_results > 0 && has_big_component) ||
CheckSegmentDistance(input_coordinate, segment, max_distance);
checkSegmentDistance(input_coordinate, segment, max_distance);
});
if (results.size() == 0)
@@ -360,7 +360,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
double ratio;
const auto current_perpendicular_distance =
util::coordinate_calculation::perpendicularDistance(
coordinates[data.u], coordinates[data.v], input_coordinate,
coordinates->at(data.u), coordinates->at(data.v), input_coordinate,
point_on_segment, ratio);
// Find the node-based-edge that this belongs to, and directly
@@ -416,9 +416,9 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
return transformed;
}
bool CheckSegmentDistance(const Coordinate input_coordinate,
bool checkSegmentDistance(const Coordinate input_coordinate,
const CandidateSegment &segment,
const double max_distance) const
const double max_distance)
{
BOOST_ASSERT(segment.data.forward_segment_id.id != SPECIAL_SEGMENTID ||
!segment.data.forward_segment_id.enabled);
@@ -432,9 +432,9 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
max_distance;
}
std::pair<bool, bool> CheckSegmentBearing(const CandidateSegment &segment,
std::pair<bool, bool> checkSegmentBearing(const CandidateSegment &segment,
const int filter_bearing,
const int filter_bearing_range) const
const int filter_bearing_range)
{
BOOST_ASSERT(segment.data.forward_segment_id.id != SPECIAL_SEGMENTID ||
!segment.data.forward_segment_id.enabled);
@@ -442,7 +442,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
!segment.data.reverse_segment_id.enabled);
const double forward_edge_bearing = util::coordinate_calculation::bearing(
coordinates[segment.data.u], coordinates[segment.data.v]);
coordinates->at(segment.data.u), coordinates->at(segment.data.v));
const double backward_edge_bearing = (forward_edge_bearing + 180) > 360
? (forward_edge_bearing - 180)
@@ -459,8 +459,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
return std::make_pair(forward_bearing_valid, backward_bearing_valid);
}
const RTreeT &rtree;
const CoordinateList &coordinates;
RTreeT &rtree;
const std::shared_ptr<CoordinateList> coordinates;
DataFacadeT &datafacade;
};
}
+5 -11
View File
@@ -43,40 +43,34 @@ LegGeometry assembleGeometry(const DataFacadeT &facade,
geometry.segment_offsets.push_back(0);
geometry.locations.push_back(source_node.location);
auto cumulative_distance = 0.;
auto current_distance = 0.;
auto prev_coordinate = geometry.locations.front();
for (const auto &path_point : leg_data)
{
auto coordinate = facade.GetCoordinateOfNode(path_point.turn_via_node);
current_distance =
current_distance +=
util::coordinate_calculation::haversineDistance(prev_coordinate, coordinate);
cumulative_distance += current_distance;
// all changes to this check have to be matched with assemble_steps
if (path_point.turn_instruction.type != extractor::guidance::TurnType::NoTurn)
{
geometry.segment_distances.push_back(cumulative_distance);
geometry.segment_distances.push_back(current_distance);
geometry.segment_offsets.push_back(geometry.locations.size());
cumulative_distance = 0.;
current_distance = 0.;
}
prev_coordinate = coordinate;
geometry.annotations.emplace_back(LegGeometry::Annotation{current_distance, path_point.duration_until_turn / 10.});
geometry.locations.push_back(std::move(coordinate));
}
current_distance =
current_distance +=
util::coordinate_calculation::haversineDistance(prev_coordinate, target_node.location);
cumulative_distance += current_distance;
// segment leading to the target node
geometry.segment_distances.push_back(cumulative_distance);
geometry.annotations.emplace_back(LegGeometry::Annotation{current_distance, target_node.forward_weight / 10.});
geometry.segment_distances.push_back(current_distance);
geometry.segment_offsets.push_back(geometry.locations.size());
geometry.locations.push_back(target_node.location);
BOOST_ASSERT(geometry.segment_distances.size() == geometry.segment_offsets.size() - 1);
BOOST_ASSERT(geometry.locations.size() > geometry.segment_distances.size());
BOOST_ASSERT(geometry.annotations.size() == geometry.locations.size() - 1);
return geometry;
}
+3 -21
View File
@@ -34,7 +34,6 @@ struct NamedSegment
};
template <std::size_t SegmentNumber>
std::array<std::uint32_t, SegmentNumber> summarizeRoute(const std::vector<PathData> &route_data)
{
// merges segments with same name id
@@ -42,14 +41,7 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const std::vector<PathDa
{
auto out = segments.begin();
auto end = segments.end();
// Do nothing if we were given an empty array
if (out == end)
{
return end;
}
for (auto in = std::next(out); in != end; ++in)
for (auto in = segments.begin(); in != end; ++in)
{
if (in->name_id == out->name_id)
{
@@ -62,8 +54,7 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const std::vector<PathDa
*out = *in;
}
}
BOOST_ASSERT(out != end);
return ++out;
return out;
};
std::vector<NamedSegment> segments(route_data.size());
@@ -81,19 +72,10 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const std::vector<PathDa
});
auto new_end = collapse_segments(segments);
segments.resize(new_end - segments.begin());
// Filter out segments with an empty name (name_id == 0)
new_end = std::remove_if(segments.begin(), segments.end(), [](const NamedSegment &segment)
{
return segment.name_id == 0;
});
segments.resize(new_end - segments.begin());
// sort descending
std::sort(segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs)
{
return lhs.duration > rhs.duration ||
(lhs.duration == rhs.duration && lhs.position < rhs.position);
return lhs.duration > rhs.duration;
});
// make sure the segments are sorted by position
+36 -82
View File
@@ -12,12 +12,8 @@
#include "util/bearing.hpp"
#include "util/coordinate.hpp"
#include "util/coordinate_calculation.hpp"
#include "util/guidance/toolkit.hpp"
#include "util/guidance/entry_class.hpp"
#include "util/typedefs.hpp"
#include <boost/optional.hpp>
#include <cstddef>
#include <vector>
namespace osrm
@@ -28,10 +24,14 @@ namespace guidance
{
namespace detail
{
std::pair<short, short> getDepartBearings(const LegGeometry &leg_geometry);
std::pair<short, short> getArriveBearings(const LegGeometry &leg_geometry);
std::pair<short, short> getIntermediateBearings(const LegGeometry &leg_geometry,
const std::size_t segment_index);
StepManeuver stepManeuverFromGeometry(extractor::guidance::TurnInstruction instruction,
const LegGeometry &leg_geometry,
const std::size_t segment_index);
StepManeuver stepManeuverFromGeometry(extractor::guidance::TurnInstruction instruction,
const WaypointType waypoint_type,
const LegGeometry &leg_geometry);
} // ns detail
template <typename DataFacadeT>
@@ -63,67 +63,34 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
std::size_t segment_index = 0;
BOOST_ASSERT(leg_geometry.locations.size() >= 2);
auto bearings = detail::getDepartBearings(leg_geometry);
StepManeuver maneuver{source_node.location, bearings.first,
bearings.second, extractor::guidance::TurnInstruction::NO_TURN(),
WaypointType::Depart, 0};
Intersection intersection{
source_node.location,
std::vector<short>({bearings.second}),
std::vector<bool>({true}), Intersection::NO_INDEX, 0};
if (leg_data.size() > 0)
{
StepManeuver maneuver = detail::stepManeuverFromGeometry(
extractor::guidance::TurnInstruction::NO_TURN(), WaypointType::Depart, leg_geometry);
maneuver.location = source_node.location;
// PathData saves the information we need of the segment _before_ the turn,
// but a RouteStep is with regard to the segment after the turn.
// We need to skip the first segment because it is already covered by the
// initial start of a route
int segment_duration = 0;
// some name changes are not announced in our processing. For these, we have to keep the
// first name on the segment
auto step_name_id = source_node.name_id;
for (std::size_t leg_data_index = 0; leg_data_index < leg_data.size(); ++leg_data_index)
for (const auto &path_point : leg_data)
{
const auto &path_point = leg_data[leg_data_index];
segment_duration += path_point.duration_until_turn;
// all changes to this check have to be matched with assemble_geometry
if (path_point.turn_instruction.type != extractor::guidance::TurnType::NoTurn)
{
BOOST_ASSERT(segment_duration >= 0);
const auto name = facade.GetNameForID(step_name_id);
const auto name = facade.GetNameForID(path_point.name_id);
const auto distance = leg_geometry.segment_distances[segment_index];
if (leg_data_index + 1 < leg_data.size())
{
step_name_id = leg_data[leg_data_index + 1].name_id;
}
else
{
step_name_id = target_node.name_id;
}
steps.push_back(RouteStep{
step_name_id, name, NO_ROTARY_NAME, segment_duration / 10.0, distance,
path_point.travel_mode, maneuver, leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1, {intersection}});
bearings = detail::getIntermediateBearings(leg_geometry, segment_index);
const auto entry_class = facade.GetEntryClass(path_point.entry_classid);
const auto bearing_class = facade.GetBearingClass(facade.GetBearingClassID(path_point.turn_via_node));
intersection.in = bearing_class.findMatchingBearing(util::bearing::reverseBearing(bearings.first));
intersection.out = bearing_class.findMatchingBearing(bearings.second);
intersection.location = facade.GetCoordinateOfNode(path_point.turn_via_node);
intersection.bearings.clear();
std::copy(bearing_class.getAvailableBearings().begin(), bearing_class.getAvailableBearings().end(),
std::back_inserter(intersection.bearings));
intersection.entry.clear();
for (auto idx : util::irange<std::size_t>(0, intersection.bearings.size()))
{
intersection.entry.push_back(entry_class.allowsEntry(idx));
}
maneuver = {intersection.location, bearings.first, bearings.second, path_point.turn_instruction, WaypointType::None, 0};
steps.push_back(RouteStep{path_point.name_id, name, NO_ROTARY_NAME,
segment_duration / 10.0, distance, path_point.travel_mode,
maneuver, leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1});
maneuver = detail::stepManeuverFromGeometry(path_point.turn_instruction,
leg_geometry, segment_index);
segment_index++;
segment_duration = 0;
}
@@ -131,10 +98,10 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
const auto distance = leg_geometry.segment_distances[segment_index];
const int duration = segment_duration + target_duration;
BOOST_ASSERT(duration >= 0);
steps.push_back(RouteStep{
step_name_id, facade.GetNameForID(step_name_id), NO_ROTARY_NAME, duration / 10.,
distance, target_mode, maneuver, leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1, {intersection}});
steps.push_back(RouteStep{target_node.name_id, facade.GetNameForID(target_node.name_id),
NO_ROTARY_NAME, duration / 10., distance, target_mode, maneuver,
leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1});
}
// In this case the source + target are on the same edge segment
else
@@ -145,42 +112,29 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
// |---| source_duration
// |---------| target_duration
StepManeuver maneuver = detail::stepManeuverFromGeometry(
extractor::guidance::TurnInstruction::NO_TURN(), WaypointType::Depart, leg_geometry);
int duration = target_duration - source_duration;
BOOST_ASSERT(duration >= 0);
steps.push_back(RouteStep{
source_node.name_id, facade.GetNameForID(source_node.name_id), NO_ROTARY_NAME,
duration / 10., leg_geometry.segment_distances[segment_index], source_mode,
std::move(maneuver), leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1, {intersection}});
steps.push_back(RouteStep{source_node.name_id, facade.GetNameForID(source_node.name_id),
NO_ROTARY_NAME, duration / 10.,
leg_geometry.segment_distances[segment_index], source_mode,
std::move(maneuver), leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1});
}
BOOST_ASSERT(segment_index == number_of_segments - 1);
bearings = detail::getArriveBearings(leg_geometry);
// This step has length zero, the only reason we need it is the target location
maneuver = {intersection.location, bearings.first, bearings.second, extractor::guidance::TurnInstruction::NO_TURN(), WaypointType::Arrive, 0};
intersection = {
target_node.location,
std::vector<short>({static_cast<short>(util::bearing::reverseBearing(bearings.first))}),
std::vector<bool>({true}), 0, Intersection::NO_INDEX};
auto final_maneuver = detail::stepManeuverFromGeometry(
extractor::guidance::TurnInstruction::NO_TURN(), WaypointType::Arrive, leg_geometry);
BOOST_ASSERT(!leg_geometry.locations.empty());
steps.push_back(RouteStep{target_node.name_id, facade.GetNameForID(target_node.name_id),
NO_ROTARY_NAME, ZERO_DURATION, ZERO_DISTANCE, target_mode,
std::move(maneuver), leg_geometry.locations.size() - 1,
leg_geometry.locations.size(),
{intersection}});
final_maneuver, leg_geometry.locations.size()-1,
leg_geometry.locations.size()});
BOOST_ASSERT(steps.front().intersections.size() == 1);
BOOST_ASSERT(steps.front().intersections.front().bearings.size() == 1);
BOOST_ASSERT(steps.front().intersections.front().entry.size() == 1);
BOOST_ASSERT(steps.front().maneuver.waypoint_type == WaypointType::Depart);
BOOST_ASSERT(steps.back().intersections.size() == 1);
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);
return steps;
}
-7
View File
@@ -31,13 +31,6 @@ struct LegGeometry
// length of the segment in meters
std::vector<double> segment_distances;
// Per-coordinate metadata
struct Annotation {
double distance;
double duration;
};
std::vector<Annotation> annotations;
std::size_t FrontIndex(std::size_t segment_index) const
{
return segment_offsets[segment_index];
@@ -17,13 +17,6 @@ namespace guidance
// passed as none-reference to modify in-place and move out again
std::vector<RouteStep> postProcess(std::vector<RouteStep> steps);
// Multiple possible reasons can result in unnecessary/confusing instructions
// A prime example would be a segregated intersection. Turning around at this
// intersection would result in two instructions to turn left.
// Collapsing such turns into a single turn instruction, we give a clearer
// set of instructionst that is not cluttered by unnecessary turns/name changes.
std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps);
// trim initial/final segment of very short length.
// This function uses in/out parameter passing to modify both steps and geometry in place.
// We use this method since both steps and geometry are closely coupled logically but
@@ -37,9 +30,6 @@ std::vector<RouteStep> assignRelativeLocations(std::vector<RouteStep> steps,
const PhantomNode &source_node,
const PhantomNode &target_node);
//remove steps invalidated by post-processing
std::vector<RouteStep> removeNoTurnInstructions(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.
-39
View File
@@ -3,9 +3,6 @@
#include "engine/guidance/step_maneuver.hpp"
#include "extractor/travel_mode.hpp"
#include "util/coordinate.hpp"
#include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp"
#include <cstddef>
@@ -24,27 +21,6 @@ namespace guidance
// Notable exceptions are Departure and Arrival steps.
// Departue: s --> a --> b. Represents the segment s,a with location being s.
// Arrive: a --> b --> t. The segment (b,t) is already covered by the previous segment.
// A represenetation of intermediate intersections
struct Intersection
{
static const constexpr std::size_t NO_INDEX = std::numeric_limits<std::size_t>::max();
util::Coordinate location;
std::vector<short> bearings;
std::vector<bool> entry;
std::size_t in;
std::size_t out;
};
inline Intersection getInvalidIntersection()
{
return {util::Coordinate{util::FloatLongitude{0.0}, util::FloatLatitude{0.0}},
{},
{},
Intersection::NO_INDEX,
Intersection::NO_INDEX};
}
struct RouteStep
{
unsigned name_id;
@@ -57,22 +33,7 @@ struct RouteStep
// indices into the locations array stored the LegGeometry
std::size_t geometry_begin;
std::size_t geometry_end;
std::vector<Intersection> intersections;
};
inline RouteStep getInvalidRouteStep()
{
return {0,
"",
"",
0,
0,
TRAVEL_MODE_INACCESSIBLE,
getInvalidStepManeuver(),
0,
0,
{getInvalidIntersection()}};
}
}
}
}
+12 -14
View File
@@ -1,8 +1,8 @@
#ifndef ENGINE_GUIDANCE_STEP_MANEUVER_HPP
#define ENGINE_GUIDANCE_STEP_MANEUVER_HPP
#include "extractor/guidance/turn_instruction.hpp"
#include "util/coordinate.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include <cstdint>
#include <vector>
@@ -21,26 +21,24 @@ enum class WaypointType : std::uint8_t
Depart,
};
//A represenetation of intermediate intersections
struct IntermediateIntersection
{
double duration;
double distance;
util::Coordinate location;
};
struct StepManeuver
{
util::Coordinate location;
short bearing_before;
short bearing_after;
double bearing_before;
double bearing_after;
extractor::guidance::TurnInstruction instruction;
WaypointType waypoint_type;
unsigned exit;
std::vector<IntermediateIntersection> intersections;
};
inline StepManeuver getInvalidStepManeuver()
{
return {util::Coordinate{util::FloatLongitude{0.0}, util::FloatLatitude{0.0}},
0,
0,
extractor::guidance::TurnInstruction::NO_TURN(),
WaypointType::None,
0};
}
} // namespace guidance
} // namespace engine
} // namespace osrmn
+5 -18
View File
@@ -1,11 +1,9 @@
#ifndef OSRM_ENGINE_GUIDANCE_TOOLKIT_HPP_
#define OSRM_ENGINE_GUIDANCE_TOOLKIT_HPP_
#ifndef OSRM_UTIL_GUIDANCE_TOOLKIT_HPP_
#define OSRM_UTIL_GUIDANCE_TOOLKIT_HPP_
#include "extractor/guidance/turn_instruction.hpp"
#include "util/bearing.hpp"
#include <algorithm>
namespace osrm
{
namespace engine
@@ -25,12 +23,9 @@ inline bool entersRoundabout(const extractor::guidance::TurnInstruction instruct
{
return (instruction.type == extractor::guidance::TurnType::EnterRoundabout ||
instruction.type == extractor::guidance::TurnType::EnterRotary ||
instruction.type == extractor::guidance::TurnType::EnterRoundaboutIntersection ||
instruction.type == extractor::guidance::TurnType::EnterRoundaboutAtExit ||
instruction.type == extractor::guidance::TurnType::EnterRotaryAtExit ||
instruction.type == extractor::guidance::TurnType::EnterRoundaboutIntersectionAtExit ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRoundabout ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRotary ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRotary);
}
@@ -38,10 +33,8 @@ inline bool leavesRoundabout(const extractor::guidance::TurnInstruction instruct
{
return (instruction.type == extractor::guidance::TurnType::ExitRoundabout ||
instruction.type == extractor::guidance::TurnType::ExitRotary ||
instruction.type == extractor::guidance::TurnType::ExitRoundaboutIntersection ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRoundabout ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRotary ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRoundaboutIntersection);
instruction.type == extractor::guidance::TurnType::EnterAndExitRotary);
}
inline bool staysOnRoundabout(const extractor::guidance::TurnInstruction instruction)
@@ -49,7 +42,7 @@ inline bool staysOnRoundabout(const extractor::guidance::TurnInstruction instruc
return instruction.type == extractor::guidance::TurnType::StayOnRoundabout;
}
inline extractor::guidance::DirectionModifier::Enum angleToDirectionModifier(const double bearing)
inline extractor::guidance::DirectionModifier angleToDirectionModifier(const double bearing)
{
if (bearing < 135)
{
@@ -63,14 +56,8 @@ inline extractor::guidance::DirectionModifier::Enum angleToDirectionModifier(con
return extractor::guidance::DirectionModifier::Left;
}
inline double angularDeviation(const double angle, const double from)
{
const double deviation = std::abs(angle - from);
return std::min(360 - deviation, deviation);
}
} // namespace guidance
} // namespace engine
} // namespace osrm
#endif /* OSRM_ENGINE_GUIDANCE_TOOLKIT_HPP_ */
#endif /* OSRM_UTIL_GUIDANCE_TOOLKIT_HPP_ */
+10 -1
View File
@@ -63,9 +63,18 @@ struct Hint
friend std::ostream &operator<<(std::ostream &, const Hint &);
};
#ifndef _MSC_VER
static_assert(sizeof(Hint) == 60 + 4, "Hint is bigger than expected");
constexpr std::size_t ENCODED_HINT_SIZE = 88;
static_assert(ENCODED_HINT_SIZE / 4 * 3 >= sizeof(Hint), "ENCODED_HINT_SIZE does not match size of Hint");
static_assert(ENCODED_HINT_SIZE / 4 * 3 >= sizeof(Hint),
"ENCODED_HINT_SIZE does not match size of Hint");
#else
// PhantomNode is bigger under windows because MSVC does not support bit packing
static_assert(sizeof(Hint) == 72 + 4, "Hint is bigger than expected");
constexpr std::size_t ENCODED_HINT_SIZE = 104;
static_assert(ENCODED_HINT_SIZE / 4 * 3 >= sizeof(Hint),
"ENCODED_HINT_SIZE does not match size of Hint");
#endif
}
}
+1 -3
View File
@@ -2,8 +2,8 @@
#define RAW_ROUTE_DATA_H
#include "engine/phantom_node.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "extractor/travel_mode.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "util/typedefs.hpp"
#include "osrm/coordinate.hpp"
@@ -29,8 +29,6 @@ struct PathData
extractor::guidance::TurnInstruction turn_instruction;
// travel mode of the street that leads to the turn
extractor::TravelMode travel_mode : 4;
// entry class of the turn, indicating possibility of turns
EntryClassID entry_classid;
};
struct InternalRouteResult
@@ -23,7 +23,7 @@ struct NormalDistribution
}
// FIXME implement log-probability version since it's faster
double Density(const double val) const
double density_function(const double val) const
{
using namespace boost::math::constants;
@@ -44,7 +44,7 @@ struct LaplaceDistribution
}
// FIXME implement log-probability version since it's faster
double Density(const double val) const
double density_function(const double val) const
{
const double x = std::abs(val - location);
return 1.0 / (2. * scale) * std::exp(-x / scale);
@@ -79,9 +79,9 @@ class BayesClassifier
ClassificationT classify(const ValueT &v) const
{
const double positive_postpriori =
positive_apriori_probability * positive_distribution.Density(v);
positive_apriori_probability * positive_distribution.density_function(v);
const double negative_postpriori =
negative_apriori_probability * negative_distribution.Density(v);
negative_apriori_probability * negative_distribution.density_function(v);
const double norm = positive_postpriori + negative_postpriori;
if (positive_postpriori > negative_postpriori)
@@ -82,10 +82,10 @@ template <class CandidateLists> struct HiddenMarkovModel
}
}
Clear(0);
clear(0);
}
void Clear(std::size_t initial_timestamp)
void clear(std::size_t initial_timestamp)
{
BOOST_ASSERT(viterbi.size() == parents.size() && parents.size() == path_distances.size() &&
path_distances.size() == pruned.size() && pruned.size() == breakage.size());
+9 -3
View File
@@ -149,11 +149,13 @@ struct PhantomNode
unsigned reverse_packed_geometry_id;
struct ComponentType
{
std::uint32_t id : 31;
std::uint32_t is_tiny : 1;
uint32_t id : 31;
bool is_tiny : 1;
} component;
// bit-fields are broken on Windows
#ifndef _MSC_VER
static_assert(sizeof(ComponentType) == 4, "ComponentType needs to be 4 bytes big");
#endif
util::Coordinate location;
util::Coordinate input_location;
unsigned short fwd_segment_position;
@@ -163,7 +165,11 @@ struct PhantomNode
extractor::TravelMode backward_travel_mode;
};
#ifndef _MSC_VER
static_assert(sizeof(PhantomNode) == 60, "PhantomNode has more padding then expected");
#else
static_assert(sizeof(PhantomNode) == 72, "PhantomNode has more padding then expected");
#endif
using PhantomNodePair = std::pair<PhantomNode, PhantomNode>;
+1
View File
@@ -35,6 +35,7 @@ class TripPlugin final : public BasePlugin
int max_locations_trip;
InternalRouteResult ComputeRoute(const std::vector<PhantomNode> &phantom_node_list,
const api::TripParameters &parameters,
const std::vector<NodeID> &trip);
public:
@@ -162,6 +162,8 @@ class AlternativeRouting final
if (path_is_a_loop)
{
// Self Loop
BOOST_ASSERT(forward_heap1.GetData(middle_node).parent == middle_node &&
reverse_heap1.GetData(middle_node).parent == middle_node);
packed_forward_path.push_back(middle_node);
packed_forward_path.push_back(middle_node);
}
@@ -206,7 +206,7 @@ class MapMatching final : public BasicRoutingInterface<DataFacadeT, MapMatching<
split_points.push_back(split_index);
// note: this preserves everything before split_index
model.Clear(split_index);
model.clear(split_index);
std::size_t new_start = model.initialize(split_index);
// no new start was found -> stop viterbi calculation
if (new_start == map_matching::INVALID_STATE)
@@ -1,10 +1,10 @@
#ifndef ROUTING_BASE_HPP
#define ROUTING_BASE_HPP
#include "util/coordinate_calculation.hpp"
#include "engine/internal_route_result.hpp"
#include "engine/search_engine_data.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "util/coordinate_calculation.hpp"
#include "util/typedefs.hpp"
#include <boost/assert.hpp>
@@ -14,10 +14,10 @@
#include <algorithm>
#include <iterator>
#include <numeric>
#include <stack>
#include <utility>
#include <vector>
#include <stack>
#include <numeric>
namespace osrm
{
@@ -226,11 +226,6 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
recursion_stack.emplace(*std::prev(current), *current);
}
BOOST_ASSERT(*packed_path_begin == phantom_node_pair.source_phantom.forward_segment_id.id ||
*packed_path_begin == phantom_node_pair.source_phantom.reverse_segment_id.id);
BOOST_ASSERT(*std::prev(packed_path_end) == phantom_node_pair.target_phantom.forward_segment_id.id ||
*std::prev(packed_path_end) == phantom_node_pair.target_phantom.reverse_segment_id.id);
std::pair<NodeID, NodeID> edge;
while (!recursion_stack.empty())
{
@@ -306,6 +301,8 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
auto total_weight = std::accumulate(weight_vector.begin(), weight_vector.end(), 0);
BOOST_ASSERT(weight_vector.size() == id_vector.size());
// ed.distance should be total_weight + penalties (turn, stop, etc)
BOOST_ASSERT(ed.distance >= total_weight);
const bool is_first_segment = unpacked_path.empty();
const std::size_t start_index =
@@ -322,12 +319,13 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
for (std::size_t i = start_index; i < end_index; ++i)
{
unpacked_path.push_back(
PathData{id_vector[i], name_index, weight_vector[i],
extractor::guidance::TurnInstruction::NO_TURN(), travel_mode,
INVALID_ENTRY_CLASSID});
PathData{id_vector[i],
name_index,
weight_vector[i],
extractor::guidance::TurnInstruction::NO_TURN(),
travel_mode});
}
BOOST_ASSERT(unpacked_path.size() > 0);
unpacked_path.back().entry_classid = facade->GetEntryClassID(ed.id);
unpacked_path.back().turn_instruction = turn_instruction;
unpacked_path.back().duration_until_turn += (ed.distance - total_weight);
}
@@ -352,8 +350,7 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
start_index =
id_vector.size() - phantom_node_pair.source_phantom.fwd_segment_position - 1;
}
end_index =
id_vector.size() - phantom_node_pair.target_phantom.fwd_segment_position - 1;
end_index = id_vector.size() - phantom_node_pair.target_phantom.fwd_segment_position - 1;
}
else
{
@@ -380,12 +377,14 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
{
BOOST_ASSERT(i < id_vector.size());
BOOST_ASSERT(phantom_node_pair.target_phantom.forward_travel_mode > 0);
unpacked_path.push_back(PathData{
id_vector[i], phantom_node_pair.target_phantom.name_id, weight_vector[i],
extractor::guidance::TurnInstruction::NO_TURN(),
target_traversed_in_reverse ? phantom_node_pair.target_phantom.backward_travel_mode
: phantom_node_pair.target_phantom.forward_travel_mode,
INVALID_ENTRY_CLASSID});
unpacked_path.push_back(
PathData{id_vector[i],
phantom_node_pair.target_phantom.name_id,
weight_vector[i],
extractor::guidance::TurnInstruction::NO_TURN(),
target_traversed_in_reverse
? phantom_node_pair.target_phantom.backward_travel_mode
: phantom_node_pair.target_phantom.forward_travel_mode});
}
if (unpacked_path.size() > 0)
@@ -397,17 +396,8 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
// However the first segment duration needs to be adjusted to the fact that the source
// phantom is in the middle of the segment. We do this by subtracting v--s from the
// duration.
// Since it's possible duration_until_turn can be less than source_weight here if
// a negative enough turn penalty is used to modify this edge weight during
// osrm-contract, we clamp to 0 here so as not to return a negative duration
// for this segment.
// TODO this creates a scenario where it's possible the duration from a phantom
// node to the first turn would be the same as from end to end of a segment,
// which is obviously incorrect and not ideal...
unpacked_path.front().duration_until_turn =
std::max(unpacked_path.front().duration_until_turn - source_weight, 0);
BOOST_ASSERT(unpacked_path.front().duration_until_turn >= source_weight);
unpacked_path.front().duration_until_turn -= source_weight;
}
// there is no equivalent to a node-based node in an edge-expanded graph.
@@ -643,8 +633,9 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
}
// TODO check if unordered_set might be faster
// sort by id and increasing by distance
auto entry_point_comparator = [](const std::pair<NodeID, EdgeWeight> &lhs,
const std::pair<NodeID, EdgeWeight> &rhs) {
auto entry_point_comparator =
[](const std::pair<NodeID, EdgeWeight> &lhs, const std::pair<NodeID, EdgeWeight> &rhs)
{
return lhs.first < rhs.first || (lhs.first == rhs.first && lhs.second < rhs.second);
};
std::sort(forward_entry_points.begin(), forward_entry_points.end(), entry_point_comparator);
@@ -780,50 +771,18 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
nodes.target_phantom = target_phantom;
UnpackPath(packed_path.begin(), packed_path.end(), nodes, unpacked_path);
using util::coordinate_calculation::detail::DEGREE_TO_RAD;
using util::coordinate_calculation::detail::EARTH_RADIUS;
util::Coordinate previous_coordinate = source_phantom.location;
util::Coordinate current_coordinate;
double distance = 0;
double prev_lat =
static_cast<double>(toFloating(source_phantom.location.lat)) * DEGREE_TO_RAD;
double prev_lon =
static_cast<double>(toFloating(source_phantom.location.lon)) * DEGREE_TO_RAD;
double prev_cos = std::cos(prev_lat);
for (const auto &p : unpacked_path)
{
const auto current_coordinate = facade->GetCoordinateOfNode(p.turn_via_node);
const double current_lat =
static_cast<double>(toFloating(current_coordinate.lat)) * DEGREE_TO_RAD;
const double current_lon =
static_cast<double>(toFloating(current_coordinate.lon)) * DEGREE_TO_RAD;
const double current_cos = std::cos(current_lat);
const double sin_dlon = std::sin((prev_lon - current_lon) / 2.0);
const double sin_dlat = std::sin((prev_lat - current_lat) / 2.0);
const double aharv = sin_dlat * sin_dlat + prev_cos * current_cos * sin_dlon * sin_dlon;
const double charv = 2. * std::atan2(std::sqrt(aharv), std::sqrt(1.0 - aharv));
distance += EARTH_RADIUS * charv;
prev_lat = current_lat;
prev_lon = current_lon;
prev_cos = current_cos;
current_coordinate = facade->GetCoordinateOfNode(p.turn_via_node);
distance += util::coordinate_calculation::haversineDistance(previous_coordinate,
current_coordinate);
previous_coordinate = current_coordinate;
}
const double current_lat =
static_cast<double>(toFloating(target_phantom.location.lat)) * DEGREE_TO_RAD;
const double current_lon =
static_cast<double>(toFloating(target_phantom.location.lon)) * DEGREE_TO_RAD;
const double current_cos = std::cos(current_lat);
const double sin_dlon = std::sin((prev_lon - current_lon) / 2.0);
const double sin_dlat = std::sin((prev_lat - current_lat) / 2.0);
const double aharv = sin_dlat * sin_dlat + prev_cos * current_cos * sin_dlon * sin_dlon;
const double charv = 2. * std::atan2(std::sqrt(aharv), std::sqrt(1.0 - aharv));
distance += EARTH_RADIUS * charv;
distance += util::coordinate_calculation::haversineDistance(previous_coordinate,
target_phantom.location);
return distance;
}
@@ -57,13 +57,15 @@ class ShortestPathRouting final
if (search_from_forward_node)
{
forward_heap.Insert(source_phantom.forward_segment_id.id,
-source_phantom.GetForwardWeightPlusOffset(),
total_distance_to_forward -
source_phantom.GetForwardWeightPlusOffset(),
source_phantom.forward_segment_id.id);
}
if (search_from_reverse_node)
{
forward_heap.Insert(source_phantom.reverse_segment_id.id,
-source_phantom.GetReverseWeightPlusOffset(),
total_distance_to_reverse -
source_phantom.GetReverseWeightPlusOffset(),
source_phantom.reverse_segment_id.id);
}
if (search_to_forward_node)
@@ -105,7 +107,6 @@ class ShortestPathRouting final
super::Search(forward_heap, reverse_heap, new_total_distance, leg_packed_path,
needs_loop_forwad, needs_loop_backwards);
}
new_total_distance += std::min(total_distance_to_forward,total_distance_to_reverse);
}
// searches shortest path between:
+41
View File
@@ -0,0 +1,41 @@
#ifndef TRIP_BRUTE_FORCE_HPP
#define TRIP_BRUTE_FORCE_HPP
#include "engine/search_engine.hpp"
#include "util/simple_logger.hpp"
#include "osrm/json_container.hpp"
#include <cstdlib>
#include <algorithm>
#include <string>
#include <vector>
#include <limits>
namespace osrm
{
namespace engine
{
namespace trip
{
// todo: yet to be implemented
void TabuSearchTrip(std::vector<unsigned> &location,
const PhantomNodeArray &phantom_node_vector,
const std::vector<EdgeWeight> &dist_table,
InternalRouteResult &min_route,
std::vector<int> &min_loc_permutation)
{
}
void TabuSearchTrip(const PhantomNodeArray &phantom_node_vector,
const std::vector<EdgeWeight> &dist_table,
InternalRouteResult &min_route,
std::vector<int> &min_loc_permutation)
{
}
}
}
}
#endif // TRIP_BRUTE_FORCE_HPP
@@ -40,9 +40,7 @@ class CompressedEdgeContainer
void SerializeInternalVector(const std::string &path) const;
unsigned GetPositionForID(const EdgeID edge_id) const;
const EdgeBucket &GetBucketReference(const EdgeID edge_id) const;
bool IsTrivial(const EdgeID edge_id) const;
NodeID GetFirstEdgeTargetID(const EdgeID edge_id) const;
NodeID GetLastEdgeTargetID(const EdgeID edge_id) const;
NodeID GetLastEdgeSourceID(const EdgeID edge_id) const;
private:
+8 -20
View File
@@ -3,35 +3,33 @@
#ifndef EDGE_BASED_GRAPH_FACTORY_HPP_
#define EDGE_BASED_GRAPH_FACTORY_HPP_
#include "extractor/compressed_edge_container.hpp"
#include "extractor/edge_based_edge.hpp"
#include "extractor/profile_properties.hpp"
#include "extractor/restriction_map.hpp"
#include "extractor/compressed_edge_container.hpp"
#include "extractor/edge_based_node.hpp"
#include "extractor/original_edge_data.hpp"
#include "extractor/profile_properties.hpp"
#include "extractor/query_node.hpp"
#include "extractor/restriction_map.hpp"
#include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp"
#include "extractor/guidance/turn_analysis.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "util/deallocating_vector.hpp"
#include "util/name_table.hpp"
#include "util/node_based_graph.hpp"
#include "util/typedefs.hpp"
#include "util/deallocating_vector.hpp"
#include "util/name_table.hpp"
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <cstddef>
#include <iosfwd>
#include <memory>
#include <queue>
#include <string>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <string>
#include <boost/filesystem/fstream.hpp>
@@ -69,12 +67,6 @@ class EdgeBasedGraphFactory
void GetStartPointMarkers(std::vector<bool> &node_is_startpoint);
void GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &output_node_weights);
// These access functions don't destroy the content
const std::vector<BearingClassID> &GetBearingClassIds() const;
std::vector<BearingClassID> &GetBearingClassIds();
std::vector<util::guidance::BearingClass> GetBearingClasses() const;
std::vector<util::guidance::EntryClass> GetEntryClasses() const;
unsigned GetHighestEdgeID();
// Basic analysis of a turn (u --(e1)-- v --(e2)-- w)
@@ -135,10 +127,6 @@ class EdgeBasedGraphFactory
std::size_t restricted_turns_counter;
std::size_t skipped_uturns_counter;
std::size_t skipped_barrier_turns_counter;
std::unordered_map<util::guidance::BearingClass, BearingClassID> bearing_class_hash;
std::vector<BearingClassID> bearing_class_by_node_based_node;
std::unordered_map<util::guidance::EntryClass, EntryClassID> entry_class_hash;
};
} // namespace extractor
} // namespace osrm
@@ -1,8 +1,13 @@
#ifndef EXTRACTION_HELPER_FUNCTIONS_HPP
#define EXTRACTION_HELPER_FUNCTIONS_HPP
#include "util/cast.hpp"
#include "util/iso_8601_duration_parser.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string_regex.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/regex.hpp>
#include <limits>
#include <string>
@@ -12,106 +17,83 @@ namespace osrm
namespace extractor
{
namespace detail
inline bool simple_duration_is_valid(const std::string &s)
{
boost::regex simple_format(
"((\\d|\\d\\d):(\\d|\\d\\d):(\\d|\\d\\d))|((\\d|\\d\\d):(\\d|\\d\\d))|(\\d|\\d\\d)",
boost::regex_constants::icase | boost::regex_constants::perl);
namespace qi = boost::spirit::qi;
template <typename Iterator> struct iso_8601_grammar : qi::grammar<Iterator, unsigned()>
{
iso_8601_grammar()
: iso_8601_grammar::base_type(root)
const bool simple_matched = regex_match(s, simple_format);
if (simple_matched)
{
using qi::_1;
using qi::_a;
using qi::_b;
using qi::_c;
using qi::_pass;
using qi::_val;
using qi::eoi;
using qi::eps;
using qi::uint_;
using qi::char_;
hh = uint2_p[_pass = bind([](unsigned x) { return x < 24; }, _1), _val = _1];
mm = uint2_p[_pass = bind([](unsigned x) { return x < 60; }, _1), _val = _1];
ss = uint2_p[_pass = bind([](unsigned x) { return x < 60; }, _1), _val = _1];
osm_time
= (uint_p[_a = _1] >> eoi) [_val = _a * 60]
| (uint_p[_a = _1] >> ':' >> uint_p[_b = _1] >> eoi) [_val = _a * 3600 + _b * 60]
| (uint_p[_a = _1] >> ':' >> uint_p[_b = _1] >> ':' >> uint_p[_c = _1] >> eoi) [_val = _a * 3600 + _b * 60 + _c]
;
alternative_time
= ('T' >> hh[_a = _1] >> mm[_b = _1] >> ss[_c = _1]) [_val = _a * 3600 + _b * 60 + _c]
;
extended_time
= ('T' >> hh[_a = _1] >> ':' >> mm[_b = _1] >> ':' >> ss[_c = _1]) [_val = _a * 3600 + _b * 60 + _c]
;
standard_time
= ('T'
>> -(uint_ >> char_("Hh"))[_a = _1]
>> -(uint_ >> char_("Mm"))[_b = _1]
>> -(uint_ >> char_("Ss"))[_c = _1]) [_val = _a * 3600 + _b * 60 + _c]
;
standard_date
= (uint_ >> char_("Dd")) [_val = _1 * 86400]
;
standard_week
= (uint_ >> char_("Ww")) [_val = _1 * 604800]
;
iso_period
= osm_time [_val = _1]
| ('P' >> standard_week >> eoi) [_val = _1]
| ('P' >> ( alternative_time[_a = 0, _b = _1]
| extended_time[_a = 0, _b = _1]
| (eps[_a = 0, _b = 0] >> -standard_date[_a = _1] >> -standard_time[_b = _1] ) )
>> eoi) [_val = _a + _b]
;
root = iso_period;
return true;
}
return false;
}
qi::rule<Iterator, unsigned()> root;
qi::rule<Iterator, unsigned(), qi::locals<unsigned, unsigned>> iso_period;
qi::rule<Iterator, unsigned(), qi::locals<unsigned, unsigned, unsigned>> osm_time, standard_time, alternative_time, extended_time;
qi::rule<Iterator, unsigned()> standard_date, standard_week;
qi::rule<Iterator, unsigned()> hh, mm, ss;
inline bool iso_8601_duration_is_valid(const std::string &s)
{
util::iso_8601_grammar<std::string::const_iterator> iso_parser;
const bool result = boost::spirit::qi::parse(s.begin(), s.end(), iso_parser);
qi::uint_parser<unsigned, 10, 1, 2> uint_p;
qi::uint_parser<unsigned, 10, 2, 2> uint2_p;
};
// check if the was an error with the request
if (result && (0 != iso_parser.get_duration()))
{
return true;
}
return false;
}
inline bool durationIsValid(const std::string &s)
{
static detail::iso_8601_grammar<std::string::const_iterator> const iso_8601_grammar;
std::string::const_iterator iter = s.begin();
unsigned duration = 0;
boost::spirit::qi::parse(iter, s.end(), iso_8601_grammar, duration);
return !s.empty() && iter == s.end();
return simple_duration_is_valid(s) || iso_8601_duration_is_valid(s);
}
inline unsigned parseDuration(const std::string &s)
{
static detail::iso_8601_grammar<std::string::const_iterator> const iso_8601_grammar;
if (simple_duration_is_valid(s))
{
unsigned hours = 0;
unsigned minutes = 0;
unsigned seconds = 0;
boost::regex e(
"((\\d|\\d\\d):(\\d|\\d\\d):(\\d|\\d\\d))|((\\d|\\d\\d):(\\d|\\d\\d))|(\\d|\\d\\d)",
boost::regex_constants::icase | boost::regex_constants::perl);
std::string::const_iterator iter = s.begin();
unsigned duration = 0;
boost::spirit::qi::parse(iter, s.end(), iso_8601_grammar, duration);
std::vector<std::string> result;
boost::algorithm::split_regex(result, s, boost::regex(":"));
const bool matched = regex_match(s, e);
if (matched)
{
if (1 == result.size())
{
minutes = std::stoul(result[0]);
}
if (2 == result.size())
{
minutes = std::stoul(result[1]);
hours = std::stoul(result[0]);
}
if (3 == result.size())
{
seconds = std::stoul(result[2]);
minutes = std::stoul(result[1]);
hours = std::stoul(result[0]);
}
return (3600 * hours + 60 * minutes + seconds);
}
}
else if (iso_8601_duration_is_valid(s))
{
util::iso_8601_grammar<std::string::const_iterator> iso_parser;
boost::spirit::qi::parse(s.begin(), s.end(), iso_parser);
return !s.empty() && iter == s.end() ? duration : std::numeric_limits<unsigned>::max();
return iso_parser.get_duration();
}
return std::numeric_limits<unsigned>::max();
}
}
}
+5 -16
View File
@@ -29,13 +29,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define EXTRACTOR_HPP
#include "extractor/edge_based_edge.hpp"
#include "extractor/edge_based_graph_factory.hpp"
#include "extractor/extractor_config.hpp"
#include "extractor/edge_based_graph_factory.hpp"
#include "extractor/graph_compressor.hpp"
#include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp"
#include "util/typedefs.hpp"
namespace osrm
@@ -55,16 +52,14 @@ class Extractor
ExtractorConfig config;
std::pair<std::size_t, std::size_t>
BuildEdgeExpandedGraph(lua_State *lua_state,
const ProfileProperties &profile_properties,
BuildEdgeExpandedGraph(lua_State* lua_state,
const ProfileProperties& profile_properties,
std::vector<QueryNode> &internal_to_external_node_map,
std::vector<EdgeBasedNode> &node_based_edge_list,
std::vector<bool> &node_is_startpoint,
std::vector<EdgeWeight> &edge_based_node_weights,
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
const std::string &intersection_class_output_file);
void WriteProfileProperties(const std::string &output_path,
const ProfileProperties &properties) const;
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list);
void WriteProfileProperties(const std::string& output_path, const ProfileProperties& properties) const;
void WriteNodeMapping(const std::vector<QueryNode> &internal_to_external_node_map);
void FindComponents(unsigned max_edge_id,
const util::DeallocatingVector<EdgeBasedEdge> &edges,
@@ -81,12 +76,6 @@ class Extractor
void WriteEdgeBasedGraph(const std::string &output_file_filename,
const size_t max_edge_id,
util::DeallocatingVector<EdgeBasedEdge> const &edge_based_edge_list);
void WriteIntersectionClassificationData(
const std::string &output_file_name,
const std::vector<std::uint32_t> &node_based_intersection_classes,
const std::vector<util::guidance::BearingClass> &bearing_classes,
const std::vector<util::guidance::EntryClass> &entry_classes) const;
};
}
}
-2
View File
@@ -72,7 +72,6 @@ struct ExtractorConfig
edge_penalty_path = basepath + ".osrm.edge_penalties";
edge_based_node_weights_output_path = basepath + ".osrm.enw";
profile_properties_output_path = basepath + ".osrm.properties";
intersection_class_data_output_path = basepath + ".osrm.icd";
}
boost::filesystem::path config_file_path;
@@ -91,7 +90,6 @@ struct ExtractorConfig
std::string rtree_nodes_output_path;
std::string rtree_leafs_output_path;
std::string profile_properties_output_path;
std::string intersection_class_data_output_path;
unsigned requested_num_threads;
unsigned small_component_size;
+2 -3
View File
@@ -16,13 +16,12 @@ const double constexpr STRAIGHT_ANGLE = 180.;
const double constexpr MAXIMAL_ALLOWED_NO_TURN_DEVIATION = 3.;
// angle that lies between two nearly indistinguishable roads
const double constexpr NARROW_TURN_ANGLE = 40.;
const double constexpr GROUP_ANGLE = 60;
const double constexpr GROUP_ANGLE = 90;
// angle difference that can be classified as straight, if its the only narrow turn
const double constexpr FUZZY_ANGLE_DIFFERENCE = 20.;
const double constexpr FUZZY_ANGLE_DIFFERENCE = 15.;
const double constexpr DISTINCTION_RATIO = 2;
const unsigned constexpr INVALID_NAME_ID = 0;
const double constexpr MAX_ROUNDABOUT_INTERSECTION_RADIUS = 5;
const double constexpr MAX_ROUNDABOUT_RADIUS = 15; // 30 m diameter as final distinction
const double constexpr INCREASES_BY_FOURTY_PERCENT = 1.4;

Some files were not shown because too many files have changed in this diff Show More