Compare commits

...

26 Commits

Author SHA1 Message Date
Patrick Niklaus
210fa9d545 Update changelog and version 2017-07-19 16:34:49 +00:00
Daniel J. Hofmann
7eafb48d20 Introduces a construction whitelist in profiles 2017-07-19 16:32:42 +00:00
Daniel J. Hofmann
df0f407591 Makes construction=minor ways routable again, see #4258 2017-07-19 16:27:31 +00:00
Patrick Niklaus
f9a8bcc75c Bump version to v5.9.0-rc.3 2017-07-18 16:50:51 +00:00
Patrick Niklaus
f815daf026 Update the changelog 2017-07-18 16:50:24 +00:00
Patrick Niklaus
f393f47d43 Move classes to intersection object and don't emit notifications 2017-07-18 16:48:59 +00:00
Daniel J. Hofmann
1e258ed3fa Changelog entry for openmp 2017-07-17 19:24:27 +02:00
Daniel J. Hofmann
de084f201c Only enables -fopenmp in case the user wants stxxl 2017-07-17 19:20:35 +02:00
Patrick Niklaus
e34a74d4ac Add changelog entry 2017-07-13 21:50:01 +00:00
Daniel J. Hofmann
bd1391f6f7 Exposes EngineConfig system-wide limits in Node.js bindings, resolves #4226 2017-07-13 21:49:27 +00:00
Patrick Niklaus
f54631619a Add bug fix to changelog 2017-07-13 09:01:08 +00:00
Moritz Kobitzsch
070fa1a24c only consider allowed entries when continuing on motorways 2017-07-13 09:00:00 +00:00
Moritz Kobitzsch
f15285e9ee add test indicating missdetection of continuing on motorways 2017-07-13 09:00:00 +00:00
Patrick Niklaus
bae21f0d5d Bump version to RC2 2017-07-12 22:13:56 +00:00
Daniel Patterson
305df1fb6e Include osrm-customize when doing 'make install' 2017-07-12 22:12:14 +00:00
Daniel J. Hofmann
9ab0fca31c Canonicalizes all OSM string list handling in the profiles 2017-07-12 22:09:28 +00:00
Michael Krasnyk
e2e398edc5 Remove STXXL from OSM parsing and enable in CMake by default 2017-07-11 08:24:29 +00:00
Michael Krasnyk
b87366132b Updated ChangeLog 2017-07-11 08:24:29 +00:00
Michael Krasnyk
f4ef4b022e Added STXXL configuration 2017-07-11 08:24:29 +00:00
Michael Krasnyk
81d479304e Don't use stxxl vector in contractor 2017-07-11 08:24:29 +00:00
Michael Krasnyk
92b53e5be0 Switch from stxxl::vector to std::vector in extractor 2017-07-11 08:24:29 +00:00
Michael Krasnyk
cc73e753bd Removed external_to_internal_node_id_map container 2017-07-11 08:24:28 +00:00
Daniel J. Hofmann
725dc396c7 Fixes Node.js bindings always enabling alternatives when using boolean overload 2017-07-10 10:45:56 +02:00
Daniel J. Hofmann
890f0d8d7e Discards construction and proposed ways, resolves #4230 2017-07-10 10:38:30 +02:00
Patrick Niklaus
c9017090a2 Bump verison to 5.9.0-rc.1 2017-07-07 17:07:52 +00:00
Patrick Niklaus
e7061591e3 Enable travis on 5.9 2017-07-07 17:06:47 +00:00
34 changed files with 504 additions and 256 deletions

View File

@ -19,6 +19,7 @@ branches:
- master - master
# enable building tags # enable building tags
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/ - /^v\d+\.\d+(\.\d+)?(-\S*)?$/
- "5.9"
cache: cache:
yarn: true yarn: true
@ -72,7 +73,7 @@ matrix:
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', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-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' ENABLE_COVERAGE=ON CUCUMBER_TIMEOUT=20000
after_success: after_success:
- bash <(curl -s https://codecov.io/bash) - bash <(curl -s https://codecov.io/bash)
@ -82,7 +83,7 @@ matrix:
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', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-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 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
@ -90,7 +91,7 @@ matrix:
addons: &clang40 addons: &clang40
apt: apt:
sources: ['ubuntu-toolchain-r-test'] sources: ['ubuntu-toolchain-r-test']
packages: ['libstdc++-5-dev', '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: ['libstdc++-5-dev', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Debug' CUCUMBER_TIMEOUT=60000 env: CLANG_VERSION='4.0.0' BUILD_TYPE='Debug' CUCUMBER_TIMEOUT=60000
- os: linux - os: linux
@ -115,7 +116,7 @@ matrix:
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', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release' env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release'
- os: linux - os: linux
@ -124,12 +125,20 @@ matrix:
TARGET_ARCH='i686' CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release' TARGET_ARCH='i686' CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release'
CFLAGS='-m32 -msse2 -mfpmath=sse' CXXFLAGS='-m32 -msse2 -mfpmath=sse' CFLAGS='-m32 -msse2 -mfpmath=sse' CXXFLAGS='-m32 -msse2 -mfpmath=sse'
- os: linux
compiler: "gcc-6-stxxl"
addons: &gcc6
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-6', 'libbz2-dev', 'libstxxl-dev', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release' ENABLE_STXXL=On
- os: linux - os: linux
compiler: "gcc-4.9-release" compiler: "gcc-4.9-release"
addons: &gcc49 addons: &gcc49
apt: apt:
sources: ['ubuntu-toolchain-r-test'] sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.9', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev', 'ccache'] packages: ['g++-4.9', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev', 'ccache']
env: CCOMPILER='gcc-4.9' CXXCOMPILER='g++-4.9' BUILD_TYPE='Release' env: CCOMPILER='gcc-4.9' CXXCOMPILER='g++-4.9' BUILD_TYPE='Release'
- os: osx - os: osx
@ -146,7 +155,7 @@ matrix:
#- addons: &clang40 #- addons: &clang40
#- apt: #- apt:
#- sources: ['llvm-toolchain-trusty-4.0', 'ubuntu-toolchain-r-test'] #- sources: ['llvm-toolchain-trusty-4.0', 'ubuntu-toolchain-r-test']
#- packages: ['clang-4.0', '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: ['clang-4.0', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
#- env: CCOMPILER='clang-4.0' CXXCOMPILER='clang++-4.0' BUILD_TYPE='Release' #- env: CCOMPILER='clang-4.0' CXXCOMPILER='clang++-4.0' BUILD_TYPE='Release'
# Shared Library # Shared Library
@ -155,7 +164,7 @@ matrix:
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', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
# Disabled because CI slowness # Disabled because CI slowness
@ -164,7 +173,7 @@ matrix:
#- addons: &clang40 #- addons: &clang40
#- apt: #- apt:
#- sources: ['llvm-toolchain-trusty-4.0', 'ubuntu-toolchain-r-test'] #- sources: ['llvm-toolchain-trusty-4.0', 'ubuntu-toolchain-r-test']
#- packages: ['clang-4.0', '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: ['clang-4.0', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
#- env: CCOMPILER='clang-4.0' CXXCOMPILER='clang++-4.0' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON #- env: CCOMPILER='clang-4.0' CXXCOMPILER='clang++-4.0' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
# Node build jobs. These skip running the tests. # Node build jobs. These skip running the tests.
@ -323,6 +332,7 @@ install:
-DENABLE_COVERAGE=${ENABLE_COVERAGE:-OFF} \ -DENABLE_COVERAGE=${ENABLE_COVERAGE:-OFF} \
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \ -DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
-DENABLE_SANITIZER=${ENABLE_SANITIZER:-OFF} \ -DENABLE_SANITIZER=${ENABLE_SANITIZER:-OFF} \
-DENABLE_STXXL=${ENABLE_STXXL:-OFF} \
-DBUILD_TOOLS=ON \ -DBUILD_TOOLS=ON \
-DENABLE_CCACHE=ON \ -DENABLE_CCACHE=ON \
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} -DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR}

View File

