Compare commits

..

63 Commits

Author SHA1 Message Date
Patrick Niklaus c7293f2024 Bump version to 5.7.2 2017-05-24 16:49:03 +00:00
Patrick Niklaus ddc8aed25d Fix formating 2017-05-24 16:47:14 +00:00
Michael Krasnyk 5f7410057c Fix OSRM_ASSERT_MSG compilation fail in Release mode 2017-05-24 16:36:21 +00:00
Patrick Niklaus d55d46e64e Add missing header after cherry-pick 2017-05-24 16:14:06 +00:00
Michael Krasnyk a83150d311 Place reverse entering_via_edge in the front of intersection_view 2017-05-24 15:52:00 +00:00
Michael Krasnyk b073bf36f3 Added example for roundabout overlapping 2017-05-24 15:47:58 +00:00
Daniel J. Hofmann aaea94f776 Asserts Valid Iterators in Roundabout Exit Invalidation, see #4024 2017-05-24 15:44:28 +00:00
Patrick Niklaus 055079192c Bump version to 5.7.1 2017-05-23 17:20:02 +00:00
Patrick Niklaus c542fc2087 Fix formating after cherry-pick 2017-05-23 16:25:26 +00:00
Patrick Niklaus 64b9b6e888 Accidentally included a un-releated test case from master 2017-05-23 16:24:58 +00:00
Michael Krasnyk c58052ca04 Adjust CHANGELOG and the test description 2017-05-23 16:02:00 +00:00
Michael Krasnyk df4d1cb9e6 Change order of guidance post-processing, fix #4030 2017-05-23 16:00:38 +00:00
Daniel J. Hofmann 3349964b96 Updates Changelog 2017-05-19 12:27:32 +02:00
Daniel J. Hofmann 443ebc2551 Applies max turn weight for turns onto restricted weights: no need for custom penalty 2017-05-19 12:22:31 +02:00
Daniel J. Hofmann e6b1e3564a Prevents possible overflow in applying a turn penalty onto restricted roads 2017-05-19 12:22:31 +02:00
Moritz Kobitzsch 3aeb39ba95 fix continue_straight interaction with bearing specification 2017-05-19 12:22:31 +02:00
Daniel J. Hofmann 51fbb4fcbd Fixes Table not checking for valid phantom nodes
We failed to check if we could actually find phantom nodes for all
coordinates in the table plugin, leading to corrupt internal state.

```
curl 'http://localhost:5000/table/v1/car/7.4151,43.7305;7.4222,43.7368?radiuses=0;'
```

```
[assert][140505627227904] /tmp/osrm-backend/include/engine/routing_algorithms/routing_base.hpp:68
in: void osrm::engine::routing_algorithms::insertNodesInHeap(osrm::engine::SearchEngineData<osrm::engine::routing_algorithms::ch::Algorithm>::ManyToManyQueryHeap&, const osrm::engine::PhantomNode&) [with bool DIRECTION = false; osrm::engine::SearchEngineData<osrm::engine::routing_algorithms::ch::Algorithm>::ManyToManyQueryHeap = osrm::util::BinaryHeap<unsigned int, unsigned int, int, osrm::engine::ManyToManyHeapData, osrm::util::UnorderedMapStorage<unsigned int, int> >]: phantom_node.IsValid()
terminate called without an active exception
```
2017-05-19 12:22:31 +02:00
Michael Krasnyk f618531cbb Add response code to test result values 2017-05-19 12:22:31 +02:00
Patrick Niklaus 3f737fce46 Update changelog 2017-05-16 16:21:36 +00:00
Patrick Niklaus 11df411da7 Fix weight value for alley 2017-05-16 16:20:46 +00:00
Patrick Niklaus 5f208b913c Add regression test 2017-05-16 16:20:46 +00:00
Patrick Niklaus 3131bffe11 Fix bicycle turn penalties 2017-05-16 16:20:46 +00:00
Michael Krasnyk 4f3a7c1ec3 Adjust method and function names 2017-05-11 09:36:04 +00:00
Michael Krasnyk 321d1988a0 Disable nodes with invalid segments 2017-05-11 09:36:02 +00:00
Michael Krasnyk b707fcdadc Add response codes of trip and routability queries 2017-05-11 09:16:01 +00:00
Patrick Niklaus 4285660c72 Update changelog 2017-05-05 22:14:50 +00:00
Michael Krasnyk 111e689b09 Added test with an empty CSV file 2017-05-05 22:13:57 +00:00
Michael Krasnyk ebbb497af2 Hide qi namespace alias 2017-05-05 22:13:57 +00:00
Michael Krasnyk dd9ad9fa08 Remove generate-edge-lookup argument in feature tests 2017-05-05 22:13:57 +00:00
Michael Krasnyk dc55edbeb1 Add zero file size check 2017-05-05 22:13:57 +00:00
Michael Krasnyk 1c59563c9c Print diagnostic information to avoid boost cryptic errors 2017-05-05 22:13:57 +00:00
Michael Krasnyk f4e1f6a752 Use mapped_file_source for CSV files 2017-05-05 22:13:57 +00:00
Patrick Niklaus 8c1e014d42 For the cyclability profile add alley penalties 2017-05-05 17:05:37 +00:00
Patrick Niklaus b27fa42b0a Add failing test case for alleys 2017-05-05 17:05:28 +00:00
Patrick Niklaus 73e008e1b0 Regenerate docs 2017-05-05 08:50:22 +00:00
Patrick Niklaus 45fe4b80dd Fix docs for radius 2017-05-05 08:50:07 +00:00
Patrick Niklaus 65732db266 Fix overloaded parameter docs 2017-05-05 08:49:51 +00:00
Patrick Niklaus 55a7e1082f Disable TOC 2017-05-05 08:49:42 +00:00
Patrick Niklaus 34d5ba8fdd Update changelog 2017-05-04 21:08:28 +00:00
Michael Krasnyk ec26756084 Updated assertions to catch negative duration values for weights > 0
but still clamping negative duration values at 0 without checking weights
2017-05-04 21:02:28 +00:00
Michael Krasnyk 0f55f24bfe Use rectified linear unit to prevent negative duration values 2017-05-04 21:02:17 +00:00
Patrick Niklaus 07f2c8fd4c Regenerate API docs 2017-05-03 15:22:28 +00:00
Patrick Niklaus 3289d53617 Update nodejs docs to document the constructor better 2017-05-03 15:22:11 +00:00
Michael Krasnyk 1ea5e44094 Adjusted to PR comments 2017-05-03 15:21:47 +00:00
Michael Krasnyk ee208cd450 Fix incorrect exit turn invalidation 2017-05-03 15:21:36 +00:00
Patrick Niklaus 4370fd126d Final version bump 2017-04-21 08:49:00 +00:00
Patrick Niklaus 15a2fdd1f8 Update changelog 2017-04-20 13:58:29 +00:00
Patrick Niklaus 0eedcf69bc Fix checking columns if route is not specified 2017-04-20 13:52:23 +00:00
Patrick Niklaus 62abea30f5 Apply traffic light penalty also for non-turns 2017-04-20 13:52:11 +00:00
Michael Krasnyk 3364be1860 Fix incorrect weight fallback for distance-based weights 2017-04-20 13:51:59 +00:00
Patrick Niklaus a5eeca9b51 Bump version to RC3 2017-04-18 17:09:49 +00:00
Michael Krasnyk 1a09ff6005 Don't remove the last original coordinate during tiding 2017-04-18 13:36:28 +00:00
Patrick Niklaus 2794a52902 Remove boost::make_unique to fix travis node builds 2017-04-13 21:18:08 +00:00
Patrick Niklaus cb796e4cfc Use .gitignore default instead of .npmignore 2017-04-13 21:17:58 +00:00
Patrick Niklaus 522ec4fc2e Restructure travis build 2017-04-13 21:17:45 +00:00
Michael Krasnyk 15dc5899b0 Use total angle for turn instruction if entry step has large distance 2017-04-12 23:32:12 +00:00
Patrick Niklaus 7e932ffbc3 Bump package version 2017-04-12 22:58:58 +00:00
Patrick Niklaus 810596bb83 Install node version as well 2017-04-12 20:28:19 +00:00
Patrick Niklaus acabf0075c Only use three jobs for node builds 2017-04-12 20:28:05 +00:00
Patrick Niklaus 1ed72db210 Use nvm instead of travis node_js key
This fixes issues on container builds that would always use
node 6 even when 4 was specified.
2017-04-12 20:27:53 +00:00
Patrick Niklaus 6bdf95dfb4 Change version to RC1 2017-04-12 14:58:51 +00:00
Patrick Niklaus 785ae89cd8 Update changelog 2017-04-12 14:58:25 +00:00
Patrick Niklaus 16680191de Enable 5.7 branch in travis 2017-04-12 14:28:37 +00:00
553 changed files with 5975 additions and 71258 deletions
+21 -40
View File
@@ -17,7 +17,7 @@ notifications:
branches: branches:
only: only:
- master - master
- "5.8" - "5.7"
# enable building tags # enable building tags
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/ - /^v\d+\.\d+(\.\d+)?(-\S*)?$/
@@ -49,43 +49,15 @@ matrix:
# Debug Builds # Debug Builds
- os: linux - os: linux
compiler: "format-taginfo-docs" compiler: "gcc-6-debug-cov-asan"
env: NODE=6
sudo: false
before_install:
install:
- source $NVM_DIR/nvm.sh
- nvm install $NODE
- nvm use $NODE
- npm --version
- npm install --ignore-scripts
- npm link --ignore-scripts
script:
- ./scripts/check_taginfo.py taginfo.json profiles/car.lua
- ${MASON} install clang-format 3.8.1
- PATH=$(${MASON} prefix clang-format 3.8.1)/bin:${PATH} ./scripts/format.sh && ./scripts/error_on_dirty.sh
# See issue 4043
#- npm run docs && ./scripts/error_on_dirty.sh
after_success:
- os: linux
compiler: "gcc-6-debug-cov"
addons: &gcc6 addons: &gcc6
apt: apt:
sources: ['ubuntu-toolchain-r-test'] sources: ['ubuntu-toolchain-r-test']
packages: ['g++-6', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev'] packages: ['g++-6', '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-6' CXXCOMPILER='g++-6' BUILD_TYPE='Debug' ENABLE_COVERAGE=ON CUCUMBER_TIMEOUT=20000 env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Debug' TARGET_ARCH='x86_64-asan' ENABLE_COVERAGE=ON ENABLE_SANITIZER=ON
after_success: after_success:
- bash <(curl -s https://codecov.io/bash) - bash <(curl -s https://codecov.io/bash)
- os: linux
compiler: "gcc-6-debug-asan"
addons: &gcc6
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-6', '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-6' CXXCOMPILER='g++-6' BUILD_TYPE='Debug' TARGET_ARCH='x86_64-asan' ENABLE_SANITIZER=ON CUCUMBER_TIMEOUT=20000
- os: linux - os: linux
compiler: "clang-4.0-debug" compiler: "clang-4.0-debug"
addons: &clang40 addons: &clang40
@@ -176,7 +148,7 @@ matrix:
apt: apt:
sources: ['ubuntu-toolchain-r-test'] sources: ['ubuntu-toolchain-r-test']
packages: ['libstdc++-5-dev'] packages: ['libstdc++-5-dev']
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 env: CLANG_VERSION='4.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON PUBLISH_NODE_BINDINGS=On JOBS=3
install: install:
- pushd ${OSRM_BUILD_DIR} - pushd ${OSRM_BUILD_DIR}
- | - |
@@ -199,7 +171,7 @@ matrix:
apt: apt:
sources: ['ubuntu-toolchain-r-test'] sources: ['ubuntu-toolchain-r-test']
packages: ['libstdc++-5-dev'] packages: ['libstdc++-5-dev']
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 env: CLANG_VERSION='4.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON PUBLISH_NODE_BINDINGS=On JOBS=3
install: install:
- pushd ${OSRM_BUILD_DIR} - pushd ${OSRM_BUILD_DIR}
- | - |
@@ -222,7 +194,7 @@ matrix:
apt: apt:
sources: ['ubuntu-toolchain-r-test'] sources: ['ubuntu-toolchain-r-test']
packages: ['libstdc++-5-dev'] packages: ['libstdc++-5-dev']
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="6" env: CLANG_VERSION='4.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON PUBLISH_NODE_BINDINGS=On JOBS=3 NODE="6"
install: install:
- pushd ${OSRM_BUILD_DIR} - pushd ${OSRM_BUILD_DIR}
- | - |
@@ -245,7 +217,7 @@ matrix:
apt: apt:
sources: ['ubuntu-toolchain-r-test'] sources: ['ubuntu-toolchain-r-test']
packages: ['libstdc++-5-dev'] packages: ['libstdc++-5-dev']
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="6" env: CLANG_VERSION='4.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON PUBLISH_NODE_BINDINGS=On JOBS=3 NODE="6"
install: install:
- pushd ${OSRM_BUILD_DIR} - pushd ${OSRM_BUILD_DIR}
- | - |
@@ -275,6 +247,10 @@ before_install:
export JOBS=$((`sysctl -n hw.ncpu` + 1)) export JOBS=$((`sysctl -n hw.ncpu` + 1))
fi fi
fi fi
- |
if [ -n "${RUN_CLANG_FORMAT}" ]; then
${MASON} install clang-format 3.8.1 && PATH=$(${MASON} prefix clang-format 3.8.1)/bin:${PATH} ./scripts/format.sh
fi
- | - |
if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
sudo mdutil -i off / sudo mdutil -i off /
@@ -287,12 +263,11 @@ before_install:
- export PUBLISH=$([[ "${TRAVIS_TAG:-}" == "v${PACKAGE_JSON_VERSION}" ]] && echo "On" || echo "Off") - export PUBLISH=$([[ "${TRAVIS_TAG:-}" == "v${PACKAGE_JSON_VERSION}" ]] && echo "On" || echo "Off")
- echo "Using ${JOBS} jobs" - echo "Using ${JOBS} jobs"
- yarn install --ignore-scripts - yarn install --ignore-scripts
- yarn check --ignore-scripts --integrity
# Bootstrap cmake to be able to run mason # Bootstrap cmake to be able to run mason
- CMAKE_URL="https://mason-binaries.s3.amazonaws.com/${TRAVIS_OS_NAME}-x86_64/cmake/${CMAKE_VERSION}.tar.gz" - CMAKE_URL="https://mason-binaries.s3.amazonaws.com/${TRAVIS_OS_NAME}-x86_64/cmake/${CMAKE_VERSION}.tar.gz"
- CMAKE_DIR="mason_packages/${TRAVIS_OS_NAME}-x86_64/cmake/${CMAKE_VERSION}" - CMAKE_DIR="mason_packages/${TRAVIS_OS_NAME}-x86_64/cmake/${CMAKE_VERSION}"
- mkdir -p ${CMAKE_DIR} - mkdir -p ${CMAKE_DIR}
- travis_retry wget --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C ${CMAKE_DIR} || travis_terminate 1 - travis_retry wget --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C ${CMAKE_DIR} || exit 1
- export PATH=${CMAKE_DIR}/bin:${PATH} - export PATH=${CMAKE_DIR}/bin:${PATH}
- ${MASON} install tbb 2017_20161128 && export LD_LIBRARY_PATH=$(${MASON} prefix tbb 2017_20161128)/lib/:${LD_LIBRARY_PATH} - ${MASON} install tbb 2017_20161128 && export LD_LIBRARY_PATH=$(${MASON} prefix tbb 2017_20161128)/lib/:${LD_LIBRARY_PATH}
- ${MASON} install ccache ${CCACHE_VERSION} && export PATH=$(${MASON} prefix ccache ${CCACHE_VERSION})/bin:${PATH} - ${MASON} install ccache ${CCACHE_VERSION} && export PATH=$(${MASON} prefix ccache ${CCACHE_VERSION})/bin:${PATH}
@@ -300,12 +275,12 @@ before_install:
if [[ ! -z ${CLANG_VERSION} ]]; then if [[ ! -z ${CLANG_VERSION} ]]; then
export CCOMPILER='clang' export CCOMPILER='clang'
export CXXCOMPILER='clang++' export CXXCOMPILER='clang++'
${MASON} install clang++ ${CLANG_VERSION} && export PATH=$(${MASON} prefix clang++ ${CLANG_VERSION})/bin:${PATH} || travis_terminate 1 ${MASON} install clang++ ${CLANG_VERSION} && export PATH=$(${MASON} prefix clang++ ${CLANG_VERSION})/bin:${PATH}
# we only enable lto for release builds # we only enable lto for release builds
# and therefore don't need to us ld.gold or llvm tools for linking # and therefore don't need to us ld.gold or llvm tools for linking
# for debug builds # for debug builds
if [[ ${BUILD_TYPE} == 'Release' ]]; then if [[ ${BUILD_TYPE} == 'Release' ]]; then
${MASON} install binutils 2.27 && export PATH=$(${MASON} prefix binutils 2.27)/bin:${PATH} || travis_terminate 1 ${MASON} install binutils 2.27 && export PATH=$(${MASON} prefix binutils 2.27)/bin:${PATH}
fi fi
fi fi
- ccache --max-size=256M # limiting the cache's size to roughly the previous job's object sizes - ccache --max-size=256M # limiting the cache's size to roughly the previous job's object sizes
@@ -315,6 +290,10 @@ before_install:
- mkdir ${OSRM_BUILD_DIR} - mkdir ${OSRM_BUILD_DIR}
install: install:
- |
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
./scripts/check_taginfo.py taginfo.json profiles/car.lua
fi
- pushd ${OSRM_BUILD_DIR} - pushd ${OSRM_BUILD_DIR}
- | - |
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \ cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
@@ -344,6 +323,8 @@ install:
- cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} - cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
- make --jobs=${JOBS} - make --jobs=${JOBS}
- popd - popd
# building docs only works with npm3+ not with yarn or npm2
#- yarn run docs
script: script:
- if [[ $TARGET_ARCH == armhf ]] ; then echo "Skip tests for $TARGET_ARCH" && exit 0 ; fi - if [[ $TARGET_ARCH == armhf ]] ; then echo "Skip tests for $TARGET_ARCH" && exit 0 ; fi
@@ -361,6 +342,6 @@ script:
if [ -z "${ENABLE_SANITIZER}" ] && [ "$TARGET_ARCH" != "i686" ]; then if [ -z "${ENABLE_SANITIZER}" ] && [ "$TARGET_ARCH" != "i686" ]; then
npm run nodejs-tests npm run nodejs-tests
fi fi
- |
- popd - popd
- yarn test - yarn test
+19 -40
View File
@@ -1,48 +1,27 @@
# 5.8.1 # 5.7.2
- Changes from 5.8.0: - Changes from 5.7.1:
- Bugfixes: - Bug fixes:
- Fixes #4152: Superflous turn left instruction, when crossing a service-road. - Fixes segmentation fault caused by the fix for 3977
- Fixes #4189: Fixes missing turn lane information after a traffic light.
- Fixes #4199: Data race-condition when updating segment speeds.
- Fixes #3987: Fixes obvious turn detection at T-intersections with slip-roads.
- Fixes #4161: Don't collapse U-Turns with other steps.
# 5.8.0
- Changes from 5.7
- API:
- polyline6 support in request string
- new parameter `approaches` for `route`, `table`, `trip` and `nearest` requests. This parameter keep waypoints on the curb side.
'approaches' accepts both 'curb' and 'unrestricted' values.
Note : the curb side depend on the `ProfileProperties::left_hand_driving`, it's a global property set once by the profile. If you are working with a planet dataset, the api will be wrong in some countries, and right in others.
- NodeJs Bindings
- new parameter `approaches` for `route`, `table`, `trip` and `nearest` requests.
- Tools
- `osrm-partition` now ensures it is called before `osrm-contract` and removes inconsitent .hsgr files automatically.
- Features
- Added conditional restriction support with `parse-conditional-restrictions=true|false` to osrm-extract. This option saves conditional turn restrictions to the .restrictions file for parsing by contract later. Added `parse-conditionals-from-now=utc time stamp` and `--time-zone-file=/path/to/file` to osrm-contract
- Command-line tools (osrm-extract, osrm-contract, osrm-routed, etc) now return error codes and legible error messages for common problem scenarios, rather than ugly C++ crashes
- Speed up pre-processing by only running the Lua `node_function` for nodes that have tags. Cuts OSM file parsing time in half.
- osrm-extract now performs generation of edge-expanded-edges using all available CPUs, which should make osrm-extract significantly faster on multi-CPU machines
- Files
- .osrm.nodes file was renamed to .nbg_nodes and .ebg_nodes was added
- Guidance
- #4075 Changed counting of exits on service roundabouts
- Debug Tiles
- added support for visualising turn penalties to the MLD plugin
- added support for showing the rate (reciprocal of weight) on each edge when used
- added support for turn weights in addition to turn durations in debug tiles
- Bugfixes
- Fixed a copy/paste issue assigning wrong directions in similar turns (left over right)
- #4074: fixed a bug that would announce entering highway ramps as u-turns
- #4122: osrm-routed/libosrm should throw exception when a dataset incompatible with the requested algorithm is loaded
- Avoid collapsing u-turns into combined turn instructions
# 5.7.1 # 5.7.1
- Bugfixes - Changes from 5.7.0:
- #4030 Roundabout edge-case crashes post-processing - Bug fixes:
- Fixes 3995: Negative duration caused by rounding issues.
- Fixes 3977: Fixes exit number in roundabout if starting inside the roundabout
- Fixes 3981: The NodeJS documentation was outdated and incomplete.
- Fixes 4010: Performance regression while parsing CSV files. Now 5x faster.
- Fixes 3919: Turn penalties on the cyclabilty metric were disabled.
- Fixes 3992: Table plugin not checking for valid phantom nodes
- Fixes 4013: `continue_straight` interaction with bearing constraints
- Fixes 4063: Potential overflow in custom profiles for restricted ways
- Fixes 4030: Roundabout edge-case crashes post-processing
# 5.7.0 # 5.7.0
- Changes from 5.6 - Changes from 5.6
- Bug fixes:
- Fixed 505: Invalid distance value for distance as routing weight.
- Fixed 3958: Fix traffic light penalties for non-turns
- Fixed 3933: crash when collapsing instructions
- Algorithm: - Algorithm:
- OSRM object has new option `algorithm` that allows the selection of a routing algorithm. - OSRM object has new option `algorithm` that allows the selection of a routing algorithm.
- New experimental algorithm: Multi-Level Dijkstra with new toolchain: - New experimental algorithm: Multi-Level Dijkstra with new toolchain:
+12 -16
View File
@@ -54,8 +54,8 @@ if (POLICY CMP0048)
endif() endif()
project(OSRM C CXX) project(OSRM C CXX)
set(OSRM_VERSION_MAJOR 5) set(OSRM_VERSION_MAJOR 5)
set(OSRM_VERSION_MINOR 8) set(OSRM_VERSION_MINOR 7)
set(OSRM_VERSION_PATCH 1) set(OSRM_VERSION_PATCH 2)
set(OSRM_VERSION "${OSRM_VERSION_MAJOR}.${OSRM_VERSION_MINOR}.${OSRM_VERSION_PATCH}") set(OSRM_VERSION "${OSRM_VERSION_MAJOR}.${OSRM_VERSION_MINOR}.${OSRM_VERSION_PATCH}")
add_definitions(-DOSRM_PROJECT_DIR="${CMAKE_CURRENT_SOURCE_DIR}") add_definitions(-DOSRM_PROJECT_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
@@ -126,7 +126,6 @@ file(GLOB UpdaterGlob src/updater/*.cpp)
file(GLOB StorageGlob src/storage/*.cpp) file(GLOB StorageGlob src/storage/*.cpp)
file(GLOB ServerGlob src/server/*.cpp src/server/**/*.cpp) file(GLOB ServerGlob src/server/*.cpp src/server/**/*.cpp)
file(GLOB EngineGlob src/engine/*.cpp src/engine/**/*.cpp) file(GLOB EngineGlob src/engine/*.cpp src/engine/**/*.cpp)
file(GLOB ErrorcodesGlob src/osrm/errorcodes.cpp)
add_library(UTIL OBJECT ${UtilGlob}) add_library(UTIL OBJECT ${UtilGlob})
add_library(EXTRACTOR OBJECT ${ExtractorGlob}) add_library(EXTRACTOR OBJECT ${ExtractorGlob})
@@ -448,6 +447,10 @@ if(ENABLE_MASON)
add_dependency_includes(${MASON_PACKAGE_tbb_INCLUDE_DIRS}) add_dependency_includes(${MASON_PACKAGE_tbb_INCLUDE_DIRS})
set(TBB_LIBRARIES ${MASON_PACKAGE_tbb_LDFLAGS}) set(TBB_LIBRARIES ${MASON_PACKAGE_tbb_LDFLAGS})
mason_use(libshp2 VERSION ${MASON_LIBSHP_VERSION})
set(LIBSHAPEFILE_INCLUDE_DIR ${MASON_PACKAGE_libshp2_INCLUDE_DIRS})
set(LIBSHAPEFILE_LIBRARY ${MASON_PACKAGE_libshp2_LDFLAGS})
if(NOT MASON_PACKAGE_tbb_LIBRARY_DIRS) if(NOT MASON_PACKAGE_tbb_LIBRARY_DIRS)
message(FATAL_ERROR "MASON_PACKAGE_tbb_LIBRARY_DIRS is empty, rpath will not work") message(FATAL_ERROR "MASON_PACKAGE_tbb_LIBRARY_DIRS is empty, rpath will not work")
endif() endif()
@@ -474,8 +477,6 @@ if(ENABLE_MASON)
# expat and bzip2 are used from mason rather than the system # expat and bzip2 are used from mason rather than the system
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/libosmium/include) include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/libosmium/include)
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/rapidjson/include)
else() else()
find_package(Boost 1.54 REQUIRED COMPONENTS ${BOOST_COMPONENTS}) find_package(Boost 1.54 REQUIRED COMPONENTS ${BOOST_COMPONENTS})
@@ -545,9 +546,6 @@ else()
find_package(Osmium REQUIRED COMPONENTS io) find_package(Osmium REQUIRED COMPONENTS io)
include_directories(SYSTEM ${OSMIUM_INCLUDE_DIR}) include_directories(SYSTEM ${OSMIUM_INCLUDE_DIR})
set(RAPIDJSON_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/rapidjson/include")
include_directories(SYSTEM ${RAPIDJSON_INCLUDE_DIR})
endif() endif()
# prefix compilation with ccache by default if available and on clang or gcc # prefix compilation with ccache by default if available and on clang or gcc
@@ -639,8 +637,7 @@ set(UPDATER_LIBRARIES
${CMAKE_THREAD_LIBS_INIT} ${CMAKE_THREAD_LIBS_INIT}
${TBB_LIBRARIES} ${TBB_LIBRARIES}
${MAYBE_RT_LIBRARY} ${MAYBE_RT_LIBRARY}
${MAYBE_COVERAGE_LIBRARIES} ${MAYBE_COVERAGE_LIBRARIES})
${ZLIB_LIBRARY})
set(CONTRACTOR_LIBRARIES set(CONTRACTOR_LIBRARIES
${BOOST_BASE_LIBRARIES} ${BOOST_BASE_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT} ${CMAKE_THREAD_LIBS_INIT}
@@ -668,7 +665,6 @@ set(UTIL_LIBRARIES
${STXXL_LIBRARY} ${STXXL_LIBRARY}
${TBB_LIBRARIES} ${TBB_LIBRARIES}
${MAYBE_COVERAGE_LIBRARIES}) ${MAYBE_COVERAGE_LIBRARIES})
# Libraries # Libraries
target_link_libraries(osrm ${ENGINE_LIBRARIES}) target_link_libraries(osrm ${ENGINE_LIBRARIES})
target_link_libraries(osrm_update ${UPDATER_LIBRARIES}) target_link_libraries(osrm_update ${UPDATER_LIBRARIES})
@@ -680,7 +676,7 @@ target_link_libraries(osrm_store ${STORAGE_LIBRARIES})
# BUILD_COMPONENTS # BUILD_COMPONENTS
add_executable(osrm-components src/tools/components.cpp $<TARGET_OBJECTS:UTIL>) add_executable(osrm-components src/tools/components.cpp $<TARGET_OBJECTS:UTIL>)
target_link_libraries(osrm-components ${TBB_LIBRARIES} ${BOOST_BASE_LIBRARIES} ${UTIL_LIBRARIES}) target_link_libraries(osrm-components ${TBB_LIBRARIES} ${BOOST_BASE_LIBRARIES})
install(TARGETS osrm-components DESTINATION bin) install(TARGETS osrm-components DESTINATION bin)
if(BUILD_TOOLS) if(BUILD_TOOLS)
@@ -690,12 +686,12 @@ if(BUILD_TOOLS)
install(TARGETS osrm-io-benchmark DESTINATION bin) install(TARGETS osrm-io-benchmark DESTINATION bin)
find_package(Shapefile) find_package(Shapefile) # package libshp-dev
if(SHAPEFILE_FOUND AND (Boost_VERSION VERSION_GREATER 106000 OR ENABLE_MASON)) if(SHAPEFILE_FOUND AND (Boost_VERSION VERSION_GREATER 106000 OR ENABLE_MASON))
add_executable(osrm-extract-conditionals src/tools/extract-conditionals.cpp $<TARGET_OBJECTS:UTIL>) add_executable(osrm-extract-conditionals src/tools/extract-conditionals.cpp $<TARGET_OBJECTS:UTIL>)
target_include_directories(osrm-extract-conditionals PRIVATE ${LIBSHAPEFILE_INCLUDE_DIR}) target_include_directories(osrm-extract-conditionals PRIVATE ${LIBSHAPEFILE_INCLUDE_DIR})
target_link_libraries(osrm-extract-conditionals ${OSMIUM_LIBRARIES} ${BOOST_BASE_LIBRARIES} ${Boost_PROGRAM_OPTIONS_LIBRARY} target_link_libraries(osrm-extract-conditionals ${OSMIUM_LIBRARIES} ${BOOST_BASE_LIBRARIES} ${Boost_PROGRAM_OPTIONS_LIBRARY}
${UTIL_LIBRARIES} ${BZIP2_LIBRARIES} ${ZLIB_LIBRARY} ${EXPAT_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) ${LIBSHAPEFILE_LIBRARY} ${BZIP2_LIBRARIES} ${ZLIB_LIBRARY} ${EXPAT_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
install(TARGETS osrm-extract-conditionals DESTINATION bin) install(TARGETS osrm-extract-conditionals DESTINATION bin)
endif() endif()
endif() endif()
@@ -717,8 +713,8 @@ set_property(TARGET osrm-routed PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
file(GLOB VariantGlob third_party/variant/include/mapbox/*.hpp) file(GLOB VariantGlob third_party/variant/include/mapbox/*.hpp)
file(GLOB LibraryGlob include/osrm/*.hpp) file(GLOB LibraryGlob include/osrm/*.hpp)
file(GLOB ParametersGlob include/engine/api/*_parameters.hpp) file(GLOB ParametersGlob include/engine/api/*_parameters.hpp)
set(EngineHeader include/engine/status.hpp include/engine/engine_config.hpp include/engine/hint.hpp include/engine/bearing.hpp include/engine/approach.hpp include/engine/phantom_node.hpp) set(EngineHeader include/engine/status.hpp include/engine/engine_config.hpp include/engine/hint.hpp include/engine/bearing.hpp include/engine/phantom_node.hpp)
set(UtilHeader include/util/coordinate.hpp include/util/json_container.hpp include/util/typedefs.hpp include/util/alias.hpp include/util/exception.hpp) set(UtilHeader include/util/coordinate.hpp include/util/json_container.hpp include/util/typedefs.hpp include/util/strong_typedef.hpp include/util/exception.hpp)
set(ExtractorHeader include/extractor/extractor.hpp include/extractor/extractor_config.hpp include/extractor/travel_mode.hpp) set(ExtractorHeader include/extractor/extractor.hpp include/extractor/extractor_config.hpp include/extractor/travel_mode.hpp)
set(PartitionerHeader include/partition/partitioner.hpp include/partition/partition_config.hpp) set(PartitionerHeader include/partition/partitioner.hpp include/partition/partition_config.hpp)
set(ContractorHeader include/contractor/contractor.hpp include/contractor/contractor_config.hpp) set(ContractorHeader include/contractor/contractor.hpp include/contractor/contractor_config.hpp)
-9
View File
@@ -69,15 +69,6 @@ In case Docker complains about not being able to connect to the Docker daemon ma
After adding yourself to the `docker` group make sure to log out and back in again with your terminal. After adding yourself to the `docker` group make sure to log out and back in again with your terminal.
We support the following images on Docker Cloud:
Name | Description
-----|------
`latest` | `master` compiled with release flag
`latest-assertions` | `master` compiled with with release flag, assertions enabled and debug symbols
`latest-debug` | `master` compiled with debug flag
`<tag>` | specific tag compiled with release flag
`<tag>-debug` | specific tag compiled with debug flag
### Building from Source ### Building from Source
+627
View File
@@ -0,0 +1,627 @@
# Vendored NodeJs.cmake to bootstrap our C++ build without
# having the user to install Node modules via `npm install`.
#
# Update via: ../node_modules/.bin/ncmake update
# Defaults for standard Node.js builds
set(NODEJS_DEFAULT_URL https://nodejs.org/download/release)
set(NODEJS_DEFAULT_VERSION installed)
set(NODEJS_VERSION_FALLBACK latest)
set(NODEJS_DEFAULT_NAME node)
set(NODEJS_DEFAULT_CHECKSUM SHASUMS256.txt)
set(NODEJS_DEFAULT_CHECKTYPE SHA256)
include(CMakeParseArguments)
# Find a path by walking upward from a base directory until the path is
# found. Sets the variable ${PATH} to False if the path can't
# be determined
function(find_path_parent NAME BASE PATH)
set(ROOT ${BASE})
set(${PATH} ${ROOT}/${NAME} PARENT_SCOPE)
set(DRIVE "^[A-Za-z]?:?/$")
while(NOT ROOT MATCHES ${DRIVE} AND NOT EXISTS ${ROOT}/${NAME})
get_filename_component(ROOT ${ROOT} DIRECTORY)
set(${PATH} ${ROOT}/${NAME} PARENT_SCOPE)
endwhile()
if(ROOT MATCHES ${DRIVE})
set(${PATH} False PARENT_SCOPE)
endif()
endfunction()
# Shortcut for finding standard node module locations
macro(find_nodejs_module NAME BASE PATH)
find_path_parent(node_modules/${NAME} ${BASE} ${PATH})
endmacro()
# Download with a bit of nice output (without spewing progress)
function(download_file URL)
message(STATUS "Downloading: ${URL}")
file(DOWNLOAD
${URL}
${ARGN}
)
endfunction()
# Embedded win_delay_load_hook file so that this file can be copied
# into projects directly (recommended practice)
function(nodejs_generate_delayload_hook OUTPUT)
file(WRITE ${OUTPUT} "")
file(APPEND ${OUTPUT} "/*\n")
file(APPEND ${OUTPUT} " * When this file is linked to a DLL, it sets up a delay-load hook that\n")
file(APPEND ${OUTPUT} " * intervenes when the DLL is trying to load 'node.exe' or 'iojs.exe'\n")
file(APPEND ${OUTPUT} " * dynamically. Instead of trying to locate the .exe file it'll just return\n")
file(APPEND ${OUTPUT} " * a handle to the process image.\n")
file(APPEND ${OUTPUT} " *\n")
file(APPEND ${OUTPUT} " * This allows compiled addons to work when node.exe or iojs.exe is renamed.\n")
file(APPEND ${OUTPUT} " */\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} "#ifdef _MSC_VER\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} "#ifndef DELAYIMP_INSECURE_WRITABLE_HOOKS\n")
file(APPEND ${OUTPUT} "#define DELAYIMP_INSECURE_WRITABLE_HOOKS\n")
file(APPEND ${OUTPUT} "#endif\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} "#ifndef WIN32_LEAN_AND_MEAN\n")
file(APPEND ${OUTPUT} "#define WIN32_LEAN_AND_MEAN\n")
file(APPEND ${OUTPUT} "#endif\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} "#include <windows.h>\n")
file(APPEND ${OUTPUT} "#include <Shlwapi.h>\n")
file(APPEND ${OUTPUT} "#include <delayimp.h>\n")
file(APPEND ${OUTPUT} "#include <string.h>\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} "static FARPROC WINAPI load_exe_hook(unsigned int event, DelayLoadInfo* info) {\n")
file(APPEND ${OUTPUT} " if (event != dliNotePreLoadLibrary) return NULL;\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} " if (_stricmp(info->szDll, \"iojs.exe\") != 0 &&\n")
file(APPEND ${OUTPUT} " _stricmp(info->szDll, \"node.exe\") != 0 &&\n")
file(APPEND ${OUTPUT} " _stricmp(info->szDll, \"node.dll\") != 0)\n")
file(APPEND ${OUTPUT} " return NULL;\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} " // Get a handle to the current process executable.\n")
file(APPEND ${OUTPUT} " HMODULE processModule = GetModuleHandle(NULL);\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} " // Get the path to the executable.\n")
file(APPEND ${OUTPUT} " TCHAR processPath[_MAX_PATH];\n")
file(APPEND ${OUTPUT} " GetModuleFileName(processModule, processPath, _MAX_PATH);\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} " // Get the name of the current executable.\n")
file(APPEND ${OUTPUT} " LPSTR processName = PathFindFileName(processPath);\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} " // If the current process is node or iojs, then just return the proccess \n")
file(APPEND ${OUTPUT} " // module.\n")
file(APPEND ${OUTPUT} " if (_stricmp(processName, \"node.exe\") == 0 ||\n")
file(APPEND ${OUTPUT} " _stricmp(processName, \"iojs.exe\") == 0) {\n")
file(APPEND ${OUTPUT} " return (FARPROC) processModule;\n")
file(APPEND ${OUTPUT} " }\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} " // If it is another process, attempt to load 'node.dll' from the same \n")
file(APPEND ${OUTPUT} " // directory.\n")
file(APPEND ${OUTPUT} " PathRemoveFileSpec(processPath);\n")
file(APPEND ${OUTPUT} " PathAppend(processPath, \"node.dll\");\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} " HMODULE nodeDllModule = GetModuleHandle(processPath);\n")
file(APPEND ${OUTPUT} " if(nodeDllModule != NULL) {\n")
file(APPEND ${OUTPUT} " // This application has a node.dll in the same directory as the executable,\n")
file(APPEND ${OUTPUT} " // use that.\n")
file(APPEND ${OUTPUT} " return (FARPROC) nodeDllModule;\n")
file(APPEND ${OUTPUT} " }\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} " // Fallback to the current executable, which must statically link to \n")
file(APPEND ${OUTPUT} " // node.lib\n")
file(APPEND ${OUTPUT} " return (FARPROC) processModule;\n")
file(APPEND ${OUTPUT} "}\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} "PfnDliHook __pfnDliNotifyHook2 = load_exe_hook;\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} "#endif\n")
endfunction()
# Sets up a project to build Node.js native modules
# - Downloads required dependencies and unpacks them to the build directory.
# Internet access is required the first invocation but not after (
# provided the download is successful)
# - Sets up several variables for building against the downloaded
# dependencies
# - Guarded to prevent multiple executions, so a single project hierarchy
# will only call this once
function(nodejs_init)
# Prevents this function from executing more than once
if(NODEJS_INIT)
return()
endif()
# Regex patterns used by the init function for component extraction
set(HEADERS_MATCH "^([A-Fa-f0-9]+)[ \t]+([^-]+)-(headers|v?[0-9.]+)-(headers|v?[0-9.]+)([.]tar[.]gz)$")
set(LIB32_MATCH "(^[0-9A-Fa-f]+)[\t ]+(win-x86)?(/)?([^/]*)(.lib)$")
set(LIB64_MATCH "(^[0-9A-Fa-f]+)[\t ]+(win-)?(x64/)(.*)(.lib)$")
# Parse function arguments
cmake_parse_arguments(nodejs_init
"" "URL;NAME;VERSION;CHECKSUM;CHECKTYPE" "" ${ARGN}
)
# Allow the download URL to be overridden by command line argument
# NODEJS_URL
if(NODEJS_URL)
set(URL ${NODEJS_URL})
else()
# Use the argument if specified, falling back to the default
set(URL ${NODEJS_DEFAULT_URL})
if(nodejs_init_URL)
set(URL ${nodejs_init_URL})
endif()
endif()
# Allow name to be overridden by command line argument NODEJS_NAME
if(NODEJS_NAME)
set(NAME ${NODEJS_NAME})
else()
# Use the argument if specified, falling back to the default
set(NAME ${NODEJS_DEFAULT_NAME})
if(nodejs_init_NAME)
set(NAME ${nodejs_init_NAME})
endif()
endif()
# Allow the checksum file to be overridden by command line argument
# NODEJS_CHECKSUM
if(NODEJS_CHECKSUM)
set(CHECKSUM ${NODEJS_CHECKSUM})
else()
# Use the argument if specified, falling back to the default
set(CHECKSUM ${NODEJS_DEFAULT_CHECKSUM})
if(nodejs_init_CHECKSUM)
set(CHECKSUM ${nodejs_init_CHECKSUM})
endif()
endif()
# Allow the checksum type to be overriden by the command line argument
# NODEJS_CHECKTYPE
if(NODEJS_CHECKTYPE)
set(CHECKTYPE ${NODEJS_CHECKTYPE})
else()
# Use the argument if specified, falling back to the default
set(CHECKTYPE ${NODEJS_DEFAULT_CHECKTYPE})
if(nodejs_init_CHECKTYPE)
set(CHECKTYPE ${nodejs_init_CHECKTYPE})
endif()
endif()
# Allow the version to be overridden by the command line argument
# NODEJS_VERSION
if(NODEJS_VERSION)
set(VERSION ${NODEJS_VERSION})
else()
# Use the argument if specified, falling back to the default
set(VERSION ${NODEJS_DEFAULT_VERSION})
if(nodejs_init_VERSION)
set(VERSION ${nodejs_init_VERSION})
endif()
endif()
# "installed" is a special version that tries to use the currently
# installed version (determined by running node)
set(NODEJS_INSTALLED False CACHE BOOL "Node.js install status" FORCE)
if(VERSION STREQUAL "installed")
if(NOT NAME STREQUAL ${NODEJS_DEFAULT_NAME})
message(FATAL_ERROR
"'Installed' version identifier can only be used with"
"the core Node.js library"
)
endif()
# Fall back to the "latest" version if node isn't installed
set(VERSION ${NODEJS_VERSION_FALLBACK})
find_program(NODEJS_BINARY NAMES node nodejs)
if(NODEJS_BINARY)
execute_process(
COMMAND ${NODEJS_BINARY} --version
RESULT_VARIABLE INSTALLED_VERSION_RESULT
OUTPUT_VARIABLE INSTALLED_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(INSTALLED_VERSION_RESULT STREQUAL "0")
set(NODEJS_INSTALLED True CACHE BOOL
"Node.js install status" FORCE
)
set(VERSION ${INSTALLED_VERSION})
endif()
endif()
endif()
# Create a temporary download directory
set(TEMP ${CMAKE_CURRENT_BINARY_DIR}/temp)
if(EXISTS ${TEMP})
file(REMOVE_RECURSE ${TEMP})
endif()
file(MAKE_DIRECTORY ${TEMP})
# Unless the target is special version "latest", the parameters
# necessary to construct the root path are known
if(NOT VERSION STREQUAL "latest")
set(ROOT ${CMAKE_CURRENT_BINARY_DIR}/${NAME}/${VERSION})
# Extract checksums from the existing checksum file
set(CHECKSUM_TARGET ${ROOT}/CHECKSUM)
endif()
# If we're trying to determine the version or we haven't saved the
# checksum file for this version, download it from the specified server
if(VERSION STREQUAL "latest" OR
(DEFINED ROOT AND NOT EXISTS ${ROOT}/CHECKSUM))
if(DEFINED ROOT)
# Clear away the old checksum in case the new one is different
# and/or it fails to download
file(REMOVE ${ROOT}/CHECKSUM)
endif()
file(REMOVE ${TEMP}/CHECKSUM)
download_file(
${URL}/${VERSION}/${CHECKSUM}
${TEMP}/CHECKSUM
INACTIVITY_TIMEOUT 10
STATUS CHECKSUM_STATUS
)
list(GET CHECKSUM_STATUS 0 CHECKSUM_STATUS)
if(CHECKSUM_STATUS GREATER 0)
file(REMOVE ${TEMP}/CHECKSUM)
message(FATAL_ERROR
"Unable to download checksum file"
)
endif()
# Extract checksums from the temporary file
set(CHECKSUM_TARGET ${TEMP}/CHECKSUM)
endif()
# Extract the version, name, header archive and archive checksum
# from the file. This first extract is what defines / specifies the
# actual version number and name.
file(STRINGS
${CHECKSUM_TARGET} HEADERS_CHECKSUM
REGEX ${HEADERS_MATCH}
LIMIT_COUNT 1
)
if(NOT HEADERS_CHECKSUM)
file(REMOVE ${TEMP}/CHECKSUM)
if(DEFINED ROOT)
file(REMOVE ${ROOT}/CHECKSUM)
endif()
message(FATAL_ERROR "Unable to extract header archive checksum")
endif()
string(REGEX MATCH ${HEADERS_MATCH} HEADERS_CHECKSUM ${HEADERS_CHECKSUM})
set(HEADERS_CHECKSUM ${CMAKE_MATCH_1})
set(NAME ${CMAKE_MATCH_2})
if(CMAKE_MATCH_3 STREQUAL "headers")
set(VERSION ${CMAKE_MATCH_4})
else()
set(VERSION ${CMAKE_MATCH_3})
endif()
set(HEADERS_ARCHIVE
${CMAKE_MATCH_2}-${CMAKE_MATCH_3}-${CMAKE_MATCH_4}${CMAKE_MATCH_5}
)
# Make sure that the root directory exists, and that the checksum
# file has been moved over from temp
if(DEFINED ROOT)
set(OLD_ROOT ${ROOT})
endif()
set(ROOT ${CMAKE_CURRENT_BINARY_DIR}/${NAME}/${VERSION})
if(DEFINED OLD_ROOT AND NOT ROOT STREQUAL "${OLD_ROOT}")
file(REMOVE ${TEMP}/CHECKSUM)
file(REMOVE ${ROOT}/CHECKSUM)
message(FATAL_ERROR "Version/Name mismatch")
endif()
file(MAKE_DIRECTORY ${ROOT})
if(EXISTS ${TEMP}/CHECKSUM)
file(REMOVE ${ROOT}/CHECKSUM)
file(RENAME ${TEMP}/CHECKSUM ${ROOT}/CHECKSUM)
endif()
# Now that its fully resolved, report the name and version of Node.js being
# used
message(STATUS "NodeJS: Using ${NAME}, version ${VERSION}")
# Download the headers for the version being used
# Theoretically, these could be found by searching the installed
# system, but in practice, this can be error prone. They're provided
# on the download servers, so just use the ones there.
if(NOT EXISTS ${ROOT}/include)
file(REMOVE ${TEMP}/${HEADERS_ARCHIVE})
download_file(
${URL}/${VERSION}/${HEADERS_ARCHIVE}
${TEMP}/${HEADERS_ARCHIVE}
INACTIVITY_TIMEOUT 10
EXPECTED_HASH ${CHECKTYPE}=${HEADERS_CHECKSUM}
STATUS HEADERS_STATUS
)
list(GET HEADERS_STATUS 0 HEADERS_STATUS)
if(HEADER_STATUS GREATER 0)
file(REMOVE ${TEMP}/${HEADERS_ARCHIVE})
message(FATAL_ERROR "Unable to download Node.js headers")
endif()
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar xfz ${TEMP}/${HEADERS_ARCHIVE}
WORKING_DIRECTORY ${TEMP}
)
# This adapts the header extraction to support a number of different
# header archive contents in addition to the one used by the
# default Node.js library
unset(NODEJS_HEADERS_PATH CACHE)
find_path(NODEJS_HEADERS_PATH
NAMES src include
PATHS
${TEMP}/${NAME}-${VERSION}-headers
${TEMP}/${NAME}-${VERSION}
${TEMP}/${NODEJS_DEFAULT_NAME}-${VERSION}-headers
${TEMP}/${NODEJS_DEFAULT_NAME}-${VERSION}
${TEMP}/${NODEJS_DEFAULT_NAME}
${TEMP}
NO_DEFAULT_PATH
)
if(NOT NODEJS_HEADERS_PATH)
message(FATAL_ERROR "Unable to find extracted headers folder")
endif()
# Move the headers into a standard location with a standard layout
file(REMOVE ${TEMP}/${HEADERS_ARCHIVE})
file(REMOVE_RECURSE ${ROOT}/include)
if(EXISTS ${NODEJS_HEADERS_PATH}/include/node)
file(RENAME ${NODEJS_HEADERS_PATH}/include/node ${ROOT}/include)
elseif(EXISTS ${NODEJS_HEADERS_PATH}/src)
file(MAKE_DIRECTORY ${ROOT}/include)
if(NOT EXISTS ${NODEJS_HEADERS_PATH}/src)
file(REMOVE_RECURSE ${ROOT}/include)
message(FATAL_ERROR "Unable to find core headers")
endif()
file(COPY ${NODEJS_HEADERS_PATH}/src/
DESTINATION ${ROOT}/include
)
if(NOT EXISTS ${NODEJS_HEADERS_PATH}/deps/uv/include)
file(REMOVE_RECURSE ${ROOT}/include)
message(FATAL_ERROR "Unable to find libuv headers")
endif()
file(COPY ${NODEJS_HEADERS_PATH}/deps/uv/include/
DESTINATION ${ROOT}/include
)
if(NOT EXISTS ${NODEJS_HEADERS_PATH}/deps/v8/include)
file(REMOVE_RECURSE ${ROOT}/include)
message(FATAL_ERROR "Unable to find v8 headers")
endif()
file(COPY ${NODEJS_HEADERS_PATH}/deps/v8/include/
DESTINATION ${ROOT}/include
)
if(NOT EXISTS ${NODEJS_HEADERS_PATH}/deps/zlib)
file(REMOVE_RECURSE ${ROOT}/include)
message(FATAL_ERROR "Unable to find zlib headers")
endif()
file(COPY ${NODEJS_HEADERS_PATH}/deps/zlib/
DESTINATION ${ROOT}/include
)
endif()
file(REMOVE_RECURSE ${NODEJS_HEADERS_PATH})
unset(NODEJS_HEADERS_PATH CACHE)
endif()
# Only download the libraries on windows, since its the only place
# its necessary. Note, this requires rerunning CMake if moving
# a module from one platform to another (should happen automatically
# with most generators)
if(WIN32)
# Download the win32 library for linking
file(STRINGS
${ROOT}/CHECKSUM LIB32_CHECKSUM
LIMIT_COUNT 1
REGEX ${LIB32_MATCH}
)
if(NOT LIB32_CHECKSUM)
message(FATAL_ERROR "Unable to extract x86 library checksum")
endif()
string(REGEX MATCH ${LIB32_MATCH} LIB32_CHECKSUM ${LIB32_CHECKSUM})
set(LIB32_CHECKSUM ${CMAKE_MATCH_1})
set(LIB32_PATH win-x86)
set(LIB32_NAME ${CMAKE_MATCH_4}${CMAKE_MATCH_5})
set(LIB32_TARGET ${CMAKE_MATCH_2}${CMAKE_MATCH_3}${LIB32_NAME})
if(NOT EXISTS ${ROOT}/${LIB32_PATH})
file(REMOVE_RECURSE ${TEMP}/${LIB32_PATH})
download_file(
${URL}/${VERSION}/${LIB32_TARGET}
${TEMP}/${LIB32_PATH}/${LIB32_NAME}
INACTIVITY_TIMEOUT 10
EXPECTED_HASH ${CHECKTYPE}=${LIB32_CHECKSUM}
STATUS LIB32_STATUS
)
list(GET LIB32_STATUS 0 LIB32_STATUS)
if(LIB32_STATUS GREATER 0)
message(FATAL_ERROR
"Unable to download Node.js windows library (32-bit)"
)
endif()
file(REMOVE_RECURSE ${ROOT}/${LIB32_PATH})
file(MAKE_DIRECTORY ${ROOT}/${LIB32_PATH})
file(RENAME
${TEMP}/${LIB32_PATH}/${LIB32_NAME}
${ROOT}/${LIB32_PATH}/${LIB32_NAME}
)
file(REMOVE_RECURSE ${TEMP}/${LIB32_PATH})
endif()
# Download the win64 library for linking
file(STRINGS
${ROOT}/CHECKSUM LIB64_CHECKSUM
LIMIT_COUNT 1
REGEX ${LIB64_MATCH}
)
if(NOT LIB64_CHECKSUM)
message(FATAL_ERROR "Unable to extract x64 library checksum")
endif()
string(REGEX MATCH ${LIB64_MATCH} LIB64_CHECKSUM ${LIB64_CHECKSUM})
set(LIB64_CHECKSUM ${CMAKE_MATCH_1})
set(LIB64_PATH win-x64)
set(LIB64_NAME ${CMAKE_MATCH_4}${CMAKE_MATCH_5})
set(LIB64_TARGET ${CMAKE_MATCH_2}${CMAKE_MATCH_3}${LIB64_NAME})
if(NOT EXISTS ${ROOT}/${LIB64_PATH})
file(REMOVE_RECURSE ${TEMP}/${LIB64_PATH})
download_file(
${URL}/${VERSION}/${LIB64_TARGET}
${TEMP}/${LIB64_PATH}/${LIB64_NAME}
INACTIVITY_TIMEOUT 10
EXPECTED_HASH ${CHECKTYPE}=${LIB64_CHECKSUM}
STATUS LIB64_STATUS
)
list(GET LIB64_STATUS 0 LIB64_STATUS)
if(LIB64_STATUS GREATER 0)
message(FATAL_ERROR
"Unable to download Node.js windows library (64-bit)"
)
endif()
file(REMOVE_RECURSE ${ROOT}/${LIB64_PATH})
file(MAKE_DIRECTORY ${ROOT}/${LIB64_PATH})
file(RENAME
${TEMP}/${LIB64_PATH}/${LIB64_NAME}
${ROOT}/${LIB64_PATH}/${LIB64_NAME}
)
file(REMOVE_RECURSE ${TEMP}/${LIB64_PATH})
endif()
endif()
# The downloaded headers should always be set for inclusion
list(APPEND INCLUDE_DIRS ${ROOT}/include)
# Look for the NAN module, and add it to the includes
find_nodejs_module(
nan
${CMAKE_CURRENT_SOURCE_DIR}
NODEJS_NAN_DIR
)
if(NODEJS_NAN_DIR)
list(APPEND INCLUDE_DIRS ${NODEJS_NAN_DIR})
endif()
# Under windows, we need a bunch of libraries (due to the way
# dynamic linking works)
if(WIN32)
# Generate and use a delay load hook to allow the node binary
# name to be changed while still loading native modules
set(DELAY_LOAD_HOOK ${CMAKE_CURRENT_BINARY_DIR}/win_delay_load_hook.c)
nodejs_generate_delayload_hook(${DELAY_LOAD_HOOK})
set(SOURCES ${DELAY_LOAD_HOOK})
# Necessary flags to get delayload working correctly
list(APPEND LINK_FLAGS
"-IGNORE:4199"
"-DELAYLOAD:iojs.exe"
"-DELAYLOAD:node.exe"
"-DELAYLOAD:node.dll"
)
# Core system libraries used by node
list(APPEND LIBRARIES
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib
odbc32.lib Shlwapi.lib DelayImp.lib
)
# Also link to the node stub itself (downloaded above)
if(CMAKE_CL_64)
list(APPEND LIBRARIES ${ROOT}/${LIB64_PATH}/${LIB64_NAME})
else()
list(APPEND LIBRARIES ${ROOT}/${LIB32_PATH}/${LIB32_NAME})
endif()
else()
# Non-windows platforms should use these flags
list(APPEND DEFINITIONS _LARGEFILE_SOURCE _FILE_OFFSET_BITS=64)
endif()
# Special handling for OSX / clang to allow undefined symbols
# Define is required by node on OSX
if(APPLE)
list(APPEND LINK_FLAGS "-undefined dynamic_lookup")
list(APPEND DEFINITIONS _DARWIN_USE_64_BIT_INODE=1)
endif()
# Export all settings for use as arguments in the rest of the build
set(NODEJS_VERSION ${VERSION} PARENT_SCOPE)
set(NODEJS_SOURCES ${SOURCES} PARENT_SCOPE)
set(NODEJS_INCLUDE_DIRS ${INCLUDE_DIRS} PARENT_SCOPE)
set(NODEJS_LIBRARIES ${LIBRARIES} PARENT_SCOPE)
set(NODEJS_LINK_FLAGS ${LINK_FLAGS} PARENT_SCOPE)
set(NODEJS_DEFINITIONS ${DEFINITIONS} PARENT_SCOPE)
# Prevents this function from executing more than once
set(NODEJS_INIT TRUE PARENT_SCOPE)
endfunction()
# Helper function for defining a node module
# After nodejs_init, all of the settings and dependencies necessary to do
# this yourself are defined, but this helps make sure everything is configured
# correctly. Feel free to use it as a model to do this by hand (or to
# tweak this configuration if you need something custom).
function(add_nodejs_module NAME)
# Validate name parameter (must be a valid C identifier)
string(MAKE_C_IDENTIFIER ${NAME} ${NAME}_SYMBOL_CHECK)
if(NOT "${NAME}" STREQUAL "${${NAME}_SYMBOL_CHECK}")
message(FATAL_ERROR
"Module name must be a valid C identifier. "
"Suggested alternative: '${${NAME}_SYMBOL_CHECK}'"
)
endif()
# Make sure node is initialized (variables set) before defining the module
if(NOT NODEJS_INIT)
message(FATAL_ERROR
"Node.js has not been initialized. "
"Call nodejs_init before adding any modules"
)
endif()
# In order to match node-gyp, we need to build into type specific folders
# ncmake takes care of this, but be sure to set CMAKE_BUILD_TYPE yourself
# if invoking CMake directly
if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
message(FATAL_ERROR
"Configuration type must be specified. "
"Set CMAKE_BUILD_TYPE or use a different generator"
)
endif()
# A node module is a shared library
add_library(${NAME} SHARED ${NODEJS_SOURCES} ${ARGN})
# Add compiler defines for the module
# Two helpful ones:
# MODULE_NAME must match the name of the build library, define that here
# ${NAME}_BUILD is for symbol visibility under windows
string(TOUPPER "${NAME}_BUILD" ${NAME}_BUILD_DEF)
target_compile_definitions(${NAME}
PRIVATE MODULE_NAME=${NAME}
PRIVATE ${${NAME}_BUILD_DEF}
PUBLIC ${NODEJS_DEFINITIONS}
)
# This properly defines includes for the module
target_include_directories(${NAME} PUBLIC ${NODEJS_INCLUDE_DIRS})
# Add link flags to the module
target_link_libraries(${NAME} ${NODEJS_LIBRARIES})
# Set required properties for the module to build properly
# Correct naming, symbol visiblity and C++ standard
set_target_properties(${NAME} PROPERTIES
OUTPUT_NAME ${NAME}
PREFIX ""
SUFFIX ".node"
MACOSX_RPATH ON
C_VISIBILITY_PRESET hidden
CXX_VISIBILITY_PRESET hidden
POSITION_INDEPENDENT_CODE TRUE
CMAKE_CXX_STANDARD_REQUIRED TRUE
CXX_STANDARD 11
LINK_FLAGS "${NODEJS_LINK_FLAGS}"
)
# Make sure we're buiilding in a build specific output directory
# Only necessary on single-target generators (Make, Ninja)
# Multi-target generators do this automatically
# This (luckily) mirrors node-gyp conventions
if(NOT CMAKE_CONFIGURATION_TYPES)
set_property(TARGET ${NAME} PROPERTY
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BUILD_TYPE}
)
endif()
endfunction()
+11 -18
View File
@@ -1,9 +1,15 @@
FROM alpine:3.5 FROM alpine:3.5
ARG DOCKER_TAG
RUN mkdir /src
COPY . /src
RUN mkdir /opt RUN mkdir /opt
WORKDIR /opt WORKDIR /opt
RUN NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \ RUN NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \
case ${DOCKER_TAG} in *"-debug"*) BUILD_TYPE="Debug";; *) BUILD_TYPE="Release";; esac && \
\
echo "@testing http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories && \ echo "@testing http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories && \
apk update && \ apk update && \
apk upgrade && \ apk upgrade && \
@@ -17,26 +23,13 @@ RUN NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \
cd build && \ cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \ cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j${NPROC} && \ make -j${NPROC} && \
make install make install && \
\
ARG DOCKER_TAG
RUN mkdir /src
COPY . /src
WORKDIR /src
RUN NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \
echo "Building OSRM ${DOCKER_TAG}" && \ echo "Building OSRM ${DOCKER_TAG}" && \
git show --format="%H" | head -n1 > /opt/OSRM_GITSHA && \ cd /src && \
echo "Building OSRM gitsha $(cat /opt/OSRM_GITSHA)" && \
mkdir build && \ mkdir build && \
cd build && \ cd build && \
BUILD_TYPE="Release" && \ cmake -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DENABLE_LTO=On .. && \
ENABLE_ASSERTIONS="Off" && \
BUILD_TOOLS="Off" && \
case ${DOCKER_TAG} in *"-debug"*) BUILD_TYPE="Debug";; esac && \
case ${DOCKER_TAG} in *"-assertions"*) BUILD_TYPE="RelWithDebInfo" && ENABLE_ASSERTIONS="On" && BUILD_TOOLS="On";; esac && \
echo "Building ${BUILD_TYPE} with ENABLE_ASSERTIONS=${ENABLE_ASSERTIONS} BUILD_TOOLS=${BUILD_TOOLS}" && \
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DENABLE_ASSERTIONS=${ENABLE_ASSERTIONS} -DBUILD_TOOLS=${BUILD_TOOLS} -DENABLE_LTO=On && \
make -j${NPROC} install && \ make -j${NPROC} install && \
cd ../profiles && \ cd ../profiles && \
cp -r * /opt && \ cp -r * /opt && \
+3 -8
View File
@@ -15,7 +15,7 @@ GET /{service}/{version}/{profile}/{coordinates}[.{format}]?option=value&option=
| `service` | One of the following values: [`route`](#route-service), [`nearest`](#nearest-service), [`table`](#table-service), [`match`](#match-service), [`trip`](#trip-service), [`tile`](#tile-service) | | `service` | One of the following values: [`route`](#route-service), [`nearest`](#nearest-service), [`table`](#table-service), [`match`](#match-service), [`trip`](#trip-service), [`tile`](#tile-service) |
| `version` | Version of the protocol implemented by the service. `v1` for all OSRM 5.x installations | | `version` | Version of the protocol implemented by the service. `v1` for all OSRM 5.x installations |
| `profile` | Mode of transportation, is determined statically by the Lua profile that is used to prepare the data using `osrm-extract`. Typically `car`, `bike` or `foot` if using one of the supplied profiles. | | `profile` | Mode of transportation, is determined statically by the Lua profile that is used to prepare the data using `osrm-extract`. Typically `car`, `bike` or `foot` if using one of the supplied profiles. |
| `coordinates`| String of format `{longitude},{latitude};{longitude},{latitude}[;{longitude},{latitude} ...]` or `polyline({polyline}) or polyline6({polyline6})`. | | `coordinates`| String of format `{longitude},{latitude};{longitude},{latitude}[;{longitude},{latitude} ...]` or `polyline({polyline})`. |
| `format`| Only `json` is supported at the moment. This parameter is optional and defaults to `json`. | | `format`| Only `json` is supported 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 by default and can be generated using [this package](https://www.npmjs.com/package/polyline). Passing any `option=value` is optional. `polyline` follows Google's polyline format with precision 5 by default and can be generated using [this package](https://www.npmjs.com/package/polyline).
@@ -30,7 +30,6 @@ To pass parameters to each location some options support an array like encoding:
|radiuses |`{radius};{radius}[;{radius} ...]` |Limits the search to given radius in meters. | |radiuses |`{radius};{radius}[;{radius} ...]` |Limits the search to given radius in meters. |
|generate\_hints |`true` (default), `false` |Adds a Hint to the response which can be used in subsequent requests, see `hints` parameter. | |generate\_hints |`true` (default), `false` |Adds a Hint to the response which can be used in subsequent requests, see `hints` parameter. |
|hints |`{hint};{hint}[;{hint} ...]` |Hint from previous request to derive position in street network. | |hints |`{hint};{hint}[;{hint} ...]` |Hint from previous request to derive position in street network. |
|approaches |`{approach};{approach}[;{approach} ...]` |Keep waypoints on curb side. |
Where the elements follow the following format: Where the elements follow the following format:
@@ -39,7 +38,6 @@ Where the elements follow the following format:
|bearing |`{value},{range}` `integer 0 .. 360,integer 0 .. 180` | |bearing |`{value},{range}` `integer 0 .. 360,integer 0 .. 180` |
|radius |`double >= 0` or `unlimited` (default) | |radius |`double >= 0` or `unlimited` (default) |
|hint |Base64 `string` | |hint |Base64 `string` |
|approach |`curb` or `unrestricted` (default) |
``` ```
{option}={element};{element}[;{element} ... ] {option}={element};{element}[;{element} ... ]
@@ -302,7 +300,7 @@ The area to search is chosen such that the correct candidate should be considere
Each `Waypoint` object has the following additional properties: Each `Waypoint` object has the following additional properties:
- `matchings_index`: Index to the `Route` object in `matchings` the sub-trace was matched to. - `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. - `waypoint_index`: Index of the waypoint inside the matched route.
- `alternatives_count`: Number of probable alternative matchings for this trace point. A value of zero indicate that this point was matched unambiguously. Split the trace at these points for incremental map matching. - `alternatives_count`: number of alternative routes leading to the destination from this trace point. 0 means there are no other routes reaching destination. Greater values mean that there are different routes available and different route can be selected if you provide more coordinates.
- `matchings`: An array of `Route` objects that assemble the trace. Each `Route` object has the following additional properties: - `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. - `confidence`: Confidence of the matching. `float` value between 0 and 1. 1 is very confident that the matching is correct.
@@ -419,10 +417,8 @@ Vector tiles contain two layers:
| `speed` | `integer` | the speed on that road segment, in km/h | | `speed` | `integer` | the speed on that road segment, in km/h |
| `is_small` | `boolean` | whether this segment belongs to a small (< 1000 node) [strongly connected component](https://en.wikipedia.org/wiki/Strongly_connected_component) | | `is_small` | `boolean` | whether this segment belongs to a small (< 1000 node) [strongly connected component](https://en.wikipedia.org/wiki/Strongly_connected_component) |
| `datasource` | `string` | the source for the speed value (normally `lua profile` unless you're using the [traffic update feature](https://github.com/Project-OSRM/osrm-backend/wiki/Traffic), in which case it contains the stem of the filename that supplied the speed value for this segment | | `datasource` | `string` | the source for the speed value (normally `lua profile` unless you're using the [traffic update feature](https://github.com/Project-OSRM/osrm-backend/wiki/Traffic), in which case it contains the stem of the filename that supplied the speed value for this segment |
| `duration` | `float` | how long this segment takes to traverse, in seconds. This value is to calculate the total route ETA. | | `duration` | `float` | how long this segment takes to traverse, in seconds |
| `weight ` | `integer` | how long this segment takes to traverse, in units (may differ from `duration` when artificial biasing is applied in the Lua profiles). ACTUAL ROUTING USES THIS VALUE. |
| `name` | `string` | the name of the road this segment belongs to | | `name` | `string` | the name of the road this segment belongs to |
| `rate` | `float` | the value of `length/weight` - analagous to `speed`, but using the `weight` value rather than `duration`, rounded to the nearest integer |
`turns` layer: `turns` layer:
@@ -431,7 +427,6 @@ Vector tiles contain two layers:
| `bearing_in` | `integer` | the absolute bearing that approaches the intersection. -180 to +180, 0 = North, 90 = East | | `bearing_in` | `integer` | the absolute bearing that approaches the intersection. -180 to +180, 0 = North, 90 = East |
| `turn_angle` | `integer` | the angle of the turn, relative to the `bearing_in`. -180 to +180, 0 = straight ahead, 90 = 90-degrees to the right | | `turn_angle` | `integer` | the angle of the turn, relative to the `bearing_in`. -180 to +180, 0 = straight ahead, 90 = 90-degrees to the right |
| `cost` | `float` | the time we think it takes to make that turn, in seconds. May be negative, depending on how the data model is constructed (some turns get a "bonus"). | | `cost` | `float` | the time we think it takes to make that turn, in seconds. May be negative, depending on how the data model is constructed (some turns get a "bonus"). |
| `weight` | `float` | the weight we think it takes to make that turn. May be negative, depending on how the data model is constructed (some turns get a "bonus"). ACTUAL ROUTING USES THIS VALUE |
## Result objects ## Result objects
-6
View File
@@ -47,7 +47,6 @@ Returns the fastest route between two or more coordinates while visiting the way
- `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`). (optional, default `simplified`) - `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`). (optional, default `simplified`)
- `options.continue_straight` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** 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. - `options.continue_straight` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** 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.
`null`/`true`/`false` `null`/`true`/`false`
- `options.approaches` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`.
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** - `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
**Examples** **Examples**
@@ -79,7 +78,6 @@ Note: `coordinates` in the general options only supports a single `{longitude},{
- `options.hints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Hints for the coordinate snapping. Array of base64 encoded strings. - `options.hints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Hints for the coordinate snapping. Array of base64 encoded strings.
- `options.number` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Number of nearest segments that should be returned. - `options.number` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Number of nearest segments that should be returned.
Must be an integer greater than or equal to `1`. (optional, default `1`) Must be an integer greater than or equal to `1`. (optional, default `1`)
- `options.approaches` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`.
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** - `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
**Examples** **Examples**
@@ -118,7 +116,6 @@ tables.
location with given index as source. Default is to use all. location with given index as source. Default is to use all.
- `options.destinations` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** An array of `index` elements (`0 <= integer < - `options.destinations` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** An array of `index` elements (`0 <= integer <
#coordinates`) to use location with given index as destination. Default is to use all. #coordinates`) to use location with given index as destination. Default is to use all.
- `options.approaches` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`.
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** - `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
**Examples** **Examples**
@@ -194,8 +191,6 @@ if they can not be matched successfully.
- `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`). (optional, default `simplified`) - `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`). (optional, default `simplified`)
- `options.timestamps` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>?** Timestamp of the input location (integers, UNIX-like timestamp). - `options.timestamps` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>?** Timestamp of the input location (integers, UNIX-like timestamp).
- `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Standard deviation of GPS precision used for map matching. If applicable use GPS accuracy. Can be `null` for default value `5` meters or `double >= 0`. - `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Standard deviation of GPS precision used for map matching. If applicable use GPS accuracy. Can be `null` for default value `5` meters or `double >= 0`.
- `options.gaps` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Allows the input track splitting based on huge timestamp gaps between points. Either `split` or `ignore`. (optional, default `split`)
- `options.tidy` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Allows the input track modification to obtain better matching quality for noisy tracks. (optional, default `false`)
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** - `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
**Examples** **Examples**
@@ -259,7 +254,6 @@ Right now, the following combinations are possible:
- `options.roundtrip` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route is a roundtrip. (optional, default `true`) - `options.roundtrip` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route is a roundtrip. (optional, default `true`)
- `options.source` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Return route starts at `any` or `first` coordinate. (optional, default `any`) - `options.source` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Return route starts at `any` or `first` coordinate. (optional, default `any`)
- `options.destination` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Return route ends at `any` or `last` coordinate. (optional, default `any`) - `options.destination` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Return route ends at `any` or `last` coordinate. (optional, default `any`)
- `options.approaches` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`.
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** - `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
**Examples** **Examples**
+23 -23
View File
@@ -29,40 +29,40 @@ The following global properties can be set in your profile:
Attribute | Type | Notes Attribute | Type | Notes
------------------------------|----------|---------------------------------------------------------------------------- ------------------------------|----------|----------------------------------------------------------------------------
weight_name | String | Name used in output for the routing weight property (default `'duration'`) weight_name | String | Name used in output for the routing weight property (default 'duration')
weight_precision | Unsigned | Decimal precision of edge weights (default `1`) weight_precision | Unsigned | Decimal precision of edge weights (default 1)
left_hand_driving | Boolean | Are vehicles assumed to drive on the left? (used in guidance, default `false`) left_hand_driving | Boolean | Are vehicles assumed to drive on the left? (used in guidance)
use_turn_restrictions | Boolean | Are turn instructions followed? (default `false`) use_turn_restrictions | Boolean | Are turn instructions followed?
continue_straight_at_waypoint | Boolean | Must the route continue straight on at a via point, or are U-turns allowed? (default `true`) continue_straight_at_waypoint | Boolean | Must the route continue straight on at a via point, or are U-turns allowed?
max_speed_for_map_matching | Float | Maximum vehicle speed to be assumed in matching (in m/s) max_speed_for_map_matching | Float | Maximum vehicle speed to be assumed in matching (in m/s)
max_turn_weight | Float | Maximum turn penalty weight max_turn_weight | Float | Maximum turn penalty weight
force_split_edges | Boolean | True value forces a split of forward and backward edges of extracted ways and guarantees that `segment_function` will be called for all segments (default `false`) force_split_edges | Boolean | True value forces a split of forward and backward edges of extracted ways and guarantees that segment_function will be called for all segments
## way_function ## 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. 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) 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. 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.
The following attributes can be set on the result in `way_function`: The following attributes can be set on the result in way_function:
Attribute | Type | Notes Attribute | Type | Notes
----------------------------------------|----------|-------------------------------------------------------------------------- ----------------------------------------|----------|--------------------------------------------------------------------------
forward_speed | Float | Speed on this way in km/h. Mandatory. forward_speed | Float | Speed on this way in km/h
backward_speed | Float | " " backward_speed | Float | " "
forward_rate | Float | Routing weight, expressed as meters/*weight* (e.g. for a fastest-route weighting, you would want this to be meters/second, so set it to forward_speed/3.6) forward_rate | Float | Routing weight, expressed as meters/*weight* (e.g. for a fastest-route weighting, you would want this to be meters/second, so set it to forward_speed/3.6)
backward_rate | Float | " " backward_rate | Float | " "
forward_mode | Enum | Mode of travel (e.g. `car`, `ferry`). Mandatory. Defined in `include/extractor/travel_mode.hpp`. forward_mode | Enum | Mode of travel (e.g. car, ferry). Defined in include/extractor/travel_mode.hpp
backward_mode | Enum | " " backward_mode | Enum | " "
duration | Float | Alternative setter for duration of the whole way in both directions duration | Float | Alternative setter for duration of the whole way in both directions
weight | Float | Alternative setter for weight of the whole way in both directions weight | Float | Alternative setter for weight of the whole way in both directions
turn_lanes_forward | String | Directions for individual lanes (normalised OSM `turn:lanes` value) turn_lanes_forward | String | Directions for individual lanes (normalised OSM turn:lanes value)
turn_lanes_backward | String | " " turn_lanes_backward | String | " "
forward_restricted | Boolean | Is this a restricted access road? (e.g. private, or deliveries only; used to enable high turn penalty, so that way is only chosen for start/end of route) forward_restricted | Boolean | Is this a restricted access road? (e.g. private, or deliveries only; used to enable high turn penalty, so that way is only chosen for start/end of route)
backward_restricted | Boolean | " " backward_restricted | Boolean | " "
is_startpoint | Boolean | Can a journey start on this way? (e.g. ferry; if `false`, prevents snapping the start point to this way) is_startpoint | Boolean | Can a journey start on this way? (e.g. ferry; if false, prevents snapping the start point to this way)
roundabout | Boolean | Is this part of a roundabout? roundabout | Boolean | Is this part of a roundabout?
circular | Boolean | Is this part of a non-roundabout circular junction? circular | Boolean | Is this part of a non-roundabout circular junction?
name | String | Name of the way name | String | Name of the way
@@ -70,7 +70,7 @@ ref | String | Road number
pronunciation | String | Name pronunciation pronunciation | String | Name pronunciation
road_classification.motorway_class | Boolean | Guidance: way is a motorway road_classification.motorway_class | Boolean | Guidance: way is a motorway
road_classification.link_class | Boolean | Guidance: way is a slip/link road road_classification.link_class | Boolean | Guidance: way is a slip/link road
road_classification.road_priority_class | Enum | Guidance: order in priority list. Defined in `include/extractor/guidance/road_classification.hpp` road_classification.road_priority_class | Enum | Guidance: order in priority list. Defined in include/extractor/guidance/road_classification.hpp
road_classification.may_be_ignored | Boolean | Guidance: way is non-highway road_classification.may_be_ignored | Boolean | Guidance: way is non-highway
road_classification.num_lanes | Unsigned | Guidance: total number of lanes in way road_classification.num_lanes | Unsigned | Guidance: total number of lanes in way
@@ -87,16 +87,16 @@ Forks can be emitted between roads of similar priority category only. Obvious ch
## node_function ## node_function
The following attributes can be set on the result in `node_function`: The following attributes can be set on the result in node_function:
Attribute | Type | Notes Attribute | Type | Notes
----------------|---------|------------------------------------------------------- ----------------|---------|-------------------------------------------------------
barrier | Boolean | Is it an impassable barrier? barrier | Boolean | Is it an impassable barrier?
traffic_lights | Boolean | Is it a traffic light (incurs delay in `turn_function`)? traffic_lights | Boolean | Is it a traffic light (incurs delay in turn_function)?
## segment_function ## segment_function
The following attributes can be read and set on the result in `segment_function`: The following attributes can be read and set on the result in segment_function:
Attribute | Read/write? | Type | Notes Attribute | Read/write? | Type | Notes
-------------------|-------------|---------|------------------------------------------------------ -------------------|-------------|---------|------------------------------------------------------
@@ -110,15 +110,15 @@ duration | Read/write | Float | Duration for this segment
## turn_function ## turn_function
The following attributes can be read and set on the result in `turn_function`: The following attributes can be read and set on the result in turn_function:
Attribute | Read/write? | Type | Notes Attribute | Read/write? | Type | Notes
-------------------|-------------|---------|------------------------------------------------------ -------------------|-------------|---------|------------------------------------------------------
direction_modifier | Read | Enum | Geometry of turn. Defined in `include/extractor/guidance/turn_instruction.hpp` direction_modifier | Read | Enum | Geometry of turn. Defined in include/extractor/guidance/turn_instruction.hpp
turn_type | Read | Enum | Priority of turn. Defined in `include/extractor/guidance/turn_instruction.hpp` turn_type | Read | Enum | Priority of turn. Defined in include/extractor/guidance/turn_instruction.hpp
has_traffic_light | Read | Boolean | Is a traffic light present at this turn? has_traffic_light | Read | Boolean | Is a traffic light present at this turn?
source_restricted | Read | Boolean | Is it from a restricted access road? (See definition in `way_function`) source_restricted | Read | Boolean | Is it from a restricted access road? (See definition in way_function)
target_restricted | Read | Boolean | Is it to a restricted access road? (See definition in `way_function`) target_restricted | Read | Boolean | Is it to a restricted access road? (See definition in way_function)
angle | Read | Float | Angle of turn in degrees (`0-360`: `0`=u-turn, `180`=straight on) angle | Read | Float | Angle of turn in degrees (0-360: 0=u-turn, 180=straight on)
duration | Read/write | Float | Penalty to be applied for this turn (duration in deciseconds) duration | Read/write | Float | Penalty to be applied for this turn (duration in deciseconds)
weight | Read/write | Float | Penalty to be applied for this turn (routing weight) weight | Read/write | Float | Penalty to be applied for this turn (routing weight)
+30 -1
View File
@@ -2,9 +2,38 @@
Feature: Turn Penalties Feature: Turn Penalties
Background: Background:
Given the profile "bicycle" Given the profile "turnbot"
Given a grid size of 200 meters Given a grid size of 200 meters
Scenario: Bike - turns should incur a delay that depend on the angle
Given the node map
"""
c d e
b j f
a s g
"""
And the ways
| nodes |
| sj |
| ja |
| jb |
| jc |
| jd |
| je |
| jf |
| jg |
When I route I should get
| from | to | route | time | distance |
| s | a | sj,ja,ja | 63s +-1 | 483m +-1 |
| s | b | sj,jb,jb | 50s +-1 | 400m +-1 |
| s | c | sj,jc,jc | 54s +-1 | 483m +-1 |
| s | d | sj,jd,jd | 40s +-1 | 400m +-1 |
| s | e | sj,je,je | 53s +-1 | 483m +-1 |
| s | f | sj,jf,jf | 50s +-1 | 400m +-1 |
| s | g | sj,jg,jg | 63s +-1 | 483m +-1 |
Scenario: Bicycle - Turn penalties on cyclability Scenario: Bicycle - Turn penalties on cyclability
Given the profile file Given the profile file
-192
View File
@@ -1,192 +0,0 @@
@routing @approach
Feature: Approach parameter
Background:
Given the profile "car"
And a grid size of 10 meters
Scenario: Start End same approach, option unrestricted for Start and End
Given the node map
"""
s e
a------b------c
"""
And the ways
| nodes |
| ab |
| bc |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted unrestricted | ab,bc |
Scenario: Start End same approach, option unrestricted for Start and curb for End
Given the node map
"""
s e
a------b------c
"""
And the ways
| nodes |
| ab |
| bc |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted curb | ab,bc,bc |
Scenario: Start End opposite approach, option unrestricted for Start and End
Given the node map
"""
s
a------b------c
e
"""
And the ways
| nodes |
| ab |
| bc |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted unrestricted | ab,bc |
Scenario: Start End opposite approach, option unrestricted for Start and curb for End
Given the node map
"""
s
a------b------c
e
"""
And the ways
| nodes |
| ab |
| bc |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted curb | ab,bc |
###############
# Oneway Test #
###############
Scenario: Test on oneway segment, Start End same approach, option unrestricted for Start and End
Given the node map
"""
s e
a------b------c
"""
And the ways
| nodes | oneway |
| ab | yes |
| bc | yes |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted unrestricted | ab,bc |
Scenario: Test on oneway segment, Start End same approach, option unrestricted for Start and curb for End
Given the node map
"""
s e
a------b------c
"""
And the ways
| nodes | oneway |
| ab | yes |
| bc | yes |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted curb | ab,bc |
Scenario: Test on oneway segment, Start End opposite approach, option unrestricted for Start and End
Given the node map
"""
s
a------b------c
e
"""
And the ways
| nodes | oneway |
| ab | yes |
| bc | yes |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted unrestricted | ab,bc |
Scenario: Test on oneway segment, Start End opposite approach, option unrestricted for Start and curb for End
Given the node map
"""
s
a------b------c
e
"""
And the ways
| nodes | oneway |
| ab | yes |
| bc | yes |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted curb | ab,bc |
##############
# UTurn Test #
##############
Scenario: UTurn test, router can't found a route because uturn unauthorized on the segment selected
Given the node map
"""
s e
a------b------c
"""
And the ways
| nodes |
| ab |
| bc |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | bc | bc | c | no_u_turn |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted curb | |
Scenario: UTurn test, router can found a route because he can use the roundabout
Given the node map
"""
h
s e / \
a------b------c g
\ /
f
"""
And the ways
| nodes | junction |
| ab | |
| bc | |
| cfghc | roundabout |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | bc | bc | c | no_u_turn |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted curb | ab,bc,bc |
@@ -1,741 +0,0 @@
@routing @car @restrictions
Feature: Car - Turn restrictions
# Handle turn restrictions as defined by http://wiki.openstreetmap.org/wiki/Relation:restriction
# Note that if u-turns are allowed, turn restrictions can lead to suprising, but correct, routes.
Background: Use car routing
Given the profile "car"
Given a grid size of 200 meters
Given the origin -9.2972,10.3811
# coordinate in Guinée, a country that observes GMT year round
@no_turning @conditionals
Scenario: Car - ignores unrecognized restriction
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | nj | j | only_right_turn @ (has_pygmies > 10 p) |
When I route I should get
| from | to | route |
| e | s | ej,js,js |
| e | n | ej,nj,nj |
| e | p | ej,jp,jp |
@no_turning @conditionals
Scenario: Car - Restriction would be on, but the restriction was badly tagged
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p |
\ |
j
| \
s m
"""
And the ways
| nodes |
| nj |
| js |
| pjm |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | nj | pjm | j | no_left_turn @ (Mo-Fr 07:00-10:30) |
| restriction | js | pjm | j | no_right_turn @ (Mo-Fr 07:00-10:30) |
When I route I should get
| from | to | route |
| n | m | nj,pjm,pjm |
| s | m | js,pjm,pjm |
@no_turning @conditionals
Scenario: Car - ignores except restriction
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | no |
| jp | no |
And the relations
| type | way:from | way:to | node:via | restriction:conditional | except |
| restriction | ej | nj | j | only_right_turn @ (Mo-Su 08:00-12:00) | motorcar |
| restriction | jp | nj | j | only_left_turn @ (Mo-Su 08:00-12:00) | bus |
When I route I should get
| from | to | route | # |
| e | s | ej,js,js | |
| e | n | ej,nj,nj | restriction does not apply to cars |
| e | p | ej,jp,jp | |
| p | s | jp,nj,nj,js,js | restriction excepting busses still applies to cars |
@no_turning @conditionals
Scenario: Car - only_right_turn
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | nj | j | only_right_turn @ (Mo-Su 07:00-14:00) |
When I route I should get
| from | to | route |
| e | s | ej,nj,nj,js,js |
| e | n | ej,nj,nj |
| e | p | ej,nj,nj,jp,jp |
@no_turning @conditionals
Scenario: Car - No right turn
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | nj | j | no_right_turn @ (Mo-Fr 07:00-13:00) |
When I route I should get
| from | to | route | # |
| e | s | ej,js,js | normal turn |
| e | n | ej,js,js,nj,nj | avoids right turn |
| e | p | ej,jp,jp | normal maneuver |
@only_turning @conditionals
Scenario: Car - only_left_turn
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | js | j | only_left_turn @ (Mo-Fr 07:00-16:00) |
When I route I should get
| from | to | route |
| e | s | ej,js,js |
| e | n | ej,js,js,nj,nj |
| e | p | ej,js,js,jp,jp |
@no_turning @conditionals
Scenario: Car - No left turn
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | js | j | no_left_turn @ (Mo-Su 00:00-23:59) |
When I route I should get
| from | to | route |
| e | s | ej,nj,nj,js,js |
| e | n | ej,nj,nj |
| e | p | ej,jp,jp |
@no_turning @conditionals
Scenario: Car - Conditional restriction is off
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | nj | j | no_right_turn @ (Mo-Su 16:00-20:00) |
When I route I should get
| from | to | route |
| e | s | ej,js,js |
| e | n | ej,nj,nj |
| e | p | ej,jp,jp |
@no_turning @conditionals
Scenario: Car - Conditional restriction is on
Given the extract extra arguments "--parse-conditional-restrictions"
# 10am utc, wed
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493805600"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493805600"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | nj | j | no_right_turn @ (Mo-Fr 07:00-14:00) |
When I route I should get
| from | to | route |
| e | s | ej,js,js |
| e | n | ej,js,js,nj,nj |
| e | p | ej,jp,jp |
@no_turning @conditionals
Scenario: Car - Conditional restriction with multiple time windows
Given the extract extra arguments "--parse-conditional-restrictions"
# 5pm Wed 02 May, 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493744400"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493744400"
Given the node map
"""
n
p |
\ |
j
| \
s m
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| jp | yes |
| mj | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | nj | jp | j | no_right_turn @ (Mo-Fr 07:00-11:00,16:00-18:30) |
When I route I should get
| from | to | route |
| n | p | nj,js,js,jp,jp |
| m | p | mj,jp,jp |
@no_turning @conditionals
Scenario: Car - only_right_turn
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | nj | j | only_right_turn @ (Mo-Su 07:00-14:00) |
When I route I should get
| from | to | route |
| e | s | ej,nj,nj,js,js |
| e | n | ej,nj,nj |
| e | p | ej,nj,nj,jp,jp |
@no_turning @conditionals
Scenario: Car - No right turn
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | nj | j | no_right_turn @ (Mo-Fr 07:00-13:00) |
When I route I should get
| from | to | route | # |
| e | s | ej,js,js | normal turn |
| e | n | ej,js,js,nj,nj | avoids right turn |
| e | p | ej,jp,jp | normal maneuver |
@only_turning @conditionals
Scenario: Car - only_left_turn
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | js | j | only_left_turn @ (Mo-Fr 07:00-16:00) |
When I route I should get
| from | to | route |
| e | s | ej,js,js |
| e | n | ej,js,js,nj,nj |
| e | p | ej,js,js,jp,jp |
@no_turning @conditionals
Scenario: Car - No left turn
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | js | j | no_left_turn @ (Mo-Su 00:00-23:59) |
When I route I should get
| from | to | route |
| e | s | ej,nj,nj,js,js |
| e | n | ej,nj,nj |
| e | p | ej,jp,jp |
@no_turning @conditionals
Scenario: Car - Conditional restriction is off
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | nj | j | no_right_turn @ (Mo-Su 16:00-20:00) |
When I route I should get
| from | to | route |
| e | s | ej,js,js |
| e | n | ej,nj,nj |
| e | p | ej,jp,jp |
@no_turning @conditionals
Scenario: Car - Conditional restriction is on
Given the extract extra arguments "--parse-conditional-restrictions"
# 10am utc, wed
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493805600"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493805600"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | nj | j | no_right_turn @ (Mo-Fr 07:00-14:00) |
When I route I should get
| from | to | route |
| e | s | ej,js,js |
| e | n | ej,js,js,nj,nj |
| e | p | ej,jp,jp |
@no_turning @conditionals
Scenario: Car - Conditional restriction with multiple time windows
Given the extract extra arguments "--parse-conditional-restrictions"
# 5pm Wed 02 May, 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493744400"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493744400"
Given the node map
"""
n
p |
\ |
j
| \
s m
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| jp | yes |
| mj | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | nj | jp | j | no_right_turn @ (Mo-Fr 07:00-11:00,16:00-18:30) |
When I route I should get
| from | to | route |
| n | p | nj,js,js,jp,jp |
| m | p | mj,jp,jp |
# https://www.openstreetmap.org/#map=18/38.91099/-77.00888
@no_turning @conditionals
Scenario: Car - DC North capitol situation, two on one off
Given the extract extra arguments "--parse-conditional-restrictions=1"
# 9pm Wed 02 May, 2017 UTC, 5pm EDT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/dc.geojson --parse-conditionals-from-now=1493845200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/dc.geojson --parse-conditionals-from-now=1493845200"
# """
# a h
# d
# b g
# e
# c f
# """
Given the node locations
| node | lat | lon |
| a | 38.9113 | -77.0091 |
| b | 38.9108 | -77.0091 |
| c | 38.9104 | -77.0091 |
| d | 38.9110 | -77.0096 |
| e | 38.9106 | -77.0086 |
| f | 38.9105 | -77.0090 |
| g | 38.9108 | -77.0090 |
| h | 38.9113 | -77.0090 |
And the ways
| nodes | oneway | name |
| ab | yes | cap south |
| bc | yes | cap south |
| fg | yes | cap north |
| gh | yes | cap north |
| db | no | florida nw |
| bg | no | florida |
| ge | no | florida ne |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ab | bg | b | no_left_turn @ (Mo-Fr 07:00-09:30,16:00-18:30) |
| restriction | fg | bg | g | no_left_turn @ (Mo-Fr 06:00-10:00) |
| restriction | bg | bc | b | no_left_turn @ (Mo-Fr 07:00-09:30,16:00-18:30) |
When I route I should get
| from | to | route | turns |
| a | e | cap south,florida nw,florida nw,florida ne | depart,turn right,continue uturn,arrive |
| f | d | cap north,florida,florida nw | depart,turn left,arrive |
| e | c | florida ne,florida nw,cap south,cap south | depart,continue uturn,turn right,arrive |
@no_turning @conditionals
Scenario: Car - DC North capitol situation, one on two off
Given the extract extra arguments "--parse-conditional-restrictions=1"
# 10:30am utc, wed, 6:30am est
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/dc.geojson --parse-conditionals-from-now=1493807400"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/dc.geojson --parse-conditionals-from-now=1493807400"
# """
# a h
# d
# b g
# e
# c f
# """
Given the node locations
| node | lat | lon |
| a | 38.9113 | -77.0091 |
| b | 38.9108 | -77.0091 |
| c | 38.9104 | -77.0091 |
| d | 38.9110 | -77.0096 |
| e | 38.9106 | -77.0086 |
| f | 38.9105 | -77.0090 |
| g | 38.9108 | -77.0090 |
| h | 38.9113 | -77.0090 |
And the ways
| nodes | oneway | name |
| ab | yes | cap south |
| bc | yes | cap south |
| fg | yes | cap north |
| gh | yes | cap north |
| db | no | florida nw |
| bg | no | florida |
| ge | no | florida ne |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ab | bg | b | no_left_turn @ (Mo-Fr 07:00-09:30,16:00-18:30) |
| restriction | fg | bg | g | no_left_turn @ (Mo-Fr 06:00-10:00) |
| restriction | bg | bc | b | no_left_turn @ (Mo-Fr 07:00-09:30,16:00-18:30) |
When I route I should get
| from | to | route | turns |
| a | e | cap south,florida,florida ne | depart,turn left,arrive |
| f | d | cap north,florida ne,florida ne,florida nw | depart,turn sharp right,continue uturn,arrive |
| e | c | florida ne,cap south,cap south | depart,turn left,arrive |
@only_turning @conditionals
Scenario: Car - Restriction is always off when point not found in timezone files
# same test as the following one, but given a different time zone file
Given the extract extra arguments "--parse-conditional-restrictions"
# 9am UTC, 10am BST
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/dc.geojson --parse-conditionals-from-now=1493802000"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/dc.geojson --parse-conditionals-from-now=1493802000"
# """
# a
# e
# b
# d
# c
# """
Given the node locations
| node | lat | lon |
| a | 51.5250 | -0.1166 |
| b | 51.5243 | -0.1159 |
| c | 51.5238 | -0.1152 |
| d | 51.5241 | -0.1167 |
| e | 51.5247 | -0.1153 |
And the ways
| nodes | name |
| ab | albic |
| bc | albic |
| db | dobe |
| be | dobe |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ab | be | b | only_left_turn @ (Mo-Fr 07:00-11:00) |
When I route I should get
| from | to | route | turns |
| a | c | albic,albic | depart,arrive |
| a | e | albic,dobe,dobe | depart,turn left,arrive |
@only_turning @conditionals
Scenario: Car - Somewhere in london, the UK, GMT timezone
Given the extract extra arguments "--parse-conditional-restrictions"
# 9am UTC, 10am BST
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/london.geojson --parse-conditionals-from-now=1493802000"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/london.geojson --parse-conditionals-from-now=1493802000"
# """
# a
# e
# b
# d
# c
# """
Given the node locations
| node | lat | lon |
| a | 51.5250 | -0.1166 |
| b | 51.5243 | -0.1159 |
| c | 51.5238 | -0.1152 |
| d | 51.5241 | -0.1167 |
| e | 51.5247 | -0.1153 |
And the ways
| nodes | name |
| ab | albic |
| bc | albic |
| db | dobe |
| be | dobe |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ab | be | b | only_left_turn @ (Mo-Fr 07:00-11:00) |
When I route I should get
| from | to | route | turns |
| a | c | albic,dobe,dobe,albic,albic | depart,turn left,continue uturn,turn left,arrive |
| a | e | albic,dobe,dobe | depart,turn left,arrive |
@only_turning @conditionals
Scenario: Car - Somewhere in London, the UK, GMT timezone
Given the extract extra arguments "--parse-conditional-restrictions=1"
# 9am UTC, 10am BST
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/london.geojson --parse-conditionals-from-now=1493802000"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/london.geojson --parse-conditionals-from-now=1493802000"
# """
# a
# e
# b
# d
# c
# """
Given the node locations
| node | lat | lon |
| a | 51.5250 | -0.1166 |
| b | 51.5243 | -0.1159 |
| c | 51.5238 | -0.1152 |
| d | 51.5241 | -0.1167 |
| e | 51.5247 | -0.1153 |
And the ways
| nodes | name |
| ab | albic |
| bc | albic |
| db | dobe |
| be | dobe |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ab | be | b | only_left_turn @ (Mo-Fr 07:00-11:00) |
When I route I should get
| from | to | route | turns |
| a | c | albic,dobe,dobe,albic,albic | depart,turn left,continue uturn,turn left,arrive |
| a | e | albic,dobe,dobe | depart,turn left,arrive |
+2 -2
View File
@@ -60,8 +60,8 @@ Feature: Basic Routing
| bc | | 101 | | bc | | 101 |
When I route I should get When I route I should get
| waypoints | route | summary | | waypoints | route | summary |
| a,c | road,, | road, 101 | | a,c | road, | road, 101 |
Scenario: Only Refs Scenario: Only Refs
Given the node map Given the node map
-33
View File
@@ -1,33 +0,0 @@
@routing @via
Feature: Via points
Background:
Given the profile "car"
# See issue #1896
Scenario: Via point at a dead end with barrier
Given the profile "car"
Given the node map
"""
a b c
1
d
f e
"""
And the nodes
| node | barrier |
| d | bollard |
And the ways
| nodes |
| abc |
| bd |
| afed |
When I route I should get
| waypoints | route |
| a,1,c | abc,bd,bd,bd,bd,abc,abc |
| c,1,a | abc,bd,bd,bd,bd,abc,abc |
+4 -4
View File
@@ -35,10 +35,10 @@ Feature: Turn Lane Guidance
| restriction | bc | cd | c | no_right_turn | | restriction | bc | cd | c | no_right_turn |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,e | in,cross,cross | depart,turn left,arrive | ,left:true straight:false, | | a,e | in,cross,cross | depart,turn left,arrive | ,left:true straight:false right:false, |
| a,g | in,straight,straight | depart,new name straight,arrive | ,left:false straight:true, | | a,g | in,straight,straight | depart,new name straight,arrive | ,left:false straight:true right:false, |
| a,f | in,cross,cross | depart,continue right,arrive | ,, | | a,f | in,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true, |
@sliproads @sliproads
Scenario: Separate Turn Lanes Scenario: Separate Turn Lanes
+9 -28
View File
@@ -359,7 +359,7 @@ Feature: Collapse
| a,g | first,second,second | depart,turn left,arrive | a,b,g | | a,g | first,second,second | depart,turn left,arrive | a,b,g |
| d,g | first,second,second | depart,turn right,arrive | d,e,g | | d,g | first,second,second | depart,turn right,arrive | d,e,g |
| g,f | second,first,first | depart,turn right,arrive | g,e,f | | g,f | second,first,first | depart,turn right,arrive | g,e,f |
| g,c | second,first,first | depart,turn left,arrive | g,e,c | | g,c | second,first,first | depart,end of road left,arrive | g,b,c |
Scenario: Do not collapse turning roads Scenario: Do not collapse turning roads
Given the node map Given the node map
@@ -690,9 +690,9 @@ Feature: Collapse
| restriction | bc | dc | c | no_right_turn | | restriction | bc | dc | c | no_right_turn |
When I route I should get When I route I should get
| waypoints | route | turns | locations | | waypoints | route | turns | locations |
| a,g | road,road,cross,cross | depart,continue slight left,turn left,arrive | a,b,c,g | | a,g | road,cross,cross | depart,turn left,arrive | a,b,g |
| a,e | road,road | depart,arrive | a,e | | a,e | road,road | depart,arrive | a,e |
Scenario: On-Off on Highway Scenario: On-Off on Highway
Given the node map Given the node map
@@ -996,8 +996,8 @@ Feature: Collapse
a . . b .' a . . b .'
` d. ` d.
f e f e
""" """
#Check collapse.detail for a similar case (shorter) that does not classify these turns as a sliproad anymore #Check collapse.detail for a similar case (shorter) that does not classify these turns as a sliproad anymore
And the ways And the ways
| nodes | name | oneway | highway | | nodes | name | oneway | highway |
@@ -1016,9 +1016,9 @@ Feature: Collapse
When I route I should get When I route I should get
| waypoints | route | turns | locations | | waypoints | route | turns | locations |
| a,g | road,road,cross,cross | depart,fork slight left,turn left,arrive | a,b,c,g | | a,g | road,cross,cross | depart,fork left,arrive | a,b,g |
| a,e | road,road,road | depart,fork slight right,arrive | a,b,e | | a,e | road,road,road | depart,fork slight right,arrive | a,b,e |
| a,f | road,road,cross,cross | depart,fork slight right,turn right,arrive | a,b,d,f | | a,f | road,road,cross,cross | depart,fork slight right,turn right,arrive | a,b,d,f |
# http://www.openstreetmap.org/way/92415447 #3933 # http://www.openstreetmap.org/way/92415447 #3933
@@ -1055,22 +1055,3 @@ Feature: Collapse
When I route I should get When I route I should get
| waypoints | route | turns | locations | | waypoints | route | turns | locations |
| a,i | President Avenue,Princes Highway,Princes Highway | depart,turn left,arrive | a,b,i | | a,i | President Avenue,Princes Highway,Princes Highway | depart,turn left,arrive | a,b,i |
Scenario: Don't combine uturns
Given the node map
"""
2 d
a - - b - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c
1
"""
And the ways
| nodes | highway |
| ab | tertiary |
| bc | tertiary |
| bd | service |
When I route I should get
| waypoints | bearings | route | turns | locations |
| 1,2 | 90 270 | ab,bd,bd,ab,ab | depart,turn left,continue uturn,turn right,arrive | _,b,d,b,_ |
-48
View File
@@ -1,48 +0,0 @@
@driveway @guidance
Feature: Driveways intersections
Background:
Given the profile "car"
Given a grid size of 5 meters
Scenario: Road with a turn to service road
Given the node map
"""
a
~.
b----c----d
|
e
"""
And the ways
| nodes | highway | name | oneway |
| abc | trunk | first | yes |
| cd | trunk | second | yes |
| be | service | parking | yes |
When I route I should get
| waypoints | route | turns | locations |
| a,d | first,second | depart,arrive | a,d |
Scenario: Turn Instead of Ramp
Given the node map
"""
a
~.
b----c----d
|
e
"""
And the ways
| nodes | highway | name | oneway |
| ab | trunk | | yes |
| bc | trunk | | yes |
| cd | trunk | second | yes |
| be | service | parking | yes |
When I route I should get
| waypoints | route | turns | locations |
| a,d | ,second | depart,arrive | a,d |
@@ -37,37 +37,3 @@ Feature: Basic Roundabout
| h,a | gh,ab,ab | depart,roundabout turn left exit-3,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,d | gh,cd,cd | depart,roundabout turn straight exit-2,arrive |
| h,f | gh,ef,ef | depart,roundabout turn right exit-1,arrive | | h,f | gh,ef,ef | depart,roundabout turn right exit-1,arrive |
# https://www.openstreetmap.org/way/223225602
Scenario: Enter and Exit with changing mode
Given the node map
"""
a
b
h g c d
e
f
"""
And the ways
| nodes | junction | highway |
| ab | | residential |
| cd | | residential |
| ef | | footway |
| gh | | footway |
| bgecb | roundabout | residential |
When I route I should get
| waypoints | route | turns |
| a,d | ab,cd,cd | depart,roundabout turn left exit-1,arrive |
| a,f | ab,ef,ef,ef | depart,roundabout turn left exit-1,notification right,arrive |
| a,h | ab,bgecb,gh,gh | depart,roundabout turn right exit-1,notification right,arrive |
| d,f | cd,ef,ef,ef | depart,roundabout turn sharp left exit-2,notification right,arrive |
| d,h | cd,gh,gh,gh | depart,roundabout turn left exit-2,notification right,arrive |
| d,a | cd,ab,ab | depart,roundabout turn right exit-1,arrive |
| f,h | ef,gh,gh,gh | depart,roundabout turn sharp left exit-3,notification right,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-2,arrive |
| h,d | gh,cd,cd | depart,roundabout turn straight exit-1,arrive |
| h,f | gh,bgecb,ef,ef | depart,roundabout turn right exit-1,notification right,arrive |
+26 -52
View File
@@ -769,6 +769,32 @@ Feature: Basic Roundabout
| g,h | 45 135 | gch,gch,gch | depart,roundabout-exit-1,arrive | | g,h | 45 135 | gch,gch,gch | depart,roundabout-exit-1,arrive |
| e,e | 90 270 | edf,edf,edf | depart,roundabout-exit-3,arrive | | e,e | 90 270 | edf,edf,edf | depart,roundabout-exit-3,arrive |
@4030 @4075
Scenario: Service roundabout with service exits
# Counting of service exits must be adjusted in #4075
Given the node map
"""
e
f a d
g b1c
h
"""
And the ways
| nodes | highway | junction |
| abcda | service | roundabout |
| de | service | |
| af | service | |
| bg | tertiary | |
| bh | service | |
When I route I should get
| from | to | route | turns |
| 1 | e | abcda,de,de | depart,roundabout-exit-1,arrive |
| 1 | f | abcda,af,af | depart,roundabout-exit-1,arrive |
| 1 | g | abcda,bg,bg | depart,roundabout-exit-1,arrive |
| 1 | h | abcda,bh,bh | depart,roundabout-exit-1,arrive |
Scenario: CCW and CW roundabouts with overlaps Scenario: CCW and CW roundabouts with overlaps
Given the node map Given the node map
""" """
@@ -794,55 +820,3 @@ Feature: Basic Roundabout
| k | l | kg,hl,hl | depart,roundabout-exit-1,arrive | 80.1m | | k | l | kg,hl,hl | depart,roundabout-exit-1,arrive | 80.1m |
| l | k | hl,kg,kg | depart,roundabout-exit-1,arrive | 120.1m | | l | k | hl,kg,kg | depart,roundabout-exit-1,arrive | 120.1m |
@4030 @4075
Scenario: Service roundabout with service exits
Given the node map
"""
g a d f
h b1c e
"""
And the ways
| nodes | highway | junction |
| abcda | service | roundabout |
| ce | service | |
| df | service | |
| ag | tertiary | |
| bh | service | |
When I route I should get
| from | to | route | turns |
| 1 | e | abcda,ce,ce | depart,roundabout-exit-1,arrive |
| 1 | f | abcda,df,df | depart,roundabout-exit-2,arrive |
| 1 | g | abcda,ag,ag | depart,roundabout-exit-3,arrive |
| 1 | h | abcda,bh,bh | depart,roundabout-exit-4,arrive |
Scenario: Collapsing a sliproad step after roundabouts
Given the node map
"""
a r j
eb1ds ufghl
`i
c t
m v k
"""
And the ways
| nodes | highway | junction | oneway | # |
| abcda | tertiary | roundabout | | circle |
| ebds | tertiary | | | road |
| cm | tertiary | | | |
| ds | tertiary | | | road |
| rstur | tertiary | roundabout | | circle2 |
| ufghl | tertiary | | | road |
| tv | tertiary | | | |
| gi | tertiary | | yes | sliproad |
| jhik | tertiary | | | crossroad |
When I route I should get
| from | to | route | turns | distance |
| e | k | ebds,ebds,ds,ufghl,jhik,jhik | depart,rotary-exit-1,rotary-exit-1,rstur-exit-2,turn right,arrive | 189.1m |
| 1 | k | ebds,ds,ufghl,jhik,jhik | depart,rotary-exit-1,rstur-exit-2,turn right,arrive | 159.1m |
+10 -10
View File
@@ -201,14 +201,14 @@ Feature: Simple Turns
| ef | residential | road | 2 | yes | | ef | residential | road | 2 | yes |
When I route I should get When I route I should get
| waypoints | route | turns | locations | | waypoints | route | turns | locations |
| a,c | road,road | depart,arrive | a,c | | a,c | road,road | depart,arrive | a,c |
| c,a | road,road | depart,arrive | c,a | | c,a | road,road | depart,arrive | c,a |
| g,a | turn,road,road | depart,turn left,arrive | g,b,a | | g,a | turn,road,road | depart,turn left,arrive | g,b,a |
| g,c | turn,road,road | depart,turn right,arrive | g,b,c | | g,c | turn,road,road | depart,turn right,arrive | g,b,c |
| g,f | turn,road,road | depart,end of road left,arrive | g,e,f | | g,f | turn,road,road | depart,turn left,arrive | g,e,f |
| c,f | road,road,road | depart,turn right,arrive | c,b,f | | c,f | road,road,road | depart,continue right,arrive | c,b,f |
| a,f | road,road,road | depart,continue uturn,arrive | a,b,f | | a,f | road,road,road | depart,continue uturn,arrive | a,b,f |
# http://www.openstreetmap.org/#map=19/52.48753/13.52838 # http://www.openstreetmap.org/#map=19/52.48753/13.52838
Scenario: Traffic Circle Scenario: Traffic Circle
@@ -1312,8 +1312,8 @@ Feature: Simple Turns
# we don't care for turn instructions, this is a coordinate extraction bug check # we don't care for turn instructions, this is a coordinate extraction bug check
When I route I should get When I route I should get
| waypoints | route | intersections | | waypoints | route | intersections |
| a,g | ab,bcdefgh,bcdefgh | true:90;true:45 false:180 false:270;true:180 | | a,g | ab,bcdefgh | true:90,true:45 false:180 false:270;true:180 |
#https://github.com/Project-OSRM/osrm-backend/pull/3469#issuecomment-270806580 #https://github.com/Project-OSRM/osrm-backend/pull/3469#issuecomment-270806580
Scenario: Oszillating Lower Priority Road Scenario: Oszillating Lower Priority Road
+2 -31
View File
@@ -134,7 +134,7 @@ Feature: Turn Lane Guidance
| a | c | 180,180 180,180 | in,straight,straight | depart,new name straight,arrive | ,left;uturn:false straight;right:true, | a,b,c | | a | c | 180,180 180,180 | in,straight,straight | depart,new name straight,arrive | ,left;uturn:false straight;right:true, | a,b,c |
| a | d | 180,180 180,180 | in,right,right | depart,turn right,arrive | ,left;uturn:false straight;right:true, | a,b,d | | a | d | 180,180 180,180 | in,right,right | depart,turn right,arrive | ,left;uturn:false straight;right:true, | a,b,d |
| a | e | 180,180 180,180 | in,left,left | depart,turn left,arrive | ,left;uturn:true straight;right:false, | a,b,e | | a | e | 180,180 180,180 | in,left,left | depart,turn left,arrive | ,left;uturn:true straight;right:false, | a,b,e |
| 1 | a | 90,2 270,2 | in,in,in | depart,continue uturn,arrive | ,left;uturn:true straight;right:false, | _,b,a | | 1 | a | 90,2 270,2 | in,in,in | depart,turn uturn,arrive | ,left;uturn:true straight;right:false, | _,b,a |
#this next test requires decision on how to announce lanes for going straight if there is no turn #this next test requires decision on how to announce lanes for going straight if there is no turn
@@ -629,7 +629,7 @@ Feature: Turn Lane Guidance
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,f | road,left,left | depart,turn left,arrive | ,left:true left:true left:true straight:false straight:false, | | a,f | road,left,left | depart,turn left,arrive | ,left:true left:true left:true straight:false straight:false, |
| a,e | road,road,road | depart,continue uturn,arrive | ,left:true left:false left:false straight:false straight:false, | | a,e | road,road,road | depart,turn uturn,arrive | ,left:true left:false left:false straight:false straight:false, |
| a,g | road,straight,straight | depart,new name straight,arrive | ,left:false left:false left:false straight:true straight:true, | | a,g | road,straight,straight | depart,new name straight,arrive | ,left:false left:false left:false straight:true straight:true, |
@todo @roundabout @todo @roundabout
@@ -1215,32 +1215,3 @@ Feature: Turn Lane Guidance
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,d | road,cross,cross | depart,turn left,arrive | ,none:true none:false right:false, | | a,d | road,cross,cross | depart,turn left,arrive | ,none:true none:false right:false, |
| a,c | road,road | depart,arrive | , | | a,c | road,road | depart,arrive | , |
@4189
Scenario: U-turn after a traffic light
Given the node map
"""
j k
: :
f---g-h-i
: :
a-b-c-d-e
: :
l m
"""
And the nodes
| node | highway |
| b | traffic_signals |
And the ways
| nodes | name | lanes | turn:lanes | oneway |
| ab | road1 | 3 | left\|through\|through;right | yes |
| bcde | road1 | 2 | | yes |
| ihgf | road1 | 2 | | yes |
| jgcl | road2 | 2 | | yes |
| mdhk | road2 | 2 | | yes |
When I route I should get
| waypoints | route | turns | lanes | locations |
| a,f | road1,road1,road1 | depart,continue uturn,arrive | ,left:true straight:false straight;right:false, | a,d,f |
-89
View File
@@ -1260,92 +1260,3 @@ Feature: Simple Turns
| waypoints | route | turns | | waypoints | route | turns |
| a,d | Goethe,Fried,Fried | depart,continue left,arrive | | a,d | Goethe,Fried,Fried | depart,continue left,arrive |
| a,g | Goethe,Fried,Fried | depart,turn right,arrive | | a,g | Goethe,Fried,Fried | depart,turn right,arrive |
# Conflicting roads (https://www.openstreetmap.org/export#map=19/37.57805/-77.46049)
Scenario: Turning at forklike structure
Given the node map
"""
c d
- - - b - - - a
-
e
"""
And the ways
| nodes | name | oneway | highway |
| abc | foo | no | residential |
| bd | bar | yes | residential |
| eb | some | yes | tertiary_link |
When I route I should get
| waypoints | route | turns |
| a,d | foo,bar,bar | depart,turn slight right,arrive |
Scenario: UTurn onto ramp
Given the node map
"""
a - - - b - c
.|
_________________ de
h-g-----------------------f
"""
And the ways
| nodes | name | ref | oneway | highway |
| abc | Road | | yes | primary |
| ce | other | | yes | primary |
| cdg | | | yes | motorway_link |
| fgh | | C 42 | yes | motorway |
When I route I should get
| waypoints | route | ref | turns |
| a,h | Road,,, | ,,C 42,C 42 | depart,on ramp right,merge slight left,arrive |
Scenario: UTurn onto ramp (same ref)
Given the node map
"""
a - - - b - c
.|
_________________ de
h-g-----------------------f
"""
And the ways
| nodes | name | ref | oneway | highway |
| abc | Road | C 42 | yes | primary |
| ce | other | | yes | primary |
| cdg | | | yes | motorway_link |
| fgh | | C 42 | yes | motorway |
When I route I should get
| waypoints | route | ref | turns |
| a,h | Road,,, | C 42,,C 42,C 42 | depart,on ramp right,merge slight left,arrive |
Scenario: End of road, T-intersection, no obvious turn, only one road allowed
Given the node map
"""
d
.
a . b . . c
' .
'e
.
f
"""
And the ways
| nodes | highway | oneway | ref |
| ab | primary | | B 191 |
| bc | primary | | B 191 |
| be | primary_link | yes | |
| dc | primary | | B 4;B 191 |
| ce | primary | | B 4 |
| ef | primary | | B 4 |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | bc | ce | c | no_right_turn |
| restriction | be | ef | e | only_right_turn |
When I route I should get
| waypoints | route | turns |
| a,d | ab,dc,dc | depart,turn left,arrive |
@@ -1,5 +1,4 @@
# Broken see issue #4065 @contract @options @edge-weight-updates-over-factor
@contract @options @edge-weight-updates-over-factor @todo
Feature: osrm-contract command line option: edge-weight-updates-over-factor Feature: osrm-contract command line option: edge-weight-updates-over-factor
Background: Log edge weight updates over given factor Background: Log edge weight updates over given factor
+1 -1
View File
@@ -14,5 +14,5 @@ Feature: osrm-routed command line options: invalid options
Scenario: osrm-routed - Missing file Scenario: osrm-routed - Missing file
When I try to run "osrm-routed over-the-rainbow.osrm" When I try to run "osrm-routed over-the-rainbow.osrm"
Then stderr should contain "over-the-rainbow.osrm" Then stderr should contain "over-the-rainbow.osrm"
And stderr should contain "Required files are missing" And stderr should contain "not found"
And it should exit with an error And it should exit with an error
+11 -3
View File
@@ -32,7 +32,9 @@ Feature: Raster - weights
Scenario: Weighting not based on raster sources Scenario: Weighting not based on raster sources
Given the profile "testbot" Given the profile "testbot"
When I route I should get When I run "osrm-extract {osm_file} -p {profile_file}"
And I run "osrm-contract {processed_file}"
And I route I should get
| from | to | route | speed | | from | to | route | speed |
| a | b | ab,ab | 36 km/h | | a | b | ab,ab | 36 km/h |
| a | c | ab,bc,bc | 36 km/h | | a | c | ab,bc,bc | 36 km/h |
@@ -42,7 +44,10 @@ Feature: Raster - weights
Scenario: Weighting based on raster sources Scenario: Weighting based on raster sources
Given the profile "rasterbot" Given the profile "rasterbot"
When I route I should get When I run "osrm-extract {osm_file} -p {profile_file}"
Then stdout should contain "evaluating segment"
And I run "osrm-contract {processed_file}"
And I route I should get
| from | to | route | speed | | from | to | route | speed |
| a | b | ab,ab | 8 km/h | | a | b | ab,ab | 8 km/h |
| b | a | ab,ab | 22 km/h | | b | a | ab,ab | 22 km/h |
@@ -58,7 +63,10 @@ Feature: Raster - weights
Scenario: Weighting based on raster sources Scenario: Weighting based on raster sources
Given the profile "rasterbotinterp" Given the profile "rasterbotinterp"
When I route I should get When I run "osrm-extract {osm_file} -p {profile_file}"
Then stdout should contain "evaluating segment"
And I run "osrm-contract {processed_file}"
And I route I should get
| from | to | route | speed | | from | to | route | speed |
| a | b | ab,ab | 8 km/h | | a | b | ab,ab | 8 km/h |
| a | c | ad,dc,dc | 15 km/h | | a | c | ad,dc,dc | 15 km/h |
+7 -7
View File
@@ -38,7 +38,7 @@ module.exports = function () {
callback(); callback();
}); });
this.Given(/^the origin ([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)$/, (lon, lat, callback) => { this.Given(/^the origin ([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)$/, (lat, lon, callback) => {
this.setOrigin([parseFloat(lon), parseFloat(lat)]); this.setOrigin([parseFloat(lon), parseFloat(lat)]);
callback(); callback();
}); });
@@ -67,7 +67,7 @@ module.exports = function () {
if (this.nameNodeHash[name]) throw new Error(util.format('*** duplicate node %s', name)); if (this.nameNodeHash[name]) throw new Error(util.format('*** duplicate node %s', name));
this.addOSMNode(name, lonLat[0], lonLat[1], null); this.addOSMNode(name, lonLat[0], lonLat[1], null);
} else if (name.match(/[0-9]/) ) { } else if (name.match(/[0-9]/) ) {
if (this.locationHash[name]) throw new Error(util.format('*** duplicate node %s', name)); if (this.locationHash[name]) throw new Error(util.format('*** duplicate node %s'), name);
this.addLocation(name, lonLat[0], lonLat[1], null); this.addLocation(name, lonLat[0], lonLat[1], null);
} }
cb(); cb();
@@ -89,7 +89,7 @@ module.exports = function () {
let addNodeLocations = (row, cb) => { let addNodeLocations = (row, cb) => {
let name = row.node; let name = row.node;
if (this.findNodeByName(name)) throw new Error(util.format('*** duplicate node %s', name)); if (this.findNodeByName(name)) throw new Error(util.format('*** duplicate node %s'), name);
if (name.match(/[a-z]/)) { if (name.match(/[a-z]/)) {
let id = row.id && parseInt(row.id); let id = row.id && parseInt(row.id);
@@ -194,19 +194,19 @@ module.exports = function () {
isColonSeparated = key.match(/^(.*):(.*)/); isColonSeparated = key.match(/^(.*):(.*)/);
if (isNode) { if (isNode) {
row[key].split(',').map(function(v) { return v.trim(); }).forEach((nodeName) => { row[key].split(',').map(function(v) { return v.trim(); }).forEach((nodeName) => {
if (nodeName.length !== 1) throw new Error(util.format('*** invalid relation node member "%s"', nodeName)); if (nodeName.length !== 1) throw new Error(util.format('*** invalid relation node member "%s"'), nodeName);
let node = this.findNodeByName(nodeName); let node = this.findNodeByName(nodeName);
if (!node) throw new Error(util.format('*** unknown relation node member "%s"', nodeName)); if (!node) throw new Error(util.format('*** unknown relation node member "%s"'), nodeName);
relation.addMember('node', node.id, isNode[1]); relation.addMember('node', node.id, isNode[1]);
}); });
} else if (isWay) { } else if (isWay) {
row[key].split(',').map(function(v) { return v.trim(); }).forEach((wayName) => { row[key].split(',').map(function(v) { return v.trim(); }).forEach((wayName) => {
let way = this.findWayByName(wayName); let way = this.findWayByName(wayName);
if (!way) throw new Error(util.format('*** unknown relation way member "%s"', wayName)); if (!way) throw new Error(util.format('*** unknown relation way member "%s"'), wayName);
relation.addMember('way', way.id, isWay[1]); relation.addMember('way', way.id, isWay[1]);
}); });
} else if (isColonSeparated && isColonSeparated[1] !== 'restriction') { } else if (isColonSeparated && isColonSeparated[1] !== 'restriction') {
throw new Error(util.format('*** unknown relation member type "%s:%s", must be either "node" or "way"', isColonSeparated[1], isColonSeparated[2])); throw new Error(util.format('*** unknown relation member type "%s:%s", must be either "node" or "way"'), isColonSeparated[1], isColonSeparated[2]);
} else { } else {
relation.addTag(key, row[key]); relation.addTag(key, row[key]);
} }
+1 -1
View File
@@ -228,7 +228,7 @@ module.exports = function () {
for (var i=0; i<row.trace.length; i++) { for (var i=0; i<row.trace.length; i++) {
var n = row.trace[i], var n = row.trace[i],
node = this.findNodeByName(n); node = this.findNodeByName(n);
if (!node) throw new Error(util.format('*** unknown waypoint node "%s"', n)); if (!node) throw new Error(util.format('*** unknown waypoint node "%s"'), n);
trace.push(node); trace.push(node);
} }
if (row.timestamps) { if (row.timestamps) {
+2 -2
View File
@@ -6,10 +6,10 @@ module.exports = function () {
if (e) return callback(e); if (e) return callback(e);
var testRow = (row, ri, cb) => { var testRow = (row, ri, cb) => {
var inNode = this.findNodeByName(row.in); var inNode = this.findNodeByName(row.in);
if (!inNode) throw new Error(util.format('*** unknown in-node "%s"', row.in)); if (!inNode) throw new Error(util.format('*** unknown in-node "%s"'), row.in);
var outNode = this.findNodeByName(row.out); var outNode = this.findNodeByName(row.out);
if (!outNode) throw new Error(util.format('*** unknown out-node "%s"', row.out)); if (!outNode) throw new Error(util.format('*** unknown out-node "%s"'), row.out);
this.requestNearest(inNode, this.queryParams, (err, response) => { this.requestNearest(inNode, this.queryParams, (err, response) => {
if (err) return cb(err); if (err) return cb(err);
+1 -1
View File
@@ -121,7 +121,7 @@ module.exports = function () {
r.which = dir; r.which = dir;
this.requestRoute((dir === 'forw' ? [a, b] : [b, a]), [], [], this.queryParams, (err, res, body) => { this.requestRoute((dir === 'forw' ? [a, b] : [b, a]), [], this.queryParams, (err, res, body) => {
if (err) return callback(err); if (err) return callback(err);
r.query = this.query; r.query = this.query;
+1 -1
View File
@@ -243,8 +243,8 @@ module.exports = function () {
processedCacheFile: this.processedCacheFile, environment: this.environment}; processedCacheFile: this.processedCacheFile, environment: this.environment};
let queue = d3.queue(1); let queue = d3.queue(1);
queue.defer(this.extractData.bind(this), p); queue.defer(this.extractData.bind(this), p);
queue.defer(this.partitionData.bind(this), p);
queue.defer(this.contractData.bind(this), p); queue.defer(this.contractData.bind(this), p);
queue.defer(this.partitionData.bind(this), p);
queue.defer(this.customizeData.bind(this), p); queue.defer(this.customizeData.bind(this), p);
queue.awaitAll(callback); queue.awaitAll(callback);
}; };
+1 -2
View File
@@ -39,8 +39,7 @@ module.exports = function () {
this.WAY_SPACING = 100; this.WAY_SPACING = 100;
this.DEFAULT_GRID_SIZE = 100; // meters this.DEFAULT_GRID_SIZE = 100; // meters
// get algorithm name from the command line profile argument // get algorithm name from the command line profile argument
this.ROUTING_ALGORITHM = process.argv[process.argv.indexOf('-p') + 1].match('mld') ? 'MLD' : 'CH'; this.ROUTING_ALGORITHM = process.argv[process.argv.indexOf('-p') + 1] === 'mld' ? 'MLD' : 'CH';
this.TIMEZONE_NAMES = this.PLATFORM_WINDOWS ? 'win' : 'iana';
this.OSRM_PORT = process.env.OSRM_PORT && parseInt(process.env.OSRM_PORT) || 5000; this.OSRM_PORT = process.env.OSRM_PORT && parseInt(process.env.OSRM_PORT) || 5000;
this.HOST = 'http://127.0.0.1:' + this.OSRM_PORT; this.HOST = 'http://127.0.0.1:' + this.OSRM_PORT;
+1 -9
View File
@@ -46,9 +46,8 @@ module.exports = function () {
return waypoints.map(w => [w.lon, w.lat].map(ensureDecimal).join(',')); return waypoints.map(w => [w.lon, w.lat].map(ensureDecimal).join(','));
}; };
this.requestRoute = (waypoints, bearings, approaches, userParams, callback) => { this.requestRoute = (waypoints, bearings, userParams, callback) => {
if (bearings.length && bearings.length !== waypoints.length) throw new Error('*** number of bearings does not equal the number of waypoints'); if (bearings.length && bearings.length !== waypoints.length) throw new Error('*** number of bearings does not equal the number of waypoints');
if (approaches.length && approaches.length !== waypoints.length) throw new Error('*** number of approaches does not equal the number of waypoints');
var defaults = { var defaults = {
output: 'json', output: 'json',
@@ -68,9 +67,6 @@ module.exports = function () {
}).join(';'); }).join(';');
} }
if (approaches.length) {
params.approaches = approaches.join(';');
}
return this.requestPath('route', params, callback); return this.requestPath('route', params, callback);
}; };
@@ -167,10 +163,6 @@ module.exports = function () {
('out' in s.intersections[0] ? s.intersections[0].bearings[s.intersections[0].out] : 0)); ('out' in s.intersections[0] ? s.intersections[0].bearings[s.intersections[0].out] : 0));
}; };
this.approachList = (instructions) => {
return this.extractInstructionList(instructions, s => s.approaches || '');
};
this.annotationList = (instructions) => { this.annotationList = (instructions) => {
if (!('annotation' in instructions.legs[0])) if (!('annotation' in instructions.legs[0]))
return ''; return '';
+1 -2
View File
@@ -15,8 +15,7 @@ module.exports = function () {
'{profile_file}': this.profileFile, '{profile_file}': this.profileFile,
'{rastersource_file}': this.rasterCacheFile, '{rastersource_file}': this.rasterCacheFile,
'{speeds_file}': this.speedsCacheFile, '{speeds_file}': this.speedsCacheFile,
'{penalties_file}': this.penaltiesCacheFile, '{penalties_file}': this.penaltiesCacheFile
'{timezone_names}': this.TIMEZONE_NAMES
}; };
for (let k in table) { for (let k in table) {
+7 -18
View File
@@ -35,7 +35,7 @@ module.exports = function () {
if (err) return cb(err); if (err) return cb(err);
if (body && body.length) { if (body && body.length) {
let destinations, pronunciations, instructions, refs, bearings, turns, modes, times, let destinations, pronunciations, instructions, refs, bearings, turns, modes, times,
distances, summary, intersections, lanes, locations, annotation, weight_name, weights, approaches; distances, summary, intersections, lanes, locations, annotation, weight_name, weights;
let json = JSON.parse(body); let json = JSON.parse(body);
@@ -60,7 +60,6 @@ module.exports = function () {
annotation = this.annotationList(json.routes[0]); annotation = this.annotationList(json.routes[0]);
weight_name = this.weightName(json.routes[0]); weight_name = this.weightName(json.routes[0]);
weights = this.weightList(json.routes[0]); weights = this.weightList(json.routes[0]);
approaches = this.approachList(json.routes[0]);
} }
if (headers.has('status')) { if (headers.has('status')) {
@@ -147,10 +146,7 @@ module.exports = function () {
if (headers.has('locations')){ if (headers.has('locations')){
got.locations = (locations || '').trim(); got.locations = (locations || '').trim();
} }
/*
if (headers.has('approaches')){
got.approaches = (approaches || '').trim();
}*/
// if header matches 'a:*', parse out the values for * // if header matches 'a:*', parse out the values for *
// and return in that header // and return in that header
headers.forEach((k) => { headers.forEach((k) => {
@@ -180,7 +176,6 @@ module.exports = function () {
putValue('weight_name', weight_name); putValue('weight_name', weight_name);
putValue('weights', weights); putValue('weights', weights);
putValue('weight', weight); putValue('weight', weight);
putValue('approach', approaches);
for (var key in row) { for (var key in row) {
if (this.FuzzyMatch.match(got[key], row[key])) { if (this.FuzzyMatch.match(got[key], row[key])) {
@@ -215,31 +210,25 @@ module.exports = function () {
var params = this.overwriteParams(defaultParams, userParams), var params = this.overwriteParams(defaultParams, userParams),
waypoints = [], waypoints = [],
bearings = [], bearings = [];
approaches = [];
if (row.bearings) { if (row.bearings) {
got.bearings = row.bearings; got.bearings = row.bearings;
bearings = row.bearings.split(' ').filter(b => !!b); bearings = row.bearings.split(' ').filter(b => !!b);
} }
if (row.approaches) {
got.approaches = row.approaches;
approaches = row.approaches.split(' ').filter(b => !!b);
}
if (row.from && row.to) { if (row.from && row.to) {
var fromNode = this.findNodeByName(row.from); var fromNode = this.findNodeByName(row.from);
if (!fromNode) return cb(new Error(util.format('*** unknown from-node "%s"', row.from))); if (!fromNode) return cb(new Error(util.format('*** unknown from-node "%s"'), row.from));
waypoints.push(fromNode); waypoints.push(fromNode);
var toNode = this.findNodeByName(row.to); var toNode = this.findNodeByName(row.to);
if (!toNode) return cb(new Error(util.format('*** unknown to-node "%s"', row.to))); if (!toNode) return cb(new Error(util.format('*** unknown to-node "%s"'), row.to));
waypoints.push(toNode); waypoints.push(toNode);
got.from = row.from; got.from = row.from;
got.to = row.to; got.to = row.to;
this.requestRoute(waypoints, bearings, approaches, params, afterRequest); this.requestRoute(waypoints, bearings, params, afterRequest);
} else if (row.waypoints) { } else if (row.waypoints) {
row.waypoints.split(',').forEach((n) => { row.waypoints.split(',').forEach((n) => {
var node = this.findNodeByName(n.trim()); var node = this.findNodeByName(n.trim());
@@ -247,7 +236,7 @@ module.exports = function () {
waypoints.push(node); waypoints.push(node);
}); });
got.waypoints = row.waypoints; got.waypoints = row.waypoints;
this.requestRoute(waypoints, bearings, approaches, params, afterRequest); this.requestRoute(waypoints, bearings, params, afterRequest);
} else { } else {
return cb(new Error('*** no waypoints')); return cb(new Error('*** no waypoints'));
} }
-35
View File
@@ -30,38 +30,3 @@ Feature: Alternative route
| 3 | 4 | bd,dc,ca,ab,bd,bd | | | 3 | 4 | bd,dc,ca,ab,bd,bd | |
| 5 | 6 | dc,ca,ab,bd,dc,dc | | | 5 | 6 | dc,ca,ab,bd,dc,dc | |
| 7 | 8 | ca,ab,bd,dc,ca,ca | | | 7 | 8 | ca,ab,bd,dc,ca,ca | |
@4111
Scenario: Alternative Loop Paths with single node path
Given the node map
"""
a1b2c3d
e f
"""
And the ways
| nodes | maxspeed |
| ab | 30 |
| bc | 3 |
| cd | 30 |
| ae | 30 |
| ef | 30 |
| fd | 30 |
And the query options
| alternatives | true |
When I route I should get
| from | to | route | alternative |
| b | c | bc,bc | ab,ae,ef,fd,cd,cd |
#| c | b | bc,bc | cd,fd,ef,ae,ab,ab | # alternative path depends on phantom snapping order
| 1 | c | ab,bc,bc | ab,ae,ef,fd,cd,cd |
#| c | 1 | bc,ab | cd,fd,ef,ae,ab | # alternative path depends on phantom snapping order
| 2 | c | bc,bc | |
| c | 2 | bc,bc | |
| 1 | 3 | ab,ae,ef,fd,cd | ab,bc,cd |
#| 3 | 1 | cd,fd,ef,ae,ab | cd,bc,ab | # alternative path depends on phantom snapping order
| b | 3 | bc,cd | ab,ae,ef,fd,cd |
#| 3 | b | cd,bc,bc | cd,fd,ef,ae,ab,ab | # alternative path depends on phantom snapping order
-5
View File
@@ -12,7 +12,6 @@ Feature: Testbot - Handle ferry routes
i j k l i j k l
m n o p m n o p
q r s t q r s t
u v w x
""" """
And the ways And the ways
@@ -27,14 +26,11 @@ Feature: Testbot - Handle ferry routes
| op | primary | | | | op | primary | | |
| qr | primary | | | | qr | primary | | |
| st | primary | | | | st | primary | | |
| uv | primary | | |
| wx | primary | | |
| bc | | ferry | 0:01 | | bc | | ferry | 0:01 |
| fg | | ferry | 0:10 | | fg | | ferry | 0:10 |
| jk | | ferry | 1:00 | | jk | | ferry | 1:00 |
| no | | ferry | 24:00 | | no | | ferry | 24:00 |
| rs | | ferry | 96:00 | | rs | | ferry | 96:00 |
| vw | | ferry | P5D |
When I route I should get When I route I should get
| from | to | route | time | | from | to | route | time |
@@ -43,7 +39,6 @@ Feature: Testbot - Handle ferry routes
| j | k | jk,jk | 3600s +-1 | | j | k | jk,jk | 3600s +-1 |
| n | o | no,no | 86400s +-1 | | n | o | no,no | 86400s +-1 |
| r | s | rs,rs | 345600s +-1 | | r | s | rs,rs | 345600s +-1 |
| v | w | vw,vw | 419430s +-1|
@todo @todo
Scenario: Testbot - Week long ferry routes Scenario: Testbot - Week long ferry routes
+18 -26
View File
@@ -2,22 +2,15 @@
Feature: Traffic - speeds Feature: Traffic - speeds
Background: Use specific speeds Background: Use specific speeds
# __ a
# / /
#c----b / g
# \ |\/
# \ e/\_.f
# \ | /
# d./
Given the node locations Given the node locations
| node | lat | lon | id | | node | lat | lon |
| a | 0.1 | 0.1 | 1 | | a | 0.1 | 0.1 |
| b | 0.05 | 0.1 | 2 | | b | 0.05 | 0.1 |
| c | 0.0 | 0.1 | 3 | | c | 0.0 | 0.1 |
| d | 0.05 | 0.03 | 4 | | d | 0.05 | 0.03 |
| e | 0.05 | 0.066 | 5 | | e | 0.05 | 0.066 |
| f | 0.075 | 0.066 | 6 | | f | 0.075 | 0.066 |
| g | 0.075 | 0.1 | 7 | | g | 0.075 | 0.1 |
And the ways And the ways
| nodes | highway | | nodes | highway |
| ab | primary | | ab | primary |
@@ -89,7 +82,7 @@ Feature: Traffic - speeds
api_version = 1 api_version = 1
properties.traffic_signal_penalty = 0 properties.traffic_signal_penalty = 0
properties.u_turn_penalty = 0 properties.u_turn_penalty = 0
properties.weight_precision = 2 properties.weight_precision = 3
""" """
And the contract extra arguments "--segment-speed-file {speeds_file}" And the contract extra arguments "--segment-speed-file {speeds_file}"
And the customize extra arguments "--segment-speed-file {speeds_file}" And the customize extra arguments "--segment-speed-file {speeds_file}"
@@ -106,15 +99,15 @@ Feature: Traffic - speeds
| annotations | datasources | | annotations | datasources |
When I route I should get When I route I should get
| from | to | route | speed | weights | a:datasources | | from | to | route | speed | weights | a:datasources |
| a | b | ab,ab | 1 km/h | 20020.73,0 | 1:0 | | a | b | ab,ab | 1 km/h | 20020.735,0 | 1:0 |
| a | c | ab,bc,bc | 2 km/h | 20020.73,741.51,0 | 1:1:0 | | a | c | ab,bc,bc | 2 km/h | 20020.735,741.509,0 | 1:1:0 |
| b | c | bc,bc | 27 km/h | 741.51,0 | 1:0 | | b | c | bc,bc | 27 km/h | 741.509,0 | 1:0 |
| a | d | ab,eb,de,de | 2 km/h | 20020.73,378.17,400.41,0 | 1:0:0 | | a | d | ab,eb,de,de | 2 km/h | 20020.735,378.169,400.415,0 | 1:0:0 |
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 | | d | c | dc,dc | 36 km/h | 956.805,0 | 0 |
| g | b | ab,ab | 1 km/h | 10010.37,0 | 1:0 | | g | b | ab,ab | 1 km/h | 10010.365,0 | 1:0 |
| a | g | ab,ab | 1 km/h | 10010.36,0 | 1 | | a | g | ab,ab | 1 km/h | 10010.37,0 | 1 |
| g | a | ab,ab | 1 km/h | 10010.36,0 | 1:1 | | g | a | ab,ab | 1 km/h | 10010.37,0 | 1:1 |
Scenario: Speeds that isolate a single node (a) Scenario: Speeds that isolate a single node (a)
@@ -168,4 +161,3 @@ Feature: Traffic - speeds
And the data has been extracted And the data has been extracted
When I try to run "osrm-contract --segment-speed-file {speeds_file} {processed_file}" When I try to run "osrm-contract --segment-speed-file {speeds_file} {processed_file}"
And it should exit successfully And it should exit successfully
@@ -1,30 +0,0 @@
@routing @speed @traffic
Feature: Traffic - speeds edge cases
Scenario: Weighting based on speed file weights that cause segment weight overflows
Given the node map
"""
a-----b
"""
And the ways
| nodes | highway |
| ab | primary |
And the profile file "testbot" extended with
"""
api_version = 1
properties.traffic_signal_penalty = 0
properties.u_turn_penalty = 0
properties.weight_precision = 2
"""
And the contract extra arguments "--segment-speed-file {speeds_file}"
And the customize extra arguments "--segment-speed-file {speeds_file}"
And the speed file
"""
1,2,1,0.001
2,1,1,0.001
"""
And the query options
| annotations | datasources |
When I route I should get
| from | to | route | speed | weights | a:datasources |
| a | b | ab,ab | 1 km/h | 41943.02,0 | 1 |
-36
View File
@@ -1,36 +0,0 @@
@routing @testbot @turn_penalty
Feature: Turn Penalties
Background:
Given the profile "turnbot"
Given a grid size of 200 meters
Scenario: Turns should incur a delay that depend on the angle
Given the node map
"""
c d e
b j f
a s g
"""
And the ways
| nodes |
| sj |
| ja |
| jb |
| jc |
| jd |
| je |
| jf |
| jg |
When I route I should get
| from | to | route | time | distance |
| s | a | sj,ja,ja | 63s +-1 | 483m +-1 |
| s | b | sj,jb,jb | 50s +-1 | 400m +-1 |
| s | c | sj,jc,jc | 54s +-1 | 483m +-1 |
| s | d | sj,jd,jd | 40s +-1 | 400m +-1 |
| s | e | sj,je,je | 53s +-1 | 483m +-1 |
| s | f | sj,jf,jf | 50s +-1 | 400m +-1 |
| s | g | sj,jg,jg | 63s +-1 | 483m +-1 |
+31 -3
View File
@@ -224,6 +224,34 @@ Feature: Via points
| a,d,c | abc,bd,bd,bd,abc,abc | | a,d,c | abc,bd,bd,bd,abc,abc |
| c,d,a | 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"
Given the node map
"""
a b c
1
d
f e
"""
And the nodes
| node | barrier |
| d | bollard |
And the ways
| nodes |
| abc |
| bd |
| afed |
When I route I should get
| waypoints | route |
| a,1,c | abc,bd,bd,bd,bd,abc,abc |
| c,1,a | abc,bd,bd,bd,bd,abc,abc |
Scenario: Via points on ring on the same oneway, forces one of the vertices to be top node Scenario: Via points on ring on the same oneway, forces one of the vertices to be top node
Given the node map Given the node map
""" """
@@ -321,9 +349,9 @@ Feature: Via points
| ab | | ab |
When I route I should get When I route I should get
| waypoints | bearings | route | turns | | waypoints | bearings | route | turns |
| 1,a | 90,2 270,2 | ab,ab,ab | depart,continue uturn,arrive | | 1,a | 90,2 270,2 | ab,ab,ab | depart,turn uturn,arrive |
| 1,b | 270,2 90,2 | ab,ab,ab | depart,continue uturn,arrive | | 1,b | 270,2 90,2 | ab,ab,ab | depart,turn uturn,arrive |
Scenario: Continue Straight in presence of Bearings Scenario: Continue Straight in presence of Bearings
Given the node map Given the node map
+2 -5
View File
@@ -1,8 +1,5 @@
Feature: Check zero speed updates Feature: Check zero speed updates
Background:
Given the profile "testbot"
Scenario: Matching on restricted way, single segment Scenario: Matching on restricted way, single segment
Given the query options Given the query options
| geometries | geojson | | geometries | geojson |
@@ -111,8 +108,8 @@ Feature: Check zero speed updates
""" """
When I route I should get When I route I should get
| from | to | bearings | code | | from | to | bearings | code |
| 1 | 2 | 270 270 | NoSegment | | 1 | 2 | 270 270 | NoRoute |
Scenario: Via routing on restricted oneway Scenario: Via routing on restricted oneway
+6 -1
View File
@@ -31,7 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "contractor/contractor_config.hpp" #include "contractor/contractor_config.hpp"
#include "contractor/query_edge.hpp" #include "contractor/query_edge.hpp"
#include "extractor/edge_based_edge.hpp" #include "extractor/edge_based_edge.hpp"
#include "extractor/edge_based_node_segment.hpp" #include "extractor/edge_based_node.hpp"
#include "util/deallocating_vector.hpp" #include "util/deallocating_vector.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
@@ -66,8 +66,13 @@ class Contractor
std::vector<bool> &is_core_node, std::vector<bool> &is_core_node,
std::vector<float> &inout_node_levels) const; std::vector<float> &inout_node_levels) const;
void WriteCoreNodeMarker(std::vector<bool> &&is_core_node) const; void WriteCoreNodeMarker(std::vector<bool> &&is_core_node) const;
void WriteNodeLevels(std::vector<float> &&node_levels) const;
void ReadNodeLevels(std::vector<float> &contraction_order) const;
void WriteContractedGraph(unsigned number_of_edge_based_nodes, void WriteContractedGraph(unsigned number_of_edge_based_nodes,
util::DeallocatingVector<QueryEdge> contracted_edge_list); util::DeallocatingVector<QueryEdge> contracted_edge_list);
void FindComponents(unsigned max_edge_id,
const util::DeallocatingVector<extractor::EdgeBasedEdge> &edges,
std::vector<extractor::EdgeBasedNode> &nodes) const;
private: private:
ContractorConfig config; ContractorConfig config;
+6 -6
View File
@@ -1,7 +1,7 @@
#ifndef OSRM_CONTRACTOR_CONTRACTOR_HEAP_HPP_ #ifndef OSRM_CONTRACTOR_CONTRACTOR_HEAP_HPP_
#define OSRM_CONTRACTOR_CONTRACTOR_HEAP_HPP_ #define OSRM_CONTRACTOR_CONTRACTOR_HEAP_HPP_
#include "util/query_heap.hpp" #include "util/binary_heap.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include "util/xor_fast_hash_storage.hpp" #include "util/xor_fast_hash_storage.hpp"
@@ -18,11 +18,11 @@ struct ContractorHeapData
bool target = false; bool target = false;
}; };
using ContractorHeap = util::QueryHeap<NodeID, using ContractorHeap = util::BinaryHeap<NodeID,
NodeID, NodeID,
EdgeWeight, EdgeWeight,
ContractorHeapData, ContractorHeapData,
util::XORFastHashStorage<NodeID, NodeID>>; util::XORFastHashStorage<NodeID, NodeID>>;
} // namespace contractor } // namespace contractor
} // namespace osrm } // namespace osrm
-19
View File
@@ -6,7 +6,6 @@
#include "util/serialization.hpp" #include "util/serialization.hpp"
#include "storage/io.hpp" #include "storage/io.hpp"
#include "storage/serialization.hpp"
namespace osrm namespace osrm
{ {
@@ -44,24 +43,6 @@ writeGraph(const boost::filesystem::path &path, unsigned checksum, const QueryGr
writer.WriteOne(checksum); writer.WriteOne(checksum);
util::serialization::write(writer, graph); util::serialization::write(writer, graph);
} }
// reads .levels file
inline void readLevels(const boost::filesystem::path &path, std::vector<float> &node_levels)
{
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
storage::io::FileReader reader{path, fingerprint};
storage::serialization::read(reader, node_levels);
}
// writes .levels file
inline void writeLevels(const boost::filesystem::path &path, const std::vector<float> &node_levels)
{
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint;
storage::io::FileWriter writer{path, fingerprint};
storage::serialization::write(writer, node_levels);
}
} }
} }
} }
+2 -2
View File
@@ -3,7 +3,7 @@
#include "partition/cell_storage.hpp" #include "partition/cell_storage.hpp"
#include "partition/multi_level_partition.hpp" #include "partition/multi_level_partition.hpp"
#include "util/query_heap.hpp" #include "util/binary_heap.hpp"
#include <tbb/enumerable_thread_specific.h> #include <tbb/enumerable_thread_specific.h>
@@ -24,7 +24,7 @@ class CellCustomizer
public: public:
using Heap = using Heap =
util::QueryHeap<NodeID, NodeID, EdgeWeight, HeapData, util::ArrayStorage<NodeID, int>>; util::BinaryHeap<NodeID, NodeID, EdgeWeight, HeapData, util::ArrayStorage<NodeID, int>>;
using HeapPtr = tbb::enumerable_thread_specific<Heap>; using HeapPtr = tbb::enumerable_thread_specific<Heap>;
CellCustomizer(const partition::MultiLevelPartition &partition) : partition(partition) {} CellCustomizer(const partition::MultiLevelPartition &partition) : partition(partition) {}
-3
View File
@@ -102,9 +102,6 @@ template <> struct HasShortestPathSearch<mld::Algorithm> final : std::true_type
template <> struct HasMapMatching<mld::Algorithm> final : std::true_type template <> struct HasMapMatching<mld::Algorithm> final : std::true_type
{ {
}; };
template <> struct HasGetTileTurns<mld::Algorithm> final : std::true_type
{
};
} }
} }
} }
+5 -10
View File
@@ -50,19 +50,14 @@ class BaseAPI
{ {
if (parameters.generate_hints) if (parameters.generate_hints)
{ {
// TODO: check forward/reverse return json::makeWaypoint(phantom.location,
return json::makeWaypoint( facade.GetNameForID(phantom.name_id).to_string(),
phantom.location, Hint{phantom, facade.GetCheckSum()});
facade.GetNameForID(facade.GetNameIndex(phantom.forward_segment_id.id)).to_string(),
Hint{phantom, facade.GetCheckSum()});
} }
else else
{ {
// TODO: check forward/reverse return json::makeWaypoint(phantom.location,
return json::makeWaypoint( facade.GetNameForID(phantom.name_id).to_string());
phantom.location,
facade.GetNameForID(facade.GetNameIndex(phantom.forward_segment_id.id))
.to_string());
} }
} }
+1 -6
View File
@@ -28,7 +28,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ENGINE_API_BASE_PARAMETERS_HPP #ifndef ENGINE_API_BASE_PARAMETERS_HPP
#define ENGINE_API_BASE_PARAMETERS_HPP #define ENGINE_API_BASE_PARAMETERS_HPP
#include "engine/approach.hpp"
#include "engine/bearing.hpp" #include "engine/bearing.hpp"
#include "engine/hint.hpp" #include "engine/hint.hpp"
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
@@ -56,7 +55,6 @@ namespace api
* optional per coordinate * optional per coordinate
* - bearings: limits the search for segments in the road network to given bearing(s) in degree * - bearings: limits the search for segments in the road network to given bearing(s) in degree
* towards true north in clockwise direction, optional per coordinate * towards true north in clockwise direction, optional per coordinate
* - approaches: force the phantom node to start towards the node with the road country side.
* *
* \see OSRM, Coordinate, Hint, Bearing, RouteParame, RouteParameters, TableParameters, * \see OSRM, Coordinate, Hint, Bearing, RouteParame, RouteParameters, TableParameters,
* NearestParameters, TripParameters, MatchParameters and TileParameters * NearestParameters, TripParameters, MatchParameters and TileParameters
@@ -67,7 +65,6 @@ struct BaseParameters
std::vector<boost::optional<Hint>> hints; std::vector<boost::optional<Hint>> hints;
std::vector<boost::optional<double>> radiuses; std::vector<boost::optional<double>> radiuses;
std::vector<boost::optional<Bearing>> bearings; std::vector<boost::optional<Bearing>> bearings;
std::vector<boost::optional<Approach>> approaches;
// Adds hints to response which can be included in subsequent requests, see `hints` above. // Adds hints to response which can be included in subsequent requests, see `hints` above.
bool generate_hints = true; bool generate_hints = true;
@@ -76,10 +73,9 @@ struct BaseParameters
const std::vector<boost::optional<Hint>> hints_ = {}, const std::vector<boost::optional<Hint>> hints_ = {},
std::vector<boost::optional<double>> radiuses_ = {}, std::vector<boost::optional<double>> radiuses_ = {},
std::vector<boost::optional<Bearing>> bearings_ = {}, std::vector<boost::optional<Bearing>> bearings_ = {},
std::vector<boost::optional<Approach>> approaches_ = {},
bool generate_hints_ = true) bool generate_hints_ = true)
: coordinates(coordinates_), hints(hints_), radiuses(radiuses_), bearings(bearings_), : coordinates(coordinates_), hints(hints_), radiuses(radiuses_), bearings(bearings_),
approaches(approaches_), generate_hints(generate_hints_) generate_hints(generate_hints_)
{ {
} }
@@ -89,7 +85,6 @@ struct BaseParameters
return (hints.empty() || hints.size() == coordinates.size()) && return (hints.empty() || hints.size() == coordinates.size()) &&
(bearings.empty() || bearings.size() == coordinates.size()) && (bearings.empty() || bearings.size() == coordinates.size()) &&
(radiuses.empty() || radiuses.size() == coordinates.size()) && (radiuses.empty() || radiuses.size() == coordinates.size()) &&
(approaches.empty() || approaches.size() == coordinates.size()) &&
std::all_of(bearings.begin(), std::all_of(bearings.begin(),
bearings.end(), bearings.end(),
[](const boost::optional<Bearing> bearing_and_range) { [](const boost::optional<Bearing> bearing_and_range) {
+17 -22
View File
@@ -41,27 +41,26 @@ class RouteAPI : public BaseAPI
{ {
} }
void MakeResponse(const InternalManyRoutesResult &raw_routes, void MakeResponse(const InternalRouteResult &raw_route, util::json::Object &response) const
util::json::Object &response) const
{ {
BOOST_ASSERT(!raw_routes.routes.empty()); auto number_of_routes = raw_route.has_alternative() ? 2UL : 1UL;
util::json::Array routes;
util::json::Array jsRoutes; routes.values.resize(number_of_routes);
routes.values[0] = MakeRoute(raw_route.segment_end_coordinates,
for (const auto &route : raw_routes.routes) raw_route.unpacked_path_segments,
raw_route.source_traversed_in_reverse,
raw_route.target_traversed_in_reverse);
if (raw_route.has_alternative())
{ {
if (!route.is_valid()) std::vector<std::vector<PathData>> wrapped_leg(1);
continue; wrapped_leg.front() = std::move(raw_route.unpacked_alternative);
routes.values[1] = MakeRoute(raw_route.segment_end_coordinates,
jsRoutes.values.push_back(MakeRoute(route.segment_end_coordinates, wrapped_leg,
route.unpacked_path_segments, raw_route.alt_source_traversed_in_reverse,
route.source_traversed_in_reverse, raw_route.alt_target_traversed_in_reverse);
route.target_traversed_in_reverse));
} }
response.values["waypoints"] = BaseAPI::MakeWaypoints(raw_route.segment_end_coordinates);
response.values["waypoints"] = response.values["routes"] = std::move(routes);
BaseAPI::MakeWaypoints(raw_routes.routes[0].segment_end_coordinates);
response.values["routes"] = std::move(jsRoutes);
response.values["code"] = "Ok"; response.values["code"] = "Ok";
} }
@@ -165,10 +164,6 @@ class RouteAPI : public BaseAPI
* to find a via point. * to find a via point.
* The same exit will be emitted, though, if we should start routing at S, making * The same exit will be emitted, though, if we should start routing at S, making
* the overall response consistent. * the overall response consistent.
*
* CAUTION: order of post-processing steps is important
* - postProcess must be called before collapseTurnInstructions that expects
* post-processed roundabouts without Exit instructions
*/ */
guidance::trimShortSegments(steps, leg_geometry); guidance::trimShortSegments(steps, leg_geometry);
-46
View File
@@ -1,46 +0,0 @@
/*
Copyright (c) 2016, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OSRM_ENGINE_APPROACH_HPP
#define OSRM_ENGINE_APPROACH_HPP
#include <cstdint>
namespace osrm
{
namespace engine
{
enum class Approach : std::uint8_t
{
CURB = 0,
UNRESTRICTED = 1
};
}
}
#endif
@@ -6,7 +6,6 @@
#include "engine/datafacade/datafacade_base.hpp" #include "engine/datafacade/datafacade_base.hpp"
#include "engine/algorithm.hpp" #include "engine/algorithm.hpp"
#include "engine/approach.hpp"
#include "engine/geospatial_query.hpp" #include "engine/geospatial_query.hpp"
#include "customizer/edge_based_graph.hpp" #include "customizer/edge_based_graph.hpp"
@@ -14,8 +13,6 @@
#include "extractor/datasources.hpp" #include "extractor/datasources.hpp"
#include "extractor/guidance/turn_instruction.hpp" #include "extractor/guidance/turn_instruction.hpp"
#include "extractor/guidance/turn_lane_types.hpp" #include "extractor/guidance/turn_lane_types.hpp"
#include "extractor/node_data_container.hpp"
#include "extractor/packed_osm_ids.hpp"
#include "extractor/profile_properties.hpp" #include "extractor/profile_properties.hpp"
#include "extractor/segment_data_container.hpp" #include "extractor/segment_data_container.hpp"
#include "extractor/turn_data_container.hpp" #include "extractor/turn_data_container.hpp"
@@ -217,7 +214,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
unsigned m_check_sum; unsigned m_check_sum;
util::vector_view<util::Coordinate> m_coordinate_list; util::vector_view<util::Coordinate> m_coordinate_list;
extractor::PackedOSMIDsView m_osmnodeid_list; util::PackedVectorView<OSMNodeID> m_osmnodeid_list;
util::NameTable m_names_table; util::NameTable m_names_table;
util::vector_view<std::uint32_t> m_lane_description_offsets; util::vector_view<std::uint32_t> m_lane_description_offsets;
util::vector_view<extractor::guidance::TurnLaneType::Mask> m_lane_description_masks; util::vector_view<extractor::guidance::TurnLaneType::Mask> m_lane_description_masks;
@@ -225,7 +222,6 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
util::vector_view<TurnPenalty> m_turn_duration_penalties; util::vector_view<TurnPenalty> m_turn_duration_penalties;
extractor::SegmentDataView segment_data; extractor::SegmentDataView segment_data;
extractor::TurnDataView turn_data; extractor::TurnDataView turn_data;
extractor::EdgeBasedNodeDataView edge_based_node_data;
util::vector_view<char> m_datasource_name_data; util::vector_view<char> m_datasource_name_data;
util::vector_view<std::size_t> m_datasource_name_offsets; util::vector_view<std::size_t> m_datasource_name_offsets;
@@ -290,69 +286,50 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
"Is any data loaded into shared memory?" + SOURCE_REF); "Is any data loaded into shared memory?" + SOURCE_REF);
} }
auto tree_nodes_ptr = auto tree_ptr =
data_layout.GetBlockPtr<RTreeNode>(memory_block, storage::DataLayout::R_SEARCH_TREE); data_layout.GetBlockPtr<RTreeNode>(memory_block, storage::DataLayout::R_SEARCH_TREE);
auto tree_level_sizes_ptr = data_layout.GetBlockPtr<std::uint64_t>(
memory_block, storage::DataLayout::R_SEARCH_TREE_LEVELS);
m_static_rtree.reset( m_static_rtree.reset(
new SharedRTree(tree_nodes_ptr, new SharedRTree(tree_ptr,
data_layout.num_entries[storage::DataLayout::R_SEARCH_TREE], data_layout.num_entries[storage::DataLayout::R_SEARCH_TREE],
tree_level_sizes_ptr,
data_layout.num_entries[storage::DataLayout::R_SEARCH_TREE_LEVELS],
file_index_path, file_index_path,
m_coordinate_list)); m_coordinate_list));
m_geospatial_query.reset( m_geospatial_query.reset(
new SharedGeospatialQuery(*m_static_rtree, m_coordinate_list, *this)); new SharedGeospatialQuery(*m_static_rtree, m_coordinate_list, *this));
} }
void InitializeNodeInformationPointers(storage::DataLayout &layout, char *memory_ptr) void InitializeNodeInformationPointers(storage::DataLayout &data_layout, char *memory_block)
{ {
const auto coordinate_list_ptr = const auto coordinate_list_ptr = data_layout.GetBlockPtr<util::Coordinate>(
layout.GetBlockPtr<util::Coordinate>(memory_ptr, storage::DataLayout::COORDINATE_LIST); memory_block, storage::DataLayout::COORDINATE_LIST);
m_coordinate_list.reset(coordinate_list_ptr, m_coordinate_list.reset(coordinate_list_ptr,
layout.num_entries[storage::DataLayout::COORDINATE_LIST]); data_layout.num_entries[storage::DataLayout::COORDINATE_LIST]);
const auto osmnodeid_ptr = layout.GetBlockPtr<extractor::PackedOSMIDsView::block_type>( for (unsigned i = 0; i < m_coordinate_list.size(); ++i)
memory_ptr, storage::DataLayout::OSM_NODE_ID_LIST); {
m_osmnodeid_list = extractor::PackedOSMIDsView( BOOST_ASSERT(GetCoordinateOfNode(i).IsValid());
util::vector_view<extractor::PackedOSMIDsView::block_type>( }
osmnodeid_ptr, layout.num_entries[storage::DataLayout::OSM_NODE_ID_LIST]),
// We (ab)use the number of coordinates here because we know we have the same amount of
// ids
layout.num_entries[storage::DataLayout::COORDINATE_LIST]);
}
void InitializeEdgeBasedNodeDataInformationPointers(storage::DataLayout &layout, const auto osmnodeid_list_ptr = data_layout.GetBlockPtr<std::uint64_t>(
char *memory_ptr) memory_block, storage::DataLayout::OSM_NODE_ID_LIST);
{ m_osmnodeid_list.reset(osmnodeid_list_ptr,
auto via_geometry_list_ptr = data_layout.num_entries[storage::DataLayout::OSM_NODE_ID_LIST]);
layout.GetBlockPtr<GeometryID>(memory_ptr, storage::DataLayout::GEOMETRY_ID_LIST); // We (ab)use the number of coordinates here because we know we have the same amount of ids
util::vector_view<GeometryID> geometry_ids( m_osmnodeid_list.set_number_of_entries(
via_geometry_list_ptr, layout.num_entries[storage::DataLayout::GEOMETRY_ID_LIST]); data_layout.num_entries[storage::DataLayout::COORDINATE_LIST]);
const auto name_id_list_ptr =
layout.GetBlockPtr<NameID>(memory_ptr, storage::DataLayout::NAME_ID_LIST);
util::vector_view<NameID> name_ids(name_id_list_ptr,
layout.num_entries[storage::DataLayout::NAME_ID_LIST]);
const auto component_id_list_ptr =
layout.GetBlockPtr<ComponentID>(memory_ptr, storage::DataLayout::COMPONENT_ID_LIST);
util::vector_view<ComponentID> component_ids(
component_id_list_ptr, layout.num_entries[storage::DataLayout::COMPONENT_ID_LIST]);
const auto travel_mode_list_ptr = layout.GetBlockPtr<extractor::TravelMode>(
memory_ptr, storage::DataLayout::TRAVEL_MODE_LIST);
util::vector_view<extractor::TravelMode> travel_modes(
travel_mode_list_ptr, layout.num_entries[storage::DataLayout::TRAVEL_MODE_LIST]);
edge_based_node_data = extractor::EdgeBasedNodeDataView(std::move(geometry_ids),
std::move(name_ids),
std::move(component_ids),
std::move(travel_modes));
} }
void InitializeEdgeInformationPointers(storage::DataLayout &layout, char *memory_ptr) void InitializeEdgeInformationPointers(storage::DataLayout &layout, char *memory_ptr)
{ {
auto via_geometry_list_ptr =
layout.GetBlockPtr<GeometryID>(memory_ptr, storage::DataLayout::VIA_NODE_LIST);
util::vector_view<GeometryID> geometry_ids(
via_geometry_list_ptr, layout.num_entries[storage::DataLayout::VIA_NODE_LIST]);
const auto travel_mode_list_ptr =
layout.GetBlockPtr<extractor::TravelMode>(memory_ptr, storage::DataLayout::TRAVEL_MODE);
util::vector_view<extractor::TravelMode> travel_modes(
travel_mode_list_ptr, layout.num_entries[storage::DataLayout::TRAVEL_MODE]);
const auto lane_data_id_ptr = const auto lane_data_id_ptr =
layout.GetBlockPtr<LaneDataID>(memory_ptr, storage::DataLayout::LANE_DATA_ID); layout.GetBlockPtr<LaneDataID>(memory_ptr, storage::DataLayout::LANE_DATA_ID);
util::vector_view<LaneDataID> lane_data_ids( util::vector_view<LaneDataID> lane_data_ids(
@@ -364,6 +341,11 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
util::vector_view<extractor::guidance::TurnInstruction> turn_instructions( util::vector_view<extractor::guidance::TurnInstruction> turn_instructions(
turn_instruction_list_ptr, layout.num_entries[storage::DataLayout::TURN_INSTRUCTION]); turn_instruction_list_ptr, layout.num_entries[storage::DataLayout::TURN_INSTRUCTION]);
const auto name_id_list_ptr =
layout.GetBlockPtr<NameID>(memory_ptr, storage::DataLayout::NAME_ID_LIST);
util::vector_view<NameID> name_ids(name_id_list_ptr,
layout.num_entries[storage::DataLayout::NAME_ID_LIST]);
const auto entry_class_id_list_ptr = const auto entry_class_id_list_ptr =
layout.GetBlockPtr<EntryClassID>(memory_ptr, storage::DataLayout::ENTRY_CLASSID); layout.GetBlockPtr<EntryClassID>(memory_ptr, storage::DataLayout::ENTRY_CLASSID);
util::vector_view<EntryClassID> entry_class_ids( util::vector_view<EntryClassID> entry_class_ids(
@@ -379,8 +361,11 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
util::vector_view<util::guidance::TurnBearing> post_turn_bearings( util::vector_view<util::guidance::TurnBearing> post_turn_bearings(
post_turn_bearing_ptr, layout.num_entries[storage::DataLayout::POST_TURN_BEARING]); post_turn_bearing_ptr, layout.num_entries[storage::DataLayout::POST_TURN_BEARING]);
turn_data = extractor::TurnDataView(std::move(turn_instructions), turn_data = extractor::TurnDataView(std::move(geometry_ids),
std::move(name_ids),
std::move(turn_instructions),
std::move(lane_data_ids), std::move(lane_data_ids),
std::move(travel_modes),
std::move(entry_class_ids), std::move(entry_class_ids),
std::move(pre_turn_bearings), std::move(pre_turn_bearings),
std::move(post_turn_bearings)); std::move(post_turn_bearings));
@@ -439,47 +424,35 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
util::vector_view<unsigned> geometry_begin_indices( util::vector_view<unsigned> geometry_begin_indices(
geometries_index_ptr, data_layout.num_entries[storage::DataLayout::GEOMETRIES_INDEX]); geometries_index_ptr, data_layout.num_entries[storage::DataLayout::GEOMETRIES_INDEX]);
auto num_entries = data_layout.num_entries[storage::DataLayout::GEOMETRIES_NODE_LIST];
auto geometries_node_list_ptr = data_layout.GetBlockPtr<NodeID>( auto geometries_node_list_ptr = data_layout.GetBlockPtr<NodeID>(
memory_block, storage::DataLayout::GEOMETRIES_NODE_LIST); memory_block, storage::DataLayout::GEOMETRIES_NODE_LIST);
util::vector_view<NodeID> geometry_node_list(geometries_node_list_ptr, num_entries); util::vector_view<NodeID> geometry_node_list(
geometries_node_list_ptr,
data_layout.num_entries[storage::DataLayout::GEOMETRIES_NODE_LIST]);
auto geometries_fwd_weight_list_ptr = auto geometries_fwd_weight_list_ptr = data_layout.GetBlockPtr<EdgeWeight>(
data_layout.GetBlockPtr<extractor::SegmentDataView::SegmentWeightVector::block_type>( memory_block, storage::DataLayout::GEOMETRIES_FWD_WEIGHT_LIST);
memory_block, storage::DataLayout::GEOMETRIES_FWD_WEIGHT_LIST); util::vector_view<EdgeWeight> geometry_fwd_weight_list(
extractor::SegmentDataView::SegmentWeightVector geometry_fwd_weight_list( geometries_fwd_weight_list_ptr,
util::vector_view<extractor::SegmentDataView::SegmentWeightVector::block_type>( data_layout.num_entries[storage::DataLayout::GEOMETRIES_FWD_WEIGHT_LIST]);
geometries_fwd_weight_list_ptr,
data_layout.num_entries[storage::DataLayout::GEOMETRIES_FWD_WEIGHT_LIST]),
num_entries);
auto geometries_rev_weight_list_ptr = auto geometries_rev_weight_list_ptr = data_layout.GetBlockPtr<EdgeWeight>(
data_layout.GetBlockPtr<extractor::SegmentDataView::SegmentWeightVector::block_type>( memory_block, storage::DataLayout::GEOMETRIES_REV_WEIGHT_LIST);
memory_block, storage::DataLayout::GEOMETRIES_REV_WEIGHT_LIST); util::vector_view<EdgeWeight> geometry_rev_weight_list(
extractor::SegmentDataView::SegmentWeightVector geometry_rev_weight_list( geometries_rev_weight_list_ptr,
util::vector_view<extractor::SegmentDataView::SegmentWeightVector::block_type>( data_layout.num_entries[storage::DataLayout::GEOMETRIES_REV_WEIGHT_LIST]);
geometries_rev_weight_list_ptr,
data_layout.num_entries[storage::DataLayout::GEOMETRIES_REV_WEIGHT_LIST]),
num_entries);
auto geometries_fwd_duration_list_ptr = auto geometries_fwd_duration_list_ptr = data_layout.GetBlockPtr<EdgeWeight>(
data_layout.GetBlockPtr<extractor::SegmentDataView::SegmentDurationVector::block_type>( memory_block, storage::DataLayout::GEOMETRIES_FWD_DURATION_LIST);
memory_block, storage::DataLayout::GEOMETRIES_FWD_DURATION_LIST); util::vector_view<EdgeWeight> geometry_fwd_duration_list(
extractor::SegmentDataView::SegmentDurationVector geometry_fwd_duration_list( geometries_fwd_duration_list_ptr,
util::vector_view<extractor::SegmentDataView::SegmentDurationVector::block_type>( data_layout.num_entries[storage::DataLayout::GEOMETRIES_FWD_DURATION_LIST]);
geometries_fwd_duration_list_ptr,
data_layout.num_entries[storage::DataLayout::GEOMETRIES_FWD_DURATION_LIST]),
num_entries);
auto geometries_rev_duration_list_ptr = auto geometries_rev_duration_list_ptr = data_layout.GetBlockPtr<EdgeWeight>(
data_layout.GetBlockPtr<extractor::SegmentDataView::SegmentDurationVector::block_type>( memory_block, storage::DataLayout::GEOMETRIES_REV_DURATION_LIST);
memory_block, storage::DataLayout::GEOMETRIES_REV_DURATION_LIST); util::vector_view<EdgeWeight> geometry_rev_duration_list(
extractor::SegmentDataView::SegmentDurationVector geometry_rev_duration_list( geometries_rev_duration_list_ptr,
util::vector_view<extractor::SegmentDataView::SegmentDurationVector::block_type>( data_layout.num_entries[storage::DataLayout::GEOMETRIES_REV_DURATION_LIST]);
geometries_rev_duration_list_ptr,
data_layout.num_entries[storage::DataLayout::GEOMETRIES_REV_DURATION_LIST]),
num_entries);
auto datasources_list_ptr = data_layout.GetBlockPtr<DatasourceID>( auto datasources_list_ptr = data_layout.GetBlockPtr<DatasourceID>(
memory_block, storage::DataLayout::DATASOURCES_LIST); memory_block, storage::DataLayout::DATASOURCES_LIST);
@@ -535,7 +508,6 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
{ {
InitializeChecksumPointer(data_layout, memory_block); InitializeChecksumPointer(data_layout, memory_block);
InitializeNodeInformationPointers(data_layout, memory_block); InitializeNodeInformationPointers(data_layout, memory_block);
InitializeEdgeBasedNodeDataInformationPointers(data_layout, memory_block);
InitializeEdgeInformationPointers(data_layout, memory_block); InitializeEdgeInformationPointers(data_layout, memory_block);
InitializeTurnPenalties(data_layout, memory_block); InitializeTurnPenalties(data_layout, memory_block);
InitializeGeometryPointers(data_layout, memory_block); InitializeGeometryPointers(data_layout, memory_block);
@@ -564,10 +536,10 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
OSMNodeID GetOSMNodeIDOfNode(const NodeID id) const override final OSMNodeID GetOSMNodeIDOfNode(const NodeID id) const override final
{ {
return m_osmnodeid_list[id]; return m_osmnodeid_list.at(id);
} }
std::vector<NodeID> GetUncompressedForwardGeometry(const EdgeID id) const override final virtual std::vector<NodeID> GetUncompressedForwardGeometry(const EdgeID id) const override final
{ {
auto range = segment_data.GetForwardGeometry(id); auto range = segment_data.GetForwardGeometry(id);
@@ -626,6 +598,11 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
return std::vector<DatasourceID>{range.begin(), range.end()}; return std::vector<DatasourceID>{range.begin(), range.end()};
} }
virtual GeometryID GetGeometryIndexForEdgeID(const EdgeID id) const override final
{
return turn_data.GetGeometryID(id);
}
virtual TurnPenalty GetWeightPenaltyForEdgeID(const unsigned id) const override final virtual TurnPenalty GetWeightPenaltyForEdgeID(const unsigned id) const override final
{ {
BOOST_ASSERT(m_turn_weight_penalties.size() > id); BOOST_ASSERT(m_turn_weight_penalties.size() > id);
@@ -644,6 +621,11 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
return turn_data.GetTurnInstruction(id); return turn_data.GetTurnInstruction(id);
} }
extractor::TravelMode GetTravelModeForEdgeID(const EdgeID id) const override final
{
return turn_data.GetTravelMode(id);
}
std::vector<RTreeLeaf> GetEdgesInBox(const util::Coordinate south_west, std::vector<RTreeLeaf> GetEdgesInBox(const util::Coordinate south_west,
const util::Coordinate north_east) const override final const util::Coordinate north_east) const override final
{ {
@@ -655,61 +637,54 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float max_distance, const float max_distance) const override final
const Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodesInRange( return m_geospatial_query->NearestPhantomNodesInRange(input_coordinate, max_distance);
input_coordinate, max_distance, approach);
} }
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float max_distance, const float max_distance,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range) const override final
const Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodesInRange( return m_geospatial_query->NearestPhantomNodesInRange(
input_coordinate, max_distance, bearing, bearing_range, approach); input_coordinate, max_distance, bearing, bearing_range);
}
std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results) const override final
{
BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results);
} }
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results, const unsigned max_results,
const Approach approach) const override final const double max_distance) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, approach); return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, max_distance);
}
std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results,
const double max_distance,
const Approach approach) const override final
{
BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodes(
input_coordinate, max_results, max_distance, approach);
} }
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results, const unsigned max_results,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range) const override final
const Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodes( return m_geospatial_query->NearestPhantomNodes(
input_coordinate, max_results, bearing, bearing_range, approach); input_coordinate, max_results, bearing, bearing_range);
} }
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
@@ -717,81 +692,60 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
const unsigned max_results, const unsigned max_results,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range) const override final
const Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodes( return m_geospatial_query->NearestPhantomNodes(
input_coordinate, max_results, max_distance, bearing, bearing_range, approach); input_coordinate, max_results, max_distance, bearing, bearing_range);
} }
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, const util::Coordinate input_coordinate) const override final
const Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent( return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, approach); input_coordinate);
} }
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, const util::Coordinate input_coordinate, const double max_distance) const override final
const double max_distance,
const Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent( return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, max_distance, approach); input_coordinate, max_distance);
} }
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range) const override final
const Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent( return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, max_distance, bearing, bearing_range, approach); input_coordinate, max_distance, bearing, bearing_range);
} }
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range) const override final
const Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent( return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, bearing, bearing_range, approach); input_coordinate, bearing, bearing_range);
} }
unsigned GetCheckSum() const override final { return m_check_sum; } unsigned GetCheckSum() const override final { return m_check_sum; }
GeometryID GetGeometryIndex(const NodeID id) const override final NameID GetNameIndexFromEdgeID(const EdgeID id) const override final
{ {
return edge_based_node_data.GetGeometryID(id); return turn_data.GetNameID(id);
}
ComponentID GetComponentID(const NodeID id) const override final
{
return edge_based_node_data.GetComponentID(id);
}
extractor::TravelMode GetTravelMode(const NodeID id) const override final
{
return edge_based_node_data.GetTravelMode(id);
}
NameID GetNameIndex(const NodeID id) const override final
{
return edge_based_node_data.GetNameID(id);
} }
StringView GetNameForID(const NameID id) const override final StringView GetNameForID(const NameID id) const override final
@@ -899,11 +853,6 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
m_lane_description_masks.begin() + m_lane_description_masks.begin() +
m_lane_description_offsets[lane_description_id + 1]); m_lane_description_offsets[lane_description_id + 1]);
} }
bool IsLeftHandDriving() const override final
{
return m_profile_properties->left_hand_driving;
}
}; };
template <typename AlgorithmT> class ContiguousInternalMemoryDataFacade; template <typename AlgorithmT> class ContiguousInternalMemoryDataFacade;
+18 -33
View File
@@ -4,12 +4,11 @@
// Exposes all data access interfaces to the algorithms via base class ptr // Exposes all data access interfaces to the algorithms via base class ptr
#include "contractor/query_edge.hpp" #include "contractor/query_edge.hpp"
#include "extractor/edge_based_node_segment.hpp" #include "extractor/edge_based_node.hpp"
#include "extractor/external_memory_node.hpp" #include "extractor/external_memory_node.hpp"
#include "extractor/guidance/turn_instruction.hpp" #include "extractor/guidance/turn_instruction.hpp"
#include "extractor/guidance/turn_lane_types.hpp" #include "extractor/guidance/turn_lane_types.hpp"
#include "extractor/original_edge_data.hpp" #include "extractor/original_edge_data.hpp"
#include "engine/approach.hpp"
#include "engine/phantom_node.hpp" #include "engine/phantom_node.hpp"
#include "util/exception.hpp" #include "util/exception.hpp"
#include "util/guidance/bearing_class.hpp" #include "util/guidance/bearing_class.hpp"
@@ -41,7 +40,7 @@ using StringView = util::StringView;
class BaseDataFacade class BaseDataFacade
{ {
public: public:
using RTreeLeaf = extractor::EdgeBasedNodeSegment; using RTreeLeaf = extractor::EdgeBasedNode;
BaseDataFacade() {} BaseDataFacade() {}
virtual ~BaseDataFacade() {} virtual ~BaseDataFacade() {}
@@ -52,9 +51,7 @@ class BaseDataFacade
virtual OSMNodeID GetOSMNodeIDOfNode(const NodeID id) const = 0; virtual OSMNodeID GetOSMNodeIDOfNode(const NodeID id) const = 0;
virtual GeometryID GetGeometryIndex(const NodeID id) const = 0; virtual GeometryID GetGeometryIndexForEdgeID(const EdgeID id) const = 0;
virtual ComponentID GetComponentID(const NodeID id) const = 0;
virtual std::vector<NodeID> GetUncompressedForwardGeometry(const EdgeID id) const = 0; virtual std::vector<NodeID> GetUncompressedForwardGeometry(const EdgeID id) const = 0;
@@ -85,7 +82,7 @@ class BaseDataFacade
virtual extractor::guidance::TurnInstruction virtual extractor::guidance::TurnInstruction
GetTurnInstructionForEdgeID(const EdgeID id) const = 0; GetTurnInstructionForEdgeID(const EdgeID id) const = 0;
virtual extractor::TravelMode GetTravelMode(const NodeID id) const = 0; virtual extractor::TravelMode GetTravelModeForEdgeID(const EdgeID id) const = 0;
virtual std::vector<RTreeLeaf> GetEdgesInBox(const util::Coordinate south_west, virtual std::vector<RTreeLeaf> GetEdgesInBox(const util::Coordinate south_west,
const util::Coordinate north_east) const = 0; const util::Coordinate north_east) const = 0;
@@ -94,61 +91,51 @@ class BaseDataFacade
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float max_distance, const float max_distance,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range) const = 0;
const Approach approach) const = 0;
virtual std::vector<PhantomNodeWithDistance> virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float max_distance, const float max_distance) const = 0;
const Approach approach) const = 0;
virtual std::vector<PhantomNodeWithDistance> virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results, const unsigned max_results,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range) const = 0;
const Approach approach) const = 0;
virtual std::vector<PhantomNodeWithDistance> virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results, const unsigned max_results,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range) const = 0;
const Approach approach) const = 0; virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results) const = 0;
virtual std::vector<PhantomNodeWithDistance> virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results, const unsigned max_results,
const Approach approach) const = 0; const double max_distance) const = 0;
virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results,
const double max_distance,
const Approach approach) const = 0;
virtual std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
const util::Coordinate input_coordinate) const = 0;
virtual std::pair<PhantomNode, PhantomNode> virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const Approach approach) const = 0; const double max_distance) const = 0;
virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance,
const Approach approach) const = 0;
virtual std::pair<PhantomNode, PhantomNode> virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range) const = 0;
const Approach approach) const = 0;
virtual std::pair<PhantomNode, PhantomNode> virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range) const = 0;
const Approach approach) const = 0;
virtual bool HasLaneData(const EdgeID id) const = 0; virtual bool HasLaneData(const EdgeID id) const = 0;
virtual util::guidance::LaneTupleIdPair GetLaneData(const EdgeID id) const = 0; virtual util::guidance::LaneTupleIdPair GetLaneData(const EdgeID id) const = 0;
virtual extractor::guidance::TurnLaneDescription virtual extractor::guidance::TurnLaneDescription
GetTurnDescription(const LaneDescriptionID lane_description_id) const = 0; GetTurnDescription(const LaneDescriptionID lane_description_id) const = 0;
virtual NameID GetNameIndex(const NodeID id) const = 0; virtual NameID GetNameIndexFromEdgeID(const EdgeID id) const = 0;
virtual StringView GetNameForID(const NameID id) const = 0; virtual StringView GetNameForID(const NameID id) const = 0;
@@ -181,8 +168,6 @@ class BaseDataFacade
virtual EntryClassID GetEntryClassID(const EdgeID eid) const = 0; virtual EntryClassID GetEntryClassID(const EdgeID eid) const = 0;
virtual util::guidance::EntryClass GetEntryClass(const EntryClassID entry_class_id) const = 0; virtual util::guidance::EntryClass GetEntryClass(const EntryClassID entry_class_id) const = 0;
virtual bool IsLeftHandDriving() const = 0;
}; };
} }
} }
+11 -37
View File
@@ -22,7 +22,6 @@
#include "engine/status.hpp" #include "engine/status.hpp"
#include "util/exception.hpp" #include "util/exception.hpp"
#include "util/exception_utils.hpp" #include "util/exception_utils.hpp"
#include "util/fingerprint.hpp"
#include "util/json_container.hpp" #include "util/json_container.hpp"
#include <memory> #include <memory>
@@ -159,12 +158,12 @@ bool Engine<routing_algorithms::ch::Algorithm>::CheckCompability(const EngineCon
} }
else else
{ {
if (!boost::filesystem::exists(config.storage_config.hsgr_data_path)) std::ifstream in(config.storage_config.hsgr_data_path.string().c_str());
if (!in)
return false; return false;
storage::io::FileReader in(config.storage_config.hsgr_data_path,
storage::io::FileReader::VerifyFingerprint);
auto size = in.GetSize(); in.seekg(0, std::ios::end);
auto size = in.tellg();
return size > 0; return size > 0;
} }
} }
@@ -185,43 +184,18 @@ bool Engine<routing_algorithms::corech::Algorithm>::CheckCompability(const Engin
auto mem = storage::makeSharedMemory(barrier.data().region); auto mem = storage::makeSharedMemory(barrier.data().region);
auto layout = reinterpret_cast<storage::DataLayout *>(mem->Ptr()); auto layout = reinterpret_cast<storage::DataLayout *>(mem->Ptr());
return layout->GetBlockSize(storage::DataLayout::CH_CORE_MARKER) > return layout->GetBlockSize(storage::DataLayout::CH_CORE_MARKER) > 4;
sizeof(std::uint64_t) + sizeof(util::FingerPrint);
} }
else else
{ {
if (!boost::filesystem::exists(config.storage_config.core_data_path)) std::ifstream in(config.storage_config.core_data_path.string().c_str());
if (!in)
return false; return false;
storage::io::FileReader in(config.storage_config.core_data_path,
storage::io::FileReader::VerifyFingerprint);
auto size = in.GetSize(); in.seekg(0, std::ios::end);
return size > sizeof(std::uint64_t); std::size_t size = in.tellg();
} // An empty core files is only the 4 byte size header.
} return size > sizeof(std::uint32_t);
template <>
bool Engine<routing_algorithms::mld::Algorithm>::CheckCompability(const EngineConfig &config)
{
if (config.use_shared_memory)
{
storage::SharedMonitor<storage::SharedDataTimestamp> barrier;
using mutex_type = typename decltype(barrier)::mutex_type;
boost::interprocess::scoped_lock<mutex_type> current_region_lock(barrier.get_mutex());
auto mem = storage::makeSharedMemory(barrier.data().region);
auto layout = reinterpret_cast<storage::DataLayout *>(mem->Ptr());
return layout->GetBlockSize(storage::DataLayout::MLD_PARTITION) > 0;
}
else
{
if (!boost::filesystem::exists(config.storage_config.mld_partition_path))
return false;
storage::io::FileReader in(config.storage_config.mld_partition_path,
storage::io::FileReader::VerifyFingerprint);
auto size = in.GetSize();
return size > 0;
} }
} }
} }
+87 -188
View File
@@ -1,7 +1,6 @@
#ifndef GEOSPATIAL_QUERY_HPP #ifndef GEOSPATIAL_QUERY_HPP
#define GEOSPATIAL_QUERY_HPP #define GEOSPATIAL_QUERY_HPP
#include "engine/approach.hpp"
#include "engine/phantom_node.hpp" #include "engine/phantom_node.hpp"
#include "util/bearing.hpp" #include "util/bearing.hpp"
#include "util/coordinate_calculation.hpp" #include "util/coordinate_calculation.hpp"
@@ -51,19 +50,15 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// Does not filter by small/big component! // Does not filter by small/big component!
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance) const
const Approach approach) const
{ {
auto results = rtree.Nearest( auto results =
input_coordinate, rtree.Nearest(input_coordinate,
[this, approach, &input_coordinate](const CandidateSegment &segment) { [this](const CandidateSegment &segment) { return HasValidEdge(segment); },
return boolPairAnd(HasValidEdge(segment), [this, max_distance, input_coordinate](const std::size_t,
CheckApproach(input_coordinate, segment, approach)); const CandidateSegment &segment) {
}, return CheckSegmentDistance(input_coordinate, segment, max_distance);
[this, max_distance, input_coordinate](const std::size_t, });
const CandidateSegment &segment) {
return CheckSegmentDistance(input_coordinate, segment, max_distance);
});
return MakePhantomNodes(input_coordinate, results); return MakePhantomNodes(input_coordinate, results);
} }
@@ -74,18 +69,13 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range) const
const Approach approach) const
{ {
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, approach, &input_coordinate, bearing, bearing_range, max_distance]( [this, bearing, bearing_range, max_distance](const CandidateSegment &segment) {
const CandidateSegment &segment) { return boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range),
auto use_direction = boolPairAnd( HasValidEdge(segment));
CheckSegmentBearing(segment, bearing, bearing_range), HasValidEdge(segment));
use_direction =
boolPairAnd(use_direction, CheckApproach(input_coordinate, segment, approach));
return use_direction;
}, },
[this, max_distance, input_coordinate](const std::size_t, [this, max_distance, input_coordinate](const std::size_t,
const CandidateSegment &segment) { const CandidateSegment &segment) {
@@ -101,17 +91,13 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
NearestPhantomNodes(const util::Coordinate input_coordinate, NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results, const unsigned max_results,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range) const
const Approach approach) const
{ {
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, approach, &input_coordinate, bearing, bearing_range]( [this, bearing, bearing_range](const CandidateSegment &segment) {
const CandidateSegment &segment) { return boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range),
auto use_direction = boolPairAnd( HasValidEdge(segment));
CheckSegmentBearing(segment, bearing, bearing_range), HasValidEdge(segment));
return boolPairAnd(use_direction,
CheckApproach(input_coordinate, segment, approach));
}, },
[max_results](const std::size_t num_results, const CandidateSegment &) { [max_results](const std::size_t num_results, const CandidateSegment &) {
return num_results >= max_results; return num_results >= max_results;
@@ -128,17 +114,13 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
const unsigned max_results, const unsigned max_results,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range) const
const Approach approach) const
{ {
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, approach, &input_coordinate, bearing, bearing_range]( [this, bearing, bearing_range](const CandidateSegment &segment) {
const CandidateSegment &segment) { return boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range),
auto use_direction = boolPairAnd( HasValidEdge(segment));
CheckSegmentBearing(segment, bearing, bearing_range), HasValidEdge(segment));
return boolPairAnd(use_direction,
CheckApproach(input_coordinate, segment, approach));
}, },
[this, max_distance, max_results, input_coordinate](const std::size_t num_results, [this, max_distance, max_results, input_coordinate](const std::size_t num_results,
const CandidateSegment &segment) { const CandidateSegment &segment) {
@@ -152,19 +134,14 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// Returns max_results nearest PhantomNodes. // Returns max_results nearest PhantomNodes.
// Does not filter by small/big component! // Does not filter by small/big component!
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, NearestPhantomNodes(const util::Coordinate input_coordinate, const unsigned max_results) const
const unsigned max_results,
const Approach approach) const
{ {
auto results = rtree.Nearest( auto results =
input_coordinate, rtree.Nearest(input_coordinate,
[this, approach, &input_coordinate](const CandidateSegment &segment) { [this](const CandidateSegment &segment) { return HasValidEdge(segment); },
return boolPairAnd(HasValidEdge(segment), [max_results](const std::size_t num_results, const CandidateSegment &) {
CheckApproach(input_coordinate, segment, approach)); return num_results >= max_results;
}, });
[max_results](const std::size_t num_results, const CandidateSegment &) {
return num_results >= max_results;
});
return MakePhantomNodes(input_coordinate, results); return MakePhantomNodes(input_coordinate, results);
} }
@@ -174,20 +151,16 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results, const unsigned max_results,
const double max_distance, const double max_distance) const
const Approach approach) const
{ {
auto results = rtree.Nearest( auto results =
input_coordinate, rtree.Nearest(input_coordinate,
[this, approach, &input_coordinate](const CandidateSegment &segment) { [this](const CandidateSegment &segment) { return HasValidEdge(segment); },
return boolPairAnd(HasValidEdge(segment), [this, max_distance, max_results, input_coordinate](
CheckApproach(input_coordinate, segment, approach)); const std::size_t num_results, const CandidateSegment &segment) {
}, return num_results >= max_results ||
[this, max_distance, max_results, input_coordinate](const std::size_t num_results, CheckSegmentDistance(input_coordinate, segment, max_distance);
const CandidateSegment &segment) { });
return num_results >= max_results ||
CheckSegmentDistance(input_coordinate, segment, max_distance);
});
return MakePhantomNodes(input_coordinate, results); return MakePhantomNodes(input_coordinate, results);
} }
@@ -196,29 +169,24 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// a second phantom node is return that is the nearest coordinate in a big component. // a second phantom node is return that is the nearest coordinate in a big component.
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance) const
const Approach approach) const
{ {
bool has_small_component = false; bool has_small_component = false;
bool has_big_component = false; bool has_big_component = false;
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, approach, &input_coordinate, &has_big_component, &has_small_component]( [this, &has_big_component, &has_small_component](const CandidateSegment &segment) {
const CandidateSegment &segment) { auto use_segment = (!has_small_component ||
auto use_segment = (!has_big_component && !segment.data.component.is_tiny));
(!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
auto use_directions = std::make_pair(use_segment, use_segment); auto use_directions = std::make_pair(use_segment, use_segment);
const auto valid_edges = HasValidEdge(segment); const auto valid_edges = HasValidEdge(segment);
use_directions = boolPairAnd(use_directions, valid_edges);
use_directions =
boolPairAnd(use_directions, CheckApproach(input_coordinate, segment, approach));
if (use_directions.first || use_directions.second) if (valid_edges.first || valid_edges.second)
{ {
has_big_component = has_big_component || !IsTinyComponent(segment); has_big_component = has_big_component || !segment.data.component.is_tiny;
has_small_component = has_small_component || IsTinyComponent(segment); has_small_component = has_small_component || segment.data.component.is_tiny;
} }
use_directions = boolPairAnd(use_directions, valid_edges);
return use_directions; return use_directions;
}, },
[this, &has_big_component, max_distance, input_coordinate]( [this, &has_big_component, max_distance, input_coordinate](
@@ -240,30 +208,28 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// Returns the nearest phantom node. If this phantom node is not from a big component // 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. // a second phantom node is return that is the nearest coordinate in a big component.
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate) const
const Approach approach) const
{ {
bool has_small_component = false; bool has_small_component = false;
bool has_big_component = false; bool has_big_component = false;
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, approach, &input_coordinate, &has_big_component, &has_small_component]( [this, &has_big_component, &has_small_component](const CandidateSegment &segment) {
const CandidateSegment &segment) { auto use_segment = (!has_small_component ||
auto use_segment = (!has_big_component && !segment.data.component.is_tiny));
(!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
auto use_directions = std::make_pair(use_segment, use_segment); auto use_directions = std::make_pair(use_segment, use_segment);
if (!use_directions.first && !use_directions.second)
return use_directions;
const auto valid_edges = HasValidEdge(segment); const auto valid_edges = HasValidEdge(segment);
use_directions = boolPairAnd(use_directions, valid_edges);
use_directions =
boolPairAnd(use_directions, CheckApproach(input_coordinate, segment, approach));
if (use_directions.first || use_directions.second) if (valid_edges.first || valid_edges.second)
{ {
has_big_component = has_big_component || !IsTinyComponent(segment);
has_small_component = has_small_component || IsTinyComponent(segment); has_big_component = has_big_component || !segment.data.component.is_tiny;
has_small_component = has_small_component || segment.data.component.is_tiny;
} }
use_directions = boolPairAnd(use_directions, valid_edges);
return use_directions; return use_directions;
}, },
[&has_big_component](const std::size_t num_results, const CandidateSegment &) { [&has_big_component](const std::size_t num_results, const CandidateSegment &) {
@@ -282,25 +248,17 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// Returns the nearest phantom node. If this phantom node is not from a big component // 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. // a second phantom node is return that is the nearest coordinate in a big component.
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, const util::Coordinate input_coordinate, const int bearing, const int bearing_range) const
const int bearing,
const int bearing_range,
const Approach approach) const
{ {
bool has_small_component = false; bool has_small_component = false;
bool has_big_component = false; bool has_big_component = false;
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, [this, bearing, bearing_range, &has_big_component, &has_small_component](
approach, const CandidateSegment &segment) {
&input_coordinate, auto use_segment = (!has_small_component ||
bearing, (!has_big_component && !segment.data.component.is_tiny));
bearing_range,
&has_big_component,
&has_small_component](const CandidateSegment &segment) {
auto use_segment =
(!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
auto use_directions = std::make_pair(use_segment, use_segment); auto use_directions = std::make_pair(use_segment, use_segment);
use_directions = boolPairAnd(use_directions, HasValidEdge(segment)); use_directions = boolPairAnd(use_directions, HasValidEdge(segment));
@@ -309,13 +267,10 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
use_directions = use_directions =
boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range), boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range),
HasValidEdge(segment)); HasValidEdge(segment));
use_directions = boolPairAnd(
use_directions, CheckApproach(input_coordinate, segment, approach));
if (use_directions.first || use_directions.second) if (use_directions.first || use_directions.second)
{ {
has_big_component = has_big_component || !IsTinyComponent(segment); has_big_component = has_big_component || !segment.data.component.is_tiny;
has_small_component = has_small_component || IsTinyComponent(segment); has_small_component = has_small_component || segment.data.component.is_tiny;
} }
} }
@@ -341,22 +296,16 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range) const
const Approach approach) const
{ {
bool has_small_component = false; bool has_small_component = false;
bool has_big_component = false; bool has_big_component = false;
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, [this, bearing, bearing_range, &has_big_component, &has_small_component](
approach, const CandidateSegment &segment) {
&input_coordinate, auto use_segment = (!has_small_component ||
bearing, (!has_big_component && !segment.data.component.is_tiny));
bearing_range,
&has_big_component,
&has_small_component](const CandidateSegment &segment) {
auto use_segment =
(!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
auto use_directions = std::make_pair(use_segment, use_segment); auto use_directions = std::make_pair(use_segment, use_segment);
use_directions = boolPairAnd(use_directions, HasValidEdge(segment)); use_directions = boolPairAnd(use_directions, HasValidEdge(segment));
@@ -365,13 +314,10 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
use_directions = use_directions =
boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range), boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range),
HasValidEdge(segment)); HasValidEdge(segment));
use_directions = boolPairAnd(
use_directions, CheckApproach(input_coordinate, segment, approach));
if (use_directions.first || use_directions.second) if (use_directions.first || use_directions.second)
{ {
has_big_component = has_big_component || !IsTinyComponent(segment); has_big_component = has_big_component || !segment.data.component.is_tiny;
has_small_component = has_small_component || IsTinyComponent(segment); has_small_component = has_small_component || segment.data.component.is_tiny;
} }
} }
@@ -425,24 +371,17 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
EdgeWeight forward_weight_offset = 0, forward_weight = 0; EdgeWeight forward_weight_offset = 0, forward_weight = 0;
EdgeWeight reverse_weight_offset = 0, reverse_weight = 0; EdgeWeight reverse_weight_offset = 0, reverse_weight = 0;
EdgeDuration forward_duration_offset = 0, forward_duration = 0; EdgeWeight forward_duration_offset = 0, forward_duration = 0;
EdgeDuration reverse_duration_offset = 0, reverse_duration = 0; EdgeWeight reverse_duration_offset = 0, reverse_duration = 0;
BOOST_ASSERT(data.forward_segment_id.enabled || data.reverse_segment_id.enabled);
BOOST_ASSERT(!data.reverse_segment_id.enabled ||
datafacade.GetGeometryIndex(data.forward_segment_id.id).id ==
datafacade.GetGeometryIndex(data.reverse_segment_id.id).id);
const auto geometry_id = datafacade.GetGeometryIndex(data.forward_segment_id.id).id;
const auto component_id = datafacade.GetComponentID(data.forward_segment_id.id);
const std::vector<EdgeWeight> forward_weight_vector = const std::vector<EdgeWeight> forward_weight_vector =
datafacade.GetUncompressedForwardWeights(geometry_id); datafacade.GetUncompressedForwardWeights(data.packed_geometry_id);
const std::vector<EdgeWeight> reverse_weight_vector = const std::vector<EdgeWeight> reverse_weight_vector =
datafacade.GetUncompressedReverseWeights(geometry_id); datafacade.GetUncompressedReverseWeights(data.packed_geometry_id);
const std::vector<EdgeWeight> forward_duration_vector = const std::vector<EdgeWeight> forward_duration_vector =
datafacade.GetUncompressedForwardDurations(geometry_id); datafacade.GetUncompressedForwardDurations(data.packed_geometry_id);
const std::vector<EdgeWeight> reverse_duration_vector = const std::vector<EdgeWeight> reverse_duration_vector =
datafacade.GetUncompressedReverseDurations(geometry_id); datafacade.GetUncompressedReverseDurations(data.packed_geometry_id);
for (std::size_t i = 0; i < data.fwd_segment_position; i++) for (std::size_t i = 0; i < data.fwd_segment_position; i++)
{ {
@@ -469,17 +408,17 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
if (data.forward_segment_id.id != SPECIAL_SEGMENTID) if (data.forward_segment_id.id != SPECIAL_SEGMENTID)
{ {
forward_weight = static_cast<EdgeWeight>(forward_weight * ratio); forward_weight = static_cast<EdgeWeight>(forward_weight * ratio);
forward_duration = static_cast<EdgeDuration>(forward_duration * ratio); forward_duration = static_cast<EdgeWeight>(forward_duration * ratio);
} }
if (data.reverse_segment_id.id != SPECIAL_SEGMENTID) if (data.reverse_segment_id.id != SPECIAL_SEGMENTID)
{ {
reverse_weight -= static_cast<EdgeWeight>(reverse_weight * ratio); reverse_weight -= static_cast<EdgeWeight>(reverse_weight * ratio);
reverse_duration -= static_cast<EdgeDuration>(reverse_duration * ratio); reverse_duration -= static_cast<EdgeWeight>(reverse_duration * ratio);
} }
// check phantom node segments validity // check phantom node segments validity
auto areSegmentsValid = [](auto first, auto last) -> bool { auto areSegmentsValid = [](auto first, auto last) -> bool {
return std::find(first, last, INVALID_SEGMENT_WEIGHT) == last; return std::find(first, last, INVALID_EDGE_WEIGHT) == last;
}; };
bool is_forward_valid_source = bool is_forward_valid_source =
areSegmentsValid(forward_weight_vector.begin(), forward_weight_vector.end()); areSegmentsValid(forward_weight_vector.begin(), forward_weight_vector.end());
@@ -492,7 +431,6 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
reverse_weight_vector.begin(), reverse_weight_vector.end() - data.fwd_segment_position); reverse_weight_vector.begin(), reverse_weight_vector.end() - data.fwd_segment_position);
auto transformed = PhantomNodeWithDistance{PhantomNode{data, auto transformed = PhantomNodeWithDistance{PhantomNode{data,
component_id,
forward_weight, forward_weight,
reverse_weight, reverse_weight,
forward_weight_offset, forward_weight_offset,
@@ -557,7 +495,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
/** /**
* Checks to see if the edge weights are valid. We might have an edge, * Checks to see if the edge weights are valid. We might have an edge,
* but a traffic update might set the speed to 0 (weight == INVALID_SEGMENT_WEIGHT). * but a traffic update might set the speed to 0 (weight == INVALID_EDGE_WEIGHT).
* which means that this edge is not currently traversible. If this is the case, * which means that this edge is not currently traversible. If this is the case,
* then we shouldn't snap to this edge. * then we shouldn't snap to this edge.
*/ */
@@ -567,64 +505,25 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
bool forward_edge_valid = false; bool forward_edge_valid = false;
bool reverse_edge_valid = false; bool reverse_edge_valid = false;
const auto &data = segment.data;
BOOST_ASSERT(data.forward_segment_id.enabled);
BOOST_ASSERT(data.forward_segment_id.id != SPECIAL_NODEID);
const auto geometry_id = datafacade.GetGeometryIndex(data.forward_segment_id.id).id;
const std::vector<EdgeWeight> forward_weight_vector = const std::vector<EdgeWeight> forward_weight_vector =
datafacade.GetUncompressedForwardWeights(geometry_id); datafacade.GetUncompressedForwardWeights(segment.data.packed_geometry_id);
if (forward_weight_vector[data.fwd_segment_position] != INVALID_SEGMENT_WEIGHT) if (forward_weight_vector[segment.data.fwd_segment_position] != INVALID_EDGE_WEIGHT)
{ {
forward_edge_valid = data.forward_segment_id.enabled; forward_edge_valid = segment.data.forward_segment_id.enabled;
} }
const std::vector<EdgeWeight> reverse_weight_vector = const std::vector<EdgeWeight> reverse_weight_vector =
datafacade.GetUncompressedReverseWeights(geometry_id); datafacade.GetUncompressedReverseWeights(segment.data.packed_geometry_id);
if (reverse_weight_vector[reverse_weight_vector.size() - data.fwd_segment_position - 1] != if (reverse_weight_vector[reverse_weight_vector.size() - segment.data.fwd_segment_position -
INVALID_SEGMENT_WEIGHT) 1] != INVALID_EDGE_WEIGHT)
{ {
reverse_edge_valid = data.reverse_segment_id.enabled; reverse_edge_valid = segment.data.reverse_segment_id.enabled;
} }
return std::make_pair(forward_edge_valid, reverse_edge_valid); return std::make_pair(forward_edge_valid, reverse_edge_valid);
} }
bool IsTinyComponent(const CandidateSegment &segment) const
{
const auto &data = segment.data;
BOOST_ASSERT(data.forward_segment_id.enabled);
BOOST_ASSERT(data.forward_segment_id.id != SPECIAL_NODEID);
return datafacade.GetComponentID(data.forward_segment_id.id).is_tiny;
}
std::pair<bool, bool> CheckApproach(const util::Coordinate &input_coordinate,
const CandidateSegment &segment,
const Approach approach) const
{
bool isOnewaySegment =
!(segment.data.forward_segment_id.enabled && segment.data.reverse_segment_id.enabled);
if (!isOnewaySegment && approach == Approach::CURB)
{
// Check the counter clockwise
//
// input_coordinate
// |
// |
// segment.data.u ---------------- segment.data.v
bool input_coordinate_is_at_right = !util::coordinate_calculation::isCCW(
coordinates[segment.data.u], coordinates[segment.data.v], input_coordinate);
if (datafacade.IsLeftHandDriving())
input_coordinate_is_at_right = !input_coordinate_is_at_right;
return std::make_pair(input_coordinate_is_at_right, (!input_coordinate_is_at_right));
}
return std::make_pair(true, true);
}
const RTreeT &rtree; const RTreeT &rtree;
const CoordinateList &coordinates; const CoordinateList &coordinates;
DataFacadeT &datafacade; DataFacadeT &datafacade;
@@ -51,11 +51,8 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
// source node rev: 2 0 <- 1 <- 2 // source node rev: 2 0 <- 1 <- 2
const auto source_segment_start_coordinate = const auto source_segment_start_coordinate =
source_node.fwd_segment_position + (reversed_source ? 1 : 0); source_node.fwd_segment_position + (reversed_source ? 1 : 0);
const auto source_node_id =
reversed_source ? source_node.reverse_segment_id.id : source_node.forward_segment_id.id;
const auto source_gemetry_id = facade.GetGeometryIndex(source_node_id).id;
const std::vector<NodeID> source_geometry = const std::vector<NodeID> source_geometry =
facade.GetUncompressedForwardGeometry(source_gemetry_id); facade.GetUncompressedForwardGeometry(source_node.packed_geometry_id);
geometry.osm_node_ids.push_back( geometry.osm_node_ids.push_back(
facade.GetOSMNodeIDOfNode(source_geometry[source_segment_start_coordinate])); facade.GetOSMNodeIDOfNode(source_geometry[source_segment_start_coordinate]));
@@ -92,11 +89,8 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
// segment leading to the target node // segment leading to the target node
geometry.segment_distances.push_back(cumulative_distance); geometry.segment_distances.push_back(cumulative_distance);
const auto target_node_id =
reversed_target ? target_node.reverse_segment_id.id : target_node.forward_segment_id.id;
const auto target_gemetry_id = facade.GetGeometryIndex(target_node_id).id;
const std::vector<DatasourceID> forward_datasources = const std::vector<DatasourceID> forward_datasources =
facade.GetUncompressedForwardDatasources(target_gemetry_id); facade.GetUncompressedForwardDatasources(target_node.packed_geometry_id);
// FIXME if source and target phantoms are on the same segment then duration and weight // FIXME if source and target phantoms are on the same segment then duration and weight
// will be from one projected point till end of segment // will be from one projected point till end of segment
@@ -119,7 +113,7 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
const auto target_segment_end_coordinate = const auto target_segment_end_coordinate =
target_node.fwd_segment_position + (reversed_target ? 0 : 1); target_node.fwd_segment_position + (reversed_target ? 0 : 1);
const std::vector<NodeID> target_geometry = const std::vector<NodeID> target_geometry =
facade.GetUncompressedForwardGeometry(target_gemetry_id); facade.GetUncompressedForwardGeometry(target_node.packed_geometry_id);
geometry.osm_node_ids.push_back( geometry.osm_node_ids.push_back(
facade.GetOSMNodeIDOfNode(target_geometry[target_segment_end_coordinate])); facade.GetOSMNodeIDOfNode(target_geometry[target_segment_end_coordinate]));
+3 -6
View File
@@ -40,8 +40,7 @@ struct NamedSegment
template <std::size_t SegmentNumber> template <std::size_t SegmentNumber>
std::array<std::uint32_t, SegmentNumber> summarizeRoute(const datafacade::BaseDataFacade &facade, std::array<std::uint32_t, SegmentNumber> summarizeRoute(const std::vector<PathData> &route_data,
const std::vector<PathData> &route_data,
const PhantomNode &target_node, const PhantomNode &target_node,
const bool target_traversed_in_reverse) const bool target_traversed_in_reverse)
{ {
@@ -81,10 +80,8 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const datafacade::BaseDa
}); });
const auto target_duration = const auto target_duration =
target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration; target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration;
const auto target_node_id = target_traversed_in_reverse ? target_node.reverse_segment_id.id
: target_node.forward_segment_id.id;
if (target_duration > 1) if (target_duration > 1)
segments.push_back({target_duration, index++, facade.GetNameIndex(target_node_id)}); segments.push_back({target_duration, index++, target_node.name_id});
// this makes sure that the segment with the lowest position comes first // this makes sure that the segment with the lowest position comes first
std::sort( std::sort(
segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs) { segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs) {
@@ -186,7 +183,7 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
if (needs_summary) if (needs_summary)
{ {
auto summary_array = detail::summarizeRoute<detail::MAX_USED_SEGMENTS>( auto summary_array = detail::summarizeRoute<detail::MAX_USED_SEGMENTS>(
facade, route_data, target_node, target_traversed_in_reverse); route_data, target_node, target_traversed_in_reverse);
BOOST_ASSERT(detail::MAX_USED_SEGMENTS > 0); BOOST_ASSERT(detail::MAX_USED_SEGMENTS > 0);
BOOST_ASSERT(summary_array.begin() != summary_array.end()); BOOST_ASSERT(summary_array.begin() != summary_array.end());
+16 -20
View File
@@ -49,19 +49,15 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
source_traversed_in_reverse ? source_node.reverse_weight : source_node.forward_weight; source_traversed_in_reverse ? source_node.reverse_weight : source_node.forward_weight;
const EdgeWeight source_duration = const EdgeWeight source_duration =
source_traversed_in_reverse ? source_node.reverse_duration : source_node.forward_duration; source_traversed_in_reverse ? source_node.reverse_duration : source_node.forward_duration;
const auto source_node_id = source_traversed_in_reverse ? source_node.reverse_segment_id.id const auto source_mode = source_traversed_in_reverse ? source_node.backward_travel_mode
: source_node.forward_segment_id.id; : source_node.forward_travel_mode;
const auto source_name_id = facade.GetNameIndex(source_node_id);
const auto source_mode = facade.GetTravelMode(source_node_id);
const EdgeWeight target_duration = const EdgeWeight target_duration =
target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration; target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration;
const EdgeWeight target_weight = const EdgeWeight target_weight =
target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight; target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight;
const auto target_node_id = target_traversed_in_reverse ? target_node.reverse_segment_id.id const auto target_mode = target_traversed_in_reverse ? target_node.backward_travel_mode
: target_node.forward_segment_id.id; : target_node.forward_travel_mode;
const auto target_name_id = facade.GetNameIndex(target_node_id);
const auto target_mode = facade.GetTravelMode(target_node_id);
const auto number_of_segments = leg_geometry.GetNumberOfSegments(); const auto number_of_segments = leg_geometry.GetNumberOfSegments();
@@ -99,7 +95,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
// some name changes are not announced in our processing. For these, we have to keep the // some name changes are not announced in our processing. For these, we have to keep the
// first name on the segment // first name on the segment
auto step_name_id = source_name_id; 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 (std::size_t leg_data_index = 0; leg_data_index < leg_data.size(); ++leg_data_index)
{ {
const auto &path_point = leg_data[leg_data_index]; const auto &path_point = leg_data[leg_data_index];
@@ -138,7 +134,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
} }
else else
{ {
step_name_id = facade.GetNameIndex(target_node_id); step_name_id = target_node.name_id;
} }
// extract bearings // extract bearings
@@ -234,11 +230,11 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
BOOST_ASSERT(target_duration >= source_duration || weight == 0); BOOST_ASSERT(target_duration >= source_duration || weight == 0);
const EdgeWeight duration = std::max(0, target_duration - source_duration); const EdgeWeight duration = std::max(0, target_duration - source_duration);
steps.push_back(RouteStep{source_name_id, steps.push_back(RouteStep{source_node.name_id,
facade.GetNameForID(source_name_id).to_string(), facade.GetNameForID(source_node.name_id).to_string(),
facade.GetRefForID(source_name_id).to_string(), facade.GetRefForID(source_node.name_id).to_string(),
facade.GetPronunciationForID(source_name_id).to_string(), facade.GetPronunciationForID(source_node.name_id).to_string(),
facade.GetDestinationsForID(source_name_id).to_string(), facade.GetDestinationsForID(source_node.name_id).to_string(),
NO_ROTARY_NAME, NO_ROTARY_NAME,
NO_ROTARY_NAME, NO_ROTARY_NAME,
duration / 10., duration / 10.,
@@ -272,11 +268,11 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
0}; 0};
BOOST_ASSERT(!leg_geometry.locations.empty()); BOOST_ASSERT(!leg_geometry.locations.empty());
steps.push_back(RouteStep{target_name_id, steps.push_back(RouteStep{target_node.name_id,
facade.GetNameForID(target_name_id).to_string(), facade.GetNameForID(target_node.name_id).to_string(),
facade.GetRefForID(target_name_id).to_string(), facade.GetRefForID(target_node.name_id).to_string(),
facade.GetPronunciationForID(target_name_id).to_string(), facade.GetPronunciationForID(target_node.name_id).to_string(),
facade.GetDestinationsForID(target_name_id).to_string(), facade.GetDestinationsForID(target_node.name_id).to_string(),
NO_ROTARY_NAME, NO_ROTARY_NAME,
NO_ROTARY_NAME, NO_ROTARY_NAME,
ZERO_DURATION, ZERO_DURATION,
+2 -2
View File
@@ -63,8 +63,8 @@ struct Hint
friend std::ostream &operator<<(std::ostream &, const Hint &); friend std::ostream &operator<<(std::ostream &, const Hint &);
}; };
static_assert(sizeof(Hint) == 64 + 4, "Hint is bigger than expected"); static_assert(sizeof(Hint) == 72 + 4, "Hint is bigger than expected");
constexpr std::size_t ENCODED_HINT_SIZE = 92; constexpr std::size_t ENCODED_HINT_SIZE = 104;
static_assert(ENCODED_HINT_SIZE / 4 * 3 >= sizeof(Hint), static_assert(ENCODED_HINT_SIZE / 4 * 3 >= sizeof(Hint),
"ENCODED_HINT_SIZE does not match size of Hint"); "ENCODED_HINT_SIZE does not match size of Hint");
} }
+12 -10
View File
@@ -16,6 +16,8 @@ namespace osrm
namespace engine namespace engine
{ {
const constexpr unsigned INVALID_EXIT_NR = 0;
struct PathData struct PathData
{ {
// id of via node of the turn // id of via node of the turn
@@ -47,28 +49,28 @@ struct PathData
struct InternalRouteResult struct InternalRouteResult
{ {
std::vector<std::vector<PathData>> unpacked_path_segments; std::vector<std::vector<PathData>> unpacked_path_segments;
std::vector<PathData> unpacked_alternative;
std::vector<PhantomNodes> segment_end_coordinates; std::vector<PhantomNodes> segment_end_coordinates;
std::vector<bool> source_traversed_in_reverse; std::vector<bool> source_traversed_in_reverse;
std::vector<bool> target_traversed_in_reverse; std::vector<bool> target_traversed_in_reverse;
EdgeWeight shortest_path_weight = INVALID_EDGE_WEIGHT; std::vector<bool> alt_source_traversed_in_reverse;
std::vector<bool> alt_target_traversed_in_reverse;
int shortest_path_length;
int alternative_path_length;
bool is_valid() const { return INVALID_EDGE_WEIGHT != shortest_path_weight; } bool is_valid() const { return INVALID_EDGE_WEIGHT != shortest_path_length; }
bool has_alternative() const { return INVALID_EDGE_WEIGHT != alternative_path_length; }
bool is_via_leg(const std::size_t leg) const bool is_via_leg(const std::size_t leg) const
{ {
return (leg != unpacked_path_segments.size() - 1); return (leg != unpacked_path_segments.size() - 1);
} }
};
struct InternalManyRoutesResult InternalRouteResult()
{ : shortest_path_length(INVALID_EDGE_WEIGHT), alternative_path_length(INVALID_EDGE_WEIGHT)
InternalManyRoutesResult() = default;
InternalManyRoutesResult(InternalRouteResult route) : routes{std::move(route)} {}
InternalManyRoutesResult(std::vector<InternalRouteResult> routes_) : routes{std::move(routes_)}
{ {
} }
std::vector<InternalRouteResult> routes;
}; };
} }
} }
+36 -17
View File
@@ -48,12 +48,16 @@ struct PhantomNode
{ {
PhantomNode() PhantomNode()
: forward_segment_id{SPECIAL_SEGMENTID, false}, : forward_segment_id{SPECIAL_SEGMENTID, false},
reverse_segment_id{SPECIAL_SEGMENTID, false}, forward_weight(INVALID_EDGE_WEIGHT), reverse_segment_id{SPECIAL_SEGMENTID, false},
name_id(std::numeric_limits<unsigned>::max()), forward_weight(INVALID_EDGE_WEIGHT),
reverse_weight(INVALID_EDGE_WEIGHT), forward_weight_offset(0), reverse_weight_offset(0), reverse_weight(INVALID_EDGE_WEIGHT), forward_weight_offset(0), reverse_weight_offset(0),
forward_duration(MAXIMAL_EDGE_DURATION), reverse_duration(MAXIMAL_EDGE_DURATION), forward_duration(MAXIMAL_EDGE_DURATION), reverse_duration(MAXIMAL_EDGE_DURATION),
forward_duration_offset(0), reverse_duration_offset(0), fwd_segment_position(0), forward_duration_offset(0), reverse_duration_offset(0),
is_valid_forward_source{false}, is_valid_forward_target{false}, packed_geometry_id(SPECIAL_GEOMETRYID), component{INVALID_COMPONENTID, false},
is_valid_reverse_source{false}, is_valid_reverse_target{false} fwd_segment_position(0), forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE), is_valid_forward_source(false),
is_valid_forward_target(false), is_valid_reverse_source(false),
is_valid_reverse_target(false)
{ {
} }
@@ -91,7 +95,7 @@ struct PhantomNode
(reverse_weight != INVALID_EDGE_WEIGHT)) && (reverse_weight != INVALID_EDGE_WEIGHT)) &&
((forward_duration != MAXIMAL_EDGE_DURATION) || ((forward_duration != MAXIMAL_EDGE_DURATION) ||
(reverse_duration != MAXIMAL_EDGE_DURATION)) && (reverse_duration != MAXIMAL_EDGE_DURATION)) &&
(component.id != INVALID_COMPONENTID); (component.id != INVALID_COMPONENTID) && (name_id != INVALID_NAMEID);
} }
bool IsValid(const unsigned number_of_nodes, const util::Coordinate queried_coordinate) const bool IsValid(const unsigned number_of_nodes, const util::Coordinate queried_coordinate) const
@@ -99,7 +103,7 @@ struct PhantomNode
return queried_coordinate == input_location && IsValid(number_of_nodes); return queried_coordinate == input_location && IsValid(number_of_nodes);
} }
bool IsValid() const { return location.IsValid(); } bool IsValid() const { return location.IsValid() && (name_id != INVALID_NAMEID); }
bool IsValidForwardSource() const bool IsValidForwardSource() const
{ {
@@ -122,7 +126,6 @@ struct PhantomNode
template <class OtherT> template <class OtherT>
explicit PhantomNode(const OtherT &other, explicit PhantomNode(const OtherT &other,
ComponentID component,
EdgeWeight forward_weight, EdgeWeight forward_weight,
EdgeWeight reverse_weight, EdgeWeight reverse_weight,
EdgeWeight forward_weight_offset, EdgeWeight forward_weight_offset,
@@ -138,13 +141,17 @@ struct PhantomNode
const util::Coordinate location, const util::Coordinate location,
const util::Coordinate input_location) const util::Coordinate input_location)
: forward_segment_id{other.forward_segment_id}, : forward_segment_id{other.forward_segment_id},
reverse_segment_id{other.reverse_segment_id}, forward_weight{forward_weight}, reverse_segment_id{other.reverse_segment_id}, name_id{other.name_id},
reverse_weight{reverse_weight}, forward_weight_offset{forward_weight_offset}, forward_weight{forward_weight}, reverse_weight{reverse_weight},
forward_weight_offset{forward_weight_offset},
reverse_weight_offset{reverse_weight_offset}, forward_duration{forward_duration}, reverse_weight_offset{reverse_weight_offset}, forward_duration{forward_duration},
reverse_duration{reverse_duration}, forward_duration_offset{forward_duration_offset}, reverse_duration{reverse_duration}, forward_duration_offset{forward_duration_offset},
reverse_duration_offset{reverse_duration_offset}, reverse_duration_offset{reverse_duration_offset},
component{component.id, component.is_tiny}, location{location}, packed_geometry_id{other.packed_geometry_id},
component{other.component.id, other.component.is_tiny}, location{location},
input_location{input_location}, fwd_segment_position{other.fwd_segment_position}, input_location{input_location}, fwd_segment_position{other.fwd_segment_position},
forward_travel_mode{other.forward_travel_mode},
backward_travel_mode{other.backward_travel_mode},
is_valid_forward_source{is_valid_forward_source}, is_valid_forward_source{is_valid_forward_source},
is_valid_forward_target{is_valid_forward_target}, is_valid_forward_target{is_valid_forward_target},
is_valid_reverse_source{is_valid_reverse_source}, is_valid_reverse_source{is_valid_reverse_source},
@@ -154,6 +161,7 @@ struct PhantomNode
SegmentID forward_segment_id; SegmentID forward_segment_id;
SegmentID reverse_segment_id; SegmentID reverse_segment_id;
unsigned name_id;
EdgeWeight forward_weight; EdgeWeight forward_weight;
EdgeWeight reverse_weight; EdgeWeight reverse_weight;
EdgeWeight forward_weight_offset; // TODO: try to remove -> requires path unpacking changes EdgeWeight forward_weight_offset; // TODO: try to remove -> requires path unpacking changes
@@ -162,21 +170,30 @@ struct PhantomNode
EdgeWeight reverse_duration; EdgeWeight reverse_duration;
EdgeWeight forward_duration_offset; // TODO: try to remove -> requires path unpacking changes EdgeWeight forward_duration_offset; // TODO: try to remove -> requires path unpacking changes
EdgeWeight reverse_duration_offset; // TODO: try to remove -> requires path unpacking changes EdgeWeight reverse_duration_offset; // TODO: try to remove -> requires path unpacking changes
ComponentID component; unsigned packed_geometry_id;
struct ComponentType
{
std::uint32_t id : 31;
std::uint32_t is_tiny : 1;
} component;
static_assert(sizeof(ComponentType) == 4, "ComponentType needs to be 4 bytes big");
util::Coordinate location; util::Coordinate location;
util::Coordinate input_location; util::Coordinate input_location;
unsigned short fwd_segment_position; unsigned short fwd_segment_position;
// note 4 bits would suffice for each,
// but the saved byte would be padding anyway
extractor::TravelMode forward_travel_mode : 4;
extractor::TravelMode backward_travel_mode : 4;
// is phantom node valid to be used as source or target // is phantom node valid to be used as source or target
private: private:
unsigned short is_valid_forward_source : 1; bool is_valid_forward_source : 1;
unsigned short is_valid_forward_target : 1; bool is_valid_forward_target : 1;
unsigned short is_valid_reverse_source : 1; bool is_valid_reverse_source : 1;
unsigned short is_valid_reverse_target : 1; bool is_valid_reverse_target : 1;
unsigned short : 12; // Unused padding out to 16 bits (2 bytes)
}; };
static_assert(sizeof(PhantomNode) == 64, "PhantomNode has more padding then expected"); static_assert(sizeof(PhantomNode) == 72, "PhantomNode has more padding then expected");
using PhantomNodePair = std::pair<PhantomNode, PhantomNode>; using PhantomNodePair = std::pair<PhantomNode, PhantomNode>;
@@ -203,6 +220,7 @@ inline std::ostream &operator<<(std::ostream &out, const PhantomNode &pn)
{ {
out << "node1: " << pn.forward_segment_id.id << ", " out << "node1: " << pn.forward_segment_id.id << ", "
<< "node2: " << pn.reverse_segment_id.id << ", " << "node2: " << pn.reverse_segment_id.id << ", "
<< "name: " << pn.name_id << ", "
<< "fwd-w: " << pn.forward_weight << ", " << "fwd-w: " << pn.forward_weight << ", "
<< "rev-w: " << pn.reverse_weight << ", " << "rev-w: " << pn.reverse_weight << ", "
<< "fwd-o: " << pn.forward_weight_offset << ", " << "fwd-o: " << pn.forward_weight_offset << ", "
@@ -211,6 +229,7 @@ inline std::ostream &operator<<(std::ostream &out, const PhantomNode &pn)
<< "rev-d: " << pn.reverse_duration << ", " << "rev-d: " << pn.reverse_duration << ", "
<< "fwd-do: " << pn.forward_duration_offset << ", " << "fwd-do: " << pn.forward_duration_offset << ", "
<< "rev-do: " << pn.reverse_duration_offset << ", " << "rev-do: " << pn.reverse_duration_offset << ", "
<< "geom: " << pn.packed_geometry_id << ", "
<< "comp: " << pn.component.is_tiny << " / " << pn.component.id << ", " << "comp: " << pn.component.is_tiny << " / " << pn.component.id << ", "
<< "pos: " << pn.fwd_segment_position << ", " << "pos: " << pn.fwd_segment_position << ", "
<< "loc: " << pn.location; << "loc: " << pn.location;
+13 -37
View File
@@ -16,8 +16,6 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <util/log.hpp>
namespace osrm namespace osrm
{ {
namespace engine namespace engine
@@ -120,14 +118,9 @@ class BasePlugin
const bool use_hints = !parameters.hints.empty(); const bool use_hints = !parameters.hints.empty();
const bool use_bearings = !parameters.bearings.empty(); const bool use_bearings = !parameters.bearings.empty();
const bool use_approaches = !parameters.approaches.empty();
for (const auto i : util::irange<std::size_t>(0UL, parameters.coordinates.size())) for (const auto i : util::irange<std::size_t>(0UL, parameters.coordinates.size()))
{ {
Approach approach = engine::Approach::UNRESTRICTED;
if (use_approaches && parameters.approaches[i])
approach = parameters.approaches[i].get();
if (use_hints && parameters.hints[i] && if (use_hints && parameters.hints[i] &&
parameters.hints[i]->IsValid(parameters.coordinates[i], facade)) parameters.hints[i]->IsValid(parameters.coordinates[i], facade))
{ {
@@ -144,13 +137,12 @@ class BasePlugin
facade.NearestPhantomNodesInRange(parameters.coordinates[i], facade.NearestPhantomNodesInRange(parameters.coordinates[i],
radiuses[i], radiuses[i],
parameters.bearings[i]->bearing, parameters.bearings[i]->bearing,
parameters.bearings[i]->range, parameters.bearings[i]->range);
approach);
} }
else else
{ {
phantom_nodes[i] = facade.NearestPhantomNodesInRange( phantom_nodes[i] =
parameters.coordinates[i], radiuses[i], approach); facade.NearestPhantomNodesInRange(parameters.coordinates[i], radiuses[i]);
} }
} }
@@ -168,15 +160,10 @@ class BasePlugin
const bool use_hints = !parameters.hints.empty(); const bool use_hints = !parameters.hints.empty();
const bool use_bearings = !parameters.bearings.empty(); const bool use_bearings = !parameters.bearings.empty();
const bool use_radiuses = !parameters.radiuses.empty(); const bool use_radiuses = !parameters.radiuses.empty();
const bool use_approaches = !parameters.approaches.empty();
BOOST_ASSERT(parameters.IsValid()); BOOST_ASSERT(parameters.IsValid());
for (const auto i : util::irange<std::size_t>(0UL, parameters.coordinates.size())) for (const auto i : util::irange<std::size_t>(0UL, parameters.coordinates.size()))
{ {
Approach approach = engine::Approach::UNRESTRICTED;
if (use_approaches && parameters.approaches[i])
approach = parameters.approaches[i].get();
if (use_hints && parameters.hints[i] && if (use_hints && parameters.hints[i] &&
parameters.hints[i]->IsValid(parameters.coordinates[i], facade)) parameters.hints[i]->IsValid(parameters.coordinates[i], facade))
{ {
@@ -196,31 +183,27 @@ class BasePlugin
number_of_results, number_of_results,
*parameters.radiuses[i], *parameters.radiuses[i],
parameters.bearings[i]->bearing, parameters.bearings[i]->bearing,
parameters.bearings[i]->range, parameters.bearings[i]->range);
approach);
} }
else else
{ {
phantom_nodes[i] = facade.NearestPhantomNodes(parameters.coordinates[i], phantom_nodes[i] = facade.NearestPhantomNodes(parameters.coordinates[i],
number_of_results, number_of_results,
parameters.bearings[i]->bearing, parameters.bearings[i]->bearing,
parameters.bearings[i]->range, parameters.bearings[i]->range);
approach);
} }
} }
else else
{ {
if (use_radiuses && parameters.radiuses[i]) if (use_radiuses && parameters.radiuses[i])
{ {
phantom_nodes[i] = facade.NearestPhantomNodes(parameters.coordinates[i], phantom_nodes[i] = facade.NearestPhantomNodes(
number_of_results, parameters.coordinates[i], number_of_results, *parameters.radiuses[i]);
*parameters.radiuses[i],
approach);
} }
else else
{ {
phantom_nodes[i] = facade.NearestPhantomNodes( phantom_nodes[i] =
parameters.coordinates[i], number_of_results, approach); facade.NearestPhantomNodes(parameters.coordinates[i], number_of_results);
} }
} }
@@ -241,15 +224,10 @@ class BasePlugin
const bool use_hints = !parameters.hints.empty(); const bool use_hints = !parameters.hints.empty();
const bool use_bearings = !parameters.bearings.empty(); const bool use_bearings = !parameters.bearings.empty();
const bool use_radiuses = !parameters.radiuses.empty(); const bool use_radiuses = !parameters.radiuses.empty();
const bool use_approaches = !parameters.approaches.empty();
BOOST_ASSERT(parameters.IsValid()); BOOST_ASSERT(parameters.IsValid());
for (const auto i : util::irange<std::size_t>(0UL, parameters.coordinates.size())) for (const auto i : util::irange<std::size_t>(0UL, parameters.coordinates.size()))
{ {
Approach approach = engine::Approach::UNRESTRICTED;
if (use_approaches && parameters.approaches[i])
approach = parameters.approaches[i].get();
if (use_hints && parameters.hints[i] && if (use_hints && parameters.hints[i] &&
parameters.hints[i]->IsValid(parameters.coordinates[i], facade)) parameters.hints[i]->IsValid(parameters.coordinates[i], facade))
{ {
@@ -267,8 +245,7 @@ class BasePlugin
parameters.coordinates[i], parameters.coordinates[i],
*parameters.radiuses[i], *parameters.radiuses[i],
parameters.bearings[i]->bearing, parameters.bearings[i]->bearing,
parameters.bearings[i]->range, parameters.bearings[i]->range);
approach);
} }
else else
{ {
@@ -276,8 +253,7 @@ class BasePlugin
facade.NearestPhantomNodeWithAlternativeFromBigComponent( facade.NearestPhantomNodeWithAlternativeFromBigComponent(
parameters.coordinates[i], parameters.coordinates[i],
parameters.bearings[i]->bearing, parameters.bearings[i]->bearing,
parameters.bearings[i]->range, parameters.bearings[i]->range);
approach);
} }
} }
else else
@@ -286,13 +262,13 @@ class BasePlugin
{ {
phantom_node_pairs[i] = phantom_node_pairs[i] =
facade.NearestPhantomNodeWithAlternativeFromBigComponent( facade.NearestPhantomNodeWithAlternativeFromBigComponent(
parameters.coordinates[i], *parameters.radiuses[i], approach); parameters.coordinates[i], *parameters.radiuses[i]);
} }
else else
{ {
phantom_node_pairs[i] = phantom_node_pairs[i] =
facade.NearestPhantomNodeWithAlternativeFromBigComponent( facade.NearestPhantomNodeWithAlternativeFromBigComponent(
parameters.coordinates[i], approach); parameters.coordinates[i]);
} }
} }
+4 -26
View File
@@ -14,9 +14,10 @@ namespace engine
{ {
namespace detail namespace detail
{ {
constexpr double POLYLINE_DECODING_PRECISION = 1e5;
constexpr double POLYLINE_TO_COORDINATE = COORDINATE_PRECISION / POLYLINE_DECODING_PRECISION;
std::string encode(std::vector<int> &numbers); std::string encode(std::vector<int> &numbers);
std::int32_t decode_polyline_integer(std::string::const_iterator &first,
std::string::const_iterator last);
} }
using CoordVectorForwardIter = std::vector<util::Coordinate>::const_iterator; using CoordVectorForwardIter = std::vector<util::Coordinate>::const_iterator;
// Encodes geometry into polyline format. // Encodes geometry into polyline format.
@@ -56,30 +57,7 @@ std::string encodePolyline(CoordVectorForwardIter begin, CoordVectorForwardIter
// Decodes geometry from polyline format // Decodes geometry from polyline format
// See: https://developers.google.com/maps/documentation/utilities/polylinealgorithm // See: https://developers.google.com/maps/documentation/utilities/polylinealgorithm
std::vector<util::Coordinate> decodePolyline(const std::string &polyline);
template <unsigned POLYLINE_PRECISION = 100000>
std::vector<util::Coordinate> decodePolyline(const std::string &polyline)
{
double polyline_to_coordinate = COORDINATE_PRECISION / POLYLINE_PRECISION;
std::vector<util::Coordinate> coordinates;
std::int32_t latitude = 0, longitude = 0;
std::string::const_iterator first = polyline.begin();
const std::string::const_iterator last = polyline.end();
while (first != last)
{
const auto dlat = detail::decode_polyline_integer(first, last);
const auto dlon = detail::decode_polyline_integer(first, last);
latitude += dlat;
longitude += dlon;
coordinates.emplace_back(util::Coordinate{
util::FixedLongitude{static_cast<std::int32_t>(longitude * polyline_to_coordinate)},
util::FixedLatitude{static_cast<std::int32_t>(latitude * polyline_to_coordinate)}});
}
return coordinates;
}
} }
} }
+14 -5
View File
@@ -19,7 +19,7 @@ namespace engine
class RoutingAlgorithmsInterface class RoutingAlgorithmsInterface
{ {
public: public:
virtual InternalManyRoutesResult virtual InternalRouteResult
AlternativePathSearch(const PhantomNodes &phantom_node_pair) const = 0; AlternativePathSearch(const PhantomNodes &phantom_node_pair) const = 0;
virtual InternalRouteResult virtual InternalRouteResult
@@ -65,7 +65,7 @@ template <typename Algorithm> class RoutingAlgorithms final : public RoutingAlgo
virtual ~RoutingAlgorithms() = default; virtual ~RoutingAlgorithms() = default;
InternalManyRoutesResult InternalRouteResult
AlternativePathSearch(const PhantomNodes &phantom_node_pair) const final override; AlternativePathSearch(const PhantomNodes &phantom_node_pair) const final override;
InternalRouteResult ShortestPathSearch( InternalRouteResult ShortestPathSearch(
@@ -129,7 +129,7 @@ template <typename Algorithm> class RoutingAlgorithms final : public RoutingAlgo
}; };
template <typename Algorithm> template <typename Algorithm>
InternalManyRoutesResult InternalRouteResult
RoutingAlgorithms<Algorithm>::AlternativePathSearch(const PhantomNodes &phantom_node_pair) const RoutingAlgorithms<Algorithm>::AlternativePathSearch(const PhantomNodes &phantom_node_pair) const
{ {
return routing_algorithms::ch::alternativePathSearch(heaps, facade, phantom_node_pair); return routing_algorithms::ch::alternativePathSearch(heaps, facade, phantom_node_pair);
@@ -188,7 +188,7 @@ inline std::vector<routing_algorithms::TurnData> RoutingAlgorithms<Algorithm>::G
// CoreCH overrides // CoreCH overrides
template <> template <>
InternalManyRoutesResult inline RoutingAlgorithms< InternalRouteResult inline RoutingAlgorithms<
routing_algorithms::corech::Algorithm>::AlternativePathSearch(const PhantomNodes &) const routing_algorithms::corech::Algorithm>::AlternativePathSearch(const PhantomNodes &) const
{ {
throw util::exception("AlternativePathSearch is disabled due to performance reasons"); throw util::exception("AlternativePathSearch is disabled due to performance reasons");
@@ -206,7 +206,7 @@ RoutingAlgorithms<routing_algorithms::corech::Algorithm>::ManyToManySearch(
// MLD overrides for not implemented // MLD overrides for not implemented
template <> template <>
InternalManyRoutesResult inline RoutingAlgorithms< InternalRouteResult inline RoutingAlgorithms<
routing_algorithms::mld::Algorithm>::AlternativePathSearch(const PhantomNodes &) const routing_algorithms::mld::Algorithm>::AlternativePathSearch(const PhantomNodes &) const
{ {
throw util::exception("AlternativePathSearch is not implemented"); throw util::exception("AlternativePathSearch is not implemented");
@@ -221,6 +221,15 @@ RoutingAlgorithms<routing_algorithms::mld::Algorithm>::ManyToManySearch(
{ {
throw util::exception("ManyToManySearch is not implemented"); throw util::exception("ManyToManySearch is not implemented");
} }
template <>
inline std::vector<routing_algorithms::TurnData>
RoutingAlgorithms<routing_algorithms::mld::Algorithm>::GetTileTurns(
const std::vector<datafacade::BaseDataFacade::RTreeLeaf> &,
const std::vector<std::size_t> &) const
{
throw util::exception("GetTileTurns is not implemented");
}
} }
} }
@@ -17,7 +17,7 @@ namespace routing_algorithms
{ {
namespace ch namespace ch
{ {
InternalManyRoutesResult InternalRouteResult
alternativePathSearch(SearchEngineData<Algorithm> &search_engine_data, alternativePathSearch(SearchEngineData<Algorithm> &search_engine_data,
const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade, const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
const PhantomNodes &phantom_node_pair); const PhantomNodes &phantom_node_pair);
@@ -83,37 +83,37 @@ void insertNodesInHeaps(Heap &forward_heap, Heap &reverse_heap, const PhantomNod
template <typename FacadeT> template <typename FacadeT>
void annotatePath(const FacadeT &facade, void annotatePath(const FacadeT &facade,
const PhantomNodes &phantom_node_pair, const NodeID source_node,
const std::vector<NodeID> &unpacked_nodes, const NodeID target_node,
const std::vector<EdgeID> &unpacked_edges, const std::vector<EdgeID> &unpacked_edges,
const PhantomNodes &phantom_node_pair,
std::vector<PathData> &unpacked_path) std::vector<PathData> &unpacked_path)
{ {
BOOST_ASSERT(!unpacked_nodes.empty()); BOOST_ASSERT(source_node != SPECIAL_NODEID && target_node != SPECIAL_NODEID);
BOOST_ASSERT(unpacked_nodes.size() == unpacked_edges.size() + 1); BOOST_ASSERT(!unpacked_edges.empty() || source_node == target_node);
const auto source_node_id = unpacked_nodes.front();
const auto target_node_id = unpacked_nodes.back();
const bool start_traversed_in_reverse = const bool start_traversed_in_reverse =
phantom_node_pair.source_phantom.forward_segment_id.id != source_node_id; phantom_node_pair.source_phantom.forward_segment_id.id != source_node;
const bool target_traversed_in_reverse = const bool target_traversed_in_reverse =
phantom_node_pair.target_phantom.forward_segment_id.id != target_node_id; phantom_node_pair.target_phantom.forward_segment_id.id != target_node;
BOOST_ASSERT(phantom_node_pair.source_phantom.forward_segment_id.id == source_node_id || BOOST_ASSERT(phantom_node_pair.source_phantom.forward_segment_id.id == source_node ||
phantom_node_pair.source_phantom.reverse_segment_id.id == source_node_id); phantom_node_pair.source_phantom.reverse_segment_id.id == source_node);
BOOST_ASSERT(phantom_node_pair.target_phantom.forward_segment_id.id == target_node_id || BOOST_ASSERT(phantom_node_pair.target_phantom.forward_segment_id.id == target_node ||
phantom_node_pair.target_phantom.reverse_segment_id.id == target_node_id); phantom_node_pair.target_phantom.reverse_segment_id.id == target_node);
auto node_from = unpacked_nodes.begin(), node_last = std::prev(unpacked_nodes.end()); for (auto edge_id : unpacked_edges)
for (auto edge = unpacked_edges.begin(); node_from != node_last; ++node_from, ++edge)
{ {
const auto &edge_data = facade.GetEdgeData(*edge); const auto &edge_data = facade.GetEdgeData(edge_id);
const auto turn_id = edge_data.turn_id; // edge-based graph edge index const auto turn_id = edge_data.turn_id; // edge-based node ID
const auto node_id = *node_from; // edge-based graph node index const auto name_index = facade.GetNameIndexFromEdgeID(turn_id);
const auto name_index = facade.GetNameIndex(node_id);
const auto turn_instruction = facade.GetTurnInstructionForEdgeID(turn_id); const auto turn_instruction = facade.GetTurnInstructionForEdgeID(turn_id);
const extractor::TravelMode travel_mode = facade.GetTravelMode(node_id); const extractor::TravelMode travel_mode =
(unpacked_path.empty() && start_traversed_in_reverse)
? phantom_node_pair.source_phantom.backward_travel_mode
: facade.GetTravelModeForEdgeID(turn_id);
const auto geometry_index = facade.GetGeometryIndex(node_id); const auto geometry_index = facade.GetGeometryIndexForEdgeID(turn_id);
std::vector<NodeID> id_vector; std::vector<NodeID> id_vector;
std::vector<EdgeWeight> weight_vector; std::vector<EdgeWeight> weight_vector;
@@ -180,16 +180,23 @@ void annotatePath(const FacadeT &facade,
std::vector<EdgeWeight> weight_vector; std::vector<EdgeWeight> weight_vector;
std::vector<EdgeWeight> duration_vector; std::vector<EdgeWeight> duration_vector;
std::vector<DatasourceID> datasource_vector; std::vector<DatasourceID> datasource_vector;
const auto source_geometry_id = facade.GetGeometryIndex(source_node_id).id; const bool is_local_path = (phantom_node_pair.source_phantom.packed_geometry_id ==
const auto target_geometry_id = facade.GetGeometryIndex(target_node_id).id; phantom_node_pair.target_phantom.packed_geometry_id) &&
const auto is_local_path = source_geometry_id == target_geometry_id && unpacked_path.empty(); unpacked_path.empty();
if (target_traversed_in_reverse) if (target_traversed_in_reverse)
{ {
id_vector = facade.GetUncompressedReverseGeometry(target_geometry_id); id_vector = facade.GetUncompressedReverseGeometry(
weight_vector = facade.GetUncompressedReverseWeights(target_geometry_id); phantom_node_pair.target_phantom.packed_geometry_id);
duration_vector = facade.GetUncompressedReverseDurations(target_geometry_id);
datasource_vector = facade.GetUncompressedReverseDatasources(target_geometry_id); weight_vector = facade.GetUncompressedReverseWeights(
phantom_node_pair.target_phantom.packed_geometry_id);
duration_vector = facade.GetUncompressedReverseDurations(
phantom_node_pair.target_phantom.packed_geometry_id);
datasource_vector = facade.GetUncompressedReverseDatasources(
phantom_node_pair.target_phantom.packed_geometry_id);
if (is_local_path) if (is_local_path)
{ {
@@ -207,10 +214,17 @@ void annotatePath(const FacadeT &facade,
} }
end_index = phantom_node_pair.target_phantom.fwd_segment_position; end_index = phantom_node_pair.target_phantom.fwd_segment_position;
id_vector = facade.GetUncompressedForwardGeometry(target_geometry_id); id_vector = facade.GetUncompressedForwardGeometry(
weight_vector = facade.GetUncompressedForwardWeights(target_geometry_id); phantom_node_pair.target_phantom.packed_geometry_id);
duration_vector = facade.GetUncompressedForwardDurations(target_geometry_id);
datasource_vector = facade.GetUncompressedForwardDatasources(target_geometry_id); weight_vector = facade.GetUncompressedForwardWeights(
phantom_node_pair.target_phantom.packed_geometry_id);
duration_vector = facade.GetUncompressedForwardDurations(
phantom_node_pair.target_phantom.packed_geometry_id);
datasource_vector = facade.GetUncompressedForwardDatasources(
phantom_node_pair.target_phantom.packed_geometry_id);
} }
// Given the following compressed geometry: // Given the following compressed geometry:
@@ -224,19 +238,20 @@ void annotatePath(const FacadeT &facade,
(start_index < end_index ? ++segment_idx : --segment_idx)) (start_index < end_index ? ++segment_idx : --segment_idx))
{ {
BOOST_ASSERT(segment_idx < id_vector.size() - 1); BOOST_ASSERT(segment_idx < id_vector.size() - 1);
BOOST_ASSERT(facade.GetTravelMode(target_node_id) > 0); BOOST_ASSERT(phantom_node_pair.target_phantom.forward_travel_mode > 0);
unpacked_path.push_back( unpacked_path.push_back(PathData{
PathData{id_vector[start_index < end_index ? segment_idx + 1 : segment_idx - 1], id_vector[start_index < end_index ? segment_idx + 1 : segment_idx - 1],
facade.GetNameIndex(target_node_id), phantom_node_pair.target_phantom.name_id,
weight_vector[segment_idx], weight_vector[segment_idx],
duration_vector[segment_idx], duration_vector[segment_idx],
extractor::guidance::TurnInstruction::NO_TURN(), extractor::guidance::TurnInstruction::NO_TURN(),
{{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID}, {{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID},
facade.GetTravelMode(target_node_id), target_traversed_in_reverse ? phantom_node_pair.target_phantom.backward_travel_mode
INVALID_ENTRY_CLASSID, : phantom_node_pair.target_phantom.forward_travel_mode,
datasource_vector[segment_idx], INVALID_ENTRY_CLASSID,
util::guidance::TurnBearing(0), datasource_vector[segment_idx],
util::guidance::TurnBearing(0)}); util::guidance::TurnBearing(0),
util::guidance::TurnBearing(0)});
} }
if (unpacked_path.size() > 0) if (unpacked_path.size() > 0)
@@ -295,19 +310,17 @@ double getPathDistance(const datafacade::ContiguousInternalMemoryDataFacade<Algo
using util::coordinate_calculation::detail::EARTH_RADIUS; using util::coordinate_calculation::detail::EARTH_RADIUS;
double distance = 0; double distance = 0;
double prev_lat = double prev_lat = static_cast<double>(toFloating(source_phantom.location.lat)) * DEGREE_TO_RAD;
static_cast<double>(util::toFloating(source_phantom.location.lat)) * DEGREE_TO_RAD; double prev_lon = static_cast<double>(toFloating(source_phantom.location.lon)) * DEGREE_TO_RAD;
double prev_lon =
static_cast<double>(util::toFloating(source_phantom.location.lon)) * DEGREE_TO_RAD;
double prev_cos = std::cos(prev_lat); double prev_cos = std::cos(prev_lat);
for (const auto &p : unpacked_path) for (const auto &p : unpacked_path)
{ {
const auto current_coordinate = facade.GetCoordinateOfNode(p.turn_via_node); const auto current_coordinate = facade.GetCoordinateOfNode(p.turn_via_node);
const double current_lat = const double current_lat =
static_cast<double>(util::toFloating(current_coordinate.lat)) * DEGREE_TO_RAD; static_cast<double>(toFloating(current_coordinate.lat)) * DEGREE_TO_RAD;
const double current_lon = const double current_lon =
static_cast<double>(util::toFloating(current_coordinate.lon)) * DEGREE_TO_RAD; static_cast<double>(toFloating(current_coordinate.lon)) * DEGREE_TO_RAD;
const double current_cos = std::cos(current_lat); const double current_cos = std::cos(current_lat);
const double sin_dlon = std::sin((prev_lon - current_lon) / 2.0); const double sin_dlon = std::sin((prev_lon - current_lon) / 2.0);
@@ -323,9 +336,9 @@ double getPathDistance(const datafacade::ContiguousInternalMemoryDataFacade<Algo
} }
const double current_lat = const double current_lat =
static_cast<double>(util::toFloating(target_phantom.location.lat)) * DEGREE_TO_RAD; static_cast<double>(toFloating(target_phantom.location.lat)) * DEGREE_TO_RAD;
const double current_lon = const double current_lon =
static_cast<double>(util::toFloating(target_phantom.location.lon)) * DEGREE_TO_RAD; static_cast<double>(toFloating(target_phantom.location.lon)) * DEGREE_TO_RAD;
const double current_cos = std::cos(current_lat); const double current_cos = std::cos(current_lat);
const double sin_dlon = std::sin((prev_lon - current_lon) / 2.0); const double sin_dlon = std::sin((prev_lon - current_lon) / 2.0);
@@ -299,25 +299,22 @@ void unpackPath(const FacadeT &facade,
const auto nodes_number = std::distance(packed_path_begin, packed_path_end); const auto nodes_number = std::distance(packed_path_begin, packed_path_end);
BOOST_ASSERT(nodes_number > 0); BOOST_ASSERT(nodes_number > 0);
std::vector<NodeID> unpacked_nodes;
std::vector<EdgeID> unpacked_edges; std::vector<EdgeID> unpacked_edges;
unpacked_nodes.reserve(nodes_number);
unpacked_edges.reserve(nodes_number);
unpacked_nodes.push_back(*packed_path_begin); auto source_node = *packed_path_begin, target_node = *packed_path_begin;
if (nodes_number > 1) if (nodes_number > 1)
{ {
unpackPath(facade, target_node = *std::prev(packed_path_end);
packed_path_begin, unpacked_edges.reserve(std::distance(packed_path_begin, packed_path_end));
packed_path_end, unpackPath(
[&](std::pair<NodeID, NodeID> &edge, const auto &edge_id) { facade,
BOOST_ASSERT(edge.first == unpacked_nodes.back()); packed_path_begin,
unpacked_nodes.push_back(edge.second); packed_path_end,
unpacked_edges.push_back(edge_id); [&facade, &unpacked_edges](std::pair<NodeID, NodeID> & /* edge */,
}); const auto &edge_id) { unpacked_edges.push_back(edge_id); });
} }
annotatePath(facade, phantom_nodes, unpacked_nodes, unpacked_edges, unpacked_path); annotatePath(facade, source_node, target_node, unpacked_edges, phantom_nodes, unpacked_path);
} }
/** /**
@@ -180,7 +180,7 @@ void routingStep(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm>
} }
template <typename... Args> template <typename... Args>
std::tuple<EdgeWeight, std::vector<NodeID>, std::vector<EdgeID>> std::tuple<EdgeWeight, NodeID, NodeID, std::vector<EdgeID>>
search(SearchEngineData<Algorithm> &engine_working_data, search(SearchEngineData<Algorithm> &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade, const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
SearchEngineData<Algorithm>::QueryHeap &forward_heap, SearchEngineData<Algorithm>::QueryHeap &forward_heap,
@@ -192,7 +192,8 @@ search(SearchEngineData<Algorithm> &engine_working_data,
{ {
if (forward_heap.Empty() || reverse_heap.Empty()) if (forward_heap.Empty() || reverse_heap.Empty())
{ {
return std::make_tuple(INVALID_EDGE_WEIGHT, std::vector<NodeID>(), std::vector<EdgeID>()); return std::make_tuple(
INVALID_EDGE_WEIGHT, SPECIAL_NODEID, SPECIAL_NODEID, std::vector<EdgeID>());
} }
const auto &partition = facade.GetMultiLevelPartition(); const auto &partition = facade.GetMultiLevelPartition();
@@ -239,7 +240,8 @@ search(SearchEngineData<Algorithm> &engine_working_data,
// No path found for both target nodes? // No path found for both target nodes?
if (weight >= weight_upper_bound || SPECIAL_NODEID == middle) if (weight >= weight_upper_bound || SPECIAL_NODEID == middle)
{ {
return std::make_tuple(INVALID_EDGE_WEIGHT, std::vector<NodeID>(), std::vector<EdgeID>()); return std::make_tuple(
INVALID_EDGE_WEIGHT, SPECIAL_NODEID, SPECIAL_NODEID, std::vector<EdgeID>());
} }
// Get packed path as edges {from node ID, to node ID, edge ID} // Get packed path as edges {from node ID, to node ID, edge ID}
@@ -263,14 +265,11 @@ search(SearchEngineData<Algorithm> &engine_working_data,
current_node = parent_node; current_node = parent_node;
parent_node = reverse_heap.GetData(parent_node).parent; parent_node = reverse_heap.GetData(parent_node).parent;
} }
const NodeID target_node = current_node;
// Unpack path // Unpack path
std::vector<NodeID> unpacked_nodes; std::vector<EdgeID> unpacked_path;
std::vector<EdgeID> unpacked_edges; unpacked_path.reserve(packed_path.size());
unpacked_nodes.reserve(packed_path.size());
unpacked_edges.reserve(packed_path.size());
unpacked_nodes.push_back(source_node);
for (auto const &packed_edge : packed_path) for (auto const &packed_edge : packed_path)
{ {
NodeID source, target; NodeID source, target;
@@ -278,8 +277,7 @@ search(SearchEngineData<Algorithm> &engine_working_data,
std::tie(source, target, overlay_edge) = packed_edge; std::tie(source, target, overlay_edge) = packed_edge;
if (!overlay_edge) if (!overlay_edge)
{ // a base graph edge { // a base graph edge
unpacked_nodes.push_back(target); unpacked_path.push_back(facade.FindEdge(source, target));
unpacked_edges.push_back(facade.FindEdge(source, target));
} }
else else
{ // an overlay graph edge { // an overlay graph edge
@@ -298,54 +296,62 @@ search(SearchEngineData<Algorithm> &engine_working_data,
// TODO: when structured bindings will be allowed change to // TODO: when structured bindings will be allowed change to
// auto [subpath_weight, subpath_source, subpath_target, subpath] = ... // auto [subpath_weight, subpath_source, subpath_target, subpath] = ...
EdgeWeight subpath_weight; EdgeWeight subpath_weight;
std::vector<NodeID> subpath_nodes; NodeID subpath_source, subpath_target;
std::vector<EdgeID> subpath_edges; std::vector<EdgeID> subpath;
std::tie(subpath_weight, subpath_nodes, subpath_edges) = search(engine_working_data, std::tie(subpath_weight, subpath_source, subpath_target, subpath) =
facade, search(engine_working_data,
forward_heap, facade,
reverse_heap, forward_heap,
force_loop_forward, reverse_heap,
force_loop_reverse, force_loop_forward,
INVALID_EDGE_WEIGHT, force_loop_reverse,
sublevel, INVALID_EDGE_WEIGHT,
parent_cell_id); sublevel,
BOOST_ASSERT(!subpath_edges.empty()); parent_cell_id);
BOOST_ASSERT(subpath_nodes.size() > 1); BOOST_ASSERT(!subpath.empty());
BOOST_ASSERT(subpath_nodes.front() == source); BOOST_ASSERT(subpath_source == source);
BOOST_ASSERT(subpath_nodes.back() == target); BOOST_ASSERT(subpath_target == target);
unpacked_nodes.insert( unpacked_path.insert(unpacked_path.end(), subpath.begin(), subpath.end());
unpacked_nodes.end(), std::next(subpath_nodes.begin()), subpath_nodes.end());
unpacked_edges.insert(unpacked_edges.end(), subpath_edges.begin(), subpath_edges.end());
} }
} }
return std::make_tuple(weight, std::move(unpacked_nodes), std::move(unpacked_edges)); return std::make_tuple(weight, source_node, target_node, std::move(unpacked_path));
} }
// Alias to be compatible with the CH-based search // TODO reorder parameters
// Alias to be compatible with the overload for CoreCH that needs 4 heaps for shortest path search
inline void search(SearchEngineData<Algorithm> &engine_working_data, inline void search(SearchEngineData<Algorithm> &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade, const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
SearchEngineData<Algorithm>::QueryHeap &forward_heap, SearchEngineData<Algorithm>::QueryHeap &forward_heap,
SearchEngineData<Algorithm>::QueryHeap &reverse_heap, SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
EdgeWeight &weight, EdgeWeight &weight,
std::vector<NodeID> &unpacked_nodes, std::vector<NodeID> &packed_leg,
const bool force_loop_forward, const bool force_loop_forward,
const bool force_loop_reverse, const bool force_loop_reverse,
const PhantomNodes &phantom_nodes, const PhantomNodes &phantom_nodes,
const EdgeWeight weight_upper_bound = INVALID_EDGE_WEIGHT) const EdgeWeight weight_upper_bound = INVALID_EDGE_WEIGHT)
{ {
// TODO: change search calling interface to use unpacked_edges result NodeID source_node, target_node;
std::tie(weight, unpacked_nodes, std::ignore) = search(engine_working_data, std::vector<EdgeID> unpacked_edges;
facade, std::tie(weight, source_node, target_node, unpacked_edges) = mld::search(engine_working_data,
forward_heap, facade,
reverse_heap, forward_heap,
force_loop_forward, reverse_heap,
force_loop_reverse, force_loop_forward,
weight_upper_bound, force_loop_reverse,
phantom_nodes); weight_upper_bound,
phantom_nodes);
if (weight != INVALID_EDGE_WEIGHT)
{
packed_leg.push_back(source_node);
std::transform(unpacked_edges.begin(),
unpacked_edges.end(),
std::back_inserter(packed_leg),
[&facade](const auto edge) { return facade.GetTarget(edge); });
}
} }
// TODO: refactor CH-related stub to use unpacked_edges
template <typename RandomIter, typename FacadeT> template <typename RandomIter, typename FacadeT>
void unpackPath(const FacadeT &facade, void unpackPath(const FacadeT &facade,
RandomIter packed_path_begin, RandomIter packed_path_begin,
@@ -356,24 +362,21 @@ void unpackPath(const FacadeT &facade,
const auto nodes_number = std::distance(packed_path_begin, packed_path_end); const auto nodes_number = std::distance(packed_path_begin, packed_path_end);
BOOST_ASSERT(nodes_number > 0); BOOST_ASSERT(nodes_number > 0);
std::vector<NodeID> unpacked_nodes;
std::vector<EdgeID> unpacked_edges; std::vector<EdgeID> unpacked_edges;
unpacked_nodes.reserve(nodes_number);
unpacked_edges.reserve(nodes_number);
unpacked_nodes.push_back(*packed_path_begin); auto source_node = *packed_path_begin, target_node = *packed_path_begin;
if (nodes_number > 1) if (nodes_number > 1)
{ {
util::for_each_pair( target_node = *std::prev(packed_path_end);
packed_path_begin, util::for_each_pair(packed_path_begin,
packed_path_end, packed_path_end,
[&facade, &unpacked_nodes, &unpacked_edges](const auto from, const auto to) { [&facade, &unpacked_edges](const auto from, const auto to) {
unpacked_nodes.push_back(to); unpacked_edges.push_back(facade.FindEdge(from, to));
unpacked_edges.push_back(facade.FindEdge(from, to)); });
});
} }
annotatePath(facade, phantom_nodes, unpacked_nodes, unpacked_edges, unpacked_path); annotatePath(facade, source_node, target_node, unpacked_edges, phantom_nodes, unpacked_path);
} }
inline double inline double
@@ -392,16 +395,16 @@ getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
insertNodesInHeaps(forward_heap, reverse_heap, phantom_nodes); insertNodesInHeaps(forward_heap, reverse_heap, phantom_nodes);
EdgeWeight weight = INVALID_EDGE_WEIGHT; EdgeWeight weight = INVALID_EDGE_WEIGHT;
std::vector<NodeID> unpacked_nodes; NodeID source_node, target_node;
std::vector<EdgeID> unpacked_edges; std::vector<EdgeID> unpacked_edges;
std::tie(weight, unpacked_nodes, unpacked_edges) = search(engine_working_data, std::tie(weight, source_node, target_node, unpacked_edges) = search(engine_working_data,
facade, facade,
forward_heap, forward_heap,
reverse_heap, reverse_heap,
DO_NOT_FORCE_LOOPS, DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS, DO_NOT_FORCE_LOOPS,
weight_upper_bound, weight_upper_bound,
phantom_nodes); phantom_nodes);
if (weight == INVALID_EDGE_WEIGHT) if (weight == INVALID_EDGE_WEIGHT)
{ {
@@ -409,8 +412,7 @@ getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
} }
std::vector<PathData> unpacked_path; std::vector<PathData> unpacked_path;
annotatePath(facade, source_node, target_node, unpacked_edges, phantom_nodes, unpacked_path);
annotatePath(facade, phantom_nodes, unpacked_nodes, unpacked_edges, unpacked_path);
return getPathDistance(facade, unpacked_path, source_phantom, target_phantom); return getPathDistance(facade, unpacked_path, source_phantom, target_phantom);
} }
@@ -33,11 +33,6 @@ getTileTurns(const datafacade::ContiguousInternalMemoryDataFacade<ch::Algorithm>
const std::vector<RTreeLeaf> &edges, const std::vector<RTreeLeaf> &edges,
const std::vector<std::size_t> &sorted_edge_indexes); const std::vector<std::size_t> &sorted_edge_indexes);
std::vector<TurnData>
getTileTurns(const datafacade::ContiguousInternalMemoryDataFacade<mld::Algorithm> &facade,
const std::vector<RTreeLeaf> &edges,
const std::vector<std::size_t> &sorted_edge_indexes);
} // namespace routing_algorithms } // namespace routing_algorithms
} // namespace engine } // namespace engine
} // namespace osrm } // namespace osrm
+14 -13
View File
@@ -4,7 +4,7 @@
#include <boost/thread/tss.hpp> #include <boost/thread/tss.hpp>
#include "engine/algorithm.hpp" #include "engine/algorithm.hpp"
#include "util/query_heap.hpp" #include "util/binary_heap.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
namespace osrm namespace osrm
@@ -14,7 +14,8 @@ namespace engine
// Algorithm-dependent heaps // Algorithm-dependent heaps
// - CH algorithms use CH heaps // - CH algorithms use CH heaps
// - CoreCH algorithms use CH // - CoreCH algorithms use CoreCH heaps that can be upcasted to CH heaps when CH algorithms reused
// by CoreCH at calling ch::routingStep, ch::retrievePackedPathFromSingleHeap and ch::unpackPath
// - MLD algorithms use MLD heaps // - MLD algorithms use MLD heaps
template <typename Algorithm> struct SearchEngineData template <typename Algorithm> struct SearchEngineData
@@ -36,14 +37,14 @@ struct ManyToManyHeapData : HeapData
template <> struct SearchEngineData<routing_algorithms::ch::Algorithm> template <> struct SearchEngineData<routing_algorithms::ch::Algorithm>
{ {
using QueryHeap = util:: using QueryHeap = util::
QueryHeap<NodeID, NodeID, EdgeWeight, HeapData, util::UnorderedMapStorage<NodeID, int>>; BinaryHeap<NodeID, NodeID, EdgeWeight, HeapData, util::UnorderedMapStorage<NodeID, int>>;
using SearchEngineHeapPtr = boost::thread_specific_ptr<QueryHeap>; using SearchEngineHeapPtr = boost::thread_specific_ptr<QueryHeap>;
using ManyToManyQueryHeap = util::QueryHeap<NodeID, using ManyToManyQueryHeap = util::BinaryHeap<NodeID,
NodeID, NodeID,
EdgeWeight, EdgeWeight,
ManyToManyHeapData, ManyToManyHeapData,
util::UnorderedMapStorage<NodeID, int>>; util::UnorderedMapStorage<NodeID, int>>;
using ManyToManyHeapPtr = boost::thread_specific_ptr<ManyToManyQueryHeap>; using ManyToManyHeapPtr = boost::thread_specific_ptr<ManyToManyQueryHeap>;
@@ -80,11 +81,11 @@ struct MultiLayerDijkstraHeapData
template <> struct SearchEngineData<routing_algorithms::mld::Algorithm> template <> struct SearchEngineData<routing_algorithms::mld::Algorithm>
{ {
using QueryHeap = util::QueryHeap<NodeID, using QueryHeap = util::BinaryHeap<NodeID,
NodeID, NodeID,
EdgeWeight, EdgeWeight,
MultiLayerDijkstraHeapData, MultiLayerDijkstraHeapData,
util::UnorderedMapStorage<NodeID, int>>; util::UnorderedMapStorage<NodeID, int>>;
using SearchEngineHeapPtr = boost::thread_specific_ptr<QueryHeap>; using SearchEngineHeapPtr = boost::thread_specific_ptr<QueryHeap>;
@@ -21,9 +21,9 @@ class CompressedEdgeContainer
struct OnewayCompressedEdge struct OnewayCompressedEdge
{ {
public: public:
NodeID node_id; // refers to an internal node-based-node NodeID node_id; // refers to an internal node-based-node
SegmentWeight weight; // the weight of the edge leading to this node EdgeWeight weight; // the weight of the edge leading to this node
SegmentDuration duration; // the duration of the edge leading to this node EdgeWeight duration; // the duration of the edge leading to this node
}; };
using OnewayEdgeBucket = std::vector<OnewayCompressedEdge>; using OnewayEdgeBucket = std::vector<OnewayCompressedEdge>;
@@ -35,13 +35,13 @@ class CompressedEdgeContainer
const NodeID target_node, const NodeID target_node,
const EdgeWeight weight1, const EdgeWeight weight1,
const EdgeWeight weight2, const EdgeWeight weight2,
const EdgeDuration duration1, const EdgeWeight duration1,
const EdgeDuration duration2); const EdgeWeight duration2);
void AddUncompressedEdge(const EdgeID edge_id, void AddUncompressedEdge(const EdgeID edge_id,
const NodeID target_node, const NodeID target_node,
const SegmentWeight weight, const EdgeWeight weight,
const SegmentWeight duration); const EdgeWeight duration);
void InitializeBothwayVector(); void InitializeBothwayVector();
unsigned ZipEdges(const unsigned f_edge_pos, const unsigned r_edge_pos); unsigned ZipEdges(const unsigned f_edge_pos, const unsigned r_edge_pos);
@@ -63,12 +63,7 @@ class CompressedEdgeContainer
std::unique_ptr<SegmentDataContainer> ToSegmentData(); std::unique_ptr<SegmentDataContainer> ToSegmentData();
private: private:
SegmentWeight ClipWeight(const SegmentWeight weight);
SegmentDuration ClipDuration(const SegmentDuration duration);
int free_list_maximum = 0; int free_list_maximum = 0;
std::atomic_size_t clipped_weights{0};
std::atomic_size_t clipped_durations{0};
void IncreaseFreeList(); void IncreaseFreeList();
std::vector<OnewayEdgeBucket> m_compressed_oneway_geometries; std::vector<OnewayEdgeBucket> m_compressed_oneway_geometries;
+18 -25
View File
@@ -13,6 +13,23 @@ namespace extractor
struct EdgeBasedEdge struct EdgeBasedEdge
{ {
public: public:
EdgeBasedEdge();
template <class EdgeT> explicit EdgeBasedEdge(const EdgeT &other);
EdgeBasedEdge(const NodeID source,
const NodeID target,
const NodeID edge_id,
const EdgeWeight weight,
const EdgeWeight duration,
const bool forward,
const bool backward);
bool operator<(const EdgeBasedEdge &other) const;
NodeID source;
NodeID target;
struct EdgeData struct EdgeData
{ {
EdgeData() : turn_id(0), weight(0), duration(0), forward(false), backward(false) {} EdgeData() : turn_id(0), weight(0), duration(0), forward(false), backward(false) {}
@@ -34,24 +51,7 @@ struct EdgeBasedEdge
std::uint32_t backward : 1; std::uint32_t backward : 1;
auto is_unidirectional() const { return !forward || !backward; } auto is_unidirectional() const { return !forward || !backward; }
}; } data;
EdgeBasedEdge();
template <class EdgeT> explicit EdgeBasedEdge(const EdgeT &other);
EdgeBasedEdge(const NodeID source,
const NodeID target,
const NodeID edge_id,
const EdgeWeight weight,
const EdgeWeight duration,
const bool forward,
const bool backward);
EdgeBasedEdge(const NodeID source, const NodeID target, const EdgeBasedEdge::EdgeData &data);
bool operator<(const EdgeBasedEdge &other) const;
NodeID source;
NodeID target;
EdgeData data;
}; };
static_assert(sizeof(extractor::EdgeBasedEdge) == 20, static_assert(sizeof(extractor::EdgeBasedEdge) == 20,
"Size of extractor::EdgeBasedEdge type is " "Size of extractor::EdgeBasedEdge type is "
@@ -73,13 +73,6 @@ inline EdgeBasedEdge::EdgeBasedEdge(const NodeID source,
{ {
} }
inline EdgeBasedEdge::EdgeBasedEdge(const NodeID source,
const NodeID target,
const EdgeBasedEdge::EdgeData &data)
: source(source), target(target), data{data}
{
}
inline bool EdgeBasedEdge::operator<(const EdgeBasedEdge &other) const inline bool EdgeBasedEdge::operator<(const EdgeBasedEdge &other) const
{ {
const auto unidirectional = data.is_unidirectional(); const auto unidirectional = data.is_unidirectional();
+12 -20
View File
@@ -5,20 +5,17 @@
#include "extractor/compressed_edge_container.hpp" #include "extractor/compressed_edge_container.hpp"
#include "extractor/edge_based_edge.hpp" #include "extractor/edge_based_edge.hpp"
#include "extractor/edge_based_node_segment.hpp" #include "extractor/edge_based_node.hpp"
#include "extractor/extraction_turn.hpp" #include "extractor/extraction_turn.hpp"
#include "extractor/guidance/turn_analysis.hpp" #include "extractor/guidance/turn_analysis.hpp"
#include "extractor/guidance/turn_instruction.hpp" #include "extractor/guidance/turn_instruction.hpp"
#include "extractor/guidance/turn_lane_types.hpp" #include "extractor/guidance/turn_lane_types.hpp"
#include "extractor/nbg_to_ebg.hpp" #include "extractor/nbg_to_ebg.hpp"
#include "extractor/node_data_container.hpp"
#include "extractor/original_edge_data.hpp" #include "extractor/original_edge_data.hpp"
#include "extractor/packed_osm_ids.hpp"
#include "extractor/profile_properties.hpp" #include "extractor/profile_properties.hpp"
#include "extractor/query_node.hpp" #include "extractor/query_node.hpp"
#include "extractor/restriction_map.hpp" #include "extractor/restriction_map.hpp"
#include "util/concurrent_id_map.hpp"
#include "util/deallocating_vector.hpp" #include "util/deallocating_vector.hpp"
#include "util/guidance/bearing_class.hpp" #include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp" #include "util/guidance/entry_class.hpp"
@@ -42,9 +39,6 @@
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
#include <tbb/concurrent_unordered_map.h>
#include <tbb/concurrent_vector.h>
namespace osrm namespace osrm
{ {
namespace extractor namespace extractor
@@ -57,13 +51,13 @@ namespace lookup
#pragma pack(push, 1) #pragma pack(push, 1)
struct TurnIndexBlock struct TurnIndexBlock
{ {
NodeID from_id; OSMNodeID from_id;
NodeID via_id; OSMNodeID via_id;
NodeID to_id; OSMNodeID to_id;
}; };
#pragma pack(pop) #pragma pack(pop)
static_assert(std::is_trivial<TurnIndexBlock>::value, "TurnIndexBlock is not trivial"); static_assert(std::is_trivial<TurnIndexBlock>::value, "TurnIndexBlock is not trivial");
static_assert(sizeof(TurnIndexBlock) == 12, "TurnIndexBlock is not packed correctly"); static_assert(sizeof(TurnIndexBlock) == 24, "TurnIndexBlock is not packed correctly");
} // ns lookup } // ns lookup
struct NodeBasedGraphToEdgeBasedGraphMappingWriter; // fwd. decl struct NodeBasedGraphToEdgeBasedGraphMappingWriter; // fwd. decl
@@ -80,7 +74,7 @@ class EdgeBasedGraphFactory
const std::unordered_set<NodeID> &traffic_lights, const std::unordered_set<NodeID> &traffic_lights,
std::shared_ptr<const RestrictionMap> restriction_map, std::shared_ptr<const RestrictionMap> restriction_map,
const std::vector<util::Coordinate> &coordinates, const std::vector<util::Coordinate> &coordinates,
const extractor::PackedOSMIDs &osm_node_ids, const util::PackedVector<OSMNodeID> &osm_node_ids,
ProfileProperties profile_properties, ProfileProperties profile_properties,
const util::NameTable &name_table, const util::NameTable &name_table,
std::vector<std::uint32_t> &turn_lane_offsets, std::vector<std::uint32_t> &turn_lane_offsets,
@@ -88,7 +82,7 @@ class EdgeBasedGraphFactory
guidance::LaneDescriptionMap &lane_description_map); guidance::LaneDescriptionMap &lane_description_map);
void Run(ScriptingEnvironment &scripting_environment, void Run(ScriptingEnvironment &scripting_environment,
const std::string &turn_data_filename, const std::string &original_edge_data_filename,
const std::string &turn_lane_data_filename, const std::string &turn_lane_data_filename,
const std::string &turn_weight_penalties_filename, const std::string &turn_weight_penalties_filename,
const std::string &turn_duration_penalties_filename, const std::string &turn_duration_penalties_filename,
@@ -97,8 +91,7 @@ class EdgeBasedGraphFactory
// The following get access functions destroy the content in the factory // The following get access functions destroy the content in the factory
void GetEdgeBasedEdges(util::DeallocatingVector<EdgeBasedEdge> &edges); void GetEdgeBasedEdges(util::DeallocatingVector<EdgeBasedEdge> &edges);
void GetEdgeBasedNodes(EdgeBasedNodeDataContainer &data_container); void GetEdgeBasedNodes(std::vector<EdgeBasedNode> &nodes);
void GetEdgeBasedNodeSegments(std::vector<EdgeBasedNodeSegment> &nodes);
void GetStartPointMarkers(std::vector<bool> &node_is_startpoint); void GetStartPointMarkers(std::vector<bool> &node_is_startpoint);
void GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &output_node_weights); void GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &output_node_weights);
@@ -133,13 +126,12 @@ class EdgeBasedGraphFactory
std::vector<EdgeWeight> m_edge_based_node_weights; std::vector<EdgeWeight> m_edge_based_node_weights;
//! list of edge based nodes (compressed segments) //! list of edge based nodes (compressed segments)
std::vector<EdgeBasedNodeSegment> m_edge_based_node_segments; std::vector<EdgeBasedNode> m_edge_based_node_list;
EdgeBasedNodeDataContainer m_edge_based_node_container;
util::DeallocatingVector<EdgeBasedEdge> m_edge_based_edge_list; util::DeallocatingVector<EdgeBasedEdge> m_edge_based_edge_list;
EdgeID m_max_edge_id; EdgeID m_max_edge_id;
const std::vector<util::Coordinate> &m_coordinates; const std::vector<util::Coordinate> &m_coordinates;
const extractor::PackedOSMIDs &m_osm_node_ids; const util::PackedVector<OSMNodeID> &m_osm_node_ids;
std::shared_ptr<util::NodeBasedDynamicGraph> m_node_based_graph; std::shared_ptr<util::NodeBasedDynamicGraph> m_node_based_graph;
std::shared_ptr<RestrictionMap const> m_restriction_map; std::shared_ptr<RestrictionMap const> m_restriction_map;
@@ -171,9 +163,9 @@ class EdgeBasedGraphFactory
std::size_t skipped_uturns_counter; std::size_t skipped_uturns_counter;
std::size_t skipped_barrier_turns_counter; std::size_t skipped_barrier_turns_counter;
util::ConcurrentIDMap<util::guidance::BearingClass, BearingClassID> bearing_class_hash; std::unordered_map<util::guidance::BearingClass, BearingClassID> bearing_class_hash;
std::vector<BearingClassID> bearing_class_by_node_based_node; std::vector<BearingClassID> bearing_class_by_node_based_node;
util::ConcurrentIDMap<util::guidance::EntryClass, EntryClassID> entry_class_hash; std::unordered_map<util::guidance::EntryClass, EntryClassID> entry_class_hash;
}; };
} // namespace extractor } // namespace extractor
} // namespace osrm } // namespace osrm
+70
View File
@@ -0,0 +1,70 @@
#ifndef EDGE_BASED_NODE_HPP
#define EDGE_BASED_NODE_HPP
#include "extractor/travel_mode.hpp"
#include "util/typedefs.hpp"
#include <boost/assert.hpp>
#include "osrm/coordinate.hpp"
#include <limits>
namespace osrm
{
namespace extractor
{
/// This is what util::StaticRTree serialized and stores on disk
/// It is generated in EdgeBasedGraphFactory.
struct EdgeBasedNode
{
EdgeBasedNode()
: forward_segment_id{SPECIAL_SEGMENTID, false},
reverse_segment_id{SPECIAL_SEGMENTID, false}, u(SPECIAL_NODEID), v(SPECIAL_NODEID),
name_id(0), packed_geometry_id(SPECIAL_GEOMETRYID), component{INVALID_COMPONENTID, false},
fwd_segment_position(std::numeric_limits<unsigned short>::max()),
forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
{
}
explicit EdgeBasedNode(const SegmentID forward_segment_id_,
const SegmentID reverse_segment_id_,
NodeID u,
NodeID v,
unsigned name_id,
unsigned packed_geometry_id_,
bool is_tiny_component,
unsigned component_id,
unsigned short fwd_segment_position,
TravelMode forward_travel_mode,
TravelMode backward_travel_mode)
: forward_segment_id(forward_segment_id_), reverse_segment_id(reverse_segment_id_), u(u),
v(v), name_id(name_id), packed_geometry_id(packed_geometry_id_),
component{component_id, is_tiny_component}, fwd_segment_position(fwd_segment_position),
forward_travel_mode(forward_travel_mode), backward_travel_mode(backward_travel_mode)
{
BOOST_ASSERT(forward_segment_id.enabled || reverse_segment_id.enabled);
}
SegmentID forward_segment_id; // needed for edge-expanded graph
SegmentID reverse_segment_id; // needed for edge-expanded graph
NodeID u; // indices into the coordinates array
NodeID v; // indices into the coordinates array
unsigned name_id; // id of the edge name
unsigned packed_geometry_id;
struct
{
unsigned id : 31;
bool is_tiny : 1;
} component;
unsigned short fwd_segment_position; // segment id in a compressed geometry
TravelMode forward_travel_mode : 4;
TravelMode backward_travel_mode : 4;
};
}
}
#endif // EDGE_BASED_NODE_HPP
@@ -1,49 +0,0 @@
#ifndef OSRM_EXTRACT_EDGE_BASED_NODE_SEGMENT_HPP
#define OSRM_EXTRACT_EDGE_BASED_NODE_SEGMENT_HPP
#include "extractor/travel_mode.hpp"
#include "util/typedefs.hpp"
#include <boost/assert.hpp>
#include "osrm/coordinate.hpp"
#include <limits>
namespace osrm
{
namespace extractor
{
/// This is what util::StaticRTree serialized and stores on disk
/// It is generated in EdgeBasedGraphFactory.
struct EdgeBasedNodeSegment
{
EdgeBasedNodeSegment()
: forward_segment_id{SPECIAL_SEGMENTID, false},
reverse_segment_id{SPECIAL_SEGMENTID, false}, u(SPECIAL_NODEID), v(SPECIAL_NODEID),
fwd_segment_position(std::numeric_limits<unsigned short>::max())
{
}
explicit EdgeBasedNodeSegment(const SegmentID forward_segment_id_,
const SegmentID reverse_segment_id_,
NodeID u,
NodeID v,
unsigned short fwd_segment_position)
: forward_segment_id(forward_segment_id_), reverse_segment_id(reverse_segment_id_), u(u),
v(v), fwd_segment_position(fwd_segment_position)
{
BOOST_ASSERT(forward_segment_id.enabled || reverse_segment_id.enabled);
}
SegmentID forward_segment_id; // edge-based graph node ID in forward direction (u->v)
SegmentID reverse_segment_id; // edge-based graph node ID in reverse direction (v->u if exists)
NodeID u; // node-based graph node ID of the start node
NodeID v; // node-based graph node ID of the target node
unsigned short fwd_segment_position; // segment id in a compressed geometry
};
}
}
#endif // OSRM_EXTRACT_EDGE_BASED_NODE_SEGMENT_HPP
+3 -4
View File
@@ -40,7 +40,7 @@ class ExtractionContainers
void PrepareEdges(ScriptingEnvironment &scripting_environment); void PrepareEdges(ScriptingEnvironment &scripting_environment);
void WriteNodes(storage::io::FileWriter &file_out) const; void WriteNodes(storage::io::FileWriter &file_out) const;
void WriteRestrictions(const std::string &restrictions_file_name); void WriteRestrictions(const std::string &restrictions_file_name) const;
void WriteEdges(storage::io::FileWriter &file_out) const; void WriteEdges(storage::io::FileWriter &file_out) const;
void WriteCharData(const std::string &file_name); void WriteCharData(const std::string &file_name);
@@ -48,7 +48,7 @@ class ExtractionContainers
using STXXLNodeIDVector = stxxl::vector<OSMNodeID>; using STXXLNodeIDVector = stxxl::vector<OSMNodeID>;
using STXXLNodeVector = stxxl::vector<ExternalMemoryNode>; using STXXLNodeVector = stxxl::vector<ExternalMemoryNode>;
using STXXLEdgeVector = stxxl::vector<InternalExtractorEdge>; using STXXLEdgeVector = stxxl::vector<InternalExtractorEdge>;
using RestrictionsVector = std::vector<InputRestrictionContainer>; using STXXLRestrictionsVector = stxxl::vector<InputRestrictionContainer>;
using STXXLWayIDStartEndVector = stxxl::vector<FirstAndLastSegmentOfWay>; using STXXLWayIDStartEndVector = stxxl::vector<FirstAndLastSegmentOfWay>;
using STXXLNameCharData = stxxl::vector<unsigned char>; using STXXLNameCharData = stxxl::vector<unsigned char>;
using STXXLNameOffsets = stxxl::vector<unsigned>; using STXXLNameOffsets = stxxl::vector<unsigned>;
@@ -59,11 +59,10 @@ class ExtractionContainers
STXXLNameCharData name_char_data; STXXLNameCharData name_char_data;
STXXLNameOffsets name_offsets; STXXLNameOffsets name_offsets;
// an adjacency array containing all turn lane masks // an adjacency array containing all turn lane masks
RestrictionsVector restrictions_list; STXXLRestrictionsVector restrictions_list;
STXXLWayIDStartEndVector way_start_end_id_list; STXXLWayIDStartEndVector way_start_end_id_list;
std::unordered_map<OSMNodeID, NodeID> external_to_internal_node_id_map; std::unordered_map<OSMNodeID, NodeID> external_to_internal_node_id_map;
unsigned max_internal_node_id; unsigned max_internal_node_id;
std::vector<TurnRestriction> unconditional_turn_restrictions;
ExtractionContainers(); ExtractionContainers();
+11 -13
View File
@@ -56,27 +56,21 @@ class Extractor
private: private:
ExtractorConfig config; ExtractorConfig config;
std::vector<TurnRestriction> ParseOSMData(ScriptingEnvironment &scripting_environment,
const unsigned number_of_threads);
std::pair<std::size_t, EdgeID> std::pair<std::size_t, EdgeID>
BuildEdgeExpandedGraph(ScriptingEnvironment &scripting_environment, BuildEdgeExpandedGraph(ScriptingEnvironment &scripting_environment,
std::vector<util::Coordinate> &coordinates, std::vector<util::Coordinate> &coordinates,
extractor::PackedOSMIDs &osm_node_ids, util::PackedVector<OSMNodeID> &osm_node_ids,
EdgeBasedNodeDataContainer &edge_based_nodes_container, std::vector<EdgeBasedNode> &node_based_edge_list,
std::vector<EdgeBasedNodeSegment> &edge_based_node_segments,
std::vector<bool> &node_is_startpoint, std::vector<bool> &node_is_startpoint,
std::vector<EdgeWeight> &edge_based_node_weights, std::vector<EdgeWeight> &edge_based_node_weights,
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list, util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
const std::string &intersection_class_output_file, const std::string &intersection_class_output_file);
std::vector<TurnRestriction> &turn_restrictions);
void WriteProfileProperties(const std::string &output_path, void WriteProfileProperties(const std::string &output_path,
const ProfileProperties &properties) const; const ProfileProperties &properties) const;
void FindComponents(unsigned max_edge_id, void FindComponents(unsigned max_edge_id,
const util::DeallocatingVector<EdgeBasedEdge> &input_edge_list, const util::DeallocatingVector<EdgeBasedEdge> &edges,
const std::vector<EdgeBasedNodeSegment> &input_node_segments, std::vector<EdgeBasedNode> &nodes) const;
EdgeBasedNodeDataContainer &nodes_container) const; void BuildRTree(std::vector<EdgeBasedNode> node_based_edge_list,
void BuildRTree(std::vector<EdgeBasedNodeSegment> edge_based_node_segments,
std::vector<bool> node_is_startpoint, std::vector<bool> node_is_startpoint,
const std::vector<util::Coordinate> &coordinates); const std::vector<util::Coordinate> &coordinates);
std::shared_ptr<RestrictionMap> LoadRestrictionMap(); std::shared_ptr<RestrictionMap> LoadRestrictionMap();
@@ -84,7 +78,11 @@ class Extractor
LoadNodeBasedGraph(std::unordered_set<NodeID> &barrier_nodes, LoadNodeBasedGraph(std::unordered_set<NodeID> &barrier_nodes,
std::unordered_set<NodeID> &traffic_lights, std::unordered_set<NodeID> &traffic_lights,
std::vector<util::Coordinate> &coordinates, std::vector<util::Coordinate> &coordinates,
extractor::PackedOSMIDs &osm_node_ids); util::PackedVector<OSMNodeID> &osm_node_ids);
void WriteEdgeBasedGraph(const std::string &output_file_filename,
const EdgeID max_edge_id,
util::DeallocatingVector<EdgeBasedEdge> const &edge_based_edge_list);
void WriteIntersectionClassificationData( void WriteIntersectionClassificationData(
const std::string &output_file_name, const std::string &output_file_name,
+2 -5
View File
@@ -65,8 +65,7 @@ struct ExtractorConfig
turn_lane_data_file_name = basepath + ".osrm.tld"; turn_lane_data_file_name = basepath + ".osrm.tld";
timestamp_file_name = basepath + ".osrm.timestamp"; timestamp_file_name = basepath + ".osrm.timestamp";
geometry_output_path = basepath + ".osrm.geometry"; geometry_output_path = basepath + ".osrm.geometry";
node_based_nodes_data_path = basepath + ".osrm.nbg_nodes"; node_output_path = basepath + ".osrm.nodes";
edge_based_nodes_data_path = basepath + ".osrm.ebg_nodes";
edge_output_path = basepath + ".osrm.edges"; edge_output_path = basepath + ".osrm.edges";
edge_graph_output_path = basepath + ".osrm.ebg"; edge_graph_output_path = basepath + ".osrm.ebg";
rtree_nodes_output_path = basepath + ".osrm.ramIndex"; rtree_nodes_output_path = basepath + ".osrm.ramIndex";
@@ -93,9 +92,8 @@ struct ExtractorConfig
std::string geometry_output_path; std::string geometry_output_path;
std::string edge_output_path; std::string edge_output_path;
std::string edge_graph_output_path; std::string edge_graph_output_path;
std::string node_based_nodes_data_path;
std::string edge_based_nodes_data_path;
std::string edge_based_node_weights_output_path; std::string edge_based_node_weights_output_path;
std::string node_output_path;
std::string rtree_nodes_output_path; std::string rtree_nodes_output_path;
std::string rtree_leafs_output_path; std::string rtree_leafs_output_path;
std::string profile_properties_output_path; std::string profile_properties_output_path;
@@ -112,7 +110,6 @@ struct ExtractorConfig
std::string turn_penalties_index_path; std::string turn_penalties_index_path;
bool use_metadata; bool use_metadata;
bool parse_conditionals;
}; };
} }
} }
+8 -65
View File
@@ -1,11 +1,8 @@
#ifndef OSRM_EXTRACTOR_FILES_HPP #ifndef OSRM_EXTRACTOR_FILES_HPP
#define OSRM_EXTRACTOR_FILES_HPP #define OSRM_EXTRACTOR_FILES_HPP
#include "extractor/edge_based_edge.hpp"
#include "extractor/guidance/turn_lane_types.hpp" #include "extractor/guidance/turn_lane_types.hpp"
#include "extractor/node_data_container.hpp"
#include "extractor/serialization.hpp" #include "extractor/serialization.hpp"
#include "extractor/turn_data_container.hpp"
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
#include "util/packed_vector.hpp" #include "util/packed_vector.hpp"
@@ -20,32 +17,6 @@ namespace extractor
namespace files namespace files
{ {
template <typename EdgeBasedEdgeVector>
void writeEdgeBasedGraph(const boost::filesystem::path &path,
EdgeID const max_edge_id,
const EdgeBasedEdgeVector &edge_based_edge_list)
{
static_assert(std::is_same<typename EdgeBasedEdgeVector::value_type, EdgeBasedEdge>::value, "");
storage::io::FileWriter writer(path, storage::io::FileWriter::GenerateFingerprint);
writer.WriteElementCount64(max_edge_id);
storage::serialization::write(writer, edge_based_edge_list);
}
template <typename EdgeBasedEdgeVector>
void readEdgeBasedGraph(const boost::filesystem::path &path,
EdgeID &max_edge_id,
EdgeBasedEdgeVector &edge_based_edge_list)
{
static_assert(std::is_same<typename EdgeBasedEdgeVector::value_type, EdgeBasedEdge>::value, "");
storage::io::FileReader reader(path, storage::io::FileReader::VerifyFingerprint);
max_edge_id = reader.ReadElementCount64();
storage::serialization::read(reader, edge_based_edge_list);
}
// reads .osrm.nodes // reads .osrm.nodes
template <typename CoordinatesT, typename PackedOSMIDsT> template <typename CoordinatesT, typename PackedOSMIDsT>
inline void readNodes(const boost::filesystem::path &path, inline void readNodes(const boost::filesystem::path &path,
@@ -100,7 +71,7 @@ inline void writeNBGMapping(const boost::filesystem::path &path,
// reads .osrm.datasource_names // reads .osrm.datasource_names
inline void readDatasources(const boost::filesystem::path &path, Datasources &sources) inline void readDatasources(const boost::filesystem::path &path, Datasources &sources)
{ {
const auto fingerprint = storage::io::FileReader::VerifyFingerprint; const auto fingerprint = storage::io::FileReader::HasNoFingerprint;
storage::io::FileReader reader{path, fingerprint}; storage::io::FileReader reader{path, fingerprint};
serialization::read(reader, sources); serialization::read(reader, sources);
@@ -109,7 +80,7 @@ inline void readDatasources(const boost::filesystem::path &path, Datasources &so
// writes .osrm.datasource_names // writes .osrm.datasource_names
inline void writeDatasources(const boost::filesystem::path &path, Datasources &sources) inline void writeDatasources(const boost::filesystem::path &path, Datasources &sources)
{ {
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint; const auto fingerprint = storage::io::FileWriter::HasNoFingerprint;
storage::io::FileWriter writer{path, fingerprint}; storage::io::FileWriter writer{path, fingerprint};
serialization::write(writer, sources); serialization::write(writer, sources);
@@ -122,7 +93,7 @@ inline void readSegmentData(const boost::filesystem::path &path, SegmentDataT &s
static_assert(std::is_same<SegmentDataContainer, SegmentDataT>::value || static_assert(std::is_same<SegmentDataContainer, SegmentDataT>::value ||
std::is_same<SegmentDataView, SegmentDataT>::value, std::is_same<SegmentDataView, SegmentDataT>::value,
""); "");
const auto fingerprint = storage::io::FileReader::VerifyFingerprint; const auto fingerprint = storage::io::FileReader::HasNoFingerprint;
storage::io::FileReader reader{path, fingerprint}; storage::io::FileReader reader{path, fingerprint};
serialization::read(reader, segment_data); serialization::read(reader, segment_data);
@@ -135,7 +106,7 @@ inline void writeSegmentData(const boost::filesystem::path &path, const SegmentD
static_assert(std::is_same<SegmentDataContainer, SegmentDataT>::value || static_assert(std::is_same<SegmentDataContainer, SegmentDataT>::value ||
std::is_same<SegmentDataView, SegmentDataT>::value, std::is_same<SegmentDataView, SegmentDataT>::value,
""); "");
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint; const auto fingerprint = storage::io::FileWriter::HasNoFingerprint;
storage::io::FileWriter writer{path, fingerprint}; storage::io::FileWriter writer{path, fingerprint};
serialization::write(writer, segment_data); serialization::write(writer, segment_data);
@@ -149,7 +120,7 @@ inline void readTurnData(const boost::filesystem::path &path, TurnDataT &turn_da
std::is_same<TurnDataView, TurnDataT>::value || std::is_same<TurnDataView, TurnDataT>::value ||
std::is_same<TurnDataExternalContainer, TurnDataT>::value, std::is_same<TurnDataExternalContainer, TurnDataT>::value,
""); "");
const auto fingerprint = storage::io::FileReader::VerifyFingerprint; const auto fingerprint = storage::io::FileReader::HasNoFingerprint;
storage::io::FileReader reader{path, fingerprint}; storage::io::FileReader reader{path, fingerprint};
serialization::read(reader, turn_data); serialization::read(reader, turn_data);
@@ -163,40 +134,12 @@ inline void writeTurnData(const boost::filesystem::path &path, const TurnDataT &
std::is_same<TurnDataView, TurnDataT>::value || std::is_same<TurnDataView, TurnDataT>::value ||
std::is_same<TurnDataExternalContainer, TurnDataT>::value, std::is_same<TurnDataExternalContainer, TurnDataT>::value,
""); "");
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint; const auto fingerprint = storage::io::FileWriter::HasNoFingerprint;
storage::io::FileWriter writer{path, fingerprint}; storage::io::FileWriter writer{path, fingerprint};
serialization::write(writer, turn_data); serialization::write(writer, turn_data);
} }
// reads .osrm.nodes_data
template <typename NodeDataT>
inline void readNodeData(const boost::filesystem::path &path, NodeDataT &node_data)
{
static_assert(std::is_same<EdgeBasedNodeDataContainer, NodeDataT>::value ||
std::is_same<EdgeBasedNodeDataView, NodeDataT>::value ||
std::is_same<EdgeBasedNodeDataExternalContainer, NodeDataT>::value,
"");
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
storage::io::FileReader reader{path, fingerprint};
serialization::read(reader, node_data);
}
// writes .osrm.nodes_data
template <typename NodeDataT>
inline void writeNodeData(const boost::filesystem::path &path, const NodeDataT &node_data)
{
static_assert(std::is_same<EdgeBasedNodeDataContainer, NodeDataT>::value ||
std::is_same<EdgeBasedNodeDataView, NodeDataT>::value ||
std::is_same<EdgeBasedNodeDataExternalContainer, NodeDataT>::value,
"");
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint;
storage::io::FileWriter writer{path, fingerprint};
serialization::write(writer, node_data);
}
// reads .osrm.tls // reads .osrm.tls
template <typename OffsetsT, typename MaskT> template <typename OffsetsT, typename MaskT>
inline void readTurnLaneDescriptions(const boost::filesystem::path &path, inline void readTurnLaneDescriptions(const boost::filesystem::path &path,
@@ -208,7 +151,7 @@ inline void readTurnLaneDescriptions(const boost::filesystem::path &path,
""); "");
static_assert(std::is_same<typename OffsetsT::value_type, std::uint32_t>::value, ""); static_assert(std::is_same<typename OffsetsT::value_type, std::uint32_t>::value, "");
const auto fingerprint = storage::io::FileReader::VerifyFingerprint; const auto fingerprint = storage::io::FileReader::HasNoFingerprint;
storage::io::FileReader reader{path, fingerprint}; storage::io::FileReader reader{path, fingerprint};
storage::serialization::read(reader, turn_offsets); storage::serialization::read(reader, turn_offsets);
@@ -226,7 +169,7 @@ inline void writeTurnLaneDescriptions(const boost::filesystem::path &path,
""); "");
static_assert(std::is_same<typename OffsetsT::value_type, std::uint32_t>::value, ""); static_assert(std::is_same<typename OffsetsT::value_type, std::uint32_t>::value, "");
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint; const auto fingerprint = storage::io::FileWriter::HasNoFingerprint;
storage::io::FileWriter writer{path, fingerprint}; storage::io::FileWriter writer{path, fingerprint};
storage::serialization::write(writer, turn_offsets); storage::serialization::write(writer, turn_offsets);
@@ -1,40 +0,0 @@
#ifndef OSRM_EXTRACTOR_GUIDANCE_DRIVEWAY_HANDLER_HPP
#define OSRM_EXTRACTOR_GUIDANCE_DRIVEWAY_HANDLER_HPP
#include "extractor/guidance/intersection_handler.hpp"
namespace osrm
{
namespace extractor
{
namespace guidance
{
// Intersection handlers deal with all issues related to intersections.
class DrivewayHandler final : public IntersectionHandler
{
public:
DrivewayHandler(const IntersectionGenerator &intersection_generator,
const util::NodeBasedDynamicGraph &node_based_graph,
const std::vector<util::Coordinate> &coordinates,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table);
~DrivewayHandler() override final = default;
// check whether the handler can actually handle the intersection
bool canProcess(const NodeID nid,
const EdgeID via_eid,
const Intersection &intersection) const override final;
// process the intersection
Intersection operator()(const NodeID nid,
const EdgeID via_eid,
Intersection intersection) const override final;
};
} // namespace guidance
} // namespace extractor
} // namespace osrm
#endif /* OSRM_EXTRACTOR_GUIDANCE_DRIVEWAY_HANDLER_HPP */
@@ -27,6 +27,7 @@ namespace guidance
{ {
// Intersection handlers deal with all issues related to intersections. // Intersection handlers deal with all issues related to intersections.
// They assign appropriate turn operations to the TurnOperations.
// This base class provides both the interface and implementations for // This base class provides both the interface and implementations for
// common functions. // common functions.
class IntersectionHandler class IntersectionHandler
@@ -113,8 +114,6 @@ class IntersectionHandler
// For this scenario returns intersection at `b` and `b`. // For this scenario returns intersection at `b` and `b`.
boost::optional<IntersectionHandler::IntersectionViewAndNode> boost::optional<IntersectionHandler::IntersectionViewAndNode>
getNextIntersection(const NodeID at, const EdgeID via) const; getNextIntersection(const NodeID at, const EdgeID via) const;
bool isSameName(const EdgeID source_edge_id, const EdgeID target_edge_id) const;
}; };
// Impl. // Impl.
@@ -411,11 +410,14 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
const auto &best_option_data = const auto &best_option_data =
node_based_graph.GetEdgeData(intersection[best_option].eid); node_based_graph.GetEdgeData(intersection[best_option].eid);
const auto adjusted_distinction_ratio = [&]() { const auto adjusted_distinction_ratio = [&]() {
// obviousness by road classes // not allowed competitors are easily distinct
if (in_way_data.road_classification == best_option_data.road_classification && if (!intersection[index].entry_allowed)
best_option_data.road_classification.GetPriority() < return 0.7 * DISTINCTION_RATIO;
node_based_graph.GetEdgeData(intersection[index].eid) // a bit less obvious are road classes
.road_classification.GetPriority()) else if (in_way_data.road_classification == best_option_data.road_classification &&
best_option_data.road_classification.GetPriority() <
node_based_graph.GetEdgeData(intersection[index].eid)
.road_classification.GetPriority())
return 0.8 * DISTINCTION_RATIO; return 0.8 * DISTINCTION_RATIO;
// if road classes are the same, we use the full ratio // if road classes are the same, we use the full ratio
else else
@@ -20,6 +20,7 @@ namespace guidance
{ {
// Intersection handlers deal with all issues related to intersections. // Intersection handlers deal with all issues related to intersections.
// They assign appropriate turn operations to the TurnOperations.
class MotorwayHandler : public IntersectionHandler class MotorwayHandler : public IntersectionHandler
{ {
public: public:
@@ -21,6 +21,7 @@ namespace guidance
{ {
// Intersection handlers deal with all issues related to intersections. // Intersection handlers deal with all issues related to intersections.
// They assign appropriate turn operations to the TurnOperations.
class SliproadHandler final : public IntersectionHandler class SliproadHandler final : public IntersectionHandler
{ {
public: public:
@@ -2,7 +2,6 @@
#define OSRM_EXTRACTOR_TURN_ANALYSIS #define OSRM_EXTRACTOR_TURN_ANALYSIS
#include "extractor/compressed_edge_container.hpp" #include "extractor/compressed_edge_container.hpp"
#include "extractor/guidance/driveway_handler.hpp"
#include "extractor/guidance/intersection.hpp" #include "extractor/guidance/intersection.hpp"
#include "extractor/guidance/intersection_generator.hpp" #include "extractor/guidance/intersection_generator.hpp"
#include "extractor/guidance/intersection_normalization_operation.hpp" #include "extractor/guidance/intersection_normalization_operation.hpp"
@@ -88,7 +87,6 @@ class TurnAnalysis
const TurnHandler turn_handler; const TurnHandler turn_handler;
const SliproadHandler sliproad_handler; const SliproadHandler sliproad_handler;
const SuppressModeHandler suppress_mode_handler; const SuppressModeHandler suppress_mode_handler;
const DrivewayHandler driveway_handler;
// Utility function, setting basic turn types. Prepares for normal turn handling. // Utility function, setting basic turn types. Prepares for normal turn handling.
Intersection Intersection
@@ -24,6 +24,7 @@ namespace guidance
{ {
// Intersection handlers deal with all issues related to intersections. // Intersection handlers deal with all issues related to intersections.
// They assign appropriate turn operations to the TurnOperations.
class TurnHandler : public IntersectionHandler class TurnHandler : public IntersectionHandler
{ {
public: public:
@@ -65,16 +65,12 @@ const constexpr char *scenario_names[] = {"Simple",
class TurnLaneHandler class TurnLaneHandler
{ {
using UpgradableMutex = boost::interprocess::interprocess_upgradable_mutex;
using ScopedReaderLock = boost::interprocess::sharable_lock<UpgradableMutex>;
using ScopedWriterLock = boost::interprocess::scoped_lock<UpgradableMutex>;
public: public:
typedef std::vector<TurnLaneData> LaneDataVector; typedef std::vector<TurnLaneData> LaneDataVector;
TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_graph, TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_graph,
const std::vector<std::uint32_t> &turn_lane_offsets, std::vector<std::uint32_t> &turn_lane_offsets,
const std::vector<TurnLaneType::Mask> &turn_lane_masks, std::vector<TurnLaneType::Mask> &turn_lane_masks,
LaneDescriptionMap &lane_description_map, LaneDescriptionMap &lane_description_map,
const TurnAnalysis &turn_analysis, const TurnAnalysis &turn_analysis,
util::guidance::LaneDataIdMap &id_map); util::guidance::LaneDataIdMap &id_map);
@@ -90,8 +86,8 @@ class TurnLaneHandler
// we need to be able to look at previous intersections to, in some cases, find the correct turn // we need to be able to look at previous intersections to, in some cases, find the correct turn
// lanes for a turn // lanes for a turn
const util::NodeBasedDynamicGraph &node_based_graph; const util::NodeBasedDynamicGraph &node_based_graph;
const std::vector<std::uint32_t> &turn_lane_offsets; std::vector<std::uint32_t> &turn_lane_offsets;
const std::vector<TurnLaneType::Mask> &turn_lane_masks; std::vector<TurnLaneType::Mask> &turn_lane_masks;
LaneDescriptionMap &lane_description_map; LaneDescriptionMap &lane_description_map;
const TurnAnalysis &turn_analysis; const TurnAnalysis &turn_analysis;
util::guidance::LaneDataIdMap &id_map; util::guidance::LaneDataIdMap &id_map;
@@ -10,7 +10,6 @@
#include <boost/functional/hash.hpp> #include <boost/functional/hash.hpp>
#include "util/concurrent_id_map.hpp"
#include "util/json_container.hpp" #include "util/json_container.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
@@ -94,9 +93,9 @@ struct TurnLaneDescription_hash
} }
}; };
typedef util::ConcurrentIDMap<guidance::TurnLaneDescription, typedef std::unordered_map<guidance::TurnLaneDescription,
LaneDescriptionID, LaneDescriptionID,
guidance::TurnLaneDescription_hash> guidance::TurnLaneDescription_hash>
LaneDescriptionMap; LaneDescriptionMap;
} // guidance } // guidance
@@ -6,6 +6,7 @@
#include "extractor/node_based_edge.hpp" #include "extractor/node_based_edge.hpp"
#include "extractor/travel_mode.hpp" #include "extractor/travel_mode.hpp"
#include "osrm/coordinate.hpp" #include "osrm/coordinate.hpp"
#include "util/strong_typedef.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <boost/assert.hpp> #include <boost/assert.hpp>
+5 -5
View File
@@ -19,7 +19,7 @@ struct NodeBasedEdge
NodeID target, NodeID target,
NodeID name_id, NodeID name_id,
EdgeWeight weight, EdgeWeight weight,
EdgeDuration duration, EdgeWeight duration,
bool forward, bool forward,
bool backward, bool backward,
bool roundabout, bool roundabout,
@@ -37,7 +37,7 @@ struct NodeBasedEdge
NodeID target; // 32 4 NodeID target; // 32 4
NodeID name_id; // 32 4 NodeID name_id; // 32 4
EdgeWeight weight; // 32 4 EdgeWeight weight; // 32 4
EdgeDuration duration; // 32 4 EdgeWeight duration; // 32 4
std::uint8_t forward : 1; // 1 std::uint8_t forward : 1; // 1
std::uint8_t backward : 1; // 1 std::uint8_t backward : 1; // 1
std::uint8_t roundabout : 1; // 1 std::uint8_t roundabout : 1; // 1
@@ -56,7 +56,7 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge
OSMNodeID target, OSMNodeID target,
NodeID name_id, NodeID name_id,
EdgeWeight weight, EdgeWeight weight,
EdgeDuration duration, EdgeWeight duration,
bool forward, bool forward,
bool backward, bool backward,
bool roundabout, bool roundabout,
@@ -86,7 +86,7 @@ inline NodeBasedEdge::NodeBasedEdge(NodeID source,
NodeID target, NodeID target,
NodeID name_id, NodeID name_id,
EdgeWeight weight, EdgeWeight weight,
EdgeDuration duration, EdgeWeight duration,
bool forward, bool forward,
bool backward, bool backward,
bool roundabout, bool roundabout,
@@ -125,7 +125,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(OSMNodeID source,
OSMNodeID target, OSMNodeID target,
NodeID name_id, NodeID name_id,
EdgeWeight weight, EdgeWeight weight,
EdgeDuration duration, EdgeWeight duration,
bool forward, bool forward,
bool backward, bool backward,
bool roundabout, bool roundabout,
-112
View File
@@ -1,112 +0,0 @@
#ifndef OSRM_EXTRACTOR_NODE_DATA_CONTAINER_HPP
#define OSRM_EXTRACTOR_NODE_DATA_CONTAINER_HPP
#include "extractor/travel_mode.hpp"
#include "storage/io_fwd.hpp"
#include "storage/shared_memory_ownership.hpp"
#include "util/permutation.hpp"
#include "util/typedefs.hpp"
#include "util/vector_view.hpp"
namespace osrm
{
namespace extractor
{
namespace detail
{
template <storage::Ownership Ownership> class EdgeBasedNodeDataContainerImpl;
}
namespace serialization
{
template <storage::Ownership Ownership>
void read(storage::io::FileReader &reader,
detail::EdgeBasedNodeDataContainerImpl<Ownership> &ebn_data);
template <storage::Ownership Ownership>
void write(storage::io::FileWriter &writer,
const detail::EdgeBasedNodeDataContainerImpl<Ownership> &ebn_data);
}
namespace detail
{
template <storage::Ownership Ownership> class EdgeBasedNodeDataContainerImpl
{
template <typename T> using Vector = util::ViewOrVector<T, Ownership>;
using TravelMode = extractor::TravelMode;
public:
EdgeBasedNodeDataContainerImpl() = default;
EdgeBasedNodeDataContainerImpl(std::size_t size)
: geometry_ids(size), name_ids(size), component_ids(size), travel_modes(size)
{
}
EdgeBasedNodeDataContainerImpl(Vector<GeometryID> geometry_ids,
Vector<NameID> name_ids,
Vector<ComponentID> component_ids,
Vector<TravelMode> travel_modes)
: geometry_ids(std::move(geometry_ids)), name_ids(std::move(name_ids)),
component_ids(std::move(component_ids)), travel_modes(std::move(travel_modes))
{
}
GeometryID GetGeometryID(const NodeID node_id) const { return geometry_ids[node_id]; }
TravelMode GetTravelMode(const NodeID node_id) const { return travel_modes[node_id]; }
NameID GetNameID(const NodeID node_id) const { return name_ids[node_id]; }
ComponentID GetComponentID(const NodeID node_id) const { return component_ids[node_id]; }
// Used by EdgeBasedGraphFactory to fill data structure
template <typename = std::enable_if<Ownership == storage::Ownership::Container>>
void SetData(NodeID node_id, GeometryID geometry_id, NameID name_id, TravelMode travel_mode)
{
geometry_ids[node_id] = geometry_id;
name_ids[node_id] = name_id;
travel_modes[node_id] = travel_mode;
}
// Used by EdgeBasedGraphFactory to fill data structure
template <typename = std::enable_if<Ownership == storage::Ownership::Container>>
void SetComponentID(NodeID node_id, ComponentID component_id)
{
component_ids[node_id] = component_id;
}
friend void serialization::read<Ownership>(storage::io::FileReader &reader,
EdgeBasedNodeDataContainerImpl &ebn_data_container);
friend void
serialization::write<Ownership>(storage::io::FileWriter &writer,
const EdgeBasedNodeDataContainerImpl &ebn_data_container);
template <typename = std::enable_if<Ownership == storage::Ownership::Container>>
void Renumber(const std::vector<std::uint32_t> &permutation)
{
util::inplacePermutation(geometry_ids.begin(), geometry_ids.end(), permutation);
util::inplacePermutation(name_ids.begin(), name_ids.end(), permutation);
util::inplacePermutation(component_ids.begin(), component_ids.end(), permutation);
util::inplacePermutation(travel_modes.begin(), travel_modes.end(), permutation);
}
private:
Vector<GeometryID> geometry_ids;
Vector<NameID> name_ids;
Vector<ComponentID> component_ids;
Vector<TravelMode> travel_modes;
};
}
using EdgeBasedNodeDataExternalContainer =
detail::EdgeBasedNodeDataContainerImpl<storage::Ownership::External>;
using EdgeBasedNodeDataContainer =
detail::EdgeBasedNodeDataContainerImpl<storage::Ownership::Container>;
using EdgeBasedNodeDataView = detail::EdgeBasedNodeDataContainerImpl<storage::Ownership::View>;
}
}
#endif
-22
View File
@@ -1,22 +0,0 @@
#ifndef OSRM_EXTRACTOR_PACKED_OSM_IDS_HPP
#define OSRM_EXTRACTOR_PACKED_OSM_IDS_HPP
#include "util/packed_vector.hpp"
#include "util/typedefs.hpp"
namespace osrm
{
namespace extractor
{
namespace detail
{
template <storage::Ownership Ownership>
using PackedOSMIDs = util::detail::PackedVector<OSMNodeID, 33, Ownership>;
}
using PackedOSMIDsView = detail::PackedOSMIDs<storage::Ownership::View>;
using PackedOSMIDs = detail::PackedOSMIDs<storage::Ownership::Container>;
}
}
#endif
+1 -3
View File
@@ -22,7 +22,7 @@ struct ProfileProperties
: traffic_signal_penalty(0), u_turn_penalty(0), : traffic_signal_penalty(0), u_turn_penalty(0),
max_speed_for_map_matching(DEFAULT_MAX_SPEED), continue_straight_at_waypoint(true), max_speed_for_map_matching(DEFAULT_MAX_SPEED), continue_straight_at_waypoint(true),
use_turn_restrictions(false), left_hand_driving(false), fallback_to_duration(true), use_turn_restrictions(false), left_hand_driving(false), fallback_to_duration(true),
weight_name{"duration"}, call_tagless_node_function(true) weight_name{"duration"}
{ {
BOOST_ASSERT(weight_name[MAX_WEIGHT_NAME_LENGTH] == '\0'); BOOST_ASSERT(weight_name[MAX_WEIGHT_NAME_LENGTH] == '\0');
} }
@@ -88,8 +88,6 @@ struct ProfileProperties
char weight_name[MAX_WEIGHT_NAME_LENGTH + 1]; char weight_name[MAX_WEIGHT_NAME_LENGTH + 1];
unsigned weight_precision = 1; unsigned weight_precision = 1;
bool force_split_edges = false; bool force_split_edges = false;
bool call_tagless_node_function = true;
}; };
} }
} }
+1 -1
View File
@@ -47,7 +47,7 @@ class RasterGrid
storage::io::FileReader file_reader(filepath, storage::io::FileReader::HasNoFingerprint); storage::io::FileReader file_reader(filepath, storage::io::FileReader::HasNoFingerprint);
std::string buffer; std::string buffer;
buffer.resize(file_reader.GetSize()); buffer.resize(file_reader.Size());
BOOST_ASSERT(buffer.size() > 1); BOOST_ASSERT(buffer.size() > 1);
-4
View File
@@ -1,8 +1,6 @@
#ifndef RESTRICTION_HPP #ifndef RESTRICTION_HPP
#define RESTRICTION_HPP #define RESTRICTION_HPP
#include "util/coordinate.hpp"
#include "util/opening_hours.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <limits> #include <limits>
@@ -22,8 +20,6 @@ struct TurnRestriction
WayOrNode from; WayOrNode from;
WayOrNode to; WayOrNode to;
std::vector<util::OpeningHours> condition;
struct Bits struct Bits
{ // mostly unused { // mostly unused
Bits() Bits()
+1 -1
View File
@@ -95,7 +95,7 @@ class RestrictionMap
return; return;
} }
// find all potential start edges. It is more efficient to get a (small) list // find all potential start edges. It is more efficent to get a (small) list
// of potential start edges than iterating over all buckets // of potential start edges than iterating over all buckets
std::vector<NodeID> predecessors; std::vector<NodeID> predecessors;
for (const EdgeID current_edge_id : graph.GetAdjacentEdgeRange(node_u)) for (const EdgeID current_edge_id : graph.GetAdjacentEdgeRange(node_u))
+3 -6
View File
@@ -41,17 +41,14 @@ class ScriptingEnvironment;
class RestrictionParser class RestrictionParser
{ {
public: public:
RestrictionParser(bool use_turn_restrictions, RestrictionParser(ScriptingEnvironment &scripting_environment);
bool parse_conditionals, boost::optional<InputRestrictionContainer> TryParse(const osmium::Relation &relation) const;
std::vector<std::string> &restrictions);
std::vector<InputRestrictionContainer> TryParse(const osmium::Relation &relation) const;
private: private:
bool ShouldIgnoreRestriction(const std::string &except_tag_string) const; bool ShouldIgnoreRestriction(const std::string &except_tag_string) const;
bool use_turn_restrictions;
bool parse_conditionals;
std::vector<std::string> restrictions; std::vector<std::string> restrictions;
bool use_turn_restrictions;
}; };
} }
} }
+7 -6
View File
@@ -58,12 +58,13 @@ class ScriptingEnvironment
virtual void ProcessTurn(ExtractionTurn &turn) = 0; virtual void ProcessTurn(ExtractionTurn &turn) = 0;
virtual void ProcessSegment(ExtractionSegment &segment) = 0; virtual void ProcessSegment(ExtractionSegment &segment) = 0;
virtual void ProcessElements( virtual void
const osmium::memory::Buffer &buffer, ProcessElements(const std::vector<osmium::memory::Buffer::const_iterator> &osm_elements,
const RestrictionParser &restriction_parser, const RestrictionParser &restriction_parser,
std::vector<std::pair<const osmium::Node &, ExtractionNode>> &resulting_nodes, tbb::concurrent_vector<std::pair<std::size_t, ExtractionNode>> &resulting_nodes,
std::vector<std::pair<const osmium::Way &, ExtractionWay>> &resulting_ways, tbb::concurrent_vector<std::pair<std::size_t, ExtractionWay>> &resulting_ways,
std::vector<boost::optional<InputRestrictionContainer>> &resulting_restrictions) = 0; tbb::concurrent_vector<boost::optional<InputRestrictionContainer>>
&resulting_restrictions) = 0;
}; };
} }
} }
@@ -31,11 +31,6 @@ struct LuaScriptingContext final
bool has_way_function; bool has_way_function;
bool has_segment_function; bool has_segment_function;
sol::function turn_function;
sol::function way_function;
sol::function node_function;
sol::function segment_function;
int api_version; int api_version;
}; };
@@ -65,12 +60,13 @@ class Sol2ScriptingEnvironment final : public ScriptingEnvironment
void ProcessTurn(ExtractionTurn &turn) override; void ProcessTurn(ExtractionTurn &turn) override;
void ProcessSegment(ExtractionSegment &segment) override; void ProcessSegment(ExtractionSegment &segment) override;
void ProcessElements( void
const osmium::memory::Buffer &buffer, ProcessElements(const std::vector<osmium::memory::Buffer::const_iterator> &osm_elements,
const RestrictionParser &restriction_parser, const RestrictionParser &restriction_parser,
std::vector<std::pair<const osmium::Node &, ExtractionNode>> &resulting_nodes, tbb::concurrent_vector<std::pair<std::size_t, ExtractionNode>> &resulting_nodes,
std::vector<std::pair<const osmium::Way &, ExtractionWay>> &resulting_ways, tbb::concurrent_vector<std::pair<std::size_t, ExtractionWay>> &resulting_ways,
std::vector<boost::optional<InputRestrictionContainer>> &resulting_restrictions) override; tbb::concurrent_vector<boost::optional<InputRestrictionContainer>>
&resulting_restrictions) override;
private: private:
void InitContext(LuaScriptingContext &context); void InitContext(LuaScriptingContext &context);
+8 -13
View File
@@ -1,7 +1,6 @@
#ifndef OSRM_EXTRACTOR_SEGMENT_DATA_CONTAINER_HPP_ #ifndef OSRM_EXTRACTOR_SEGMENT_DATA_CONTAINER_HPP_
#define OSRM_EXTRACTOR_SEGMENT_DATA_CONTAINER_HPP_ #define OSRM_EXTRACTOR_SEGMENT_DATA_CONTAINER_HPP_
#include "util/packed_vector.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include "util/vector_view.hpp" #include "util/vector_view.hpp"
@@ -44,8 +43,6 @@ namespace detail
template <storage::Ownership Ownership> class SegmentDataContainerImpl template <storage::Ownership Ownership> class SegmentDataContainerImpl
{ {
template <typename T> using Vector = util::ViewOrVector<T, Ownership>; template <typename T> using Vector = util::ViewOrVector<T, Ownership>;
template <typename T, std::size_t Bits>
using PackedVector = util::detail::PackedVector<T, Bits, Ownership>;
friend CompressedEdgeContainer; friend CompressedEdgeContainer;
@@ -53,17 +50,15 @@ template <storage::Ownership Ownership> class SegmentDataContainerImpl
// FIXME We should change the indexing to Edge-Based-Node id // FIXME We should change the indexing to Edge-Based-Node id
using DirectionalGeometryID = std::uint32_t; using DirectionalGeometryID = std::uint32_t;
using SegmentOffset = std::uint32_t; using SegmentOffset = std::uint32_t;
using SegmentWeightVector = PackedVector<SegmentWeight, SEGMENT_WEIGHT_BITS>;
using SegmentDurationVector = PackedVector<SegmentDuration, SEGMENT_DURAITON_BITS>;
SegmentDataContainerImpl() = default; SegmentDataContainerImpl() = default;
SegmentDataContainerImpl(Vector<std::uint32_t> index_, SegmentDataContainerImpl(Vector<std::uint32_t> index_,
Vector<NodeID> nodes_, Vector<NodeID> nodes_,
SegmentWeightVector fwd_weights_, Vector<EdgeWeight> fwd_weights_,
SegmentWeightVector rev_weights_, Vector<EdgeWeight> rev_weights_,
SegmentDurationVector fwd_durations_, Vector<EdgeWeight> fwd_durations_,
SegmentDurationVector rev_durations_, Vector<EdgeWeight> rev_durations_,
Vector<DatasourceID> datasources_) Vector<DatasourceID> datasources_)
: index(std::move(index_)), nodes(std::move(nodes_)), fwd_weights(std::move(fwd_weights_)), : index(std::move(index_)), nodes(std::move(nodes_)), fwd_weights(std::move(fwd_weights_)),
rev_weights(std::move(rev_weights_)), fwd_durations(std::move(fwd_durations_)), rev_weights(std::move(rev_weights_)), fwd_durations(std::move(fwd_durations_)),
@@ -206,10 +201,10 @@ template <storage::Ownership Ownership> class SegmentDataContainerImpl
private: private:
Vector<std::uint32_t> index; Vector<std::uint32_t> index;
Vector<NodeID> nodes; Vector<NodeID> nodes;
SegmentWeightVector fwd_weights; Vector<EdgeWeight> fwd_weights;
SegmentWeightVector rev_weights; Vector<EdgeWeight> rev_weights;
SegmentDurationVector fwd_durations; Vector<EdgeWeight> fwd_durations;
SegmentDurationVector rev_durations; Vector<EdgeWeight> rev_durations;
Vector<DatasourceID> datasources; Vector<DatasourceID> datasources;
}; };
} }
+14 -78
View File
@@ -3,8 +3,6 @@
#include "extractor/datasources.hpp" #include "extractor/datasources.hpp"
#include "extractor/nbg_to_ebg.hpp" #include "extractor/nbg_to_ebg.hpp"
#include "extractor/node_data_container.hpp"
#include "extractor/restriction.hpp"
#include "extractor/segment_data_container.hpp" #include "extractor/segment_data_container.hpp"
#include "extractor/turn_data_container.hpp" #include "extractor/turn_data_container.hpp"
@@ -20,7 +18,6 @@ namespace extractor
namespace serialization namespace serialization
{ {
// read/write for datasources file
inline void read(storage::io::FileReader &reader, Datasources &sources) inline void read(storage::io::FileReader &reader, Datasources &sources)
{ {
reader.ReadInto(sources); reader.ReadInto(sources);
@@ -31,17 +28,16 @@ inline void write(storage::io::FileWriter &writer, Datasources &sources)
writer.WriteFrom(sources); writer.WriteFrom(sources);
} }
// read/write for segment data file
template <storage::Ownership Ownership> template <storage::Ownership Ownership>
inline void read(storage::io::FileReader &reader, inline void read(storage::io::FileReader &reader,
detail::SegmentDataContainerImpl<Ownership> &segment_data) detail::SegmentDataContainerImpl<Ownership> &segment_data)
{ {
storage::serialization::read(reader, segment_data.index); storage::serialization::read(reader, segment_data.index);
storage::serialization::read(reader, segment_data.nodes); storage::serialization::read(reader, segment_data.nodes);
util::serialization::read(reader, segment_data.fwd_weights); storage::serialization::read(reader, segment_data.fwd_weights);
util::serialization::read(reader, segment_data.rev_weights); storage::serialization::read(reader, segment_data.rev_weights);
util::serialization::read(reader, segment_data.fwd_durations); storage::serialization::read(reader, segment_data.fwd_durations);
util::serialization::read(reader, segment_data.rev_durations); storage::serialization::read(reader, segment_data.rev_durations);
storage::serialization::read(reader, segment_data.datasources); storage::serialization::read(reader, segment_data.datasources);
} }
@@ -51,20 +47,22 @@ inline void write(storage::io::FileWriter &writer,
{ {
storage::serialization::write(writer, segment_data.index); storage::serialization::write(writer, segment_data.index);
storage::serialization::write(writer, segment_data.nodes); storage::serialization::write(writer, segment_data.nodes);
util::serialization::write(writer, segment_data.fwd_weights); storage::serialization::write(writer, segment_data.fwd_weights);
util::serialization::write(writer, segment_data.rev_weights); storage::serialization::write(writer, segment_data.rev_weights);
util::serialization::write(writer, segment_data.fwd_durations); storage::serialization::write(writer, segment_data.fwd_durations);
util::serialization::write(writer, segment_data.rev_durations); storage::serialization::write(writer, segment_data.rev_durations);
storage::serialization::write(writer, segment_data.datasources); storage::serialization::write(writer, segment_data.datasources);
} }
// read/write for turn data file
template <storage::Ownership Ownership> template <storage::Ownership Ownership>
inline void read(storage::io::FileReader &reader, inline void read(storage::io::FileReader &reader,
detail::TurnDataContainerImpl<Ownership> &turn_data_container) detail::TurnDataContainerImpl<Ownership> &turn_data_container)
{ {
storage::serialization::read(reader, turn_data_container.geometry_ids);
storage::serialization::read(reader, turn_data_container.name_ids);
storage::serialization::read(reader, turn_data_container.turn_instructions); storage::serialization::read(reader, turn_data_container.turn_instructions);
storage::serialization::read(reader, turn_data_container.lane_data_ids); storage::serialization::read(reader, turn_data_container.lane_data_ids);
storage::serialization::read(reader, turn_data_container.travel_modes);
storage::serialization::read(reader, turn_data_container.entry_class_ids); storage::serialization::read(reader, turn_data_container.entry_class_ids);
storage::serialization::read(reader, turn_data_container.pre_turn_bearings); storage::serialization::read(reader, turn_data_container.pre_turn_bearings);
storage::serialization::read(reader, turn_data_container.post_turn_bearings); storage::serialization::read(reader, turn_data_container.post_turn_bearings);
@@ -74,77 +72,15 @@ template <storage::Ownership Ownership>
inline void write(storage::io::FileWriter &writer, inline void write(storage::io::FileWriter &writer,
const detail::TurnDataContainerImpl<Ownership> &turn_data_container) const detail::TurnDataContainerImpl<Ownership> &turn_data_container)
{ {
storage::serialization::write(writer, turn_data_container.geometry_ids);
storage::serialization::write(writer, turn_data_container.name_ids);
storage::serialization::write(writer, turn_data_container.turn_instructions); storage::serialization::write(writer, turn_data_container.turn_instructions);
storage::serialization::write(writer, turn_data_container.lane_data_ids); storage::serialization::write(writer, turn_data_container.lane_data_ids);
storage::serialization::write(writer, turn_data_container.travel_modes);
storage::serialization::write(writer, turn_data_container.entry_class_ids); storage::serialization::write(writer, turn_data_container.entry_class_ids);
storage::serialization::write(writer, turn_data_container.pre_turn_bearings); storage::serialization::write(writer, turn_data_container.pre_turn_bearings);
storage::serialization::write(writer, turn_data_container.post_turn_bearings); storage::serialization::write(writer, turn_data_container.post_turn_bearings);
} }
template <storage::Ownership Ownership>
inline void read(storage::io::FileReader &reader,
detail::EdgeBasedNodeDataContainerImpl<Ownership> &node_data_container)
{
storage::serialization::read(reader, node_data_container.geometry_ids);
storage::serialization::read(reader, node_data_container.name_ids);
storage::serialization::read(reader, node_data_container.component_ids);
storage::serialization::read(reader, node_data_container.travel_modes);
}
template <storage::Ownership Ownership>
inline void write(storage::io::FileWriter &writer,
const detail::EdgeBasedNodeDataContainerImpl<Ownership> &node_data_container)
{
storage::serialization::write(writer, node_data_container.geometry_ids);
storage::serialization::write(writer, node_data_container.name_ids);
storage::serialization::write(writer, node_data_container.component_ids);
storage::serialization::write(writer, node_data_container.travel_modes);
}
// read/write for conditional turn restrictions file
inline void read(storage::io::FileReader &reader, std::vector<TurnRestriction> &restrictions)
{
auto num_indices = reader.ReadElementCount64();
restrictions.reserve(num_indices);
TurnRestriction restriction;
while (num_indices > 0)
{
bool is_only;
reader.ReadInto(restriction.via);
reader.ReadInto(restriction.from);
reader.ReadInto(restriction.to);
reader.ReadInto(is_only);
auto num_conditions = reader.ReadElementCount64();
restriction.condition.resize(num_conditions);
for (uint64_t i = 0; i < num_conditions; i++)
{
reader.ReadInto(restriction.condition[i].modifier);
storage::serialization::read(reader, restriction.condition[i].times);
storage::serialization::read(reader, restriction.condition[i].weekdays);
storage::serialization::read(reader, restriction.condition[i].monthdays);
}
restriction.flags.is_only = is_only;
restrictions.push_back(std::move(restriction));
num_indices--;
}
}
inline void write(storage::io::FileWriter &writer, const TurnRestriction &restriction)
{
writer.WriteOne(restriction.via);
writer.WriteOne(restriction.from);
writer.WriteOne(restriction.to);
writer.WriteOne(restriction.flags.is_only);
writer.WriteElementCount64(restriction.condition.size());
for (const auto &c : restriction.condition)
{
writer.WriteOne(c.modifier);
storage::serialization::write(writer, c.times);
storage::serialization::write(writer, c.weekdays);
storage::serialization::write(writer, c.monthdays);
}
}
} }
} }
} }
+2 -6
View File
@@ -69,7 +69,6 @@ template <typename GraphT> class TarjanSCC
std::stack<NodeID> tarjan_stack; std::stack<NodeID> tarjan_stack;
std::vector<TarjanNode> tarjan_node_list(max_node_id); std::vector<TarjanNode> tarjan_node_list(max_node_id);
unsigned component_index = 0, size_of_current_component = 0; unsigned component_index = 0, size_of_current_component = 0;
unsigned large_component_count = 0;
unsigned index = 0; unsigned index = 0;
std::vector<bool> processing_node_before_recursion(max_node_id, true); std::vector<bool> processing_node_before_recursion(max_node_id, true);
for (const NodeID node : util::irange(0u, max_node_id)) for (const NodeID node : util::irange(0u, max_node_id))
@@ -147,9 +146,8 @@ template <typename GraphT> class TarjanSCC
if (size_of_current_component > 1000) if (size_of_current_component > 1000)
{ {
++large_component_count; util::Log() << "large component [" << component_index
util::Log(logDEBUG) << "large component [" << component_index << "]=" << size_of_current_component;
<< "]=" << size_of_current_component;
} }
++component_index; ++component_index;
@@ -160,8 +158,6 @@ template <typename GraphT> class TarjanSCC
} }
TIMER_STOP(SCC_RUN); TIMER_STOP(SCC_RUN);
util::Log() << "Found " << component_index << " SCC (" << large_component_count
<< " large, " << (component_index - large_component_count) << " small)";
util::Log() << "SCC run took: " << TIMER_MSEC(SCC_RUN) / 1000. << "s"; util::Log() << "SCC run took: " << TIMER_MSEC(SCC_RUN) / 1000. << "s";
size_one_counter = std::count_if(component_size_vector.begin(), size_one_counter = std::count_if(component_size_vector.begin(),

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