@ -7,15 +7,22 @@
- API: - API:
- Exposes `alternatives=Number` parameter overload in addition to the boolean flag. - Exposes `alternatives=Number` parameter overload in addition to the boolean flag.
- Support for exits numbers and names. New member `exits` in `RouteStep`, based on `junction:ref` on ways - Support for exits numbers and names. New member `exits` in `RouteStep`, based on `junction:ref` on ways
- `RouteStep` now has new parameter `classes` that can be set in the profile on each way. - `Intersection` now has new parameter `classes` that can be set in the profile on each way.
- Profiles: - Profiles:
- `result.exits` allows you to set a way's exit numbers and names, see [`junction:ref`](http://wiki.openstreetmap.org/wiki/Proposed_features/junction_details) - `result.exits` allows you to set a way's exit numbers and names, see [`junction:ref`](http://wiki.openstreetmap.org/wiki/Proposed_features/junction_details)
- `ExtractionWay` now as new property `forward_classes` and `backward_classes` that can set in the `way_function`. - `ExtractionWay` now as new property `forward_classes` and `backward_classes` that can set in the `way_function`.
The maximum number of classes is 8. The maximum number of classes is 8.
- We now respect the `construction` tag. If the `construction` tag value is not on our whitelist (`minor`, `widening`, `no`) we will exclude the road.
- Node.js Bindings: - Node.js Bindings:
- Exposes `alternatives=Number` parameter overload in addition to the boolean flag - Exposes `alternatives=Number` parameter overload in addition to the boolean flag
- Expose `EngineConfig` options in the node bindings
- Tools: - Tools:
- Exposes engine limit on number of alternatives to generate `--max-alternatives` in `osrm-routed` (3 by default) - Exposes engine limit on number of alternatives to generate `--max-alternatives` in `osrm-routed` (3 by default)
- Infrastructure
- STXXL is not required to build OSRM and is an optional dependency for back-compatibility (ENABLE_STXXL=On)
- OpenMP is only required when the optional STXXL dependency is used
- Bug fixes:
- #4278: Remove superflous continious instruction on a motorway.
# 5.8.0 # 5.8.0
- Changes from 5.7 - Changes from 5.7

View File

@ -21,6 +21,7 @@ option(BUILD_PACKAGE "Build OSRM package" OFF)
option(ENABLE_ASSERTIONS "Use assertions in release mode" OFF) option(ENABLE_ASSERTIONS "Use assertions in release mode" OFF)
option(ENABLE_COVERAGE "Build with coverage instrumentalisation" OFF) option(ENABLE_COVERAGE "Build with coverage instrumentalisation" OFF)
option(ENABLE_SANITIZER "Use memory sanitizer for Debug build" OFF) option(ENABLE_SANITIZER "Use memory sanitizer for Debug build" OFF)
option(ENABLE_STXXL "Use STXXL library" ON)
option(ENABLE_LTO "Use LTO if available" OFF) option(ENABLE_LTO "Use LTO if available" OFF)
option(ENABLE_FUZZING "Fuzz testing using LLVM's libFuzzer" OFF) option(ENABLE_FUZZING "Fuzz testing using LLVM's libFuzzer" OFF)
option(ENABLE_GOLD_LINKER "Use GNU gold linker if available" ON) option(ENABLE_GOLD_LINKER "Use GNU gold linker if available" ON)
@ -428,9 +429,12 @@ if(ENABLE_MASON)
mason_use(boost_libsystem VERSION ${MASON_BOOST_VERSION}) mason_use(boost_libsystem VERSION ${MASON_BOOST_VERSION})
set(Boost_SYSTEM_LIBRARY ${MASON_PACKAGE_boost_libsystem_STATIC_LIBS}) set(Boost_SYSTEM_LIBRARY ${MASON_PACKAGE_boost_libsystem_STATIC_LIBS})
if (ENABLE_STXXL)
mason_use(stxxl VERSION ${MASON_STXXL_VERSION}) mason_use(stxxl VERSION ${MASON_STXXL_VERSION})
add_dependency_includes(${MASON_PACKAGE_stxxl_INCLUDE_DIRS}) add_dependency_includes(${MASON_PACKAGE_stxxl_INCLUDE_DIRS})
set(STXXL_LIBRARY ${MASON_PACKAGE_stxxl_STATIC_LIBS}) set(MAYBE_STXXL_LIBRARY ${MASON_PACKAGE_stxxl_STATIC_LIBS})
add_definitions(-DUSE_STXXL_LIBRARY)
endif()
mason_use(expat VERSION ${MASON_EXPAT_VERSION}) mason_use(expat VERSION ${MASON_EXPAT_VERSION})
add_dependency_includes(${MASON_PACKAGE_expat_INCLUDE_DIRS}) add_dependency_includes(${MASON_PACKAGE_expat_INCLUDE_DIRS})
@ -493,8 +497,16 @@ else()
find_package(EXPAT REQUIRED) find_package(EXPAT REQUIRED)
add_dependency_includes(${EXPAT_INCLUDE_DIRS}) add_dependency_includes(${EXPAT_INCLUDE_DIRS})
find_package(STXXL REQUIRED) if (ENABLE_STXXL)
find_package(STXXL)
if (STXXL_FOUND)
add_dependency_includes(${STXXL_INCLUDE_DIR}) add_dependency_includes(${STXXL_INCLUDE_DIR})
set(MAYBE_STXXL_LIBRARY ${STXXL_LIBRARY})
add_definitions(-DUSE_STXXL_LIBRARY)
else()
MESSAGE(STATUS "STXXL was requested but not found, default STL will be used")
endif()
endif()
find_package(BZip2 REQUIRED) find_package(BZip2 REQUIRED)
add_dependency_includes(${BZIP2_INCLUDE_DIR}) add_dependency_includes(${BZIP2_INCLUDE_DIR})
@ -578,12 +590,14 @@ add_dependency_defines(-DBOOST_SPIRIT_USE_PHOENIX_V3)
add_dependency_defines(-DBOOST_RESULT_OF_USE_DECLTYPE) add_dependency_defines(-DBOOST_RESULT_OF_USE_DECLTYPE)
add_dependency_defines(-DBOOST_FILESYSTEM_NO_DEPRECATED) add_dependency_defines(-DBOOST_FILESYSTEM_NO_DEPRECATED)
if (ENABLE_STXXL)
set(OpenMP_FIND_QUIETLY ON) set(OpenMP_FIND_QUIETLY ON)
find_package(OpenMP) find_package(OpenMP)
if(OPENMP_FOUND) if(OPENMP_FOUND)
message(STATUS "OpenMP support found. Linking just in case for stxxl") message(STATUS "OpenMP support found. Linking just in case for stxxl")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif() endif()
endif()
add_definitions(${OSRM_DEFINES}) add_definitions(${OSRM_DEFINES})
include_directories(SYSTEM ${DEPENDENCIES_INCLUDE_DIRS}) include_directories(SYSTEM ${DEPENDENCIES_INCLUDE_DIRS})
@ -617,7 +631,7 @@ set(EXTRACTOR_LIBRARIES
${EXPAT_LIBRARIES} ${EXPAT_LIBRARIES}
${USED_LUA_LIBRARIES} ${USED_LUA_LIBRARIES}
${OSMIUM_LIBRARIES} ${OSMIUM_LIBRARIES}
${STXXL_LIBRARY} ${MAYBE_STXXL_LIBRARY}
${TBB_LIBRARIES} ${TBB_LIBRARIES}
${ZLIB_LIBRARY} ${ZLIB_LIBRARY}
${MAYBE_COVERAGE_LIBRARIES}) ${MAYBE_COVERAGE_LIBRARIES})
@ -645,7 +659,7 @@ set(CONTRACTOR_LIBRARIES
${BOOST_BASE_LIBRARIES} ${BOOST_BASE_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT} ${CMAKE_THREAD_LIBS_INIT}
${USED_LUA_LIBRARIES} ${USED_LUA_LIBRARIES}
${STXXL_LIBRARY} ${MAYBE_STXXL_LIBRARY}
${TBB_LIBRARIES} ${TBB_LIBRARIES}
${MAYBE_RT_LIBRARY} ${MAYBE_RT_LIBRARY}
${MAYBE_COVERAGE_LIBRARIES}) ${MAYBE_COVERAGE_LIBRARIES})
@ -665,7 +679,7 @@ set(STORAGE_LIBRARIES
set(UTIL_LIBRARIES set(UTIL_LIBRARIES
${BOOST_BASE_LIBRARIES} ${BOOST_BASE_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT} ${CMAKE_THREAD_LIBS_INIT}
${STXXL_LIBRARY} ${MAYBE_STXXL_LIBRARY}
${TBB_LIBRARIES} ${TBB_LIBRARIES}
${MAYBE_COVERAGE_LIBRARIES}) ${MAYBE_COVERAGE_LIBRARIES})
@ -734,12 +748,14 @@ install(FILES ${ParametersGlob} DESTINATION include/osrm/engine/api)
install(FILES ${VariantGlob} DESTINATION include/mapbox) install(FILES ${VariantGlob} DESTINATION include/mapbox)
install(TARGETS osrm-extract DESTINATION bin) install(TARGETS osrm-extract DESTINATION bin)
install(TARGETS osrm-partition DESTINATION bin) install(TARGETS osrm-partition DESTINATION bin)
install(TARGETS osrm-customize DESTINATION bin)
install(TARGETS osrm-contract DESTINATION bin) install(TARGETS osrm-contract DESTINATION bin)
install(TARGETS osrm-datastore DESTINATION bin) install(TARGETS osrm-datastore DESTINATION bin)
install(TARGETS osrm-routed DESTINATION bin) install(TARGETS osrm-routed DESTINATION bin)
install(TARGETS osrm DESTINATION lib) install(TARGETS osrm DESTINATION lib)
install(TARGETS osrm_extract DESTINATION lib) install(TARGETS osrm_extract DESTINATION lib)
install(TARGETS osrm_partition DESTINATION lib) install(TARGETS osrm_partition DESTINATION lib)
install(TARGETS osrm_customize DESTINATION lib)
install(TARGETS osrm_update DESTINATION lib) install(TARGETS osrm_update DESTINATION lib)
install(TARGETS osrm_contract DESTINATION lib) install(TARGETS osrm_contract DESTINATION lib)
install(TARGETS osrm_store DESTINATION lib) install(TARGETS osrm_store DESTINATION lib)

View File

@ -583,7 +583,6 @@ step.
- `destinations`: The destinations of the way. Will be `undefined` if there are no destinations. - `destinations`: The destinations of the way. Will be `undefined` if there are no destinations.
- `exits`: The exit numbers or names of the way. Will be `undefined` if there are no exit numbers or names. - `exits`: The exit numbers or names of the way. Will be `undefined` if there are no exit numbers or names.
- `mode`: A string signifying the mode of transportation. - `mode`: A string signifying the mode of transportation.
- `classes`: An array of strings signifying the classes of the road as specified in the profile.
- `maneuver`: A `StepManeuver` object representing the maneuver. - `maneuver`: A `StepManeuver` object representing the maneuver.
- `intersections`: A list of `Intersection` objects that are passed along the segment, the very first belonging to the StepManeuver - `intersections`: A list of `Intersection` objects that are passed along the segment, the very first belonging to the StepManeuver
- `rotary_name`: The name for the rotary. Optionally included, if the step is a rotary and a rotary name is available. - `rotary_name`: The name for the rotary. Optionally included, if the step is a rotary and a rotary name is available.
@ -597,7 +596,6 @@ step.
"mode" : "driving", "mode" : "driving",
"duration" : 15.6, "duration" : 15.6,
"weight" : 15.6, "weight" : 15.6,
"classes": ["toll", "restricted"],
"intersections" : [ "intersections" : [
{ "bearings" : [ 10, 92, 184, 270 ], { "bearings" : [ 10, 92, 184, 270 ],
"lanes" : [ "lanes" : [
@ -735,6 +733,7 @@ location of the StepManeuver. Further intersections are listed for every cross-w
- `location`: A `[longitude, latitude]` pair describing the location of the turn. - `location`: A `[longitude, latitude]` pair describing the location of the turn.
- `bearings`: A list of bearing values (e.g. [0,90,180,270]) that are available at the intersection. The bearings describe all available roads at the intersection. Values are between 0-359 (0=true north) - `bearings`: A list of bearing values (e.g. [0,90,180,270]) that are available at the intersection. The bearings describe all available roads at the intersection. Values are between 0-359 (0=true north)
- `classes`: An array of strings signifying the classes (as specified in the profile) of the road exiting the intersection.
- `entry`: A list of entry flags, corresponding in a 1:1 relationship to the bearings. A value of `true` indicates that the respective road could be entered on a valid route. - `entry`: A list of entry flags, corresponding in a 1:1 relationship to the bearings. A value of `true` indicates that the respective road could be entered on a valid route.
`false` indicates that the turn onto the respective road would violate a restriction. `false` indicates that the turn onto the respective road would violate a restriction.
- `in`: index into bearings/entry array. Used to calculate the bearing just before the turn. Namely, the clockwise angle from true north to the - `in`: index into bearings/entry array. Used to calculate the bearing just before the turn. Namely, the clockwise angle from true north to the
@ -753,6 +752,7 @@ location of the StepManeuver. Further intersections are listed for every cross-w
"out":2, "out":2,
"bearings":[60,150,240,330], "bearings":[60,150,240,330],
"entry":["false","true","true","true"], "entry":["false","true","true","true"],
"classes": ["toll", "restricted"],
"lanes":{ "lanes":{
"indications": ["left", "straight"], "indications": ["left", "straight"],
"valid": "false" "valid": "false"

View File

@ -18,12 +18,12 @@ Feature: Car - Mode flag
When I route I should get When I route I should get
| from | to | route | turns | classes | | from | to | route | turns | classes |
| a | d | ab,bc,cd,cd | depart,notification right,notification left,arrive | ,ferry,, | | a | d | ab,bc,cd,cd | depart,notification right,notification left,arrive | [()],[(ferry)],[()],[()] |
| d | a | cd,bc,ab,ab | depart,notification right,notification left,arrive | ,ferry,, | | d | a | cd,bc,ab,ab | depart,notification right,notification left,arrive | [()],[(ferry)],[()],[()] |
| c | a | bc,ab,ab | depart,notification left,arrive | ferry,, | | c | a | bc,ab,ab | depart,notification left,arrive | [(ferry)],[()],[()] |
| d | b | cd,bc,bc | depart,notification right,arrive | ,ferry,ferry | | d | b | cd,bc,bc | depart,notification right,arrive | [()],[(ferry)],[()] |
| a | c | ab,bc,bc | depart,notification right,arrive | ,ferry,ferry | | a | c | ab,bc,bc | depart,notification right,arrive | [()],[(ferry)],[()] |
| b | d | bc,cd,cd | depart,notification left,arrive | ferry,, | | b | d | bc,cd,cd | depart,notification left,arrive | [(ferry)],[()],[()] |
Scenario: Car - We tag motorways with a class Scenario: Car - We tag motorways with a class
@ -40,10 +40,10 @@ Feature: Car - Mode flag
| cd | primary | | cd | primary |
When I route I should get When I route I should get
| from | to | route | turns | classes | # | | from | to | route | turns | classes |
| a | d | ab,bc,cd | depart,notification right,arrive | ,motorway, | | | a | d | ab,cd | depart,arrive | [(),(motorway),()],[()] |
| a | c | ab,bc,bc | depart,notification right,arrive | ,motorway,motorway | | | a | c | ab,bc | depart,arrive | [(),(motorway)],[()] |
| b | d | bc,cd | depart,arrive | motorway, | we don't announce when we leave the highway | | b | d | bc,cd | depart,arrive | [(motorway),()],[()] |
Scenario: Car - We tag motorway_link with a class Scenario: Car - We tag motorway_link with a class
Given the node map Given the node map
@ -60,9 +60,9 @@ Feature: Car - Mode flag
When I route I should get When I route I should get
| from | to | route | turns | classes | # | | from | to | route | turns | classes | # |
| a | d | ab,bc,cd | depart,on ramp right,arrive | ,motorway, | notification replaced by on-ramp | | a | d | ab,bc,cd | depart,on ramp right,arrive | [()],[(motorway),()],[()] | on-ramp at class change |
| a | c | ab,bc,bc | depart,on ramp right,arrive | ,motorway,motorway | " " | | a | c | ab,bc,bc | depart,on ramp right,arrive | [()],[(motorway)],[()] | " " |
| b | d | bc,cd | depart,arrive | motorway, | no announcement | | b | d | bc,cd | depart,arrive | [(motorway),()],[()] | no announcement |
Scenario: Car - We tag restricted with a class Scenario: Car - We tag restricted with a class
@ -80,7 +80,7 @@ Feature: Car - Mode flag
When I route I should get When I route I should get
| from | to | route | turns | classes | | from | to | route | turns | classes |
| a | d | ab,bc,cd | depart,notification right,arrive| restricted,motorway;restricted, | | a | d | ab,cd | depart,arrive| [(restricted),(motorway,restricted),()],[()] |
Scenario: Car - We toll restricted with a class Scenario: Car - We toll restricted with a class
Given the node map Given the node map
@ -97,5 +97,31 @@ Feature: Car - Mode flag
When I route I should get When I route I should get
| from | to | route | turns | classes | | from | to | route | turns | classes |
| a | d | ab,bc,cd | depart,notification right,arrive | toll,motorway;toll, | | a | d | ab,cd | depart,arrive | [(toll),(motorway,toll),()],[()] |
Scenario: Car - From roundabout on toll road
Given the node map
"""
c
/ \
a---b d---f
\ /
e
|
g
"""
And the ways
| nodes | oneway | highway | junction | toll |
| ab | yes | primary | | |
| cb | yes | primary | roundabout | |
| dc | yes | primary | roundabout | |
| be | yes | primary | roundabout | |
| ed | yes | motorway| roundabout | |
| eg | yes | primary | | |
| df | yes | motorway| | yes |
When I route I should get
| from | to | route | turns | classes |
| a | f | ab,df,df | depart,roundabout-exit-2,arrive | [()],[(),(motorway),(toll,motorway)],[()] |

View File

@ -0,0 +1,17 @@
@routing @car @construction
Feature: Car - all construction tags the OpenStreetMap community could think of and then some
Background:
Given the profile "car"
Scenario: Various ways to tag construction and proposed roads
Then routability should be
| highway | construction | proposed | bothw |
| primary | | | x |
| construction | | | |
| proposed | | | |
| primary | yes | | |
| primary | | yes | |
| primary | no | | x |
| primary | widening | | x |
| primary | minor | | x |

View File

@ -23,11 +23,11 @@ Feature: Car - Destination only, no passing through
When I route I should get When I route I should get
| from | to | route | | from | to | route |
| a | b | ab,ab | | a | b | ab,ab |
| a | c | ab,bcd,bcd | | a | c | ab,bcd |
| a | d | ab,bcd,bcd | | a | d | ab,bcd,bcd |
| a | e | axye,axye | | a | e | axye,axye |
| e | d | de,de | | e | d | de,de |
| e | c | de,bcd,bcd | | e | c | de,bcd |
| e | b | de,bcd,bcd | | e | b | de,bcd,bcd |
| e | a | axye,axye | | e | a | axye,axye |
@ -51,12 +51,12 @@ Feature: Car - Destination only, no passing through
When I route I should get When I route I should get
| from | to | route | | from | to | route |
| a | b | ab,ab | | a | b | ab,ab |
| a | c | ab,bc,bc | | a | c | ab,bc |
| a | d | ab,bc,cd | | a | d | ab,cd |
| a | e | axye,axye | | a | e | axye,axye |
| e | d | de,de | | e | d | de,de |
| e | c | de,cd,cd | | e | c | de,cd |
| e | b | de,cd,bc | | e | b | de,bc |
| e | a | axye,axye | | e | a | axye,axye |
Scenario: Car - Routing inside a destination only area Scenario: Car - Routing inside a destination only area

View File

@ -261,3 +261,23 @@ Feature: Motorway Guidance
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,d | On,Hwy,Off,Off | depart,merge slight right,off ramp right,arrive | | a,d | On,Hwy,Off,Off | depart,merge slight right,off ramp right,arrive |
#http://0.0.0.0:9966/?z=18&center=38.893323%2C-77.055117&loc=38.893551%2C-77.054833&loc=38.893112%2C-77.055536&hl=en&alt=0
Scenario: Merging with same name
Given the node map
"""
a - - -
> c - d
b
"""
And the ways
| nodes | name | ref | highway | oneway |
| ac | | US 50 | motorway | yes |
| bc | | I 66 | motorway | yes |
| cd | | US 50; I 66 | motorway | yes |
When I route I should get
| waypoints | route | turns |
| a,d | , | depart,arrive |
| b,d | , | depart,arrive |

View File

@ -261,7 +261,7 @@ module.exports = function () {
}; };
this.classesList = (instructions) => { this.classesList = (instructions) => {
return this.extractInstructionList(instructions, s => s.classes ? s.classes.join(';') : ''); return this.extractInstructionList(instructions, s => '[' + s.intersections.map(i => '(' + (i.classes ? i.classes.join(',') : '') + ')').join(',') + ']');
}; };
this.timeList = (instructions) => { this.timeList = (instructions) => {

View File

@ -14,8 +14,6 @@
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <stxxl/vector>
#include <tbb/enumerable_thread_specific.h> #include <tbb/enumerable_thread_specific.h>
#include <tbb/parallel_for.h> #include <tbb/parallel_for.h>
#include <tbb/parallel_sort.h> #include <tbb/parallel_sort.h>
@ -25,6 +23,10 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#if USE_STXXL_LIBRARY
#include <stxxl/vector>
#endif
namespace osrm namespace osrm
{ {
namespace contractor namespace contractor
@ -33,6 +35,12 @@ namespace contractor
class GraphContractor class GraphContractor
{ {
private: private:
#if USE_STXXL_LIBRARY
template <typename T> using ExternalVector = stxxl::vector<T>;
#else
template <typename T> using ExternalVector = std::vector<T>;
#endif
struct ContractorThreadData struct ContractorThreadData
{ {
ContractorDijkstra dijkstra; ContractorDijkstra dijkstra;
@ -401,7 +409,7 @@ class GraphContractor
bool Bias(const NodeID a, const NodeID b) const; bool Bias(const NodeID a, const NodeID b) const;
std::shared_ptr<ContractorGraph> contractor_graph; std::shared_ptr<ContractorGraph> contractor_graph;
stxxl::vector<QueryEdge> external_edge_list; ExternalVector<QueryEdge> external_edge_list;
std::vector<NodeID> orig_node_id_from_new_node_id_map; std::vector<NodeID> orig_node_id_from_new_node_id_map;
std::vector<float> node_levels; std::vector<float> node_levels;

View File

@ -63,7 +63,6 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
: target_node.forward_segment_id.id; : target_node.forward_segment_id.id;
const auto target_name_id = facade.GetNameIndex(target_node_id); const auto target_name_id = facade.GetNameIndex(target_node_id);
const auto target_mode = facade.GetTravelMode(target_node_id); const auto target_mode = facade.GetTravelMode(target_node_id);
auto target_classes = facade.GetClasses(facade.GetClassData(target_node_id));
const auto number_of_segments = leg_geometry.GetNumberOfSegments(); const auto number_of_segments = leg_geometry.GetNumberOfSegments();
@ -88,7 +87,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
IntermediateIntersection::NO_INDEX, IntermediateIntersection::NO_INDEX,
0, 0,
util::guidance::LaneTuple(), util::guidance::LaneTuple(),
{}}; {},
source_classes};
if (leg_data.size() > 0) if (leg_data.size() > 0)
{ {
@ -118,7 +118,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
const auto destinations = facade.GetDestinationsForID(step_name_id); const auto destinations = facade.GetDestinationsForID(step_name_id);
const auto exits = facade.GetExitsForID(step_name_id); const auto exits = facade.GetExitsForID(step_name_id);
const auto distance = leg_geometry.segment_distances[segment_index]; const auto distance = leg_geometry.segment_distances[segment_index];
auto classes = facade.GetClasses(path_point.classes); // intersections contain the classes of exiting road
intersection.classes = facade.GetClasses(path_point.classes);
steps.push_back(RouteStep{step_name_id, steps.push_back(RouteStep{step_name_id,
name.to_string(), name.to_string(),
@ -135,8 +136,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
maneuver, maneuver,
leg_geometry.FrontIndex(segment_index), leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1, leg_geometry.BackIndex(segment_index) + 1,
{intersection}, {intersection}});
std::move(classes)});
if (leg_data_index + 1 < leg_data.size()) if (leg_data_index + 1 < leg_data.size())
{ {
@ -196,6 +196,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
const auto distance = leg_geometry.segment_distances[segment_index]; const auto distance = leg_geometry.segment_distances[segment_index];
const EdgeWeight duration = segment_duration + target_duration; const EdgeWeight duration = segment_duration + target_duration;
const EdgeWeight weight = segment_weight + target_weight; const EdgeWeight weight = segment_weight + target_weight;
// intersections contain the classes of exiting road
intersection.classes = facade.GetClasses(facade.GetClassData(target_node_id));
BOOST_ASSERT(duration >= 0); BOOST_ASSERT(duration >= 0);
steps.push_back(RouteStep{step_name_id, steps.push_back(RouteStep{step_name_id,
facade.GetNameForID(step_name_id).to_string(), facade.GetNameForID(step_name_id).to_string(),
@ -212,8 +214,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
maneuver, maneuver,
leg_geometry.FrontIndex(segment_index), leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1, leg_geometry.BackIndex(segment_index) + 1,
{intersection}, {intersection}});
std::move(target_classes)});
} }
// In this case the source + target are on the same edge segment // In this case the source + target are on the same edge segment
else else
@ -255,8 +256,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
std::move(maneuver), std::move(maneuver),
leg_geometry.FrontIndex(segment_index), leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1, leg_geometry.BackIndex(segment_index) + 1,
{intersection}, {intersection}});
std::move(source_classes)});
} }
BOOST_ASSERT(segment_index == number_of_segments - 1); BOOST_ASSERT(segment_index == number_of_segments - 1);
@ -269,6 +269,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
0, 0,
IntermediateIntersection::NO_INDEX, IntermediateIntersection::NO_INDEX,
util::guidance::LaneTuple(), util::guidance::LaneTuple(),
{},
{}}; {}};
// This step has length zero, the only reason we need it is the target location // This step has length zero, the only reason we need it is the target location
@ -295,8 +296,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
std::move(maneuver), std::move(maneuver),
leg_geometry.locations.size() - 1, leg_geometry.locations.size() - 1,
leg_geometry.locations.size(), leg_geometry.locations.size(),
{intersection}, {intersection}});
std::move(target_classes)});
BOOST_ASSERT(steps.front().intersections.size() == 1); BOOST_ASSERT(steps.front().intersections.size() == 1);
BOOST_ASSERT(steps.front().intersections.front().bearings.size() == 1); BOOST_ASSERT(steps.front().intersections.front().bearings.size() == 1);

View File

@ -42,6 +42,7 @@ struct IntermediateIntersection
// turn lane information // turn lane information
util::guidance::LaneTuple lanes; util::guidance::LaneTuple lanes;
extractor::guidance::TurnLaneDescription lane_description; extractor::guidance::TurnLaneDescription lane_description;
std::vector<std::string> classes;
}; };
inline IntermediateIntersection getInvalidIntersection() inline IntermediateIntersection getInvalidIntersection()
@ -52,6 +53,7 @@ inline IntermediateIntersection getInvalidIntersection()
IntermediateIntersection::NO_INDEX, IntermediateIntersection::NO_INDEX,
IntermediateIntersection::NO_INDEX, IntermediateIntersection::NO_INDEX,
util::guidance::LaneTuple(), util::guidance::LaneTuple(),
{},
{}}; {}};
} }
@ -74,7 +76,6 @@ struct RouteStep
std::size_t geometry_begin; std::size_t geometry_begin;
std::size_t geometry_end; std::size_t geometry_end;
std::vector<IntermediateIntersection> intersections; std::vector<IntermediateIntersection> intersections;
std::vector<std::string> classes;
// remove all information from the route step, marking it as invalid (used to indicate empty // remove all information from the route step, marking it as invalid (used to indicate empty
// steps to be removed). // steps to be removed).
@ -128,7 +129,6 @@ inline void RouteStep::Invalidate()
geometry_end = 0; geometry_end = 0;
intersections.clear(); intersections.clear();
intersections.push_back(getInvalidIntersection()); intersections.push_back(getInvalidIntersection());
classes.clear();
} }
// Elongate by another step in front // Elongate by another step in front

View File

@ -10,31 +10,19 @@
#include "storage/io.hpp" #include "storage/io.hpp"
#include <cstdint>
#include <stxxl/vector>
#include <unordered_map>
namespace osrm namespace osrm
{ {
namespace extractor namespace extractor
{ {
/** /**
* Uses external memory containers from stxxl to store all the data that * Uses memory containers to store all the data that
* is collected by the extractor callbacks. * is collected by the extractor callbacks.
* *
* The data is the filtered, aggregated and finally written to disk. * The data is the filtered, aggregated and finally written to disk.
*/ */
class ExtractionContainers class ExtractionContainers
{ {
#ifndef _MSC_VER
constexpr static unsigned stxxl_memory =
((sizeof(std::size_t) == 4) ? std::numeric_limits<int>::max()
: std::numeric_limits<unsigned>::max());
#else
const static unsigned stxxl_memory = ((sizeof(std::size_t) == 4) ? INT_MAX : UINT_MAX);
#endif
void FlushVectors();
void PrepareNodes(); void PrepareNodes();
void PrepareRestrictions(); void PrepareRestrictions();
void PrepareEdges(ScriptingEnvironment &scripting_environment); void PrepareEdges(ScriptingEnvironment &scripting_environment);
@ -45,25 +33,24 @@ class ExtractionContainers
void WriteCharData(const std::string &file_name); void WriteCharData(const std::string &file_name);
public: public:
using STXXLNodeIDVector = stxxl::vector<OSMNodeID>; using NodeIDVector = std::vector<OSMNodeID>;
using STXXLNodeVector = stxxl::vector<QueryNode>; using NodeVector = std::vector<QueryNode>;
using STXXLEdgeVector = stxxl::vector<InternalExtractorEdge>; using EdgeVector = std::vector<InternalExtractorEdge>;
using RestrictionsVector = std::vector<InputRestrictionContainer>; using RestrictionsVector = std::vector<InputRestrictionContainer>;
using STXXLWayIDStartEndVector = stxxl::vector<FirstAndLastSegmentOfWay>; using WayIDStartEndVector = std::vector<FirstAndLastSegmentOfWay>;
using STXXLNameCharData = stxxl::vector<unsigned char>; using NameCharData = std::vector<unsigned char>;
using STXXLNameOffsets = stxxl::vector<unsigned>; using NameOffsets = std::vector<unsigned>;
std::vector<OSMNodeID> barrier_nodes; std::vector<OSMNodeID> barrier_nodes;
std::vector<OSMNodeID> traffic_lights; std::vector<OSMNodeID> traffic_lights;
STXXLNodeIDVector used_node_id_list; NodeIDVector used_node_id_list;
STXXLNodeVector all_nodes_list; NodeVector all_nodes_list;
STXXLEdgeVector all_edges_list; EdgeVector all_edges_list;
STXXLNameCharData name_char_data; NameCharData name_char_data;
STXXLNameOffsets name_offsets; NameOffsets name_offsets;
// an adjacency array containing all turn lane masks // an adjacency array containing all turn lane masks
RestrictionsVector restrictions_list; RestrictionsVector restrictions_list;
STXXLWayIDStartEndVector way_start_end_id_list; WayIDStartEndVector way_start_end_id_list;
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; std::vector<TurnRestriction> unconditional_turn_restrictions;

View File

@ -43,7 +43,7 @@ struct FirstAndLastSegmentOfWay
} }
}; };
struct FirstAndLastSegmentOfWayStxxlCompare struct FirstAndLastSegmentOfWayCompare
{ {
using value_type = FirstAndLastSegmentOfWay; using value_type = FirstAndLastSegmentOfWay;
bool operator()(const FirstAndLastSegmentOfWay &a, const FirstAndLastSegmentOfWay &b) const bool operator()(const FirstAndLastSegmentOfWay &a, const FirstAndLastSegmentOfWay &b) const

View File

@ -176,6 +176,64 @@ inline engine_config_ptr argumentsToEngineConfig(const Nan::FunctionCallbackInfo
return engine_config_ptr(); return engine_config_ptr();
} }
// Set EngineConfig system-wide limits on construction, if requested
auto max_locations_trip = params->Get(Nan::New("max_locations_trip").ToLocalChecked());
auto max_locations_viaroute = params->Get(Nan::New("max_locations_viaroute").ToLocalChecked());
auto max_locations_distance_table =
params->Get(Nan::New("max_locations_distance_table").ToLocalChecked());
auto max_locations_map_matching =
params->Get(Nan::New("max_locations_map_matching").ToLocalChecked());
auto max_results_nearest = params->Get(Nan::New("max_results_nearest").ToLocalChecked());
auto max_alternatives = params->Get(Nan::New("max_alternatives").ToLocalChecked());
if (!max_locations_trip->IsUndefined() && !max_locations_trip->IsNumber())
{
Nan::ThrowError("max_locations_trip must be an integral number");
return engine_config_ptr();
}
if (!max_locations_viaroute->IsUndefined() && !max_locations_viaroute->IsNumber())
{
Nan::ThrowError("max_locations_viaroute must be an integral number");
return engine_config_ptr();
}
if (!max_locations_distance_table->IsUndefined() && !max_locations_distance_table->IsNumber())
{
Nan::ThrowError("max_locations_distance_table must be an integral number");
return engine_config_ptr();
}
if (!max_locations_map_matching->IsUndefined() && !max_locations_map_matching->IsNumber())
{
Nan::ThrowError("max_locations_map_matching must be an integral number");
return engine_config_ptr();
}
if (!max_results_nearest->IsUndefined() && !max_results_nearest->IsNumber())
{
Nan::ThrowError("max_results_nearest must be an integral number");
return engine_config_ptr();
}
if (!max_alternatives->IsUndefined() && !max_alternatives->IsNumber())
{
Nan::ThrowError("max_alternatives must be an integral number");
return engine_config_ptr();
}
if (max_locations_trip->IsNumber())
engine_config->max_locations_trip = static_cast<int>(max_locations_trip->NumberValue());
if (max_locations_viaroute->IsNumber())
engine_config->max_locations_viaroute =
static_cast<int>(max_locations_viaroute->NumberValue());
if (max_locations_distance_table->IsNumber())
engine_config->max_locations_distance_table =
static_cast<int>(max_locations_distance_table->NumberValue());
if (max_locations_map_matching->IsNumber())
engine_config->max_locations_map_matching =
static_cast<int>(max_locations_map_matching->NumberValue());
if (max_results_nearest->IsNumber())
engine_config->max_results_nearest = static_cast<int>(max_results_nearest->NumberValue());
if (max_alternatives->IsNumber())
engine_config->max_alternatives = static_cast<int>(max_alternatives->NumberValue());
return engine_config; return engine_config;
} }
@ -721,7 +779,7 @@ argumentsToRouteParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
if (value->IsBoolean()) if (value->IsBoolean())
{ {
params->alternatives = value->BooleanValue(); params->alternatives = value->BooleanValue();
params->number_of_alternatives = 1u; params->number_of_alternatives = value->BooleanValue() ? 1u : 0u;
} }
else if (value->IsNumber()) else if (value->IsNumber())
{ {

View File

@ -7,8 +7,13 @@
#include "storage/io.hpp" #include "storage/io.hpp"
#include <cmath>
#include <cstdint> #include <cstdint>
#if USE_STXXL_LIBRARY
#include <stxxl/vector>
#endif
namespace osrm namespace osrm
{ {
namespace storage namespace storage
@ -58,6 +63,7 @@ inline void write(storage::io::FileWriter &writer, const util::DeallocatingVecto
writer.WriteFrom(vec.bucket_list.back(), last_block_size); writer.WriteFrom(vec.bucket_list.back(), last_block_size);
} }
#if USE_STXXL_LIBRARY
template <typename T> inline void read(storage::io::FileReader &reader, stxxl::vector<T> &vec) template <typename T> inline void read(storage::io::FileReader &reader, stxxl::vector<T> &vec)
{ {
auto size = reader.ReadOne<std::uint64_t>(); auto size = reader.ReadOne<std::uint64_t>();
@ -78,6 +84,7 @@ inline void write(storage::io::FileWriter &writer, const stxxl::vector<T> &vec)
writer.WriteOne<T>(vec[idx]); writer.WriteOne<T>(vec[idx]);
} }
} }
#endif
template <typename T> void read(io::FileReader &reader, std::vector<T> &data) template <typename T> void read(io::FileReader &reader, std::vector<T> &data)
{ {

View File

@ -3,11 +3,14 @@
#include "util/log.hpp" #include "util/log.hpp"
#include <stxxl/mng>
#ifndef _WIN32 #ifndef _WIN32
#include <sys/resource.h> #include <sys/resource.h>
#endif #endif
#if USE_STXXL_LIBRARY
#include <stxxl/mng>
#endif
namespace osrm namespace osrm
{ {
namespace util namespace util
@ -15,6 +18,7 @@ namespace util
inline void DumpSTXXLStats() inline void DumpSTXXLStats()
{ {
#if USE_STXXL_LIBRARY
#if STXXL_VERSION_MAJOR > 1 || (STXXL_VERSION_MAJOR == 1 && STXXL_VERSION_MINOR >= 4) #if STXXL_VERSION_MAJOR > 1 || (STXXL_VERSION_MAJOR == 1 && STXXL_VERSION_MINOR >= 4)
auto manager = stxxl::block_manager::get_instance(); auto manager = stxxl::block_manager::get_instance();
util::Log() << "STXXL: peak bytes used: " << manager->get_maximum_allocation(); util::Log() << "STXXL: peak bytes used: " << manager->get_maximum_allocation();
@ -23,6 +27,7 @@ inline void DumpSTXXLStats()
#warning STXXL 1.4+ recommended - STXXL memory summary will not be available #warning STXXL 1.4+ recommended - STXXL memory summary will not be available
util::Log() << "STXXL: memory summary not available, needs STXXL 1.4 or higher"; util::Log() << "STXXL: memory summary not available, needs STXXL 1.4 or higher";
#endif #endif
#endif
} }
inline void DumpMemoryStats() inline void DumpMemoryStats()

View File

@ -6,8 +6,6 @@
#include "storage/shared_memory_ownership.hpp" #include "storage/shared_memory_ownership.hpp"
#include <stxxl/vector>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/iterator/iterator_facade.hpp> #include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/reverse_iterator.hpp> #include <boost/iterator/reverse_iterator.hpp>
@ -21,6 +19,10 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#if USE_STXXL_LIBRARY
#include <stxxl/vector>
#endif
namespace osrm namespace osrm
{ {
namespace util namespace util
@ -209,10 +211,16 @@ template <typename DataT> void swap(vector_view<DataT> &lhs, vector_view<DataT>
std::swap(lhs.m_size, rhs.m_size); std::swap(lhs.m_size, rhs.m_size);
} }
#if USE_STXXL_LIBRARY
template <typename T> using ExternalVector = stxxl::vector<T>;
#else
template <typename T> using ExternalVector = std::vector<T>;
#endif
template <typename DataT, storage::Ownership Ownership> template <typename DataT, storage::Ownership Ownership>
using InternalOrExternalVector = using InternalOrExternalVector =
typename std::conditional<Ownership == storage::Ownership::External, typename std::conditional<Ownership == storage::Ownership::External,
stxxl::vector<DataT>, ExternalVector<DataT>,
std::vector<DataT>>::type; std::vector<DataT>>::type;
template <typename DataT, storage::Ownership Ownership> template <typename DataT, storage::Ownership Ownership>

View File

@ -1,6 +1,6 @@
{ {
"name": "osrm", "name": "osrm",
"version": "5.9.0-latest.1", "version": "5.9.0",
"private": false, "private": false,
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.", "description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.",
"dependencies": { "dependencies": {

View File

@ -72,6 +72,12 @@ local profile = {
restricted_highway_whitelist = Set { }, restricted_highway_whitelist = Set { },
construction_whitelist = Set {
'no',
'widening',
'minor',
},
access_tags_hierarchy = Sequence { access_tags_hierarchy = Sequence {
'bicycle', 'bicycle',
'vehicle', 'vehicle',
@ -189,7 +195,8 @@ local profile = {
avoid = Set { avoid = Set {
'impassable', 'impassable',
'construction' 'construction',
'proposed'
} }
} }

View File

@ -94,6 +94,13 @@ local profile = {
'access' 'access'
}, },
construction_whitelist = Set {
'no',
'widening',
'minor',
},
service_tag_forbidden = Set { service_tag_forbidden = Set {
'emergency_access' 'emergency_access'
}, },
@ -110,7 +117,9 @@ local profile = {
'reversible', 'reversible',
'impassable', 'impassable',
'hov_lanes', 'hov_lanes',
'steps' 'steps',
'construction',
'proposed'
}, },
speeds = Sequence { speeds = Sequence {

View File

@ -61,6 +61,8 @@ local profile = {
restricted_highway_whitelist = Set { }, restricted_highway_whitelist = Set { },
construction_whitelist = Set {},
access_tags_hierarchy = Sequence { access_tags_hierarchy = Sequence {
'foot', 'foot',
'access' 'access'
@ -76,7 +78,9 @@ local profile = {
}, },
avoid = Set { avoid = Set {
'impassable' 'impassable',
'construction',
'proposed'
}, },
speeds = Sequence { speeds = Sequence {

View File

@ -48,7 +48,7 @@ function Handlers.handle_names(way,result,data,profile)
end end
if exits then if exits then
result.exits = exits result.exits = canonicalizeStringList(exits, ";")
end end
end end
@ -513,6 +513,25 @@ function Handlers.handle_blocked_ways(way,result,data,profile)
return false return false
end end
-- In addition to the highway=construction tag above handle the construction=* tag
-- http://wiki.openstreetmap.org/wiki/Key:construction
-- https://taginfo.openstreetmap.org/keys/construction#values
if profile.avoid.construction then
local construction = way:get_value_by_key('construction')
-- Of course there are negative tags to handle, too
if construction and not profile.construction_whitelist[construction] then
return false
end
end
-- Not only are there multiple construction tags there is also a proposed=* tag.
-- http://wiki.openstreetmap.org/wiki/Key:proposed
-- https://taginfo.openstreetmap.org/keys/proposed#values
if profile.avoid.proposed and way:get_value_by_key('proposed') then
return false
end
-- Reversible oneways change direction with low frequency (think twice a day): -- Reversible oneways change direction with low frequency (think twice a day):
-- do not route over these at all at the moment because of time dependence. -- do not route over these at all at the moment because of time dependence.
-- Note: alternating (high frequency) oneways are handled below with penalty. -- Note: alternating (high frequency) oneways are handled below with penalty.

View File

@ -234,6 +234,18 @@ util::json::Object makeIntersection(const guidance::IntermediateIntersection &in
if (detail::hasValidLanes(intersection)) if (detail::hasValidLanes(intersection))
result.values["lanes"] = detail::lanesFromIntersection(intersection); result.values["lanes"] = detail::lanesFromIntersection(intersection);
if (!intersection.classes.empty())
{
util::json::Array classes;
classes.values.reserve(intersection.classes.size());
std::transform(
intersection.classes.begin(),
intersection.classes.end(),
std::back_inserter(classes.values),
[](const std::string &class_name) { return util::json::String{class_name}; });
result.values["classes"] = std::move(classes);
}
return result; return result;
} }
@ -265,18 +277,6 @@ util::json::Object makeRouteStep(guidance::RouteStep step, util::json::Value geo
route_step.values["maneuver"] = makeStepManeuver(std::move(step.maneuver)); route_step.values["maneuver"] = makeStepManeuver(std::move(step.maneuver));
route_step.values["geometry"] = std::move(geometry); route_step.values["geometry"] = std::move(geometry);
if (!step.classes.empty())
{
util::json::Array classes;
classes.values.reserve(step.classes.size());
std::transform(
step.classes.begin(),
step.classes.end(),
std::back_inserter(classes.values),
[](const std::string &class_name) { return util::json::String{class_name}; });
route_step.values["classes"] = std::move(classes);
}
util::json::Array intersections; util::json::Array intersections;
intersections.values.reserve(step.intersections.size()); intersections.values.reserve(step.intersections.size());
std::transform(step.intersections.begin(), std::transform(step.intersections.begin(),

View File

@ -486,7 +486,6 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
auto &new_next_to_last = *(steps.end() - 2); auto &new_next_to_last = *(steps.end() - 2);
next_to_last_step.AdaptStepSignage(new_next_to_last); next_to_last_step.AdaptStepSignage(new_next_to_last);
next_to_last_step.mode = new_next_to_last.mode; next_to_last_step.mode = new_next_to_last.mode;
next_to_last_step.classes = new_next_to_last.classes;
// the geometry indices of the last step are already correct; // the geometry indices of the last step are already correct;
} }
else if (util::coordinate_calculation::haversineDistance( else if (util::coordinate_calculation::haversineDistance(

View File

@ -21,7 +21,7 @@
#include <boost/numeric/conversion/cast.hpp> #include <boost/numeric/conversion/cast.hpp>
#include <boost/ref.hpp> #include <boost/ref.hpp>
#include <stxxl/sort> #include <tbb/parallel_sort.h>
#include <chrono> #include <chrono>
#include <limits> #include <limits>
@ -32,16 +32,6 @@ namespace
{ {
namespace oe = osrm::extractor; namespace oe = osrm::extractor;
// Needed for STXXL comparison - STXXL requires max_value(), min_value(), so we can not use
// std::less<OSMNodeId>{}. Anonymous namespace to keep translation unit local.
struct OSMNodeIDSTXXLLess
{
using value_type = OSMNodeID;
bool operator()(const value_type left, const value_type right) const { return left < right; }
value_type max_value() { return MAX_OSM_NODEID; }
value_type min_value() { return MIN_OSM_NODEID; }
};
struct CmpEdgeByOSMStartID struct CmpEdgeByOSMStartID
{ {
using value_type = oe::InternalExtractorEdge; using value_type = oe::InternalExtractorEdge;
@ -49,9 +39,6 @@ struct CmpEdgeByOSMStartID
{ {
return lhs.result.osm_source_id < rhs.result.osm_source_id; return lhs.result.osm_source_id < rhs.result.osm_source_id;
} }
value_type max_value() { return value_type::max_osm_value(); }
value_type min_value() { return value_type::min_osm_value(); }
}; };
struct CmpEdgeByOSMTargetID struct CmpEdgeByOSMTargetID
@ -61,9 +48,6 @@ struct CmpEdgeByOSMTargetID
{ {
return lhs.result.osm_target_id < rhs.result.osm_target_id; return lhs.result.osm_target_id < rhs.result.osm_target_id;
} }
value_type max_value() { return value_type::max_osm_value(); }
value_type min_value() { return value_type::min_osm_value(); }
}; };
struct CmpEdgeByInternalSourceTargetAndName struct CmpEdgeByInternalSourceTargetAndName
@ -92,22 +76,25 @@ struct CmpEdgeByInternalSourceTargetAndName
if (rhs.result.name_id == EMPTY_NAMEID) if (rhs.result.name_id == EMPTY_NAMEID)
return true; return true;
std::lock_guard<std::mutex> lock(mutex);
BOOST_ASSERT(!name_offsets.empty() && name_offsets.back() == name_data.size()); BOOST_ASSERT(!name_offsets.empty() && name_offsets.back() == name_data.size());
const oe::ExtractionContainers::STXXLNameCharData::const_iterator data = name_data.begin(); const oe::ExtractionContainers::NameCharData::const_iterator data = name_data.begin();
return std::lexicographical_compare(data + name_offsets[lhs.result.name_id], return std::lexicographical_compare(data + name_offsets[lhs.result.name_id],
data + name_offsets[lhs.result.name_id + 1], data + name_offsets[lhs.result.name_id + 1],
data + name_offsets[rhs.result.name_id], data + name_offsets[rhs.result.name_id],
data + name_offsets[rhs.result.name_id + 1]); data + name_offsets[rhs.result.name_id + 1]);
} }
value_type max_value() { return value_type::max_internal_value(); } const oe::ExtractionContainers::NameCharData &name_data;
value_type min_value() { return value_type::min_internal_value(); } const oe::ExtractionContainers::NameOffsets &name_offsets;
std::mutex &mutex;
const oe::ExtractionContainers::STXXLNameCharData &name_data;
const oe::ExtractionContainers::STXXLNameOffsets &name_offsets;
}; };
template <typename Iter>
inline NodeID mapExternalToInternalNodeID(Iter first, Iter last, const OSMNodeID value)
{
const auto it = std::lower_bound(first, last, value);
return (it == last || value < *it) ? SPECIAL_NODEID
: static_cast<NodeID>(std::distance(first, it));
}
} }
namespace osrm namespace osrm
@ -117,9 +104,6 @@ namespace extractor
ExtractionContainers::ExtractionContainers() ExtractionContainers::ExtractionContainers()
{ {
// Check if stxxl can be instantiated
stxxl::vector<unsigned> dummy_vector;
// Insert four empty strings offsets for name, ref, destination, pronunciation, and exits // Insert four empty strings offsets for name, ref, destination, pronunciation, and exits
name_offsets.push_back(0); name_offsets.push_back(0);
name_offsets.push_back(0); name_offsets.push_back(0);
@ -130,16 +114,6 @@ ExtractionContainers::ExtractionContainers()
name_offsets.push_back(0); name_offsets.push_back(0);
} }
void ExtractionContainers::FlushVectors()
{
used_node_id_list.flush();
all_nodes_list.flush();
all_edges_list.flush();
name_char_data.flush();
name_offsets.flush();
way_start_end_id_list.flush();
}
/** /**
* Processes the collected data and serializes it. * Processes the collected data and serializes it.
* At this point nodes are still referenced by their OSM id. * At this point nodes are still referenced by their OSM id.
@ -158,11 +132,11 @@ void ExtractionContainers::PrepareData(ScriptingEnvironment &scripting_environme
storage::io::FileWriter file_out(output_file_name, storage::io::FileWriter file_out(output_file_name,
storage::io::FileWriter::GenerateFingerprint); storage::io::FileWriter::GenerateFingerprint);
FlushVectors();
PrepareNodes(); PrepareNodes();
WriteNodes(file_out); WriteNodes(file_out);
PrepareEdges(scripting_environment); PrepareEdges(scripting_environment);
all_nodes_list.clear(); // free all_nodes_list before allocation of normal_edges
all_nodes_list.shrink_to_fit();
WriteEdges(file_out); WriteEdges(file_out);
PrepareRestrictions(); PrepareRestrictions();
@ -190,8 +164,7 @@ void ExtractionContainers::PrepareNodes()
util::UnbufferedLog log; util::UnbufferedLog log;
log << "Sorting used nodes ... " << std::flush; log << "Sorting used nodes ... " << std::flush;
TIMER_START(sorting_used_nodes); TIMER_START(sorting_used_nodes);
stxxl::sort( tbb::parallel_sort(used_node_id_list.begin(), used_node_id_list.end());
used_node_id_list.begin(), used_node_id_list.end(), OSMNodeIDSTXXLLess(), stxxl_memory);
TIMER_STOP(sorting_used_nodes); TIMER_STOP(sorting_used_nodes);
log << "ok, after " << TIMER_SEC(sorting_used_nodes) << "s"; log << "ok, after " << TIMER_SEC(sorting_used_nodes) << "s";
} }
@ -207,23 +180,13 @@ void ExtractionContainers::PrepareNodes()
} }
{ {
struct QueryNodeSTXXLCompare
{
using value_type = QueryNode;
value_type max_value() { return value_type::max_value(); }
value_type min_value() { return value_type::min_value(); }
bool operator()(const value_type &left, const value_type &right) const
{
return left.node_id < right.node_id;
}
};
util::UnbufferedLog log; util::UnbufferedLog log;
log << "Sorting all nodes ... " << std::flush; log << "Sorting all nodes ... " << std::flush;
TIMER_START(sorting_nodes); TIMER_START(sorting_nodes);
stxxl::sort( tbb::parallel_sort(
all_nodes_list.begin(), all_nodes_list.end(), QueryNodeSTXXLCompare(), stxxl_memory); all_nodes_list.begin(), all_nodes_list.end(), [](const auto &left, const auto &right) {
return left.node_id < right.node_id;
});
TIMER_STOP(sorting_nodes); TIMER_STOP(sorting_nodes);
log << "ok, after " << TIMER_SEC(sorting_nodes) << "s"; log << "ok, after " << TIMER_SEC(sorting_nodes) << "s";
} }
@ -232,16 +195,11 @@ void ExtractionContainers::PrepareNodes()
util::UnbufferedLog log; util::UnbufferedLog log;
log << "Building node id map ... " << std::flush; log << "Building node id map ... " << std::flush;
TIMER_START(id_map); TIMER_START(id_map);
external_to_internal_node_id_map.reserve(used_node_id_list.size());
auto node_iter = all_nodes_list.begin(); auto node_iter = all_nodes_list.begin();
auto ref_iter = used_node_id_list.begin(); auto ref_iter = used_node_id_list.begin();
auto used_nodes_iter = used_node_id_list.begin();
const auto all_nodes_list_end = all_nodes_list.end(); const auto all_nodes_list_end = all_nodes_list.end();
const auto used_node_id_list_end = used_node_id_list.end(); const auto used_node_id_list_end = used_node_id_list.end();
// Note: despite being able to handle 64 bit OSM node ids, we can't
// handle > uint32_t actual usable nodes. This should be OK for a while
// because we usually route on a *lot* less than 2^32 of the OSM
// graph nodes.
std::uint64_t internal_id = 0;
// compute the intersection of nodes that were referenced and nodes we actually have // compute the intersection of nodes that were referenced and nodes we actually have
while (node_iter != all_nodes_list_end && ref_iter != used_node_id_list_end) while (node_iter != all_nodes_list_end && ref_iter != used_node_id_list_end)
@ -257,17 +215,21 @@ void ExtractionContainers::PrepareNodes()
continue; continue;
} }
BOOST_ASSERT(node_iter->node_id == *ref_iter); BOOST_ASSERT(node_iter->node_id == *ref_iter);
external_to_internal_node_id_map[*ref_iter] = static_cast<NodeID>(internal_id++); *used_nodes_iter = std::move(*ref_iter);
used_nodes_iter++;
node_iter++; node_iter++;
ref_iter++; ref_iter++;
} }
if (internal_id > std::numeric_limits<NodeID>::max())
// Remove unused nodes and check maximal internal node id
used_node_id_list.resize(std::distance(used_node_id_list.begin(), used_nodes_iter));
if (used_node_id_list.size() > std::numeric_limits<NodeID>::max())
{ {
throw util::exception("There are too many nodes remaining after filtering, OSRM only " throw util::exception("There are too many nodes remaining after filtering, OSRM only "
"supports 2^32 unique nodes, but there were " + "supports 2^32 unique nodes, but there were " +
std::to_string(internal_id) + SOURCE_REF); std::to_string(used_node_id_list.size()) + SOURCE_REF);
} }
max_internal_node_id = boost::numeric_cast<std::uint64_t>(internal_id); max_internal_node_id = boost::numeric_cast<std::uint64_t>(used_node_id_list.size());
TIMER_STOP(id_map); TIMER_STOP(id_map);
log << "ok, after " << TIMER_SEC(id_map) << "s"; log << "ok, after " << TIMER_SEC(id_map) << "s";
} }
@ -280,8 +242,7 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
util::UnbufferedLog log; util::UnbufferedLog log;
log << "Sorting edges by start ... " << std::flush; log << "Sorting edges by start ... " << std::flush;
TIMER_START(sort_edges_by_start); TIMER_START(sort_edges_by_start);
stxxl::sort( tbb::parallel_sort(all_edges_list.begin(), all_edges_list.end(), CmpEdgeByOSMStartID());
all_edges_list.begin(), all_edges_list.end(), CmpEdgeByOSMStartID(), stxxl_memory);
TIMER_STOP(sort_edges_by_start); TIMER_STOP(sort_edges_by_start);
log << "ok, after " << TIMER_SEC(sort_edges_by_start) << "s"; log << "ok, after " << TIMER_SEC(sort_edges_by_start) << "s";
} }
@ -325,9 +286,10 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
BOOST_ASSERT(edge_iterator->result.osm_source_id == node_iterator->node_id); BOOST_ASSERT(edge_iterator->result.osm_source_id == node_iterator->node_id);
// assign new node id // assign new node id
auto id_iter = external_to_internal_node_id_map.find(node_iterator->node_id); const auto node_id = mapExternalToInternalNodeID(
BOOST_ASSERT(id_iter != external_to_internal_node_id_map.end()); used_node_id_list.begin(), used_node_id_list.end(), node_iterator->node_id);
edge_iterator->result.source = id_iter->second; BOOST_ASSERT(node_id != SPECIAL_NODEID);
edge_iterator->result.source = node_id;
edge_iterator->source_coordinate.lat = node_iterator->lat; edge_iterator->source_coordinate.lat = node_iterator->lat;
edge_iterator->source_coordinate.lon = node_iterator->lon; edge_iterator->source_coordinate.lon = node_iterator->lon;
@ -351,8 +313,7 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
util::UnbufferedLog log; util::UnbufferedLog log;
log << "Sorting edges by target ... " << std::flush; log << "Sorting edges by target ... " << std::flush;
TIMER_START(sort_edges_by_target); TIMER_START(sort_edges_by_target);
stxxl::sort( tbb::parallel_sort(all_edges_list.begin(), all_edges_list.end(), CmpEdgeByOSMTargetID());
all_edges_list.begin(), all_edges_list.end(), CmpEdgeByOSMTargetID(), stxxl_memory);
TIMER_STOP(sort_edges_by_target); TIMER_STOP(sort_edges_by_target);
log << "ok, after " << TIMER_SEC(sort_edges_by_target) << "s"; log << "ok, after " << TIMER_SEC(sort_edges_by_target) << "s";
} }
@ -419,9 +380,10 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
edge.duration = std::max<EdgeWeight>(1, std::round(segment.duration * 10.)); edge.duration = std::max<EdgeWeight>(1, std::round(segment.duration * 10.));
// assign new node id // assign new node id
auto id_iter = external_to_internal_node_id_map.find(node_iterator->node_id); const auto node_id = mapExternalToInternalNodeID(
BOOST_ASSERT(id_iter != external_to_internal_node_id_map.end()); used_node_id_list.begin(), used_node_id_list.end(), node_iterator->node_id);
edge.target = id_iter->second; BOOST_ASSERT(node_id != SPECIAL_NODEID);
edge.target = node_id;
// orient edges consistently: source id < target id // orient edges consistently: source id < target id
// important for multi-edge removal // important for multi-edge removal
@ -454,11 +416,9 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
log << "Sorting edges by renumbered start ... "; log << "Sorting edges by renumbered start ... ";
TIMER_START(sort_edges_by_renumbered_start); TIMER_START(sort_edges_by_renumbered_start);
std::mutex name_data_mutex; std::mutex name_data_mutex;
stxxl::sort( tbb::parallel_sort(all_edges_list.begin(),
all_edges_list.begin(),
all_edges_list.end(), all_edges_list.end(),
CmpEdgeByInternalSourceTargetAndName{name_data_mutex, name_char_data, name_offsets}, CmpEdgeByInternalSourceTargetAndName{name_char_data, name_offsets});
stxxl_memory);
TIMER_STOP(sort_edges_by_renumbered_start); TIMER_STOP(sort_edges_by_renumbered_start);
log << "ok, after " << TIMER_SEC(sort_edges_by_renumbered_start) << "s"; log << "ok, after " << TIMER_SEC(sort_edges_by_renumbered_start) << "s";
} }
@ -640,12 +600,13 @@ void ExtractionContainers::WriteNodes(storage::io::FileWriter &file_out) const
log << "Writing barrier nodes ... "; log << "Writing barrier nodes ... ";
TIMER_START(write_nodes); TIMER_START(write_nodes);
std::vector<NodeID> internal_barrier_nodes; std::vector<NodeID> internal_barrier_nodes;
for (const auto id : barrier_nodes) for (const auto osm_id : barrier_nodes)
{ {
auto iter = external_to_internal_node_id_map.find(id); const auto node_id = mapExternalToInternalNodeID(
if (iter != external_to_internal_node_id_map.end()) used_node_id_list.begin(), used_node_id_list.end(), osm_id);
if (node_id != SPECIAL_NODEID)
{ {
internal_barrier_nodes.push_back(iter->second); internal_barrier_nodes.push_back(node_id);
} }
} }
storage::serialization::write(file_out, internal_barrier_nodes); storage::serialization::write(file_out, internal_barrier_nodes);
@ -657,12 +618,13 @@ void ExtractionContainers::WriteNodes(storage::io::FileWriter &file_out) const
log << "Writing traffic light nodes ... "; log << "Writing traffic light nodes ... ";
TIMER_START(write_nodes); TIMER_START(write_nodes);
std::vector<NodeID> internal_traffic_lights; std::vector<NodeID> internal_traffic_lights;
for (const auto id : traffic_lights) for (const auto osm_id : traffic_lights)
{ {
auto iter = external_to_internal_node_id_map.find(id); const auto node_id = mapExternalToInternalNodeID(
if (iter != external_to_internal_node_id_map.end()) used_node_id_list.begin(), used_node_id_list.end(), osm_id);
if (node_id != SPECIAL_NODEID)
{ {
internal_traffic_lights.push_back(iter->second); internal_traffic_lights.push_back(node_id);
} }
} }
storage::serialization::write(file_out, internal_traffic_lights); storage::serialization::write(file_out, internal_traffic_lights);
@ -716,10 +678,9 @@ void ExtractionContainers::PrepareRestrictions()
util::UnbufferedLog log; util::UnbufferedLog log;
log << "Sorting used ways ... "; log << "Sorting used ways ... ";
TIMER_START(sort_ways); TIMER_START(sort_ways);
stxxl::sort(way_start_end_id_list.begin(), tbb::parallel_sort(way_start_end_id_list.begin(),
way_start_end_id_list.end(), way_start_end_id_list.end(),
FirstAndLastSegmentOfWayStxxlCompare(), FirstAndLastSegmentOfWayCompare());
stxxl_memory);
TIMER_STOP(sort_ways); TIMER_STOP(sort_ways);
log << "ok, after " << TIMER_SEC(sort_ways) << "s"; log << "ok, after " << TIMER_SEC(sort_ways) << "s";
} }
@ -728,7 +689,7 @@ void ExtractionContainers::PrepareRestrictions()
util::UnbufferedLog log; util::UnbufferedLog log;
log << "Sorting " << restrictions_list.size() << " restriction. by from... "; log << "Sorting " << restrictions_list.size() << " restriction. by from... ";
TIMER_START(sort_restrictions); TIMER_START(sort_restrictions);
std::sort( tbb::parallel_sort(
restrictions_list.begin(), restrictions_list.end(), CmpRestrictionContainerByFrom()); restrictions_list.begin(), restrictions_list.end(), CmpRestrictionContainerByFrom());
TIMER_STOP(sort_restrictions); TIMER_STOP(sort_restrictions);
log << "ok, after " << TIMER_SEC(sort_restrictions) << "s"; log << "ok, after " << TIMER_SEC(sort_restrictions) << "s";
@ -766,26 +727,30 @@ void ExtractionContainers::PrepareRestrictions()
BOOST_ASSERT( BOOST_ASSERT(
way_start_and_end_iterator->way_id == way_start_and_end_iterator->way_id ==
OSMWayID{static_cast<std::uint32_t>(restrictions_iterator->restriction.from.way)}); OSMWayID{static_cast<std::uint32_t>(restrictions_iterator->restriction.from.way)});
// we do not remap the via id yet, since we will need it for the to node as well // we do not remap the via id yet, since we will need it for the to node as well
const OSMNodeID via_node_id = OSMNodeID{restrictions_iterator->restriction.via.node}; const OSMNodeID via_osm_node_id =
OSMNodeID{restrictions_iterator->restriction.via.node};
// check if via is actually valid, if not invalidate // check if via is actually valid, if not invalidate
auto via_id_iter = external_to_internal_node_id_map.find(via_node_id); auto via_node_id = mapExternalToInternalNodeID(
if (via_id_iter == external_to_internal_node_id_map.end()) used_node_id_list.begin(), used_node_id_list.end(), via_osm_node_id);
if (via_node_id == SPECIAL_NODEID)
{ {
util::Log(logDEBUG) << "Restriction references invalid node: " util::Log(logDEBUG) << "Restriction references invalid node: " << via_osm_node_id;
<< restrictions_iterator->restriction.via.node;
restrictions_iterator->restriction.via.node = SPECIAL_NODEID; restrictions_iterator->restriction.via.node = SPECIAL_NODEID;
++restrictions_iterator; ++restrictions_iterator;
continue; continue;
} }
if (way_start_and_end_iterator->first_segment_source_id == via_node_id) if (way_start_and_end_iterator->first_segment_source_id == via_osm_node_id)
{ {
// assign new from node id // assign new from node id
auto id_iter = external_to_internal_node_id_map.find( const auto from_node_id = mapExternalToInternalNodeID(
used_node_id_list.begin(),
used_node_id_list.end(),
way_start_and_end_iterator->first_segment_target_id); way_start_and_end_iterator->first_segment_target_id);
if (id_iter == external_to_internal_node_id_map.end()) if (from_node_id == SPECIAL_NODEID)
{ {
util::Log(logDEBUG) << "Way references invalid node: " util::Log(logDEBUG) << "Way references invalid node: "
<< way_start_and_end_iterator->first_segment_target_id; << way_start_and_end_iterator->first_segment_target_id;
@ -794,14 +759,16 @@ void ExtractionContainers::PrepareRestrictions()
++way_start_and_end_iterator; ++way_start_and_end_iterator;
continue; continue;
} }
restrictions_iterator->restriction.from.node = id_iter->second; restrictions_iterator->restriction.from.node = from_node_id;
} }
else if (way_start_and_end_iterator->last_segment_target_id == via_node_id) else if (way_start_and_end_iterator->last_segment_target_id == via_osm_node_id)
{ {
// assign new from node id // assign new from node id
auto id_iter = external_to_internal_node_id_map.find( const auto from_node_id =
mapExternalToInternalNodeID(used_node_id_list.begin(),
used_node_id_list.end(),
way_start_and_end_iterator->last_segment_source_id); way_start_and_end_iterator->last_segment_source_id);
if (id_iter == external_to_internal_node_id_map.end()) if (from_node_id == SPECIAL_NODEID)
{ {
util::Log(logDEBUG) << "Way references invalid node: " util::Log(logDEBUG) << "Way references invalid node: "
<< way_start_and_end_iterator->last_segment_target_id; << way_start_and_end_iterator->last_segment_target_id;
@ -810,7 +777,7 @@ void ExtractionContainers::PrepareRestrictions()
++way_start_and_end_iterator; ++way_start_and_end_iterator;
continue; continue;
} }
restrictions_iterator->restriction.from.node = id_iter->second; restrictions_iterator->restriction.from.node = from_node_id;
} }
else else
{ {
@ -828,7 +795,7 @@ void ExtractionContainers::PrepareRestrictions()
util::UnbufferedLog log; util::UnbufferedLog log;
log << "Sorting restrictions. by to ... " << std::flush; log << "Sorting restrictions. by to ... " << std::flush;
TIMER_START(sort_restrictions_to); TIMER_START(sort_restrictions_to);
std::sort( tbb::parallel_sort(
restrictions_list.begin(), restrictions_list.end(), CmpRestrictionContainerByTo()); restrictions_list.begin(), restrictions_list.end(), CmpRestrictionContainerByTo());
TIMER_STOP(sort_restrictions_to); TIMER_STOP(sort_restrictions_to);
log << "ok, after " << TIMER_SEC(sort_restrictions_to) << "s"; log << "ok, after " << TIMER_SEC(sort_restrictions_to) << "s";
@ -870,18 +837,22 @@ void ExtractionContainers::PrepareRestrictions()
BOOST_ASSERT( BOOST_ASSERT(
way_start_and_end_iterator->way_id == way_start_and_end_iterator->way_id ==
OSMWayID{static_cast<std::uint32_t>(restrictions_iterator->restriction.to.way)}); OSMWayID{static_cast<std::uint32_t>(restrictions_iterator->restriction.to.way)});
const OSMNodeID via_node_id = OSMNodeID{restrictions_iterator->restriction.via.node}; const OSMNodeID via_osm_node_id =
OSMNodeID{restrictions_iterator->restriction.via.node};
// assign new via node id // assign new via node id
auto via_id_iter = external_to_internal_node_id_map.find(via_node_id); const auto via_node_id = mapExternalToInternalNodeID(
BOOST_ASSERT(via_id_iter != external_to_internal_node_id_map.end()); used_node_id_list.begin(), used_node_id_list.end(), via_osm_node_id);
restrictions_iterator->restriction.via.node = via_id_iter->second; BOOST_ASSERT(via_node_id != SPECIAL_NODEID);
restrictions_iterator->restriction.via.node = via_node_id;
if (way_start_and_end_iterator->first_segment_source_id == via_node_id) if (way_start_and_end_iterator->first_segment_source_id == via_osm_node_id)
{ {
auto to_id_iter = external_to_internal_node_id_map.find( const auto to_node_id = mapExternalToInternalNodeID(
used_node_id_list.begin(),
used_node_id_list.end(),
way_start_and_end_iterator->first_segment_target_id); way_start_and_end_iterator->first_segment_target_id);
if (to_id_iter == external_to_internal_node_id_map.end()) if (to_node_id == SPECIAL_NODEID)
{ {
util::Log(logDEBUG) << "Way references invalid node: " util::Log(logDEBUG) << "Way references invalid node: "
<< way_start_and_end_iterator->first_segment_source_id; << way_start_and_end_iterator->first_segment_source_id;
@ -890,13 +861,15 @@ void ExtractionContainers::PrepareRestrictions()
++way_start_and_end_iterator; ++way_start_and_end_iterator;
continue; continue;
} }
restrictions_iterator->restriction.to.node = to_id_iter->second; restrictions_iterator->restriction.to.node = to_node_id;
} }
else if (way_start_and_end_iterator->last_segment_target_id == via_node_id) else if (way_start_and_end_iterator->last_segment_target_id == via_osm_node_id)
{ {
auto to_id_iter = external_to_internal_node_id_map.find( const auto to_node_id =
mapExternalToInternalNodeID(used_node_id_list.begin(),
used_node_id_list.end(),
way_start_and_end_iterator->last_segment_source_id); way_start_and_end_iterator->last_segment_source_id);
if (to_id_iter == external_to_internal_node_id_map.end()) if (to_node_id == SPECIAL_NODEID)
{ {
util::Log(logDEBUG) << "Way references invalid node: " util::Log(logDEBUG) << "Way references invalid node: "
<< way_start_and_end_iterator->last_segment_source_id; << way_start_and_end_iterator->last_segment_source_id;
@ -905,7 +878,7 @@ void ExtractionContainers::PrepareRestrictions()
++way_start_and_end_iterator; ++way_start_and_end_iterator;
continue; continue;
} }
restrictions_iterator->restriction.to.node = to_id_iter->second; restrictions_iterator->restriction.to.node = to_node_id;
} }
else else
{ {

View File

@ -88,10 +88,7 @@ TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t
// handle travel modes: // handle travel modes:
const auto in_mode = node_based_graph.GetEdgeData(via_edge).travel_mode; const auto in_mode = node_based_graph.GetEdgeData(via_edge).travel_mode;
const auto out_mode = node_based_graph.GetEdgeData(road.eid).travel_mode; const auto out_mode = node_based_graph.GetEdgeData(road.eid).travel_mode;
const auto in_classes = node_based_graph.GetEdgeData(via_edge).classes; const auto needs_notification = in_mode != out_mode;
const auto out_classes = node_based_graph.GetEdgeData(road.eid).classes;
// if we just lose class flags we don't want to notify
const auto needs_notification = in_mode != out_mode || !isSubset(out_classes, in_classes);
if (type == TurnType::Turn) if (type == TurnType::Turn)
{ {

View File

@ -118,6 +118,9 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
const auto getContinueAngle = [this, in_data](const Intersection &intersection) { const auto getContinueAngle = [this, in_data](const Intersection &intersection) {
for (const auto &road : intersection) for (const auto &road : intersection)
{ {
if (!road.entry_allowed)
continue;
const auto &out_data = node_based_graph.GetEdgeData(road.eid); const auto &out_data = node_based_graph.GetEdgeData(road.eid);
const auto same_name = !util::guidance::requiresNameAnnounced( const auto same_name = !util::guidance::requiresNameAnnounced(

View File

@ -366,6 +366,16 @@
"value": "circular", "value": "circular",
"description": "A Roundabout where the traffic on the roundabout not always has right of way." "description": "A Roundabout where the traffic on the roundabout not always has right of way."
}, },
{
"key": "proposed",
"object_types": [ "way" ],
"description": "Proposed ways. Discarded for routing"
},
{
"key": "construction",
"object_types": [ "way" ],
"description": "Ways under construction. Discarded for routing except construction=no, construction=widening"
},
{ {
"key": "type", "key": "type",
"value": "restriction", "value": "restriction",

View File

@ -98,6 +98,37 @@ test('constructor: throws if data doesn\'t match algorithm', function(assert) {
assert.throws(function() { new OSRM({algorithm: 'MLD', path: monaco_path}); }); assert.throws(function() { new OSRM({algorithm: 'MLD', path: monaco_path}); });
}); });
test('constructor: parses custom limits', function(assert) {
assert.plan(1);
var osrm = new OSRM({
path: monaco_mld_path,
algorithm: 'MLD',
max_locations_trip: 1,
max_locations_viaroute: 1,
max_locations_distance_table: 1,
max_locations_map_matching: 1,
max_results_nearest: 1,
max_alternatives: 1,
});
assert.ok(osrm);
});
test('constructor: throws on invalid custom limits', function(assert) {
assert.plan(1);
assert.throws(function() {
var osrm = new OSRM({
path: monaco_mld_path,
algorithm: 'MLD',
max_locations_trip: 'unlimited',
max_locations_viaroute: true,
max_locations_distance_table: false,
max_locations_map_matching: 'a lot',
max_results_nearest: null,
max_alternatives: '10'
})
});
});
require('./route.js'); require('./route.js');
require('./trip.js'); require('./trip.js');
require('./match.js'); require('./match.js');

View File

@ -549,3 +549,30 @@ test('route: throws on bad approaches', function(assert) {
}, function(err, route) {}) }, }, function(err, route) {}) },
/Approach must be a string: \[curb, unrestricted\] or null/); /Approach must be a string: \[curb, unrestricted\] or null/);
}); });
test('route: routes Monaco with custom limits on MLD', function(assert) {
assert.plan(2);
var osrm = new OSRM({
path: monaco_mld_path,
algorithm: 'MLD',
max_alternatives: 10,
});
osrm.route({coordinates: two_test_coordinates, alternatives: 10}, function(err, route) {
assert.ifError(err);
assert.ok(Array.isArray(route.routes));
});
});
test('route: in Monaco with custom limits on MLD', function(assert) {
assert.plan(1);
var osrm = new OSRM({
path: monaco_mld_path,
algorithm: 'MLD',
max_alternatives: 10,
});
osrm.route({coordinates: two_test_coordinates, alternatives: 11}, function(err, route) {
console.log(err)
assert.equal(err.message, 'TooBig');
});
});

View File

@ -23,6 +23,7 @@ BOOST_AUTO_TEST_CASE(trim_short_segments)
IntermediateIntersection::NO_INDEX, IntermediateIntersection::NO_INDEX,
0, 0,
{0, 255}, {0, 255},
{},
{}}; {}};
IntermediateIntersection intersection2{{FloatLongitude{-73.981495}, FloatLatitude{40.768275}}, IntermediateIntersection intersection2{{FloatLongitude{-73.981495}, FloatLatitude{40.768275}},
{180}, {180},
@ -30,6 +31,7 @@ BOOST_AUTO_TEST_CASE(trim_short_segments)
0, 0,
IntermediateIntersection::NO_INDEX, IntermediateIntersection::NO_INDEX,
{0, 255}, {0, 255},
{},
{}}; {}};
// Check that duplicated coordinate in the end is removed // Check that duplicated coordinate in the end is removed
@ -53,8 +55,7 @@ BOOST_AUTO_TEST_CASE(trim_short_segments)
0}, 0},
0, 0,
3, 3,
{intersection1}, {intersection1}},
{}},
{324, {324,
"Central Park West", "Central Park West",
"", "",
@ -75,8 +76,7 @@ BOOST_AUTO_TEST_CASE(trim_short_segments)
0}, 0},
2, 2,
3, 3,
{intersection2}, {intersection2}}};
{}}};
LegGeometry geometry; LegGeometry geometry;
geometry.locations = {{FloatLongitude{-73.981492}, FloatLatitude{40.768258}}, geometry.locations = {{FloatLongitude{-73.981492}, FloatLatitude{40.768258}},

View File

@ -5,7 +5,7 @@
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <numeric> #include <numeric>
#include <stxxl/vector> #include <vector>
BOOST_AUTO_TEST_SUITE(range_table) BOOST_AUTO_TEST_SUITE(range_table)
@ -15,7 +15,7 @@ using namespace osrm::util;
constexpr unsigned BLOCK_SIZE = 16; constexpr unsigned BLOCK_SIZE = 16;
typedef RangeTable<BLOCK_SIZE, osrm::storage::Ownership::Container> TestRangeTable; typedef RangeTable<BLOCK_SIZE, osrm::storage::Ownership::Container> TestRangeTable;
void ConstructionTest(stxxl::vector<unsigned> lengths, std::vector<unsigned> offsets) void ConstructionTest(std::vector<unsigned> lengths, std::vector<unsigned> offsets)
{ {
BOOST_ASSERT(lengths.size() == offsets.size() - 1); BOOST_ASSERT(lengths.size() == offsets.size() - 1);
@ -29,7 +29,7 @@ void ConstructionTest(stxxl::vector<unsigned> lengths, std::vector<unsigned> off
} }
} }
void ComputeLengthsOffsets(stxxl::vector<unsigned> &lengths, void ComputeLengthsOffsets(std::vector<unsigned> &lengths,
std::vector<unsigned> &offsets, std::vector<unsigned> &offsets,
unsigned num) unsigned num)
{ {
@ -54,12 +54,12 @@ void ComputeLengthsOffsets(stxxl::vector<unsigned> &lengths,
BOOST_AUTO_TEST_CASE(construction_test) BOOST_AUTO_TEST_CASE(construction_test)
{ {
// only offset empty block // only offset empty block
stxxl::vector<unsigned> empty_lengths; std::vector<unsigned> empty_lengths;
empty_lengths.push_back(1); empty_lengths.push_back(1);
ConstructionTest(empty_lengths, {0, 1}); ConstructionTest(empty_lengths, {0, 1});
// first block almost full => sentinel is last element of block // first block almost full => sentinel is last element of block
// [0] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, (16)} // [0] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, (16)}
stxxl::vector<unsigned> almost_full_lengths; std::vector<unsigned> almost_full_lengths;
std::vector<unsigned> almost_full_offsets; std::vector<unsigned> almost_full_offsets;
ComputeLengthsOffsets(almost_full_lengths, almost_full_offsets, BLOCK_SIZE); ComputeLengthsOffsets(almost_full_lengths, almost_full_offsets, BLOCK_SIZE);
ConstructionTest(almost_full_lengths, almost_full_offsets); ConstructionTest(almost_full_lengths, almost_full_offsets);
@ -67,7 +67,7 @@ BOOST_AUTO_TEST_CASE(construction_test)
// first block full => sentinel is offset of new block, next block empty // first block full => sentinel is offset of new block, next block empty
// [0] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} // [0] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
// [(153)] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} // [(153)] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
stxxl::vector<unsigned> full_lengths; std::vector<unsigned> full_lengths;
std::vector<unsigned> full_offsets; std::vector<unsigned> full_offsets;
ComputeLengthsOffsets(full_lengths, full_offsets, BLOCK_SIZE + 1); ComputeLengthsOffsets(full_lengths, full_offsets, BLOCK_SIZE + 1);
ConstructionTest(full_lengths, full_offsets); ConstructionTest(full_lengths, full_offsets);
@ -75,13 +75,13 @@ BOOST_AUTO_TEST_CASE(construction_test)
// first block full and offset of next block not sentinel, but the first differential value // first block full and offset of next block not sentinel, but the first differential value
// [0] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} // [0] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
// [153] {(17), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} // [153] {(17), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
stxxl::vector<unsigned> over_full_lengths; std::vector<unsigned> over_full_lengths;
std::vector<unsigned> over_full_offsets; std::vector<unsigned> over_full_offsets;
ComputeLengthsOffsets(over_full_lengths, over_full_offsets, BLOCK_SIZE + 2); ComputeLengthsOffsets(over_full_lengths, over_full_offsets, BLOCK_SIZE + 2);
ConstructionTest(over_full_lengths, over_full_offsets); ConstructionTest(over_full_lengths, over_full_offsets);
// test multiple blocks // test multiple blocks
stxxl::vector<unsigned> multiple_lengths; std::vector<unsigned> multiple_lengths;
std::vector<unsigned> multiple_offsets; std::vector<unsigned> multiple_offsets;
ComputeLengthsOffsets(multiple_lengths, multiple_offsets, (BLOCK_SIZE + 1) * 10); ComputeLengthsOffsets(multiple_lengths, multiple_offsets, (BLOCK_SIZE + 1) * 10);
ConstructionTest(multiple_lengths, multiple_offsets); ConstructionTest(multiple_lengths, multiple_offsets);