This commit is contained in:
Desone Burns II 2020-09-25 14:33:53 -07:00
commit f957c8fb7b
793 changed files with 139213 additions and 2752 deletions

2
.eslintignore Normal file
View File

@ -0,0 +1,2 @@
features/support/flatbuffers.js
features/support/fbresult_generated.js

8
.gitignore vendored
View File

@ -49,7 +49,7 @@ Thumbs.db
/_build* /_build*
/build/ /build/
/example/build/ /example/build/
/test/data/monaco* /test/data/monaco.osrm*
/test/data/ch /test/data/ch
/test/data/corech /test/data/corech
/test/data/mld /test/data/mld
@ -72,12 +72,6 @@ Thumbs.db
########################### ###########################
.idea/ .idea/
# stxxl related files #
#######################
.stxxl
stxxl.log
stxxl.errlog
# Compiled Binary Files # # Compiled Binary Files #
#################################### ####################################
/osrm-extract /osrm-extract

View File

@ -121,6 +121,22 @@ matrix:
packages: ['libstdc++-4.9-dev'] packages: ['libstdc++-4.9-dev']
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON RUN_CLANG_FORMAT=ON ENABLE_LTO=ON env: CLANG_VERSION='5.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON RUN_CLANG_FORMAT=ON ENABLE_LTO=ON
- os: linux
compiler: "gcc-9-release"
addons: &gcc9
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-9', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libboost-all-dev']
env: CCOMPILER='gcc-9' CXXCOMPILER='g++-9' BUILD_TYPE='Release' CXXFLAGS='-Wno-cast-function-type'
- os: linux
compiler: "gcc-8-release"
addons: &gcc8
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-8', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libboost-all-dev']
env: CCOMPILER='gcc-8' CXXCOMPILER='g++-8' BUILD_TYPE='Release' CXXFLAGS='-Wno-cast-function-type'
- os: linux - os: linux
compiler: "gcc-7-release" compiler: "gcc-7-release"
addons: &gcc7 addons: &gcc7
@ -135,14 +151,6 @@ matrix:
TARGET_ARCH='i686' CCOMPILER='gcc-7' CXXCOMPILER='g++-7' BUILD_TYPE='Release' TARGET_ARCH='i686' CCOMPILER='gcc-7' CXXCOMPILER='g++-7' 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-7-stxxl"
addons: &gcc7
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-7', 'libbz2-dev', 'libstxxl-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libboost-all-dev']
env: CCOMPILER='gcc-7' CXXCOMPILER='g++-7' BUILD_TYPE='Release' ENABLE_STXXL=On
- os: linux - os: linux
compiler: "gcc-5-release" compiler: "gcc-5-release"
addons: &gcc49 addons: &gcc49
@ -467,7 +475,6 @@ 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

@ -2,14 +2,27 @@
- Changes from 5.21.0 - Changes from 5.21.0
- Build: - Build:
- ADDED: optionally build Node `lts` and `latest` bindings [#5347](https://github.com/Project-OSRM/osrm-backend/pull/5347) - ADDED: optionally build Node `lts` and `latest` bindings [#5347](https://github.com/Project-OSRM/osrm-backend/pull/5347)
- FIXED: pessimistic calls to std::move [#5560](https://github.com/Project-OSRM/osrm-backend/pull/5561)
- Features: - Features:
- ADDED: new waypoints parameter to the `route` plugin, enabling silent waypoints [#5345](https://github.com/Project-OSRM/osrm-backend/pull/5345) - ADDED: new waypoints parameter to the `route` plugin, enabling silent waypoints [#5345](https://github.com/Project-OSRM/osrm-backend/pull/5345)
- ADDED: data timestamp information in the response (saved in new file `.osrm.timestamp`). [#5115](https://github.com/Project-OSRM/osrm-backend/issues/5115) - ADDED: data timestamp information in the response (saved in new file `.osrm.timestamp`). [#5115](https://github.com/Project-OSRM/osrm-backend/issues/5115)
- ADDED: new API parameter - `snapping=any|default` to allow snapping to previously unsnappable edges [#5361](https://github.com/Project-OSRM/osrm-backend/pull/5361) - ADDED: new API parameter - `snapping=any|default` to allow snapping to previously unsnappable edges [#5361](https://github.com/Project-OSRM/osrm-backend/pull/5361)
- ADDED: keepalive support to the osrm-routed HTTP server [#5518](https://github.com/Project-OSRM/osrm-backend/pull/5518)
- ADDED: flatbuffers output format support [#5513](https://github.com/Project-OSRM/osrm-backend/pull/5513)
- ADDED: Global 'skip_waypoints' option [#5556](https://github.com/Project-OSRM/osrm-backend/pull/5556)
- FIXED: Install the libosrm_guidance library correctly [#5604](https://github.com/Project-OSRM/osrm-backend/pull/5604)
- FIXED: Http Handler can now deal witch optional whitespace between header-key and -value [#5606](https://github.com/Project-OSRM/osrm-backend/issues/5606)
- Routing: - Routing:
- CHANGED: allow routing past `barrier=arch` [#5352](https://github.com/Project-OSRM/osrm-backend/pull/5352) - CHANGED: allow routing past `barrier=arch` [#5352](https://github.com/Project-OSRM/osrm-backend/pull/5352)
- CHANGED: default car weight was reduced to 2000 kg. [#5371](https://github.com/Project-OSRM/osrm-backend/pull/5371) - CHANGED: default car weight was reduced to 2000 kg. [#5371](https://github.com/Project-OSRM/osrm-backend/pull/5371)
- CHANGED: default car height was reduced to 2 meters. [#5389](https://github.com/Project-OSRM/osrm-backend/pull/5389)
- FIXED: treat `bicycle=use_sidepath` as no access on the tagged way. [#5622](https://github.com/Project-OSRM/osrm-backend/pull/5622)
- Misc:
- CHANGED: Reduce memory usage for raster source handling. [#5572](https://github.com/Project-OSRM/osrm-backend/pull/5572)
- CHANGED: Add cmake option `ENABLE_DEBUG_LOGGING` to control whether output debug logging. [#3427](https://github.com/Project-OSRM/osrm-backend/issues/3427)
- CHANGED: updated extent of Hong Kong as left hand drive country. [#5535](https://github.com/Project-OSRM/osrm-backend/issues/5535)
- Infrastructure
- REMOVED: STXXL support removed as STXXL became abandonware. [#5760](https://github.com/Project-OSRM/osrm-backend/pull/5760)
# 5.21.0 # 5.21.0
- Changes from 5.20.0 - Changes from 5.20.0
- Features: - Features:

View File

@ -23,9 +23,9 @@ option(ENABLE_CCACHE "Speed up incremental rebuilds via ccache" ON)
option(BUILD_TOOLS "Build OSRM tools" OFF) option(BUILD_TOOLS "Build OSRM tools" OFF)
option(BUILD_PACKAGE "Build OSRM package" OFF) 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_DEBUG_LOGGING "Use debug logging 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" OFF)
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)
@ -37,7 +37,6 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
if(ENABLE_MASON) if(ENABLE_MASON)
# versions in use # versions in use
set(MASON_BOOST_VERSION "1.65.1") set(MASON_BOOST_VERSION "1.65.1")
set(MASON_STXXL_VERSION "1.4.1-1")
set(MASON_EXPAT_VERSION "2.2.0") set(MASON_EXPAT_VERSION "2.2.0")
set(MASON_LUA_VERSION "5.2.4") set(MASON_LUA_VERSION "5.2.4")
set(MASON_BZIP2_VERSION "1.0.6") set(MASON_BZIP2_VERSION "1.0.6")
@ -57,6 +56,12 @@ endif()
if (POLICY CMP0048) if (POLICY CMP0048)
cmake_policy(SET CMP0048 OLD) cmake_policy(SET CMP0048 OLD)
endif() endif()
if (POLICY CMP0057)
cmake_policy(SET CMP0057 NEW)
endif()
if (POLICY CMP0074)
cmake_policy(SET CMP0074 NEW)
endif()
project(OSRM C CXX) project(OSRM C CXX)
include(JSONParser) include(JSONParser)
@ -227,6 +232,7 @@ endif()
if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES RelWithDebInfo) if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)
message(STATUS "Configuring debug mode flags") message(STATUS "Configuring debug mode flags")
set(ENABLE_ASSERTIONS ON) set(ENABLE_ASSERTIONS ON)
set(ENABLE_DEBUG_LOGGING ON)
endif() endif()
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC") if(NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
@ -439,6 +445,12 @@ include_directories(SYSTEM ${PROTOZERO_INCLUDE_DIR})
set(VTZERO_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/vtzero/include") set(VTZERO_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/vtzero/include")
include_directories(SYSTEM ${VTZERO_INCLUDE_DIR}) include_directories(SYSTEM ${VTZERO_INCLUDE_DIR})
set(FLATBUFFERS_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/flatbuffers")
set(FLATBUFFERS_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/flatbuffers/include")
include_directories(${FLATBUFFERS_INCLUDE_DIR})
add_subdirectory(${FLATBUFFERS_SRC_DIR}
${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-build
EXCLUDE_FROM_ALL)
# if mason is enabled no find_package calls are made # if mason is enabled no find_package calls are made
# to ensure that we are only compiling and linking against # to ensure that we are only compiling and linking against
@ -466,13 +478,6 @@ 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})
add_dependency_includes(${MASON_PACKAGE_stxxl_INCLUDE_DIRS})
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})
set(EXPAT_LIBRARIES ${MASON_PACKAGE_expat_STATIC_LIBS}) set(EXPAT_LIBRARIES ${MASON_PACKAGE_expat_STATIC_LIBS})
@ -518,30 +523,16 @@ else()
find_package(Boost 1.54 REQUIRED COMPONENTS ${BOOST_COMPONENTS}) find_package(Boost 1.54 REQUIRED COMPONENTS ${BOOST_COMPONENTS})
add_dependency_includes(${Boost_INCLUDE_DIRS}) add_dependency_includes(${Boost_INCLUDE_DIRS})
if(WIN32 AND Boost_VERSION VERSION_LESS 106200)
message(FATAL_ERROR "Building with MSVC needs Boost 1.62 with CXX11_CONSTEXPR support")
endif()
find_package(TBB REQUIRED) find_package(TBB REQUIRED)
add_dependency_includes(${TBB_INCLUDE_DIR}) add_dependency_includes(${TBB_INCLUDE_DIR})
if(WIN32 AND CMAKE_BUILD_TYPE MATCHES Debug) if(WIN32)
set(TBB_LIBRARIES ${TBB_DEBUG_LIBRARIES}) set(TBB_LIBRARIES optimized ${TBB_LIBRARY} optimized ${TBB_MALLOC_LIBRARY} debug ${TBB_LIBRARY_DEBUG} debug ${TBB_MALLOC_LIBRARY_DEBUG})
endif() endif()
find_package(EXPAT REQUIRED) find_package(EXPAT REQUIRED)
add_dependency_includes(${EXPAT_INCLUDE_DIRS}) add_dependency_includes(${EXPAT_INCLUDE_DIRS})
if (ENABLE_STXXL)
find_package(STXXL)
if (STXXL_FOUND)
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})
@ -601,15 +592,6 @@ 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)
find_package(OpenMP)
if(OPENMP_FOUND)
message(STATUS "OpenMP support found. Linking just in case for stxxl")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()
endif()
add_definitions(${OSRM_DEFINES}) add_definitions(${OSRM_DEFINES})
include_directories(SYSTEM ${DEPENDENCIES_INCLUDE_DIRS}) include_directories(SYSTEM ${DEPENDENCIES_INCLUDE_DIRS})
@ -642,7 +624,6 @@ set(EXTRACTOR_LIBRARIES
${EXPAT_LIBRARIES} ${EXPAT_LIBRARIES}
${USED_LUA_LIBRARIES} ${USED_LUA_LIBRARIES}
${OSMIUM_LIBRARIES} ${OSMIUM_LIBRARIES}
${MAYBE_STXXL_LIBRARY}
${TBB_LIBRARIES} ${TBB_LIBRARIES}
${ZLIB_LIBRARY} ${ZLIB_LIBRARY}
${MAYBE_COVERAGE_LIBRARIES}) ${MAYBE_COVERAGE_LIBRARIES})
@ -676,7 +657,6 @@ set(CONTRACTOR_LIBRARIES
${BOOST_BASE_LIBRARIES} ${BOOST_BASE_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT} ${CMAKE_THREAD_LIBS_INIT}
${USED_LUA_LIBRARIES} ${USED_LUA_LIBRARIES}
${MAYBE_STXXL_LIBRARY}
${TBB_LIBRARIES} ${TBB_LIBRARIES}
${MAYBE_RT_LIBRARY} ${MAYBE_RT_LIBRARY}
${MAYBE_COVERAGE_LIBRARIES}) ${MAYBE_COVERAGE_LIBRARIES})
@ -696,7 +676,6 @@ set(STORAGE_LIBRARIES
set(UTIL_LIBRARIES set(UTIL_LIBRARIES
${BOOST_BASE_LIBRARIES} ${BOOST_BASE_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT} ${CMAKE_THREAD_LIBS_INIT}
${MAYBE_STXXL_LIBRARY}
${TBB_LIBRARIES} ${TBB_LIBRARIES}
${MAYBE_COVERAGE_LIBRARIES} ${MAYBE_COVERAGE_LIBRARIES}
${ZLIB_LIBRARY}) ${ZLIB_LIBRARY})
@ -728,6 +707,11 @@ if (ENABLE_ASSERTIONS)
add_definitions(-DBOOST_ENABLE_ASSERT_HANDLER) add_definitions(-DBOOST_ENABLE_ASSERT_HANDLER)
endif() endif()
if (ENABLE_DEBUG_LOGGING)
message(STATUS "Enabling debug logging")
add_definitions(-DENABLE_DEBUG_LOGGING)
endif()
# Add RPATH info to executables so that when they are run after being installed # Add RPATH info to executables so that when they are run after being installed
# (i.e., from /usr/local/bin/) the linker can find library dependencies. For # (i.e., from /usr/local/bin/) the linker can find library dependencies. For
# more info see http://www.cmake.org/Wiki/CMake_RPATH_handling # more info see http://www.cmake.org/Wiki/CMake_RPATH_handling
@ -738,8 +722,10 @@ set_property(TARGET osrm-datastore PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
set_property(TARGET osrm-routed PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE) 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 FlatbuffersGlob third_party/flatbuffers/include/flatbuffers/*.h)
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(ApiHeader include/engine/api/base_result.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/approach.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 include/util/bearing.hpp) set(UtilHeader include/util/coordinate.hpp include/util/json_container.hpp include/util/typedefs.hpp include/util/alias.hpp include/util/exception.hpp include/util/bearing.hpp)
set(ExtractorHeader include/extractor/extractor.hpp include/storage/io_config.hpp include/extractor/extractor_config.hpp include/extractor/travel_mode.hpp) set(ExtractorHeader include/extractor/extractor.hpp include/storage/io_config.hpp include/extractor/extractor_config.hpp include/extractor/travel_mode.hpp)
@ -754,7 +740,9 @@ install(FILES ${PartitionerHeader} DESTINATION include/osrm/partitioner)
install(FILES ${ContractorHeader} DESTINATION include/osrm/contractor) install(FILES ${ContractorHeader} DESTINATION include/osrm/contractor)
install(FILES ${LibraryGlob} DESTINATION include/osrm) install(FILES ${LibraryGlob} DESTINATION include/osrm)
install(FILES ${ParametersGlob} DESTINATION include/osrm/engine/api) install(FILES ${ParametersGlob} DESTINATION include/osrm/engine/api)
install(FILES ${ApiHeader} DESTINATION include/osrm/engine/api)
install(FILES ${VariantGlob} DESTINATION include/mapbox) install(FILES ${VariantGlob} DESTINATION include/mapbox)
install(FILES ${FlatbuffersGlob} DESTINATION include/flatbuffers)
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-customize DESTINATION bin)
@ -768,6 +756,7 @@ 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)
install(TARGETS osrm_guidance DESTINATION lib)
# Install profiles and support library to /usr/local/share/osrm/profiles by default # Install profiles and support library to /usr/local/share/osrm/profiles by default

View File

@ -10,7 +10,7 @@ ECHO NUMBER_OF_PROCESSORS^: %NUMBER_OF_PROCESSORS%
:: Check CMake version :: Check CMake version
SET CMAKE_VERSION=3.9.2 SET CMAKE_VERSION=3.16.3
SET PATH=%PROJECT_DIR%\cmake-%CMAKE_VERSION%-win32-x86\bin;%PATH% SET PATH=%PROJECT_DIR%\cmake-%CMAKE_VERSION%-win32-x86\bin;%PATH%
ECHO cmake^: && cmake --version ECHO cmake^: && cmake --version
IF %ERRORLEVEL% NEQ 0 ECHO CMAKE not found && GOTO CMAKE_NOT_OK IF %ERRORLEVEL% NEQ 0 ECHO CMAKE not found && GOTO CMAKE_NOT_OK
@ -19,7 +19,7 @@ cmake --version | findstr /C:%CMAKE_VERSION% && GOTO CMAKE_OK
:CMAKE_NOT_OK :CMAKE_NOT_OK
ECHO CMAKE NOT OK - downloading new CMake %CMAKE_VERSION% ECHO CMAKE NOT OK - downloading new CMake %CMAKE_VERSION%
powershell Invoke-WebRequest https://cmake.org/files/v3.9/cmake-%CMAKE_VERSION%-win32-x86.zip -OutFile $env:PROJECT_DIR\cm.zip powershell Invoke-WebRequest https://cmake.org/files/v3.16/cmake-%CMAKE_VERSION%-win32-x86.zip -OutFile $env:PROJECT_DIR\cm.zip
IF %ERRORLEVEL% NEQ 0 GOTO ERROR IF %ERRORLEVEL% NEQ 0 GOTO ERROR
IF NOT EXIST cmake-%CMAKE_VERSION%-win32-x86 7z -y x cm.zip | %windir%\system32\FIND "ing archive" IF NOT EXIST cmake-%CMAKE_VERSION%-win32-x86 7z -y x cm.zip | %windir%\system32\FIND "ing archive"
IF %ERRORLEVEL% NEQ 0 GOTO ERROR IF %ERRORLEVEL% NEQ 0 GOTO ERROR
@ -29,8 +29,8 @@ ECHO CMAKE_OK
cmake --version cmake --version
ECHO activating VS command prompt ... ECHO activating VS command prompt ...
SET PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%PATH% SET PATH=C:\Program Files (x86)\MSBuild\15.0\Bin;%PATH%
CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64 CALL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
ECHO platform^: %platform% ECHO platform^: %platform%
@ -40,7 +40,7 @@ ECHO msbuild version
msbuild /version msbuild /version
:: HARDCODE "x64" as it is uppercase on AppVeyor and download from S3 is case sensitive :: HARDCODE "x64" as it is uppercase on AppVeyor and download from S3 is case sensitive
SET DEPSPKG=osrm-deps-win-x64-14.0-2017.09.7z SET DEPSPKG=osrm-deps-win-x64-14.2-2019.01.7z
:: local development :: local development
ECHO. ECHO.
@ -52,7 +52,7 @@ IF EXIST %DEPSPKG% DEL %DEPSPKG%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO downloading %DEPSPKG% ECHO downloading %DEPSPKG%
powershell Invoke-WebRequest https://mapbox.s3.amazonaws.com/windows-builds/windows-build-deps/$env:DEPSPKG -OutFile $env:PROJECT_DIR\$env:DEPSPKG powershell Invoke-WebRequest http://project-osrm.wolt.com/windows-build-deps/$env:DEPSPKG -OutFile $env:PROJECT_DIR\$env:DEPSPKG
IF %ERRORLEVEL% NEQ 0 GOTO ERROR IF %ERRORLEVEL% NEQ 0 GOTO ERROR
:SKIPDL :SKIPDL
@ -74,27 +74,35 @@ IF %ERRORLEVEL% NEQ 0 GOTO ERROR
SET OSRMDEPSDIR=%PROJECT_DIR%/osrm-deps SET OSRMDEPSDIR=%PROJECT_DIR%/osrm-deps
set PREFIX=%OSRMDEPSDIR%/libs set PREFIX=%OSRMDEPSDIR%/libs
set BOOST_ROOT=%OSRMDEPSDIR%/boost set BOOST_ROOT=%OSRMDEPSDIR%
set BOOST_LIBRARYDIR=%BOOST_ROOT%/lib set BOOST_LIBRARYDIR=%BOOST_ROOT%/lib
set TBB_INSTALL_DIR=%OSRMDEPSDIR%/tbb set TBB_INSTALL_DIR=%OSRMDEPSDIR%
set TBB_ARCH_PLATFORM=intel64/vc14 REM set TBB_ARCH_PLATFORM=intel64/vc17
ECHO OSRMDEPSDIR ^: %OSRMDEPSDIR% ECHO OSRMDEPSDIR ^: %OSRMDEPSDIR%
ECHO PREFIX ^: %PREFIX% ECHO PREFIX ^: %PREFIX%
ECHO BOOST_ROOT ^: %BOOST_ROOT% ECHO BOOST_ROOT ^: %BOOST_ROOT%
ECHO BOOST_LIBRARYDIR ^: %BOOST_LIBRARYDIR% ECHO BOOST_LIBRARYDIR ^: %BOOST_LIBRARYDIR%
ECHO TBB_INSTALL_DIR ^: %TBB_INSTALL_DIR% ECHO TBB_INSTALL_DIR ^: %TBB_INSTALL_DIR%
ECHO TBB_ARCH_PLATFORM ^: %TBB_ARCH_PLATFORM% REM ECHO TBB_ARCH_PLATFORM ^: %TBB_ARCH_PLATFORM%
ECHO calling cmake .... ECHO calling cmake ....
cmake .. ^ cmake .. ^
-G "Visual Studio 14 2015 Win64" ^ -G "Visual Studio 16 2019" ^
-DBOOST_ROOT=%BOOST_ROOT% ^ -DBOOST_ROOT=%BOOST_ROOT% ^
-DBOOST_LIBRARYDIR=%BOOST_LIBRARYDIR% ^ -DBOOST_LIBRARYDIR=%BOOST_LIBRARYDIR% ^
-DBoost_ADDITIONAL_VERSIONS=1.58 ^ -DBoost_ADDITIONAL_VERSIONS=1.73.0 ^
-DBoost_USE_MULTITHREADED=ON ^ -DBoost_USE_MULTITHREADED=ON ^
-DBoost_USE_STATIC_LIBS=ON ^ -DBoost_USE_STATIC_LIBS=ON ^
-DEXPAT_INCLUDE_DIR=%OSRMDEPSDIR% ^
-DEXPAT_LIBRARY=%OSRMDEPSDIR%/lib/libexpat.lib ^
-DBZIP2_INCLUDE_DIR=%OSRMDEPSDIR% ^
-DBZIP2_LIBRARIES=%OSRMDEPSDIR%/lib/libbz2.lib ^
-DLUA_INCLUDE_DIR=%OSRMDEPSDIR% ^
-DLUA_LIBRARIES=%OSRMDEPSDIR%/lib/lua5.3.5.lib ^
-DZLIB_INCLUDE_DIR=%OSRMDEPSDIR% ^
-DZLIB_LIBRARY=%OSRMDEPSDIR%/lib/libz.lib ^
-DCMAKE_BUILD_TYPE=%CONFIGURATION% ^ -DCMAKE_BUILD_TYPE=%CONFIGURATION% ^
-DCMAKE_INSTALL_PREFIX=%PREFIX% -DCMAKE_INSTALL_PREFIX=%PREFIX%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR IF %ERRORLEVEL% NEQ 0 GOTO ERROR
@ -106,60 +114,63 @@ msbuild OSRM.sln ^
/t:rebuild ^ /t:rebuild ^
/p:BuildInParallel=true ^ /p:BuildInParallel=true ^
/m:%NUMBER_OF_PROCESSORS% ^ /m:%NUMBER_OF_PROCESSORS% ^
/toolsversion:14.0 ^ /toolsversion:Current ^
/p:PlatformToolset=v140 ^ /p:PlatformToolset=v142 ^
/clp:Verbosity=normal ^ /clp:Verbosity=normal ^
/nologo ^ /nologo ^
/flp1:logfile=build_errors.txt;errorsonly ^ /flp1:logfile=build_errors.txt;errorsonly ^
/flp2:logfile=build_warnings.txt;warningsonly /flp2:logfile=build_warnings.txt;warningsonly
IF %ERRORLEVEL% NEQ 0 GOTO ERROR IF %ERRORLEVEL% EQU 1 GOTO ERROR
CD %PROJECT_DIR%\build CD %PROJECT_DIR%\build
IF %ERRORLEVEL% NEQ 0 GOTO ERROR IF %ERRORLEVEL% EQU 1 GOTO ERROR
SET PATH=%PROJECT_DIR%\osrm-deps\libs\bin;%PATH% SET PATH=%PROJECT_DIR%\osrm-deps\lib;%PATH%
ECHO running extractor-tests.exe ... ECHO running extractor-tests.exe ...
unit_tests\%Configuration%\extractor-tests.exe unit_tests\%Configuration%\extractor-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR IF %ERRORLEVEL% EQU 1 GOTO ERROR
ECHO running engine-tests.exe ... ECHO running engine-tests.exe ...
unit_tests\%Configuration%\engine-tests.exe unit_tests\%Configuration%\engine-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR IF %ERRORLEVEL% EQU 1 GOTO ERROR
ECHO running util-tests.exe ... ECHO running util-tests.exe ...
unit_tests\%Configuration%\util-tests.exe unit_tests\%Configuration%\util-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR IF %ERRORLEVEL% EQU 1 GOTO ERROR
ECHO running server-tests.exe ... ECHO running server-tests.exe ...
unit_tests\%Configuration%\server-tests.exe unit_tests\%Configuration%\server-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR IF %ERRORLEVEL% EQU 1 GOTO ERROR
ECHO running library-tests.exe ... ::TODO: CH processing sometimes mysteriously hangs, need to find why and enable tests below.
SET test_region=monaco ::ECHO running library-tests.exe ...
SET test_region_ch=ch\monaco ::SET test_region=monaco
SET test_region_corech=corech\monaco ::SET test_region_ch=ch\monaco
SET test_region_mld=mld\monaco ::SET test_region_corech=corech\monaco
SET test_osm=%test_region%.osm.pbf ::SET test_region_mld=mld\monaco
IF NOT EXIST %test_osm% powershell Invoke-WebRequest https://s3.amazonaws.com/mapbox/osrm/testing/monaco.osm.pbf -OutFile %test_osm% ::SET test_osm=%test_region%.osm.pbf
%Configuration%\osrm-extract.exe -p ../profiles/car.lua %test_osm% ::IF NOT EXIST %test_osm% powershell Invoke-WebRequest http://project-osrm.wolt.com/testing/monaco.osm.pbf -OutFile %test_osm%
MKDIR ch ::ECHO running %Configuration%\osrm-extract.exe -p ../profiles/car.lua %test_osm%
XCOPY %test_region%.osrm.* ch\ ::%Configuration%\osrm-extract.exe
XCOPY %test_region%.osrm ch\ ::%Configuration%\osrm-extract.exe -p ../profiles/car.lua %test_osm%
MKDIR corech ::MKDIR ch
XCOPY %test_region%.osrm.* corech\ ::XCOPY %test_region%.osrm.* ch\
XCOPY %test_region%.osrm corech\ ::XCOPY %test_region%.osrm ch\
MKDIR mld ::MKDIR corech
XCOPY %test_region%.osrm.* mld\ ::XCOPY %test_region%.osrm.* corech\
XCOPY %test_region%.osrm mld\ ::XCOPY %test_region%.osrm corech\
%Configuration%\osrm-contract.exe %test_region_ch%.osrm ::MKDIR mld
%Configuration%\osrm-contract.exe --core 0.8 %test_region_corech%.osrm ::XCOPY %test_region%.osrm.* mld\
%Configuration%\osrm-partition.exe %test_region_mld%.osrm ::XCOPY %test_region%.osrm mld\
%Configuration%\osrm-customize.exe %test_region_mld%.osrm ::%Configuration%\osrm-contract.exe %test_region_ch%.osrm
XCOPY /Y ch\*.* ..\test\data\ch\ ::%Configuration%\osrm-contract.exe --core 0.8 %test_region_corech%.osrm
XCOPY /Y corech\*.* ..\test\data\corech\ ::%Configuration%\osrm-partition.exe %test_region_mld%.osrm
XCOPY /Y mld\*.* ..\test\data\mld\ ::%Configuration%\osrm-customize.exe %test_region_mld%.osrm
unit_tests\%Configuration%\library-tests.exe ::XCOPY /Y ch\*.* ..\test\data\ch\
::XCOPY /Y corech\*.* ..\test\data\corech\
::XCOPY /Y mld\*.* ..\test\data\mld\
::unit_tests\%Configuration%\library-tests.exe
:ERROR :ERROR
ECHO ~~~~~~~~~~~~~~~~~~~~~~ ERROR %~f0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ECHO ~~~~~~~~~~~~~~~~~~~~~~ ERROR %~f0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -10,7 +10,7 @@ install:
init: init:
- git config --global core.autocrlf input - git config --global core.autocrlf input
os: Visual Studio 2015 os: Visual Studio 2019
# clone directory # clone directory
clone_folder: c:\projects\osrm clone_folder: c:\projects\osrm
@ -25,9 +25,10 @@ before_test:
- npm --version - npm --version
- npm install --ignore-scripts - npm install --ignore-scripts
- npm link --ignore-scripts - npm link --ignore-scripts
- SET PATH=%CD%\osrm-deps\libs\bin;%PATH% - SET PATH=%CD%\osrm-deps\lib;%PATH%
- SET OSRM_BUILD_DIR=build\%Configuration% - SET OSRM_BUILD_DIR=build\%Configuration%
- npm test # TODO tests fail with "JavaScript heap out of memory", need a better host?
# - npm test
branches: branches:
only: only:

View File

@ -11,7 +11,6 @@ SET CONFIGURATION=Release
FOR /F "tokens=*" %%i in ('git rev-parse --abbrev-ref HEAD') do SET APPVEYOR_REPO_BRANCH=%%i FOR /F "tokens=*" %%i in ('git rev-parse --abbrev-ref HEAD') do SET APPVEYOR_REPO_BRANCH=%%i
ECHO APPVEYOR_REPO_BRANCH^: %APPVEYOR_REPO_BRANCH% ECHO APPVEYOR_REPO_BRANCH^: %APPVEYOR_REPO_BRANCH%
SET PATH=C:\mb\windows-builds-64\tmp-bin\cmake-3.7.0-rc2-win32-x86\bin;%PATH%
SET PATH=C:\Program Files\7-Zip;%PATH% SET PATH=C:\Program Files\7-Zip;%PATH%
powershell Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted -Force powershell Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted -Force

View File

@ -1,51 +0,0 @@
# Locate STXXL library
# This module defines
# STXXL_FOUND, if false, do not try to link to libstxxl
# STXXL_LIBRARY
# STXXL_INCLUDE_DIR, where to find stxxl.h
#
IF( NOT STXXL_FIND_QUIETLY )
MESSAGE(STATUS "Looking for STXXL...")
ENDIF()
FIND_PATH(STXXL_INCLUDE_DIR stxxl.h
HINTS
$ENV{STXXL_DIR}
PATH_SUFFIXES stxxl include/stxxl/stxxl include/stxxl include
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/opt/local # DarwinPorts
/opt
)
FIND_LIBRARY(STXXL_LIBRARY
NAMES stxxl stxxl_debug
HINTS
$ENV{STXXL_DIR}
PATH_SUFFIXES lib64 lib
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/opt/local
/opt
)
INCLUDE(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set STXXL_FOUND to TRUE if
# all listed variables are TRUE
FIND_PACKAGE_HANDLE_STANDARD_ARGS(STXXL DEFAULT_MSG STXXL_LIBRARY STXXL_INCLUDE_DIR)
IF( NOT STXXL_FIND_QUIETLY )
IF( STXXL_FOUND )
MESSAGE(STATUS "Found STXXL: ${STXXL_LIBRARY}" )
ENDIF()
ENDIF()
MARK_AS_ADVANCED(STXXL_INCLUDE_DIR STXXL_LIBRARY)

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,8 @@
# OSRM HTTP server
Built-in HTTP server is a basic HTTP/1.0 server that supports 'keep-alive' extension. Persistent connections are limited to 512 requests per
connection and allow no more then 5 seconds between requests.
## General options ## General options
All OSRM HTTP requests use a common structure. All OSRM HTTP requests use a common structure.
@ -16,7 +21,7 @@ GET /{service}/{version}/{profile}/{coordinates}[.{format}]?option=value&option=
| `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}) or polyline6({polyline6})`. |
| `format`| Only `json` is supported at the moment. This parameter is optional and defaults to `json`. | | `format`| `json` or `flatbuffers`. 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).
@ -25,7 +30,7 @@ To pass parameters to each location some options support an array like encoding:
**Request options** **Request options**
| Option | Values | Description | | Option | Values | Description |
|----------------|--------------------------------------------------------|-------------------------------------------------------------------------------------------------------| |----------------|--------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|bearings |`{bearing};{bearing}[;{bearing} ...]` |Limits the search to segments with given bearing in degrees towards true north in clockwise direction. | |bearings |`{bearing};{bearing}[;{bearing} ...]` |Limits the search to segments with given bearing in degrees towards true north in clockwise direction. |
|radiuses |`{radius};{radius}[;{radius} ...]` |Limits the search to given radius in meters. | |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. |
@ -33,6 +38,7 @@ To pass parameters to each location some options support an array like encoding:
|approaches |`{approach};{approach}[;{approach} ...]` |Keep waypoints on curb side. | |approaches |`{approach};{approach}[;{approach} ...]` |Keep waypoints on curb side. |
|exclude |`{class}[,{class}]` |Additive list of classes to avoid, order does not matter. | |exclude |`{class}[,{class}]` |Additive list of classes to avoid, order does not matter. |
|snapping |`default` (default), `any` |Default snapping avoids is_startpoint (see profile) edges, `any` will snap to any edge in the graph | |snapping |`default` (default), `any` |Default snapping avoids is_startpoint (see profile) edges, `any` will snap to any edge in the graph |
|skip_waypoints |`true`, `false` (default) |Removes waypoints from the response. Waypoints are still calculated, but not serialized. Could be useful in case you are interested in some other part of response and do not want to transfer waste data. |
Where the elements follow the following format: Where the elements follow the following format:
@ -123,6 +129,9 @@ In addition to the [general options](#general-options) the following options are
|------------|------------------------------|----------------------------------------------------| |------------|------------------------------|----------------------------------------------------|
|number |`integer >= 1` (default `1`) |Number of nearest segments that should be returned. | |number |`integer >= 1` (default `1`) |Number of nearest segments that should be returned. |
As `waypoints` is a single thing, returned byt that service, using it with option `skip_waypoints` set to `true` is quite useless, but still
possible. In that case only `code` field will be returned.
**Response** **Response**
- `code` if the request was successful `Ok` otherwise see the service dependent and general status codes. - `code` if the request was successful `Ok` otherwise see the service dependent and general status codes.
@ -252,6 +261,8 @@ In addition to the [general options](#general-options) the following options are
Unlike other array encoded options, the length of `sources` and `destinations` can be **smaller or equal** Unlike other array encoded options, the length of `sources` and `destinations` can be **smaller or equal**
to number of input locations; to number of input locations;
With `skip_waypoints` set to `true`, both `sources` and `destinations` arrays will be skipped.
**Example:** **Example:**
``` ```
@ -939,3 +950,175 @@ Object used to describe waypoint on a route.
] ]
} }
``` ```
## Flatbuffers format
Default response format is `json`, but OSRM supports binary [`flatbuffers`](https://google.github.io/flatbuffers/) format, which
is much faster in serialization/deserialization, comparing to `json`.
The format itself is described in message descriptors, located at `include/engine/api/flatbuffers directory`. Those descriptors could
be compiled to provide protocol parsers in Go/Javascript/Typescript/Java/Dart/C#/Python/Lobster/Lua/Rust/PHP/Kotlin. Precompiled
protocol parser for C++ is supplied with OSRM.
`Flatbuffers` format provides exactly same data, as `json` format with a slightly different layout, which was optimized to minimize
in-transfer size.
### Root object
Root object is the only object, available from a 'raw' `flatbuffers` buffer. It can be constructed with a following call:
auto osrm = osrm::engine::api::fbresult::GetFBResult(some_input_buffer);
**Properties**
- `error`: `bool` Marks response as erroneous. Erroneus response should include `code` field set, all the other field may not present.
- `code`: `Error` Error description object, only present, when `error` is `true`
- `waypoints`: `[Waypoint]` Array of `Waypoint` objects. Should present for every service call, unless `skip_waypoints` is set to `true`. Table service will put `sources` array here.
- `routes`: `[RouteObject]` Array of `RouteObject` objects. May be empty or absent. Should present for Route/Trip/Match services call.
- `table`: `Table` Table object, may absent. Should be present in case of Table service call.
### Error object
Contains error information.
**Properties**
- `code`: `string` Error code
- `message`: `string` Detailed error message
### Waypoint object
Almost same as `json` Waypoint object. The following properties differ:
- `location`: `Position` Same as `json` location field, but different format.
- `nodes`: `Uint64Pair` Same as `json` nodes field, but different format.
### RouteObject object
Almost same as `json` Route object. The following properties differ:
- `polyline`: `string` Same as `json` geometry.polyline or geometry.polyline6 fields. One field for both formats.
- `coordinates`: `[Position]` Same as `json` geometry.coordinates field, but different format.
- `legs`: `[Leg]` Array of `Leg` objects.
### Leg object
Almost same as `json` Leg object. The following properties differ:
- `annotations`: `Annotation` Same as `json` annotation field, but different format.
- `steps`: `[Step]` Same as `step` annotation field, but different format.
### Step object
Almost same as `json` Step object. The following properties differ:
- `polyline`: `string` Same as `json` geometry.polyline or geometry.polyline6 fields. One field for both formats.
- `coordinates`: `[Position]` Same as `json` geometry.coordinates field, but different format.
- `maneuver`: `StepManeuver` Same as `json` maneuver field, but different format.
| `type` | Description |
|------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `Turn` | a basic turn into direction of the `modifier` |
| `NewName` | no turn is taken/possible, but the road name changes. The road can take a turn itself, following `modifier`. |
| `Depart` | indicates the departure of the leg |
| `Arrive` | indicates the destination of the leg |
| `Merge` | merge onto a street (e.g. getting on the highway from a ramp, the `modifier specifies the direction of the merge`) |
| `OnRamp` | take a ramp to enter a highway (direction given my `modifier`) |
| `OffRamp` | take a ramp to exit a highway (direction given my `modifier`) |
| `Fork` | take the left/right side at a fork depending on `modifier` |
| `EndOfRoad` | road ends in a T intersection turn in direction of `modifier` |
| `Continue` | Turn in direction of `modifier` to stay on the same road |
| `Roundabout` | traverse roundabout, if the route leaves the roundabout there will be an additional property `exit` for exit counting. The modifier specifies the direction of entering the roundabout. |
| `Rotary` | a traffic circle. While very similar to a larger version of a roundabout, it does not necessarily follow roundabout rules for right of way. It can offer `rotary_name` and/or `rotary_pronunciation` parameters (located in the RouteStep object) in addition to the `exit` parameter (located on the StepManeuver object). |
| `RoundaboutTurn` | Describes a turn at a small roundabout that should be treated as normal turn. The `modifier` indicates the turn direciton. Example instruction: `At the roundabout turn left`. |
| `Notification` | not an actual turn but a change in the driving conditions. For example the travel mode or classes. If the road takes a turn itself, the `modifier` describes the direction |
| `ExitRoundabout` | Describes a maneuver exiting a roundabout (usually preceeded by a `roundabout` instruction) |
| `ExitRotary` | Describes the maneuver exiting a rotary (large named roundabout) |
- `driving_side`: `bool` Ttrue stands for the left side driving.
- `intersections`: `[Intersection]` Same as `json` intersections field, but different format.
### Intersection object
Almost same as `json` Intersection object. The following properties differ:
- `location`: `Position` Same as `json` location property, but in different format.
- `lanes`: `[Lane]` Array of `Lane` objects.
### Lane object
Almost same as `json` Lane object. The following properties differ:
- `indications`: `Turn` Array of `Turn` enum values.
| `value` | Description |
|------------------------|---------------------------------------------------------------------------------------------------------------------------|
| `None` | No dedicated indication is shown. |
| `UTurn` | An indication signaling the possibility to reverse (i.e. fully bend arrow). |
| `SharpRight` | An indication indicating a sharp right turn (i.e. strongly bend arrow). |
| `Right` | An indication indicating a right turn (i.e. bend arrow). |
| `SlightRight` | An indication indicating a slight right turn (i.e. slightly bend arrow). |
| `Straight` | No dedicated indication is shown (i.e. straight arrow). |
| `SlightLeft` | An indication indicating a slight left turn (i.e. slightly bend arrow). |
| `Left` | An indication indicating a left turn (i.e. bend arrow). |
| `SharpLeft` | An indication indicating a sharp left turn (i.e. strongly bend arrow). |
### StepManeuver object
Almost same as `json` StepManeuver object. The following properties differ:
- `location`: `Position` Same as `json` location property, but in different format.
- `type`: `ManeuverType` Type of a maneuver (enum)
| `type` | Description |
|------------------|--------------------------------------------------------------|
| `Turn` | a basic turn into direction of the `modifier` |
| `NewName` | no turn is taken/possible, but the road name changes. The road can take a turn itself, following `modifier`. |
| `Depart` | indicates the departure of the leg |
| `Arrive` | indicates the destination of the leg |
| `Merge` | merge onto a street (e.g. getting on the highway from a ramp, the `modifier specifies the direction of the merge`) |
| `OnRamp` | take a ramp to enter a highway (direction given my `modifier`) |
| `OffRamp` | take a ramp to exit a highway (direction given my `modifier`) |
| `Fork` | take the left/right side at a fork depending on `modifier` |
| `EndOfRoad` | road ends in a T intersection turn in direction of `modifier`|
| `Continue` | Turn in direction of `modifier` to stay on the same road |
| `Roundabout` | traverse roundabout, if the route leaves the roundabout there will be an additional property `exit` for exit counting. The modifier specifies the direction of entering the roundabout. |
| `Rotary` | a traffic circle. While very similar to a larger version of a roundabout, it does not necessarily follow roundabout rules for right of way. It can offer `rotary_name` and/or `rotary_pronunciation` parameters (located in the RouteStep object) in addition to the `exit` parameter (located on the StepManeuver object). |
| `RoundaboutTurn` | Describes a turn at a small roundabout that should be treated as normal turn. The `modifier` indicates the turn direciton. Example instruction: `At the roundabout turn left`. |
| `Notification` | not an actual turn but a change in the driving conditions. For example the travel mode or classes. If the road takes a turn itself, the `modifier` describes the direction |
| `ExitRoundabout` | Describes a maneuver exiting a roundabout (usually preceeded by a `roundabout` instruction) |
| `ExitRotary` | Describes the maneuver exiting a rotary (large named roundabout) |
- `modifier`: `Turn` Maneuver turn (enum)
### Annotation object
Exactly same as `json` annotation object.
### Position object
A point on Earth.
***Properties***
- `longitute`: `float` Point's longitude
- `latitude`: `float` Point's latitude
### Uint64Pair
A pair of long long integers. Used only by `Waypoint` object.
***Properties***
- `first`: `uint64` First pair value.
- `second`: `uint64` Second pair value.
### Table object
Almost same as `json` Table object. The main difference is that 'sources' field is absent and root's object 'waypoints' field is
used instead. All the other differences follow:
- `durations`: `[float]` Flat representation of a durations matrix. Element at row;col can be adressed as [row * cols + col]
- `distances`: `[float]` Flat representation of a destinations matrix. Element at row;col can be adressed as [row * cols + col]
- `destinations`: `[Waypoint]` Array of `Waypoint` objects. Will be `null` if `skip_waypoints` will be set to `true`
- `rows`: `ushort` Number of rows in durations/destinations matrices.
- `cols`: `ushort` Number of cols in durations/destinations matrices.

View File

@ -25,6 +25,8 @@ var osrm = new OSRM('network.osrm');
Make sure you prepared the dataset with the correct toolchain. Make sure you prepared the dataset with the correct toolchain.
- `options.shared_memory` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Connects to the persistent shared memory datastore. - `options.shared_memory` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Connects to the persistent shared memory datastore.
This requires you to run `osrm-datastore` prior to creating an `OSRM` object. This requires you to run `osrm-datastore` prior to creating an `OSRM` object.
- `options.dataset_name` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** Connects to the persistent shared memory datastore defined by `--dataset_name` option when running `osrm-datastore`
This requires you to run `osrm-datastore --dataset_name` prior to creating an `OSRM` object.
- `options.memory_file` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** *DEPRECATED* - `options.memory_file` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** *DEPRECATED*
Old behaviour: Path to a file on disk to store the memory using mmap. Current behaviour: setting this value is the same as setting `mmap_memory: true`. Old behaviour: Path to a file on disk to store the memory using mmap. Current behaviour: setting this value is the same as setting `mmap_memory: true`.
- `options.mmap_memory` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Map on-disk files to virtual memory addresses (mmap), rather than loading into RAM. - `options.mmap_memory` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Map on-disk files to virtual memory addresses (mmap), rather than loading into RAM.
@ -48,6 +50,7 @@ Returns the fastest route between two or more coordinates while visiting the way
Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`. Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`.
- `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the coordinate snapping to streets in the given radius in meters. Can be `null` (unlimited, default) or `double >= 0`. - `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the coordinate snapping to streets in the given radius in meters. Can be `null` (unlimited, default) or `double >= 0`.
- `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.generate_hints` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Whether or not adds a Hint to the response which can be used in subsequent requests. (optional, default `true`)
- `options.alternatives` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Search for alternative routes. (optional, default `false`) - `options.alternatives` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Search for alternative routes. (optional, default `false`)
- `options.alternatives` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Search for up to this many alternative routes. - `options.alternatives` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Search for up to this many alternative routes.
_Please note that even if alternative routes are requested, a result cannot be guaranteed._ (optional, default `0`) _Please note that even if alternative routes are requested, a result cannot be guaranteed._ (optional, default `0`)
@ -89,6 +92,7 @@ Note: `coordinates` in the general options only supports a single `{longitude},{
Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`. Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`.
- `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the coordinate snapping to streets in the given radius in meters. Can be `null` (unlimited, default) or `double >= 0`. - `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the coordinate snapping to streets in the given radius in meters. Can be `null` (unlimited, default) or `double >= 0`.
- `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.generate_hints` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Whether or not adds a Hint to the response which can be used in subsequent requests. (optional, default `true`)
- `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`. - `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`.
@ -126,6 +130,7 @@ tables. Optionally returns distance table.
Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`. Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`.
- `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the coordinate snapping to streets in the given radius in meters. Can be `null` (unlimited, default) or `double >= 0`. - `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the coordinate snapping to streets in the given radius in meters. Can be `null` (unlimited, default) or `double >= 0`.
- `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.generate_hints` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Whether or not adds a Hint to the response which can be used in subsequent requests. (optional, default `true`)
- `options.sources` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** An array of `index` elements (`0 <= integer < #coordinates`) to - `options.sources` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** An array of `index` elements (`0 <= integer < #coordinates`) to
use use
location with given index as source. Default is to use all. location with given index as source. Default is to use all.
@ -136,6 +141,8 @@ tables. Optionally returns distance table.
- `options.fallback_coordinate` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** Either `input` (default) or `snapped`. If using a `fallback_speed`, use either the user-supplied coordinate (`input`), or the snapped coordinate (`snapped`) for calculating the as-the-crow-flies diestance between two points. - `options.fallback_coordinate` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** Either `input` (default) or `snapped`. If using a `fallback_speed`, use either the user-supplied coordinate (`input`), or the snapped coordinate (`snapped`) for calculating the as-the-crow-flies diestance between two points.
- `options.scale_factor` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Multiply the table duration values in the table by this number for more controlled input into a route optimization solver. - `options.scale_factor` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Multiply the table duration values in the table by this number for more controlled input into a route optimization solver.
- `options.snapping` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** Which edges can be snapped to, either `default`, or `any`. `default` only snaps to edges marked by the profile as `is_startpoint`, `any` will allow snapping to any edge in the routing graph. - `options.snapping` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** Which edges can be snapped to, either `default`, or `any`. `default` only snaps to edges marked by the profile as `is_startpoint`, `any` will allow snapping to any edge in the routing graph.
- `options.annotations` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Return the requested table or tables in response. Can be `['duration']` (return the duration matrix, default) or `['duration', distance']` (return both the duration matrix and the distance matrix).
- `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**
@ -206,6 +213,7 @@ if they can not be matched successfully.
- `options.bearings` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the search to segments with given bearing in degrees towards true north in clockwise direction. - `options.bearings` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the search to segments with given bearing in degrees towards true north in clockwise direction.
Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`. Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`.
- `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.generate_hints` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Whether or not adds a Hint to the response which can be used in subsequent requests. (optional, default `true`)
- `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route steps for each route. (optional, default `false`) - `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route steps for each route. (optional, default `false`)
- `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`) - `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`)
- `options.geometries` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route geometry format (influences overview and per step). Can also be `geojson`. (optional, default `polyline`) - `options.geometries` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route geometry format (influences overview and per step). Can also be `geojson`. (optional, default `polyline`)
@ -272,6 +280,7 @@ Right now, the following combinations are possible:
Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`. Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`.
- `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the coordinate snapping to streets in the given radius in meters. Can be `double >= 0` or `null` (unlimited, default). - `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the coordinate snapping to streets in the given radius in meters. Can be `double >= 0` or `null` (unlimited, default).
- `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.generate_hints` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Whether or not adds a Hint to the response which can be used in subsequent requests. (optional, default `true`)
- `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route steps for each route. (optional, default `false`) - `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route steps for each route. (optional, default `false`)
- `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`) - `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`)
- `options.geometries` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route geometry format (influences overview and per step). Can also be `geojson`. (optional, default `polyline`) - `options.geometries` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route geometry format (influences overview and per step). Can also be `geojson`. (optional, default `polyline`)

View File

@ -89,7 +89,7 @@ They all return a table of functions when you use `require` to load them. You ca
### setup() ### setup()
The `setup` function is called once when the profile is loaded and must return a table of configurations. It's also where you can do other global setup, like loading data sources that are used during processing. The `setup` function is called once when the profile is loaded and must return a table of configurations. It's also where you can do other global setup, like loading data sources that are used during processing.
Note that processing of data is parallelized and several unconnected LUA interpreters will be running at the same time. The `setup` function will be called once for each. Each LUA iinterpreter will have its own set of globals. Note that processing of data is parallelized and several unconnected LUA interpreters will be running at the same time. The `setup` function will be called once for each. Each LUA interpreter will have its own set of globals.
The following global properties can be set under `properties` in the hash you return in the `setup` function: The following global properties can be set under `properties` in the hash you return in the `setup` function:
@ -98,7 +98,7 @@ 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, default `false`)
use_turn_restrictions | Boolean | Are turn instructions followed? (default `false`) use_turn_restrictions | Boolean | Are turn restrictions followed? (default `false`)
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? (default `true`)
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
@ -178,7 +178,7 @@ exits | String | The ramp's exit numbers or
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/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
@ -223,7 +223,7 @@ source_number_of_lanes | Read | Integer |
source_highway_turn_classification | Read | Integer | Classification based on highway tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15)) source_highway_turn_classification | Read | Integer | Classification based on highway tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15))
source_access_turn_classification | Read | Integer | Classification based on access tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15)) source_access_turn_classification | Read | Integer | Classification based on access tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15))
source_speed | Read | Integer | Speed on this source road in km/h source_speed | Read | Integer | Speed on this source road in km/h
source_priority_class | Read | Enum | The type of road priority class of the source. Defined in `include/extractor/guidance/road_classification.hpp` source_priority_class | Read | Enum | The type of road priority class of the source. Defined in `include/extractor/road_classification.hpp`
target_restricted | Read | Boolean | Is the target a restricted access road? (See definition in `process_way`) target_restricted | Read | Boolean | Is the target a restricted access road? (See definition in `process_way`)
target_mode | Read | Enum | Travel mode after the turn. Defined in `include/extractor/travel_mode.hpp` target_mode | Read | Enum | Travel mode after the turn. Defined in `include/extractor/travel_mode.hpp`
target_is_motorway | Read | Boolean | Is the target road a motorway? target_is_motorway | Read | Boolean | Is the target road a motorway?
@ -232,7 +232,7 @@ target_number_of_lanes | Read | Integer |
target_highway_turn_classification | Read | Integer | Classification based on highway tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15)) target_highway_turn_classification | Read | Integer | Classification based on highway tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15))
target_access_turn_classification | Read | Integer | Classification based on access tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15)) target_access_turn_classification | Read | Integer | Classification based on access tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15))
target_speed | Read | Integer | Speed on this target road in km/h target_speed | Read | Integer | Speed on this target road in km/h
target_priority_class | Read | Enum | The type of road priority class of the target. Defined in `include/extractor/guidance/road_classification.hpp` target_priority_class | Read | Enum | The type of road priority class of the target. Defined in `include/extractor/road_classification.hpp`
roads_on_the_right | Read | Vector<ExtractionTurnLeg> | Vector with information about other roads on the right of the turn that are also connected at the intersection roads_on_the_right | Read | Vector<ExtractionTurnLeg> | Vector with information about other roads on the right of the turn that are also connected at the intersection
roads_on_the_left | Read | Vector<ExtractionTurnLeg> | Vector with information about other roads on the left of the turn that are also connected at the intersection. If turn is a u turn, this is empty. roads_on_the_left | Read | Vector<ExtractionTurnLeg> | Vector with information about other roads on the left of the turn that are also connected at the intersection. If turn is a u turn, this is empty.
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)
@ -252,7 +252,7 @@ number_of_lanes | Read | Integer | How many lanes does th
highway_turn_classification | Read | Integer | Classification based on highway tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15) highway_turn_classification | Read | Integer | Classification based on highway tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15)
access_turn_classification | Read | Integer | Classification based on access tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15) access_turn_classification | Read | Integer | Classification based on access tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15)
speed | Read | Integer | Speed on this road in km/h speed | Read | Integer | Speed on this road in km/h
priority_class | Read | Enum | The type of road priority class of the leg. Defined in `include/extractor/guidance/road_classification.hpp` priority_class | Read | Enum | The type of road priority class of the leg. Defined in `include/extractor/road_classification.hpp`
is_incoming | Read | Boolean | Is the road an incoming road of the intersection is_incoming | Read | Boolean | Is the road an incoming road of the intersection
is_outgoing | Read | Boolean | Is the road an outgoing road of the intersection is_outgoing | Read | Boolean | Is the road an outgoing road of the intersection

97
docs/windows-deps.md Normal file
View File

@ -0,0 +1,97 @@
# Building OSRM for Windows
## Dependencies
Get a decent Windows with decent Visual Studio (14 at least for C++11 support). The published binaries are build with
VS2019 and Windows SDK8.1.
In case you are using [prepacked Windows VM with VS2019](https://developer.microsoft.com/en-us/windows/downloads/virtual-machines/), you
have to install [Windows SDK 8.1](https://go.microsoft.com/fwlink/p/?LinkId=323507)
Prepare directories for dependencies, build and target file location.Target directory ($target starting from that moment) should have /include and /lib subdirectories.
### Bzip2
1. Download either from Wolt OSRM mirror or original distribution and unpack.
* https://project-osrm.wolt.com/deps/bzip2-1.0.8.tar.gz
* https://sourceware.org/pub/bzip2/bzip2-1.0.8.tar.gz
2. Start 'x64 Native Tools Command Prompt for VS2019' and change directory to unpacked source tree.
3. Issue `nmake /f makefile.msc`
4. Copy bzlib.h to $target\include and libbz2.lib to $target\lib
### ZLib
1. Download either from Wolt OSRM mirror or original distribution and unpack.
* https://project-osrm.wolt.com/deps/zlib-1.2.11.tar.gz
* https://www.zlib.net/zlib-1.2.11.tar.gz
2. Start 'x64 Native Tools Command Prompt for VS2019' and change directory to unpacked source tree.
3. Switch to `contrib\vstudio\vc14`
4. If needed, open `zlibvc.sln` with Visual Studio and retarget to your version of compiler and SDK.
5. Issue `msbuild zlibvc.sln /p:BuildInParallel=true /p:Configuration=Release /p:Platform=x64 /m:<Number of cpu cores>`
6. Copy x64\ZlibStatRelease\zlibstat.lib to $target\lib\libz.lib, copy zlib.h and zconf.h to $target\include
### ICU
1. Download either from Wolt OSRM mirror or original distribution and unpack.
* https://wolt-project.wolt.com/deps/icu4c-66_1-src.zip
* https://github.com/unicode-org/icu/releases/download/release-66-1/icu4c-66_1-src.zip
* https://wolt-project.wolt.com/deps/icu4c-66_1-data.zip
* https://github.com/unicode-org/icu/releases/download/release-66-1/icu4c-66_1-data.zip
2. Do retarget if neededby openinig .\source\allinone\allinone.sln and editing projects
3. Start 'x64 Native Tools Command Prompt for VS2019' and change directory to unpacked source tree.
4. Run build:
msbuild .\source\allinone\allinone.sln /nologo /p:BuildInParallel=true /p:Configuration=Release /p:Platform=x64 /m:<Number of cpu cores>
5. Copy lib64\*.lib to $target\lib, copy include contents to $target\include
6. Copy bin64\*dll to any dir withing your $PATH. At the same time copy them to $target\lib
### Boost
1. Download either from Wolt OSRM mirror or original distribution and unpack.
* https://project-osrm.wolt.com/deps/boost_1_73_0.zip
* https://dl.bintray.com/boostorg/release/1.73.0/source/boost_1_73_0.zip
2. Start 'x64 Native Tools Command Prompt for VS2019' and change directory to unpacked source tree.
3. Build b2:
bootstrap.bat --with-toolset=msvc-14.2
4. Build boost:
b2 -a -d release state --build-type=minimal toolset=msvc-14.2 -q runtime-link=shared link=static address-model=64 --with-iostreams --with-test --with-thread --with-filesystem --with-date_time --with-system --with-program_options --with-regex --disable-filesystem2 -sHAVE_ICU=1 include=<target>\include library-path=<target>\lib -sZLIB_SOURCE=<builddir>/zlib -zBZIP2_BINARY=libbz2 -sBZIP2_INCLUDE=<target>\include -sBZIP2_LIBPATH=<target>\lib -sICU_ICUUC_NAME=icuuc -sICU_ICUDT_NAME=icudt -sICU_ICUIN_NAME=icuin -sBUILD=boost_unit_test_framework -j<number of cpu cores>
5. Copy `boost` subdirectory to <target>\include and contents of `stage` to <target>\lib
### Expat
1. Download either from Wolt OSRM mirror or original distribution and unpack.
* https://project-osrm.wolt.com/deps/libexpat-2_2_9.zip
* https://github.com/libexpat/libexpat/archive/R_2_2_9.zip
2. Start 'x64 Native Tools Command Prompt for VS2019' and change directory to unpacked source tree.
3. Configure build my calling cmake:
mkdir expat\build
cd expat\build
cmake -G"Visual Studio 16 2019" -DCMAKE_BUILD_TYPE=Release -DEXPAT_MSVC_STATIC_CRT=ON -DEXPAT_BUILD_EXAMPLES=OFF -DEXPAT_BUILD_TESTS=OFF -DEXPAT_SHARED_LIBS=OFF ..
4. Build expat: `msbuild expat.sln /nologo /p:Configuration=Release /p:Platform=x64`
5. Copy `Release\libexpat.*` to <target>/lib. Copy `expat/lib/expat.h` and `expat/lib/expat_external.h` to <target>/include
### LUA
1. Download either from Wolt OSRM mirror or original distribution and unpack.
* https://project-osrm.wolt.com/deps/lua-5.3.5.tar.gz
* https://www.lua.org/ftp/lua-5.3.5.tar.gz
2. Start 'x64 Native Tools Command Prompt for VS2019' and change directory to unpacked source tree.
3. Lua doesn't have native MSVC support, so you have to compile it by hand:
cd src
cl /MD /O2 /c /DLUA_COMPAT_5_2 *.c
ren lua.obj lua.o
ren luac.obj luac.o
link /LIB /OUT:lua5.3.5.dll *.obj
4. Copy `lua5.3.5.lib` to <target>/lib. Copy `lua.h`,`lauxlib,h`,`lua.hpp`,`lualib.h`,`luaconf.h` to <target>/include
### TBB
1. Download either from Wolt OSRM mirror or original distribution and unpack.
* https://project-osrm.wolt.com/deps/oneTBB-v2020.2.zip
* https://github.com/oneapi-src/oneTBB/archive/v2020.2.zip
2. Retarget by opening build\vs2013\makefile.sln
3. Start 'x64 Native Tools Command Prompt for VS2019' and change directory to unpacked source tree.
4. Switch to build\vs2013 and build: `msbuild makefle.sln /nologo /p:Configuration=Release /p:Platform=x64`
5. Copy x64/Release/*.{dll,lib} files to <target>/lib and copy contents of include directory to <target>/include

View File

@ -52,14 +52,15 @@ int main(int argc, const char *argv[])
params.coordinates.push_back({util::FloatLongitude{7.419505}, util::FloatLatitude{43.736825}}); params.coordinates.push_back({util::FloatLongitude{7.419505}, util::FloatLatitude{43.736825}});
// Response is in JSON format // Response is in JSON format
json::Object result; engine::api::ResultT result = json::Object();
// Execute routing request, this does the heavy lifting // Execute routing request, this does the heavy lifting
const auto status = osrm.Route(params, result); const auto status = osrm.Route(params, result);
auto &json_result = result.get<json::Object>();
if (status == Status::Ok) if (status == Status::Ok)
{ {
auto &routes = result.values["routes"].get<json::Array>(); auto &routes = json_result.values["routes"].get<json::Array>();
// Let's just use the first route // Let's just use the first route
auto &route = routes.values.at(0).get<json::Object>(); auto &route = routes.values.at(0).get<json::Object>();
@ -79,8 +80,8 @@ int main(int argc, const char *argv[])
} }
else if (status == Status::Error) else if (status == Status::Error)
{ {
const auto code = result.values["code"].get<json::String>().value; const auto code = json_result.values["code"].get<json::String>().value;
const auto message = result.values["message"].get<json::String>().value; const auto message = json_result.values["message"].get<json::String>().value;
std::cout << "Code: " << code << "\n"; std::cout << "Code: " << code << "\n";
std::cout << "Message: " << code << "\n"; std::cout << "Message: " << code << "\n";

View File

@ -127,6 +127,7 @@ Feature: Bike - Access tags on ways
| | | agricultural | | | | | agricultural | |
| | | forestry | | | | | forestry | |
| | | delivery | | | | | delivery | |
| | | use_sidepath | |
Scenario: Bike - Access tags on both node and way Scenario: Bike - Access tags on both node and way
Then routability should be Then routability should be

View File

@ -43,6 +43,7 @@ Feature: Car - Handle physical limitation
| primary | 1 | | | | primary | 1 | | |
| primary | 3 | | x | | primary | 3 | | x |
| primary | | 1 | | | primary | | 1 | |
| primary | | 8' | x |
| primary | | 3 | x | | primary | | 3 | x |
| primary | | default | x | | primary | | default | x |
| primary | | none | x | | primary | | none | x |

View File

@ -111,3 +111,28 @@ Feature: Locating Nearest node on a Way - basic projection onto way
| 7 | b | | 7 | b |
| 8 | a | | 8 | a |
| 9 | b | | 9 | b |
Scenario: Nearest - easy-west way with flatbuffers
Given the node map
"""
0 1 2 3 4
a x b
5 6 7 8 9
"""
And the ways
| nodes |
| ab |
When I request nearest with flatbuffers I should get
| in | out |
| 0 | a |
| 1 | a |
| 2 | x |
| 3 | b |
| 4 | b |
| 5 | a |
| 6 | a |
| 7 | x |
| 8 | b |
| 9 | b |

View File

@ -1,27 +1,38 @@
var util = require('util'); var util = require('util');
var flatbuffers = require('../support/flatbuffers').flatbuffers;
var FBResult = require('../support/fbresult_generated').osrm.engine.api.fbresult.FBResult;
module.exports = function () { module.exports = function () {
const durationsRegex = new RegExp(/^I request a travel time matrix I should get$/); const durationsRegex = new RegExp(/^I request a travel time matrix I should get$/);
const distancesRegex = new RegExp(/^I request a travel distance matrix I should get$/); const distancesRegex = new RegExp(/^I request a travel distance matrix I should get$/);
const estimatesRegex = new RegExp(/^I request a travel time matrix I should get estimates for$/); const estimatesRegex = new RegExp(/^I request a travel time matrix I should get estimates for$/);
const durationsRegexFb = new RegExp(/^I request a travel time matrix with flatbuffers I should get$/);
const distancesRegexFb = new RegExp(/^I request a travel distance matrix with flatbuffers I should get$/);
const DURATIONS_NO_ROUTE = 2147483647; // MAX_INT const DURATIONS_NO_ROUTE = 2147483647; // MAX_INT
const DISTANCES_NO_ROUTE = 3.40282e+38; // MAX_FLOAT const DISTANCES_NO_ROUTE = 3.40282e+38; // MAX_FLOAT
this.When(durationsRegex, function(table, callback) {tableParse.call(this, table, DURATIONS_NO_ROUTE, 'durations', callback);}.bind(this)); const FORMAT_JSON = 'json';
this.When(distancesRegex, function(table, callback) {tableParse.call(this, table, DISTANCES_NO_ROUTE, 'distances', callback);}.bind(this)); const FORMAT_FB = 'flatbuffers';
this.When(estimatesRegex, function(table, callback) {tableParse.call(this, table, DISTANCES_NO_ROUTE, 'fallback_speed_cells', callback);}.bind(this));
this.When(durationsRegex, function(table, callback) {tableParse.call(this, table, DURATIONS_NO_ROUTE, 'durations', FORMAT_JSON, callback);}.bind(this));
this.When(distancesRegex, function(table, callback) {tableParse.call(this, table, DISTANCES_NO_ROUTE, 'distances', FORMAT_JSON, callback);}.bind(this));
this.When(estimatesRegex, function(table, callback) {tableParse.call(this, table, DISTANCES_NO_ROUTE, 'fallback_speed_cells', FORMAT_JSON, callback);}.bind(this));
this.When(durationsRegexFb, function(table, callback) {tableParse.call(this, table, DURATIONS_NO_ROUTE, 'durations', FORMAT_FB, callback);}.bind(this));
this.When(distancesRegexFb, function(table, callback) {tableParse.call(this, table, DISTANCES_NO_ROUTE, 'distances', FORMAT_FB, callback);}.bind(this));
}; };
const durationsParse = function(v) { return isNaN(parseInt(v)); }; const durationsParse = function(v) { return isNaN(parseInt(v)); };
const distancesParse = function(v) { return isNaN(parseFloat(v)); }; const distancesParse = function(v) { return isNaN(parseFloat(v)); };
const estimatesParse = function(v) { return isNaN(parseFloat(v)); }; const estimatesParse = function(v) { return isNaN(parseFloat(v)); };
function tableParse(table, noRoute, annotation, callback) { function tableParse(table, noRoute, annotation, format, callback) {
const parse = annotation == 'distances' ? distancesParse : (annotation == 'durations' ? durationsParse : estimatesParse); const parse = annotation == 'distances' ? distancesParse : (annotation == 'durations' ? durationsParse : estimatesParse);
const params = this.queryParams; const params = this.queryParams;
params.annotations = ['durations','fallback_speed_cells'].indexOf(annotation) !== -1 ? 'duration' : 'distance'; params.annotations = ['durations','fallback_speed_cells'].indexOf(annotation) !== -1 ? 'duration' : 'distance';
params.output = format;
var tableRows = table.raw(); var tableRows = table.raw();
@ -62,9 +73,10 @@ function tableParse(table, noRoute, annotation, callback) {
if (err) return callback(err); if (err) return callback(err);
if (!response.body.length) return callback(new Error('Invalid response body')); if (!response.body.length) return callback(new Error('Invalid response body'));
var result = [];
if (format === 'json') {
var json = JSON.parse(response.body); var json = JSON.parse(response.body);
var result = {};
if (annotation === 'fallback_speed_cells') { if (annotation === 'fallback_speed_cells') {
result = table.raw().map(row => row.map(() => '')); result = table.raw().map(row => row.map(() => ''));
json[annotation].forEach(pair => { json[annotation].forEach(pair => {
@ -84,6 +96,31 @@ function tableParse(table, noRoute, annotation, callback) {
return hashes; return hashes;
}); });
} }
} else { //flatbuffers
var body = response.body;
var bytes = new Uint8Array(body.length);
for (var indx = 0; indx < body.length; ++indx) {
bytes[indx] = body.charCodeAt(indx);
}
var buf = new flatbuffers.ByteBuffer(bytes);
var fb = FBResult.getRootAsFBResult(buf);
var matrix;
if (annotation === 'durations') {
matrix = fb.table().durationsArray();
}
if (annotation === 'distances') {
matrix = fb.table().distancesArray();
}
var cols = fb.table().cols();
var rows = fb.table().rows();
for (let r = 0; r < rows; ++r) {
result[r]={};
for(let c=0; c < cols; ++c) {
result[r][tableRows[0][c+1]] = matrix[r*cols + c];
}
}
}
var testRow = (row, ri, cb) => { var testRow = (row, ri, cb) => {
for (var k in result[ri]) { for (var k in result[ri]) {

View File

@ -1,5 +1,8 @@
var util = require('util'); var util = require('util');
var flatbuffers = require('../support/flatbuffers').flatbuffers;
var FBResult = require('../support/fbresult_generated').osrm.engine.api.fbresult.FBResult;
module.exports = function () { module.exports = function () {
this.When(/^I request nearest I should get$/, (table, callback) => { this.When(/^I request nearest I should get$/, (table, callback) => {
this.reprocessAndLoadData((e) => { this.reprocessAndLoadData((e) => {
@ -43,4 +46,55 @@ module.exports = function () {
this.processRowsAndDiff(table, testRow, callback); this.processRowsAndDiff(table, testRow, callback);
}); });
}); });
this.When(/^I request nearest with flatbuffers I should get$/, (table, callback) => {
this.reprocessAndLoadData((e) => {
if (e) return callback(e);
var testRow = (row, ri, cb) => {
var inNode = this.findNodeByName(row.in);
if (!inNode) throw new Error(util.format('*** unknown in-node "%s"', row.in));
var outNode = this.findNodeByName(row.out);
if (!outNode) throw new Error(util.format('*** unknown out-node "%s"', row.out));
this.queryParams.output = 'flatbuffers';
this.requestNearest(inNode, this.queryParams, (err, response) => {
if (err) return cb(err);
var coord;
if (response.statusCode === 200 && response.body.length) {
var body = response.body;
var bytes = new Uint8Array(body.length);
for (var indx = 0; indx < body.length; ++indx) {
bytes[indx] = body.charCodeAt(indx);
}
var buf = new flatbuffers.ByteBuffer(bytes);
var fb = FBResult.getRootAsFBResult(buf);
var location = fb.waypoints(0).location();
coord = [location.longitude(), location.latitude()];
var got = { in: row.in, out: row.out };
Object.keys(row).forEach((key) => {
if (key === 'out') {
if (this.FuzzyMatch.matchLocation(coord, outNode)) {
got[key] = row[key];
} else {
row[key] = util.format('%s [%d,%d]', row[key], outNode.lat, outNode.lon);
}
}
});
cb(null, got);
}
else {
cb();
}
});
};
this.processRowsAndDiff(table, testRow, callback);
});
});
}; };

View File

@ -12,4 +12,9 @@ module.exports = function () {
q.awaitAll(callback); q.awaitAll(callback);
}); });
this.Given(/^skip waypoints$/, (callback) => {
this.queryParams['skip_waypoints'] = true;
callback();
});
}; };

View File

@ -22,14 +22,9 @@ module.exports = function () {
this.PROFILES_PATH = path.resolve(this.ROOT_PATH, 'profiles'); this.PROFILES_PATH = path.resolve(this.ROOT_PATH, 'profiles');
this.FIXTURES_PATH = path.resolve(this.ROOT_PATH, 'unit_tests/fixtures'); this.FIXTURES_PATH = path.resolve(this.ROOT_PATH, 'unit_tests/fixtures');
this.BIN_PATH = process.env.OSRM_BUILD_DIR && process.env.OSRM_BUILD_DIR || path.resolve(this.ROOT_PATH, 'build'); this.BIN_PATH = process.env.OSRM_BUILD_DIR && process.env.OSRM_BUILD_DIR || path.resolve(this.ROOT_PATH, 'build');
var stxxl_config = path.resolve(this.ROOT_PATH, 'test/.stxxl');
if (!fs.existsSync(stxxl_config)) {
return callback(new Error('*** '+stxxl_config+ 'does not exist'));
}
this.DATASET_NAME = 'cucumber'; this.DATASET_NAME = 'cucumber';
this.PLATFORM_WINDOWS = process.platform.match(/^win.*/); this.PLATFORM_WINDOWS = process.platform.match(/^win.*/);
this.DEFAULT_ENVIRONMENT = Object.assign({STXXLCFG: stxxl_config}, process.env); this.DEFAULT_ENVIRONMENT = process.env;
this.DEFAULT_PROFILE = 'bicycle'; this.DEFAULT_PROFILE = 'bicycle';
this.DEFAULT_INPUT_FORMAT = 'osm'; this.DEFAULT_INPUT_FORMAT = 'osm';
this.DEFAULT_LOAD_METHOD = process.argv[process.argv.indexOf('-m') +1].match('mmap') ? 'mmap' : 'datastore'; this.DEFAULT_LOAD_METHOD = process.argv[process.argv.indexOf('-m') +1].match('mmap') ? 'mmap' : 'datastore';

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -155,6 +155,13 @@ module.exports = function () {
if (headers.has('locations')){ if (headers.has('locations')){
got.locations = (locations || '').trim(); got.locations = (locations || '').trim();
} }
if (headers.has('waypoints_count')) {
if ('waypoints' in json) {
got.waypoints_count = json.waypoints.length;
} else{
got.waypoints_count = 0;
}
}
/* /*
if (headers.has('approaches')){ if (headers.has('approaches')){
got.approaches = (approaches || '').trim(); got.approaches = (approaches || '').trim();

View File

@ -17,9 +17,9 @@ Feature: Basic Routing
| ab | | ab |
When I route I should get When I route I should get
| from | to | route | data_version | | from | to | route | data_version | waypoints_count |
| a | b | ab,ab | | | a | b | ab,ab | | 2 |
| b | a | ab,ab | | | b | a | ab,ab | | 2 |
Scenario: Data_version test Scenario: Data_version test
Given the node map Given the node map
@ -38,6 +38,23 @@ Feature: Basic Routing
| a | b | ab,ab | cucumber_data_version | | a | b | ab,ab | cucumber_data_version |
| b | a | ab,ab | cucumber_data_version | | b | a | ab,ab | cucumber_data_version |
Scenario: Skip_waypoints test
Given the node map
"""
a b
"""
And skip waypoints
And the ways
| nodes |
| ab |
When I route I should get
| from | to | route | waypoints_count |
| a | b | ab,ab | 0 |
| b | a | ab,ab | 0 |
Scenario: Routing in between two nodes of way Scenario: Routing in between two nodes of way
Given the node map Given the node map
""" """

View File

@ -21,6 +21,21 @@ Feature: Basic Duration Matrix
| a | 0 | 10 | | a | 0 | 10 |
| b | 10 | 0 | | b | 10 | 0 |
Scenario: Testbot - Travel time matrix of minimal network requested with flatbuffer format
Given the node map
"""
a b
"""
And the ways
| nodes |
| ab |
When I request a travel time matrix with flatbuffers I should get
| | a | b |
| a | 0 | 10 |
| b | 10 | 0 |
@ch @ch
Scenario: Testbot - Travel time matrix of minimal network with toll exclude Scenario: Testbot - Travel time matrix of minimal network with toll exclude
Given the query options Given the query options

View File

@ -2,6 +2,7 @@
#define ENGINE_API_BASE_API_HPP #define ENGINE_API_BASE_API_HPP
#include "engine/api/base_parameters.hpp" #include "engine/api/base_parameters.hpp"
#include "engine/api/flatbuffers/fbresult_generated.h"
#include "engine/datafacade/datafacade_base.hpp" #include "engine/datafacade/datafacade_base.hpp"
#include "engine/api/json_factory.hpp" #include "engine/api/json_factory.hpp"
@ -11,6 +12,7 @@
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/range/algorithm/transform.hpp> #include <boost/range/algorithm/transform.hpp>
#include <memory>
#include <vector> #include <vector>
namespace osrm namespace osrm
@ -71,6 +73,57 @@ class BaseAPI
} }
} }
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<fbresult::Waypoint>>>
MakeWaypoints(flatbuffers::FlatBufferBuilder *builder,
const std::vector<PhantomNodes> &segment_end_coordinates) const
{
BOOST_ASSERT(parameters.coordinates.size() > 0);
BOOST_ASSERT(parameters.coordinates.size() == segment_end_coordinates.size() + 1);
std::vector<flatbuffers::Offset<fbresult::Waypoint>> waypoints;
waypoints.resize(parameters.coordinates.size());
waypoints[0] =
MakeWaypoint(builder, segment_end_coordinates.front().source_phantom)->Finish();
std::transform(segment_end_coordinates.begin(),
segment_end_coordinates.end(),
std::next(waypoints.begin()),
[this, builder](const PhantomNodes &phantom_pair) {
return MakeWaypoint(builder, phantom_pair.target_phantom)->Finish();
});
return builder->CreateVector(waypoints);
}
// FIXME: gcc 4.9 does not like MakeWaypoints to be protected
// protected:
std::unique_ptr<fbresult::WaypointBuilder> MakeWaypoint(flatbuffers::FlatBufferBuilder *builder,
const PhantomNode &phantom) const
{
auto location =
fbresult::Position(static_cast<double>(util::toFloating(phantom.location.lon)),
static_cast<double>(util::toFloating(phantom.location.lat)));
auto name_string = builder->CreateString(
facade.GetNameForID(facade.GetNameIndex(phantom.forward_segment_id.id)).to_string());
flatbuffers::Offset<flatbuffers::String> hint_string;
if (parameters.generate_hints)
{
hint_string = builder->CreateString(Hint{phantom, facade.GetCheckSum()}.ToBase64());
}
auto waypoint = std::make_unique<fbresult::WaypointBuilder>(*builder);
waypoint->add_location(&location);
waypoint->add_distance(util::coordinate_calculation::fccApproximateDistance(
phantom.location, phantom.input_location));
waypoint->add_name(name_string);
if (parameters.generate_hints)
{
waypoint->add_hint(hint_string);
}
return waypoint;
}
const datafacade::BaseDataFacade &facade; const datafacade::BaseDataFacade &facade;
const BaseParameters &parameters; const BaseParameters &parameters;
}; };

View File

@ -70,16 +70,26 @@ struct BaseParameters
Any Any
}; };
enum class OutputFormatType
{
JSON,
FLATBUFFERS
};
std::vector<util::Coordinate> coordinates; std::vector<util::Coordinate> coordinates;
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; std::vector<boost::optional<Approach>> approaches;
std::vector<std::string> exclude; std::vector<std::string> exclude;
boost::optional<OutputFormatType> format = OutputFormatType::JSON;
// 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;
// Remove waypoints array from the response.
bool skip_waypoints = false;
SnappingType snapping = SnappingType::Default; SnappingType snapping = SnappingType::Default;
BaseParameters(const std::vector<util::Coordinate> coordinates_ = {}, BaseParameters(const std::vector<util::Coordinate> coordinates_ = {},

View File

@ -0,0 +1,23 @@
#ifndef ENGINE_API_BASE_RESULT_HPP
#define ENGINE_API_BASE_RESULT_HPP
#include <flatbuffers/flatbuffers.h>
#include <mapbox/variant.hpp>
#include <string>
#include "util/json_container.hpp"
namespace osrm
{
namespace engine
{
namespace api
{
using ResultT =
mapbox::util::variant<util::json::Object, std::string, flatbuffers::FlatBufferBuilder>;
} // ns api
} // ns engine
} // ns osrm
#endif

View File

@ -0,0 +1,20 @@
include "route.fbs";
include "table.fbs";
namespace osrm.engine.api.fbresult;
table Error {
code: string;
message: string;
}
table FBResult {
error: bool = false;
code: Error;
data_version: string;
waypoints: [Waypoint]; //Used as 'sources' waypoints for a 'Table' service
routes: [RouteObject];
table: Table;
}
root_type FBResult;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,6 @@
namespace osrm.engine.api.fbresult;
struct Position {
longitude: float;
latitude: float;
}

View File

@ -0,0 +1,110 @@
include "waypoint.fbs";
namespace osrm.engine.api.fbresult;
table Metadata {
datasource_names: [string];
}
table Annotation {
distance: [uint];
duration: [uint];
datasources: [uint];
nodes: [uint];
weight: [uint];
speed: [float];
metadata: Metadata;
}
enum ManeuverType: byte {
Turn,
NewName,
Depart,
Arrive,
Merge,
OnRamp,
OffRamp,
Fork,
EndOfRoad,
Continue,
Roundabout,
Rotary,
RoundaboutTurn,
Notification,
ExitRoundabout,
ExitRotary
}
enum Turn: byte {
None,
UTurn,
SharpRight,
Right,
SlightRight,
Straight,
SlightLeft,
Left,
SharpLeft
}
table StepManeuver {
location: Position;
bearing_before: ushort;
bearing_after: ushort;
type: ManeuverType;
modifier: Turn;
exit: ubyte;
}
table Lane {
indications: [Turn];
valid: bool;
}
table Intersection {
location: Position;
bearings: [short];
classes: [string];
entry: [bool];
in_bearing: uint;
out_bearing: uint;
lanes: [Lane];
}
table Step {
distance: float;
duration: float;
polyline: string;
coordinates: [Position];
weight: float;
name: string;
ref: string;
pronunciation: string;
destinations: string;
exits: string;
mode: string;
maneuver: StepManeuver;
intersections: [Intersection];
rotary_name: string;
rotary_pronunciation: string;
driving_side: bool; //Where true stands for the left side.
}
table Leg {
distance: double;
duration: double;
weight: double;
summary: string;
annotations: Annotation;
steps: [Step];
}
table RouteObject {
distance: float;
duration: float;
weight: float;
weight_name: string;
confidence: float; //Used only by 'Match' service
polyline: string;
coordinates: [Position];
legs: [Leg];
}

View File

@ -0,0 +1,11 @@
include "waypoint.fbs";
namespace osrm.engine.api.fbresult;
table Table {
durations: [float];
rows: ushort;
cols: ushort;
distances: [float];
destinations: [Waypoint];
fallback_speed_cells: [uint];
}

View File

@ -0,0 +1,19 @@
include "position.fbs";
namespace osrm.engine.api.fbresult;
struct Uint64Pair {
first: uint64;
second: uint64;
}
table Waypoint {
hint: string;
distance: float;
name: string;
location: Position;
nodes: Uint64Pair; //Used only by 'Nearest' service
matchings_index: uint; //Used only by 'Match' service
waypoint_index: uint; //Used by 'Match' and 'Trip' services
alternatives_count: uint; //Used only by 'Match' service
trips_index: uint; //Used only by 'Trip' service
}

View File

@ -33,6 +33,18 @@ namespace json
namespace detail namespace detail
{ {
// Check whether to include a modifier in the result of the API
inline bool isValidModifier(const guidance::StepManeuver maneuver)
{
return (maneuver.waypoint_type == guidance::WaypointType::None ||
maneuver.instruction.direction_modifier != osrm::guidance::DirectionModifier::UTurn);
}
inline bool hasValidLanes(const guidance::IntermediateIntersection &intersection)
{
return intersection.lanes.lanes_in_turn > 0;
}
util::json::Array coordinateToLonLat(const util::Coordinate &coordinate); util::json::Array coordinateToLonLat(const util::Coordinate &coordinate);
/** /**

View File

@ -29,6 +29,44 @@ class MatchAPI final : public RouteAPI
{ {
} }
void MakeResponse(const std::vector<map_matching::SubMatching> &sub_matchings,
const std::vector<InternalRouteResult> &sub_routes,
osrm::engine::api::ResultT &response) const
{
BOOST_ASSERT(sub_matchings.size() == sub_routes.size());
if (response.is<flatbuffers::FlatBufferBuilder>())
{
auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
MakeResponse(sub_matchings, sub_routes, fb_result);
}
else
{
auto &json_result = response.get<util::json::Object>();
MakeResponse(sub_matchings, sub_routes, json_result);
}
}
void MakeResponse(const std::vector<map_matching::SubMatching> &sub_matchings,
const std::vector<InternalRouteResult> &sub_routes,
flatbuffers::FlatBufferBuilder &fb_result) const
{
auto data_timestamp = facade.GetTimestamp();
flatbuffers::Offset<flatbuffers::String> data_version_string;
if (!data_timestamp.empty())
{
data_version_string = fb_result.CreateString(data_timestamp);
}
auto response = MakeFBResponse(sub_routes, fb_result, [this, &fb_result, &sub_matchings]() {
return MakeTracepoints(fb_result, sub_matchings);
});
if (!data_timestamp.empty())
{
response->add_data_version(data_version_string);
}
fb_result.Finish(response->Finish());
}
void MakeResponse(const std::vector<map_matching::SubMatching> &sub_matchings, void MakeResponse(const std::vector<map_matching::SubMatching> &sub_matchings,
const std::vector<InternalRouteResult> &sub_routes, const std::vector<InternalRouteResult> &sub_routes,
util::json::Object &response) const util::json::Object &response) const
@ -36,7 +74,6 @@ class MatchAPI final : public RouteAPI
auto number_of_routes = sub_matchings.size(); auto number_of_routes = sub_matchings.size();
util::json::Array routes; util::json::Array routes;
routes.values.reserve(number_of_routes); routes.values.reserve(number_of_routes);
BOOST_ASSERT(sub_matchings.size() == sub_routes.size());
for (auto index : util::irange<std::size_t>(0UL, sub_matchings.size())) for (auto index : util::irange<std::size_t>(0UL, sub_matchings.size()))
{ {
auto route = MakeRoute(sub_routes[index].segment_end_coordinates, auto route = MakeRoute(sub_routes[index].segment_end_coordinates,
@ -46,7 +83,10 @@ class MatchAPI final : public RouteAPI
route.values["confidence"] = sub_matchings[index].confidence; route.values["confidence"] = sub_matchings[index].confidence;
routes.values.push_back(std::move(route)); routes.values.push_back(std::move(route));
} }
if (!parameters.skip_waypoints)
{
response.values["tracepoints"] = MakeTracepoints(sub_matchings); response.values["tracepoints"] = MakeTracepoints(sub_matchings);
}
response.values["matchings"] = std::move(routes); response.values["matchings"] = std::move(routes);
response.values["code"] = "Ok"; response.values["code"] = "Ok";
} }
@ -55,12 +95,6 @@ class MatchAPI final : public RouteAPI
// FIXME this logic is a little backwards. We should change the output format of the // FIXME this logic is a little backwards. We should change the output format of the
// map_matching // map_matching
// routing algorithm to be easier to consume here. // routing algorithm to be easier to consume here.
util::json::Array
MakeTracepoints(const std::vector<map_matching::SubMatching> &sub_matchings) const
{
util::json::Array waypoints;
waypoints.values.reserve(parameters.coordinates.size());
struct MatchingIndex struct MatchingIndex
{ {
MatchingIndex() = default; MatchingIndex() = default;
@ -79,23 +113,69 @@ class MatchAPI final : public RouteAPI
} }
}; };
std::vector<MatchingIndex> trace_idx_to_matching_idx(parameters.coordinates.size()); flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<fbresult::Waypoint>>>
for (auto sub_matching_index : MakeTracepoints(flatbuffers::FlatBufferBuilder &fb_result,
util::irange(0u, static_cast<unsigned>(sub_matchings.size()))) const std::vector<map_matching::SubMatching> &sub_matchings) const
{ {
for (auto point_index : util::irange( std::vector<flatbuffers::Offset<fbresult::Waypoint>> waypoints;
0u, static_cast<unsigned>(sub_matchings[sub_matching_index].indices.size()))) waypoints.reserve(parameters.coordinates.size());
auto trace_idx_to_matching_idx = MakeMatchingIndices(sub_matchings);
BOOST_ASSERT(parameters.waypoints.empty() || sub_matchings.size() == 1);
std::size_t was_waypoint_idx = 0;
for (auto trace_index : util::irange<std::size_t>(0UL, parameters.coordinates.size()))
{ {
// tidied_to_original: index of the input coordinate that a tidied coordinate
// corresponds to. if (tidy_result.can_be_removed[trace_index])
// sub_matching indices: index of the coordinate passed to map matching plugin that {
// a matched node corresponds to. waypoints.push_back(fbresult::WaypointBuilder(fb_result).Finish());
trace_idx_to_matching_idx[tidy_result continue;
.tidied_to_original[sub_matchings[sub_matching_index] }
.indices[point_index]]] = auto matching_index = trace_idx_to_matching_idx[trace_index];
MatchingIndex{sub_matching_index, point_index}; if (matching_index.NotMatched())
{
waypoints.push_back(fbresult::WaypointBuilder(fb_result).Finish());
continue;
}
const auto &phantom =
sub_matchings[matching_index.sub_matching_index].nodes[matching_index.point_index];
auto waypoint = BaseAPI::MakeWaypoint(&fb_result, phantom);
waypoint->add_matchings_index(matching_index.sub_matching_index);
waypoint->add_alternatives_count(sub_matchings[matching_index.sub_matching_index]
.alternatives_count[matching_index.point_index]);
// waypoint indices need to be adjusted if route legs were collapsed
// waypoint parameter assumes there is only one match object
if (!parameters.waypoints.empty())
{
if (tidy_result.was_waypoint[trace_index])
{
waypoint->add_waypoint_index(was_waypoint_idx);
was_waypoint_idx++;
}
else
{
waypoint->add_waypoint_index(0);
} }
} }
else
{
waypoint->add_waypoint_index(matching_index.point_index);
}
waypoints.push_back(waypoint->Finish());
}
return fb_result.CreateVector(waypoints);
}
util::json::Array
MakeTracepoints(const std::vector<map_matching::SubMatching> &sub_matchings) const
{
util::json::Array waypoints;
waypoints.values.reserve(parameters.coordinates.size());
auto trace_idx_to_matching_idx = MakeMatchingIndices(sub_matchings);
BOOST_ASSERT(parameters.waypoints.empty() || sub_matchings.size() == 1); BOOST_ASSERT(parameters.waypoints.empty() || sub_matchings.size() == 1);
@ -141,6 +221,29 @@ class MatchAPI final : public RouteAPI
return waypoints; return waypoints;
} }
std::vector<MatchingIndex>
MakeMatchingIndices(const std::vector<map_matching::SubMatching> &sub_matchings) const
{
std::vector<MatchingIndex> trace_idx_to_matching_idx(parameters.coordinates.size());
for (auto sub_matching_index :
util::irange(0u, static_cast<unsigned>(sub_matchings.size())))
{
for (auto point_index : util::irange(
0u, static_cast<unsigned>(sub_matchings[sub_matching_index].indices.size())))
{
// tidied_to_original: index of the input coordinate that a tidied coordinate
// corresponds to.
// sub_matching indices: index of the coordinate passed to map matching plugin that
// a matched node corresponds to.
trace_idx_to_matching_idx[tidy_result
.tidied_to_original[sub_matchings[sub_matching_index]
.indices[point_index]]] =
MatchingIndex{sub_matching_index, point_index};
}
}
return trace_idx_to_matching_idx;
}
const MatchParameters &parameters; const MatchParameters &parameters;
const tidy::Result &tidy_result; const tidy::Result &tidy_result;
}; };

View File

@ -2,6 +2,7 @@
#define ENGINE_API_NEAREST_API_HPP #define ENGINE_API_NEAREST_API_HPP
#include "engine/api/base_api.hpp" #include "engine/api/base_api.hpp"
#include "engine/api/base_result.hpp"
#include "engine/api/nearest_parameters.hpp" #include "engine/api/nearest_parameters.hpp"
#include "engine/api/json_factory.hpp" #include "engine/api/json_factory.hpp"
@ -27,15 +28,74 @@ class NearestAPI final : public BaseAPI
} }
void MakeResponse(const std::vector<std::vector<PhantomNodeWithDistance>> &phantom_nodes, void MakeResponse(const std::vector<std::vector<PhantomNodeWithDistance>> &phantom_nodes,
util::json::Object &response) const osrm::engine::api::ResultT &response) const
{ {
BOOST_ASSERT(phantom_nodes.size() == 1); BOOST_ASSERT(phantom_nodes.size() == 1);
BOOST_ASSERT(parameters.coordinates.size() == 1); BOOST_ASSERT(parameters.coordinates.size() == 1);
util::json::Array waypoints; if (response.is<flatbuffers::FlatBufferBuilder>())
waypoints.values.resize(phantom_nodes.front().size()); {
auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
MakeResponse(phantom_nodes, fb_result);
}
else
{
auto &json_result = response.get<util::json::Object>();
MakeResponse(phantom_nodes, json_result);
}
}
void MakeResponse(const std::vector<std::vector<PhantomNodeWithDistance>> &phantom_nodes,
flatbuffers::FlatBufferBuilder &fb_result) const
{
auto data_timestamp = facade.GetTimestamp();
boost::optional<flatbuffers::Offset<flatbuffers::String>> data_version_string = boost::none;
if (!data_timestamp.empty())
{
data_version_string = fb_result.CreateString(data_timestamp);
}
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<fbresult::Waypoint>>>
waypoints_vector;
if (!parameters.skip_waypoints)
{
std::vector<flatbuffers::Offset<fbresult::Waypoint>> waypoints;
waypoints.resize(phantom_nodes.front().size());
std::transform( std::transform(
phantom_nodes.front().begin(), phantom_nodes.front().begin(),
phantom_nodes.front().end(),
waypoints.begin(),
[this, &fb_result](const PhantomNodeWithDistance &phantom_with_distance) {
auto &phantom_node = phantom_with_distance.phantom_node;
auto node_values = MakeNodes(phantom_node);
fbresult::Uint64Pair nodes{node_values.first, node_values.second};
auto waypoint = MakeWaypoint(&fb_result, phantom_node);
waypoint->add_nodes(&nodes);
return waypoint->Finish();
});
waypoints_vector = fb_result.CreateVector(waypoints);
}
fbresult::FBResultBuilder response(fb_result);
response.add_waypoints(waypoints_vector);
if (data_version_string)
{
response.add_data_version(*data_version_string);
}
fb_result.Finish(response.Finish());
}
void MakeResponse(const std::vector<std::vector<PhantomNodeWithDistance>> &phantom_nodes,
util::json::Object &response) const
{
if (!parameters.skip_waypoints)
{
util::json::Array waypoints;
waypoints.values.resize(phantom_nodes.front().size());
std::transform(phantom_nodes.front().begin(),
phantom_nodes.front().end(), phantom_nodes.front().end(),
waypoints.values.begin(), waypoints.values.begin(),
[this](const PhantomNodeWithDistance &phantom_with_distance) { [this](const PhantomNodeWithDistance &phantom_with_distance) {
@ -44,6 +104,25 @@ class NearestAPI final : public BaseAPI
util::json::Array nodes; util::json::Array nodes;
auto node_values = MakeNodes(phantom_node);
nodes.values.push_back(node_values.first);
nodes.values.push_back(node_values.second);
waypoint.values["nodes"] = std::move(nodes);
return waypoint;
});
response.values["waypoints"] = std::move(waypoints);
}
response.values["code"] = "Ok";
}
const NearestParameters &parameters;
protected:
std::pair<uint64_t, uint64_t> MakeNodes(const PhantomNode &phantom_node) const
{
std::uint64_t from_node = 0; std::uint64_t from_node = 0;
std::uint64_t to_node = 0; std::uint64_t to_node = 0;
@ -54,8 +133,8 @@ class NearestAPI final : public BaseAPI
const auto geometry_id = facade.GetGeometryIndex(segment_id).id; const auto geometry_id = facade.GetGeometryIndex(segment_id).id;
forward_geometry = facade.GetUncompressedForwardGeometry(geometry_id); forward_geometry = facade.GetUncompressedForwardGeometry(geometry_id);
auto osm_node_id = facade.GetOSMNodeIDOfNode( auto osm_node_id =
forward_geometry(phantom_node.fwd_segment_position)); facade.GetOSMNodeIDOfNode(forward_geometry(phantom_node.fwd_segment_position));
to_node = static_cast<std::uint64_t>(osm_node_id); to_node = static_cast<std::uint64_t>(osm_node_id);
} }
@ -68,26 +147,16 @@ class NearestAPI final : public BaseAPI
facade.GetOSMNodeIDOfNode(geometry(phantom_node.fwd_segment_position + 1)); facade.GetOSMNodeIDOfNode(geometry(phantom_node.fwd_segment_position + 1));
from_node = static_cast<std::uint64_t>(osm_node_id); from_node = static_cast<std::uint64_t>(osm_node_id);
} }
else if (phantom_node.forward_segment_id.enabled && else if (phantom_node.forward_segment_id.enabled && phantom_node.fwd_segment_position > 0)
phantom_node.fwd_segment_position > 0)
{ {
// In the case of one way, rely on forward segment only // In the case of one way, rely on forward segment only
auto osm_node_id = facade.GetOSMNodeIDOfNode( auto osm_node_id =
forward_geometry(phantom_node.fwd_segment_position - 1)); facade.GetOSMNodeIDOfNode(forward_geometry(phantom_node.fwd_segment_position - 1));
from_node = static_cast<std::uint64_t>(osm_node_id); from_node = static_cast<std::uint64_t>(osm_node_id);
} }
nodes.values.push_back(from_node);
nodes.values.push_back(to_node);
waypoint.values["nodes"] = std::move(nodes);
return waypoint; return std::make_pair(from_node, to_node);
});
response.values["code"] = "Ok";
response.values["waypoints"] = std::move(waypoints);
} }
const NearestParameters &parameters;
}; };
} // ns api } // ns api

View File

@ -3,6 +3,7 @@
#include "extractor/maneuver_override.hpp" #include "extractor/maneuver_override.hpp"
#include "engine/api/base_api.hpp" #include "engine/api/base_api.hpp"
#include "engine/api/base_result.hpp"
#include "engine/api/json_factory.hpp" #include "engine/api/json_factory.hpp"
#include "engine/api/route_parameters.hpp" #include "engine/api/route_parameters.hpp"
@ -48,10 +49,54 @@ class RouteAPI : public BaseAPI
MakeResponse(const InternalManyRoutesResult &raw_routes, MakeResponse(const InternalManyRoutesResult &raw_routes,
const std::vector<PhantomNodes> const std::vector<PhantomNodes>
&all_start_end_points, // all used coordinates, ignoring waypoints= parameter &all_start_end_points, // all used coordinates, ignoring waypoints= parameter
util::json::Object &response) const osrm::engine::api::ResultT &response) const
{ {
BOOST_ASSERT(!raw_routes.routes.empty()); BOOST_ASSERT(!raw_routes.routes.empty());
if (response.is<flatbuffers::FlatBufferBuilder>())
{
auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
MakeResponse(raw_routes, all_start_end_points, fb_result);
}
else
{
auto &json_result = response.get<util::json::Object>();
MakeResponse(raw_routes, all_start_end_points, json_result);
}
}
void
MakeResponse(const InternalManyRoutesResult &raw_routes,
const std::vector<PhantomNodes>
&all_start_end_points, // all used coordinates, ignoring waypoints= parameter
flatbuffers::FlatBufferBuilder &fb_result) const
{
auto data_timestamp = facade.GetTimestamp();
flatbuffers::Offset<flatbuffers::String> data_version_string;
if (!data_timestamp.empty())
{
data_version_string = fb_result.CreateString(data_timestamp);
}
auto response =
MakeFBResponse(raw_routes, fb_result, [this, &all_start_end_points, &fb_result]() {
return BaseAPI::MakeWaypoints(&fb_result, all_start_end_points);
});
if (!data_timestamp.empty())
{
response->add_data_version(data_version_string);
}
fb_result.Finish(response->Finish());
}
void
MakeResponse(const InternalManyRoutesResult &raw_routes,
const std::vector<PhantomNodes>
&all_start_end_points, // all used coordinates, ignoring waypoints= parameter
util::json::Object &response) const
{
util::json::Array jsRoutes; util::json::Array jsRoutes;
for (const auto &route : raw_routes.routes) for (const auto &route : raw_routes.routes)
@ -65,7 +110,10 @@ class RouteAPI : public BaseAPI
route.target_traversed_in_reverse)); route.target_traversed_in_reverse));
} }
if (!parameters.skip_waypoints)
{
response.values["waypoints"] = BaseAPI::MakeWaypoints(all_start_end_points); response.values["waypoints"] = BaseAPI::MakeWaypoints(all_start_end_points);
}
response.values["routes"] = std::move(jsRoutes); response.values["routes"] = std::move(jsRoutes);
response.values["code"] = "Ok"; response.values["code"] = "Ok";
auto data_timestamp = facade.GetTimestamp(); auto data_timestamp = facade.GetTimestamp();
@ -76,21 +124,101 @@ class RouteAPI : public BaseAPI
} }
protected: protected:
template <typename GetWptsFn>
std::unique_ptr<fbresult::FBResultBuilder>
MakeFBResponse(const InternalManyRoutesResult &raw_routes,
flatbuffers::FlatBufferBuilder &fb_result,
GetWptsFn getWaypoints) const
{
std::vector<flatbuffers::Offset<fbresult::RouteObject>> routes;
for (const auto &raw_route : raw_routes.routes)
{
if (!raw_route.is_valid())
continue;
routes.push_back(MakeRoute(fb_result,
raw_route.segment_end_coordinates,
raw_route.unpacked_path_segments,
raw_route.source_traversed_in_reverse,
raw_route.target_traversed_in_reverse));
}
auto routes_vector = fb_result.CreateVector(routes);
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<fbresult::Waypoint>>>
waypoints_vector;
if (!parameters.skip_waypoints)
{
waypoints_vector = getWaypoints();
}
auto response = std::make_unique<fbresult::FBResultBuilder>(fb_result);
response->add_routes(routes_vector);
response->add_waypoints(waypoints_vector);
return response;
}
template <typename ForwardIter> template <typename ForwardIter>
util::json::Value MakeGeometry(ForwardIter begin, ForwardIter end) const mapbox::util::variant<flatbuffers::Offset<flatbuffers::String>,
flatbuffers::Offset<flatbuffers::Vector<const fbresult::Position *>>>
MakeGeometry(flatbuffers::FlatBufferBuilder &builder, ForwardIter begin, ForwardIter end) const
{ {
if (parameters.geometries == RouteParameters::GeometriesType::Polyline) if (parameters.geometries == RouteParameters::GeometriesType::Polyline)
{ {
return json::makePolyline<100000>(begin, end); return builder.CreateString(encodePolyline<100000>(begin, end));
} }
else if (parameters.geometries == RouteParameters::GeometriesType::Polyline6)
if (parameters.geometries == RouteParameters::GeometriesType::Polyline6)
{ {
return json::makePolyline<1000000>(begin, end); return builder.CreateString(encodePolyline<1000000>(begin, end));
}
std::vector<fbresult::Position> coordinates;
coordinates.resize(std::distance(begin, end));
std::transform(begin, end, coordinates.begin(), [](const Coordinate &c) {
return fbresult::Position{static_cast<float>(util::toFloating(c.lon).__value),
static_cast<float>(util::toFloating(c.lat).__value)};
});
return builder.CreateVectorOfStructs(coordinates);
} }
boost::optional<util::json::Value>
MakeGeometry(boost::optional<std::vector<Coordinate>> &&annotations) const
{
boost::optional<util::json::Value> json_geometry;
if (annotations)
{
auto begin = annotations->begin();
auto end = annotations->end();
if (parameters.geometries == RouteParameters::GeometriesType::Polyline)
{
json_geometry = json::makePolyline<100000>(begin, end);
}
else if (parameters.geometries == RouteParameters::GeometriesType::Polyline6)
{
json_geometry = json::makePolyline<1000000>(begin, end);
}
else
{
BOOST_ASSERT(parameters.geometries == RouteParameters::GeometriesType::GeoJSON); BOOST_ASSERT(parameters.geometries == RouteParameters::GeometriesType::GeoJSON);
return json::makeGeoJSONGeometry(begin, end); json_geometry = json::makeGeoJSONGeometry(begin, end);
}
}
return json_geometry;
}
template <typename ValueType, typename GetFn>
flatbuffers::Offset<flatbuffers::Vector<ValueType>> GetAnnotations(
flatbuffers::FlatBufferBuilder &fb_result, guidance::LegGeometry &leg, GetFn Get) const
{
std::vector<ValueType> annotations_store;
annotations_store.reserve(leg.annotations.size());
for (const auto &step : leg.annotations)
{
annotations_store.push_back(Get(step));
}
return fb_result.CreateVector(annotations_store);
} }
template <typename GetFn> template <typename GetFn>
@ -107,118 +235,491 @@ class RouteAPI : public BaseAPI
return annotations_store; return annotations_store;
} }
fbresult::ManeuverType WaypointTypeToFB(guidance::WaypointType type) const
{
switch (type)
{
case guidance::WaypointType::Arrive:
return fbresult::ManeuverType_Arrive;
case guidance::WaypointType::Depart:
return fbresult::ManeuverType_Depart;
default:
return fbresult::ManeuverType_Notification;
}
}
fbresult::ManeuverType TurnTypeToFB(osrm::guidance::TurnType::Enum turn) const
{
static std::map<osrm::guidance::TurnType::Enum, fbresult::ManeuverType> mappings = {
{osrm::guidance::TurnType::Invalid, fbresult::ManeuverType_Notification},
{osrm::guidance::TurnType::NewName, fbresult::ManeuverType_NewName},
{osrm::guidance::TurnType::Continue, fbresult::ManeuverType_Continue},
{osrm::guidance::TurnType::Turn, fbresult::ManeuverType_Turn},
{osrm::guidance::TurnType::Merge, fbresult::ManeuverType_Merge},
{osrm::guidance::TurnType::OnRamp, fbresult::ManeuverType_OnRamp},
{osrm::guidance::TurnType::OffRamp, fbresult::ManeuverType_OffRamp},
{osrm::guidance::TurnType::Fork, fbresult::ManeuverType_Fork},
{osrm::guidance::TurnType::EndOfRoad, fbresult::ManeuverType_EndOfRoad},
{osrm::guidance::TurnType::Notification, fbresult::ManeuverType_Notification},
{osrm::guidance::TurnType::EnterRoundabout, fbresult::ManeuverType_Roundabout},
{osrm::guidance::TurnType::EnterAndExitRoundabout,
fbresult::ManeuverType_ExitRoundabout},
{osrm::guidance::TurnType::EnterRotary, fbresult::ManeuverType_Rotary},
{osrm::guidance::TurnType::EnterAndExitRotary, fbresult::ManeuverType_ExitRotary},
{osrm::guidance::TurnType::EnterRoundaboutIntersection,
fbresult::ManeuverType_Roundabout},
{osrm::guidance::TurnType::EnterAndExitRoundaboutIntersection,
fbresult::ManeuverType_ExitRoundabout},
{osrm::guidance::TurnType::NoTurn, fbresult::ManeuverType_Notification},
{osrm::guidance::TurnType::Suppressed, fbresult::ManeuverType_Notification},
{osrm::guidance::TurnType::EnterRoundaboutAtExit, fbresult::ManeuverType_Roundabout},
{osrm::guidance::TurnType::ExitRoundabout, fbresult::ManeuverType_ExitRoundabout},
{osrm::guidance::TurnType::EnterRotaryAtExit, fbresult::ManeuverType_Rotary},
{osrm::guidance::TurnType::ExitRotary, fbresult::ManeuverType_ExitRotary},
{osrm::guidance::TurnType::EnterRoundaboutIntersectionAtExit,
fbresult::ManeuverType_Roundabout},
{osrm::guidance::TurnType::ExitRoundaboutIntersection,
fbresult::ManeuverType_ExitRoundabout},
{osrm::guidance::TurnType::StayOnRoundabout, fbresult::ManeuverType_RoundaboutTurn},
{osrm::guidance::TurnType::Sliproad, fbresult::ManeuverType_Notification},
{osrm::guidance::TurnType::MaxTurnType, fbresult::ManeuverType_Notification}};
return mappings[turn];
}
fbresult::Turn TurnModifierToFB(osrm::guidance::DirectionModifier::Enum modifier) const
{
static std::map<osrm::guidance::DirectionModifier::Enum, fbresult::Turn> mappings = {
{osrm::guidance::DirectionModifier::UTurn, fbresult::Turn_UTurn},
{osrm::guidance::DirectionModifier::SharpRight, fbresult::Turn_SharpRight},
{osrm::guidance::DirectionModifier::Right, fbresult::Turn_Right},
{osrm::guidance::DirectionModifier::SlightRight, fbresult::Turn_SlightRight},
{osrm::guidance::DirectionModifier::Straight, fbresult::Turn_Straight},
{osrm::guidance::DirectionModifier::SlightLeft, fbresult::Turn_SlightLeft},
{osrm::guidance::DirectionModifier::Left, fbresult::Turn_Left},
{osrm::guidance::DirectionModifier::SharpLeft, fbresult::Turn_SharpLeft},
};
return mappings[modifier];
}
std::vector<int8_t> TurnLaneTypeToFB(const extractor::TurnLaneType::Mask lane_type) const
{
const static fbresult::Turn mapping[] = {fbresult::Turn_None,
fbresult::Turn_Straight,
fbresult::Turn_SharpLeft,
fbresult::Turn_Left,
fbresult::Turn_SlightLeft,
fbresult::Turn_SlightRight,
fbresult::Turn_Right,
fbresult::Turn_SharpRight,
fbresult::Turn_UTurn,
fbresult::Turn_SlightLeft,
fbresult::Turn_SlightRight};
std::vector<int8_t> result;
std::bitset<8 * sizeof(extractor::TurnLaneType::Mask)> mask(lane_type);
for (auto index : util::irange<std::size_t>(0, extractor::TurnLaneType::NUM_TYPES))
{
if (mask[index])
{
result.push_back(mapping[index]);
}
}
return result;
}
flatbuffers::Offset<fbresult::RouteObject>
MakeRoute(flatbuffers::FlatBufferBuilder &fb_result,
const std::vector<PhantomNodes> &segment_end_coordinates,
const std::vector<std::vector<PathData>> &unpacked_path_segments,
const std::vector<bool> &source_traversed_in_reverse,
const std::vector<bool> &target_traversed_in_reverse) const
{
auto legs_info = MakeLegs(segment_end_coordinates,
unpacked_path_segments,
source_traversed_in_reverse,
target_traversed_in_reverse);
std::vector<guidance::RouteLeg> legs = legs_info.first;
std::vector<guidance::LegGeometry> leg_geometries = legs_info.second;
auto route = guidance::assembleRoute(legs);
// Fill legs
std::vector<flatbuffers::Offset<fbresult::Leg>> routeLegs;
routeLegs.reserve(legs.size());
for (const auto idx : util::irange<std::size_t>(0UL, legs.size()))
{
auto leg = legs[idx];
auto &leg_geometry = leg_geometries[idx];
// Fill steps
std::vector<flatbuffers::Offset<fbresult::Step>> legSteps;
if (!leg.steps.empty())
{
legSteps.resize(leg.steps.size());
std::transform(leg.steps.begin(),
leg.steps.end(),
legSteps.begin(),
[this, &fb_result, &leg_geometry](auto &step) {
return this->MakeFBStep(fb_result, leg_geometry, step);
});
}
auto steps_vector = fb_result.CreateVector(legSteps);
// Fill annotations
// To maintain support for uses of the old default constructors, we check
// if annotations property was set manually after default construction
auto requested_annotations = parameters.annotations_type;
if ((parameters.annotations == true) &&
(parameters.annotations_type == RouteParameters::AnnotationsType::None))
{
requested_annotations = RouteParameters::AnnotationsType::All;
}
flatbuffers::Offset<fbresult::Annotation> annotation_buffer;
if (requested_annotations != RouteParameters::AnnotationsType::None)
{
annotation_buffer =
MakeFBAnnotations(fb_result, leg_geometry, requested_annotations);
}
flatbuffers::Offset<flatbuffers::String> summary_string;
if (!leg.summary.empty())
{
summary_string = fb_result.CreateString(leg.summary);
}
fbresult::LegBuilder legBuilder(fb_result);
legBuilder.add_distance(leg.distance);
legBuilder.add_duration(leg.duration);
legBuilder.add_weight(leg.weight);
if (!leg.summary.empty())
{
legBuilder.add_summary(summary_string);
}
legBuilder.add_steps(steps_vector);
if (requested_annotations != RouteParameters::AnnotationsType::None)
{
legBuilder.add_annotations(annotation_buffer);
}
routeLegs.emplace_back(legBuilder.Finish());
}
auto legs_vector = fb_result.CreateVector(routeLegs);
// Fill geometry
auto overview = MakeOverview(leg_geometries);
mapbox::util::variant<flatbuffers::Offset<flatbuffers::String>,
flatbuffers::Offset<flatbuffers::Vector<const fbresult::Position *>>>
geometry;
if (overview)
{
geometry = MakeGeometry(fb_result, overview->begin(), overview->end());
}
auto weight_name_string = fb_result.CreateString(facade.GetWeightName());
fbresult::RouteObjectBuilder routeObject(fb_result);
routeObject.add_distance(route.distance);
routeObject.add_duration(route.duration);
routeObject.add_weight(route.weight);
routeObject.add_weight_name(weight_name_string);
routeObject.add_legs(legs_vector);
if (overview)
{
mapbox::util::apply_visitor(GeometryVisitor<fbresult::RouteObjectBuilder>(routeObject),
geometry);
}
return routeObject.Finish();
}
flatbuffers::Offset<fbresult::Annotation>
MakeFBAnnotations(flatbuffers::FlatBufferBuilder &fb_result,
guidance::LegGeometry &leg_geometry,
const RouteParameters::AnnotationsType &requested_annotations) const
{
// AnnotationsType uses bit flags, & operator checks if a property is set
flatbuffers::Offset<flatbuffers::Vector<float>> speed;
if (parameters.annotations_type & RouteParameters::AnnotationsType::Speed)
{
double prev_speed = 0;
speed =
GetAnnotations<float>(fb_result,
leg_geometry,
[&prev_speed](const guidance::LegGeometry::Annotation &anno) {
if (anno.duration < std::numeric_limits<float>::min())
{
return prev_speed;
}
else
{
auto speed =
round(anno.distance / anno.duration * 10.) / 10.;
prev_speed = speed;
return util::json::clamp_float(speed);
}
});
}
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> duration;
if (requested_annotations & RouteParameters::AnnotationsType::Duration)
{
duration = GetAnnotations<uint32_t>(
fb_result, leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
return anno.duration;
});
}
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> distance;
if (requested_annotations & RouteParameters::AnnotationsType::Distance)
{
distance = GetAnnotations<uint32_t>(
fb_result, leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
return anno.distance;
});
}
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> weight;
if (requested_annotations & RouteParameters::AnnotationsType::Weight)
{
weight = GetAnnotations<uint32_t>(
fb_result, leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
return anno.weight;
});
}
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> datasources;
if (requested_annotations & RouteParameters::AnnotationsType::Datasources)
{
datasources = GetAnnotations<uint32_t>(
fb_result, leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
return anno.datasource;
});
}
std::vector<uint32_t> nodes;
if (requested_annotations & RouteParameters::AnnotationsType::Nodes)
{
nodes.reserve(leg_geometry.osm_node_ids.size());
for (const auto node_id : leg_geometry.osm_node_ids)
{
nodes.emplace_back(static_cast<uint64_t>(node_id));
}
}
auto nodes_vector = fb_result.CreateVector(nodes);
// Add any supporting metadata, if needed
bool use_metadata = requested_annotations & RouteParameters::AnnotationsType::Datasources;
flatbuffers::Offset<fbresult::Metadata> metadata_buffer;
if (use_metadata)
{
const auto MAX_DATASOURCE_ID = 255u;
std::vector<flatbuffers::Offset<flatbuffers::String>> names;
for (auto i = 0u; i < MAX_DATASOURCE_ID; i++)
{
const auto name = facade.GetDatasourceName(i);
// Length of 0 indicates the first empty name, so we can stop here
if (name.size() == 0)
break;
names.emplace_back(
fb_result.CreateString(std::string(facade.GetDatasourceName(i))));
}
metadata_buffer = fbresult::CreateMetadataDirect(fb_result, &names);
}
fbresult::AnnotationBuilder annotation(fb_result);
annotation.add_speed(speed);
annotation.add_duration(duration);
annotation.add_distance(distance);
annotation.add_weight(weight);
annotation.add_datasources(datasources);
annotation.add_nodes(nodes_vector);
if (use_metadata)
{
annotation.add_metadata(metadata_buffer);
}
return annotation.Finish();
}
template <typename Builder> class GeometryVisitor
{
public:
GeometryVisitor(Builder &builder) : builder(builder) {}
void operator()(const flatbuffers::Offset<flatbuffers::String> &value)
{
builder.add_polyline(value);
}
void operator()(
const flatbuffers::Offset<flatbuffers::Vector<const fbresult::Position *>> &value)
{
builder.add_coordinates(value);
}
private:
Builder &builder;
};
flatbuffers::Offset<fbresult::Step> MakeFBStep(flatbuffers::FlatBufferBuilder &builder,
const guidance::LegGeometry &leg_geometry,
const guidance::RouteStep &step) const
{
auto name_string = builder.CreateString(step.name);
flatbuffers::Offset<flatbuffers::String> ref_string;
if (!step.ref.empty())
{
ref_string = builder.CreateString(step.ref);
}
flatbuffers::Offset<flatbuffers::String> pronunciation_string;
if (!step.pronunciation.empty())
{
pronunciation_string = builder.CreateString(step.pronunciation);
}
flatbuffers::Offset<flatbuffers::String> destinations_string;
if (!step.destinations.empty())
{
destinations_string = builder.CreateString(step.destinations);
}
flatbuffers::Offset<flatbuffers::String> exists_string;
if (!step.exits.empty())
{
exists_string = builder.CreateString(step.exits);
}
flatbuffers::Offset<flatbuffers::String> rotary_name_string;
flatbuffers::Offset<flatbuffers::String> rotary_pronunciation_string;
if (!step.rotary_name.empty())
{
rotary_name_string = builder.CreateString(step.rotary_name);
if (!step.rotary_pronunciation.empty())
{
rotary_pronunciation_string = builder.CreateString(step.rotary_pronunciation);
}
}
auto mode_string = builder.CreateString(extractor::travelModeToString(step.mode));
// Geometry
auto geometry = MakeGeometry(builder,
leg_geometry.locations.begin() + step.geometry_begin,
leg_geometry.locations.begin() + step.geometry_end);
// Maneuver
fbresult::StepManeuverBuilder maneuver(builder);
fbresult::Position maneuverPosition{
static_cast<float>(util::toFloating(step.maneuver.location.lon).__value),
static_cast<float>(util::toFloating(step.maneuver.location.lat).__value)};
maneuver.add_location(&maneuverPosition);
maneuver.add_bearing_before(step.maneuver.bearing_before);
maneuver.add_bearing_after(step.maneuver.bearing_after);
if (step.maneuver.waypoint_type == guidance::WaypointType::None)
maneuver.add_type(TurnTypeToFB(step.maneuver.instruction.type));
else
maneuver.add_type(WaypointTypeToFB(step.maneuver.waypoint_type));
if (osrm::engine::api::json::detail::isValidModifier(step.maneuver))
{
maneuver.add_modifier(TurnModifierToFB(step.maneuver.instruction.direction_modifier));
}
if (step.maneuver.exit != 0)
{
maneuver.add_exit(step.maneuver.exit);
}
auto maneuver_buffer = maneuver.Finish();
// intersections
auto intersections_vector = MakeFBIntersections(builder, step);
fbresult::StepBuilder stepBuilder(builder);
stepBuilder.add_duration(step.duration);
stepBuilder.add_distance(step.distance);
stepBuilder.add_weight(step.weight);
stepBuilder.add_name(name_string);
stepBuilder.add_mode(mode_string);
stepBuilder.add_driving_side(step.is_left_hand_driving);
stepBuilder.add_ref(ref_string);
stepBuilder.add_pronunciation(pronunciation_string);
stepBuilder.add_destinations(destinations_string);
stepBuilder.add_exits(exists_string);
stepBuilder.add_rotary_name(rotary_name_string);
stepBuilder.add_rotary_pronunciation(rotary_pronunciation_string);
stepBuilder.add_intersections(intersections_vector);
stepBuilder.add_maneuver(maneuver_buffer);
mapbox::util::apply_visitor(GeometryVisitor<fbresult::StepBuilder>(stepBuilder), geometry);
return stepBuilder.Finish();
};
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<fbresult::Intersection>>>
MakeFBIntersections(flatbuffers::FlatBufferBuilder &fb_result,
const guidance::RouteStep &step) const
{
std::vector<flatbuffers::Offset<fbresult::Intersection>> intersections;
intersections.resize(step.intersections.size());
std::transform(
step.intersections.begin(),
step.intersections.end(),
intersections.begin(),
[&fb_result, this](const guidance::IntermediateIntersection &intersection) {
std::vector<flatbuffers::Offset<fbresult::Lane>> lanes;
if (json::detail::hasValidLanes(intersection))
{
BOOST_ASSERT(intersection.lanes.lanes_in_turn >= 1);
lanes.reserve(intersection.lane_description.size());
LaneID lane_id = intersection.lane_description.size();
for (const auto &lane_desc : intersection.lane_description)
{
--lane_id;
auto indications = TurnLaneTypeToFB(lane_desc);
auto lane_valid = lane_id >= intersection.lanes.first_lane_from_the_right &&
lane_id < intersection.lanes.first_lane_from_the_right +
intersection.lanes.lanes_in_turn;
lanes.push_back(
fbresult::CreateLaneDirect(fb_result, &indications, lane_valid));
}
}
auto lanes_vector = fb_result.CreateVector(lanes);
fbresult::Position maneuverPosition{
static_cast<float>(util::toFloating(intersection.location.lon).__value),
static_cast<float>(util::toFloating(intersection.location.lat).__value)};
auto bearings_vector = fb_result.CreateVector(intersection.bearings);
std::vector<flatbuffers::Offset<flatbuffers::String>> classes;
classes.resize(intersection.classes.size());
std::transform(
intersection.classes.begin(),
intersection.classes.end(),
classes.begin(),
[&fb_result](const std::string cls) { return fb_result.CreateString(cls); });
auto classes_vector = fb_result.CreateVector(classes);
auto entry_vector = fb_result.CreateVector(intersection.entry);
fbresult::IntersectionBuilder intersectionBuilder(fb_result);
intersectionBuilder.add_location(&maneuverPosition);
intersectionBuilder.add_bearings(bearings_vector);
intersectionBuilder.add_classes(classes_vector);
intersectionBuilder.add_entry(entry_vector);
intersectionBuilder.add_in_bearing(intersection.in);
intersectionBuilder.add_out_bearing(intersection.out);
intersectionBuilder.add_lanes(lanes_vector);
return intersectionBuilder.Finish();
});
return fb_result.CreateVector(intersections);
}
util::json::Object MakeRoute(const std::vector<PhantomNodes> &segment_end_coordinates, util::json::Object MakeRoute(const std::vector<PhantomNodes> &segment_end_coordinates,
const std::vector<std::vector<PathData>> &unpacked_path_segments, const std::vector<std::vector<PathData>> &unpacked_path_segments,
const std::vector<bool> &source_traversed_in_reverse, const std::vector<bool> &source_traversed_in_reverse,
const std::vector<bool> &target_traversed_in_reverse) const const std::vector<bool> &target_traversed_in_reverse) const
{ {
std::vector<guidance::RouteLeg> legs; auto legs_info = MakeLegs(segment_end_coordinates,
std::vector<guidance::LegGeometry> leg_geometries; unpacked_path_segments,
auto number_of_legs = segment_end_coordinates.size(); source_traversed_in_reverse,
legs.reserve(number_of_legs); target_traversed_in_reverse);
leg_geometries.reserve(number_of_legs); std::vector<guidance::RouteLeg> legs = legs_info.first;
std::vector<guidance::LegGeometry> leg_geometries = legs_info.second;
for (auto idx : util::irange<std::size_t>(0UL, number_of_legs))
{
const auto &phantoms = segment_end_coordinates[idx];
const auto &path_data = unpacked_path_segments[idx];
const bool reversed_source = source_traversed_in_reverse[idx];
const bool reversed_target = target_traversed_in_reverse[idx];
auto leg_geometry = guidance::assembleGeometry(BaseAPI::facade,
path_data,
phantoms.source_phantom,
phantoms.target_phantom,
reversed_source,
reversed_target);
auto leg = guidance::assembleLeg(facade,
path_data,
leg_geometry,
phantoms.source_phantom,
phantoms.target_phantom,
reversed_target,
parameters.steps);
util::Log(logDEBUG) << "Assembling steps " << std::endl;
if (parameters.steps)
{
auto steps = guidance::assembleSteps(BaseAPI::facade,
path_data,
leg_geometry,
phantoms.source_phantom,
phantoms.target_phantom,
reversed_source,
reversed_target);
// Apply maneuver overrides before any other post
// processing is performed
guidance::applyOverrides(BaseAPI::facade, steps, leg_geometry);
// Collapse segregated steps before others
steps = guidance::collapseSegregatedTurnInstructions(std::move(steps));
/* Perform step-based post-processing.
*
* Using post-processing on basis of route-steps for a single leg at a time
* comes at the cost that we cannot count the correct exit for roundabouts.
* We can only emit the exit nr/intersections up to/starting at a part of the leg.
* If a roundabout is not terminated in a leg, we will end up with a
*enter-roundabout
* and exit-roundabout-nr where the exit nr is out of sync with the previous enter.
*
* | S |
* * *
* ----* * ----
* T
* ----* * ----
* V * *
* | |
* | |
*
* Coming from S via V to T, we end up with the legs S->V and V->T. V-T will say to
*take
* the second exit, even though counting from S it would be the third.
* For S, we only emit `roundabout` without an exit number, showing that we enter a
*roundabout
* to find a via point.
* The same exit will be emitted, though, if we should start routing at S, making
* the overall response consistent.
*
* CAUTION: order of post-processing steps is important
* - handleRoundabouts must be called before collapseTurnInstructions that
* expects post-processed roundabouts
*/
guidance::trimShortSegments(steps, leg_geometry);
leg.steps = guidance::handleRoundabouts(std::move(steps));
leg.steps = guidance::collapseTurnInstructions(std::move(leg.steps));
leg.steps = guidance::anticipateLaneChange(std::move(leg.steps));
leg.steps = guidance::buildIntersections(std::move(leg.steps));
leg.steps = guidance::suppressShortNameSegments(std::move(leg.steps));
leg.steps = guidance::assignRelativeLocations(std::move(leg.steps),
leg_geometry,
phantoms.source_phantom,
phantoms.target_phantom);
leg_geometry = guidance::resyncGeometry(std::move(leg_geometry), leg.steps);
}
leg_geometries.push_back(std::move(leg_geometry));
legs.push_back(std::move(leg));
}
auto route = guidance::assembleRoute(legs); auto route = guidance::assembleRoute(legs);
boost::optional<util::json::Value> json_overview; boost::optional<util::json::Value> json_overview =
if (parameters.overview != RouteParameters::OverviewType::False) MakeGeometry(MakeOverview(leg_geometries));
{
const auto use_simplification =
parameters.overview == RouteParameters::OverviewType::Simplified;
BOOST_ASSERT(use_simplification ||
parameters.overview == RouteParameters::OverviewType::Full);
auto overview = guidance::assembleOverview(leg_geometries, use_simplification);
json_overview = MakeGeometry(overview.begin(), overview.end());
}
std::vector<util::json::Value> step_geometries; std::vector<util::json::Value> step_geometries;
const auto total_step_count = const auto total_step_count =
@ -364,6 +865,127 @@ class RouteAPI : public BaseAPI
} }
const RouteParameters &parameters; const RouteParameters &parameters;
std::pair<std::vector<guidance::RouteLeg>, std::vector<guidance::LegGeometry>>
MakeLegs(const std::vector<PhantomNodes> &segment_end_coordinates,
const std::vector<std::vector<PathData>> &unpacked_path_segments,
const std::vector<bool> &source_traversed_in_reverse,
const std::vector<bool> &target_traversed_in_reverse) const
{
auto result =
std::make_pair(std::vector<guidance::RouteLeg>(), std::vector<guidance::LegGeometry>());
auto &legs = result.first;
auto &leg_geometries = result.second;
auto number_of_legs = segment_end_coordinates.size();
legs.reserve(number_of_legs);
leg_geometries.reserve(number_of_legs);
for (auto idx : util::irange<std::size_t>(0UL, number_of_legs))
{
const auto &phantoms = segment_end_coordinates[idx];
const auto &path_data = unpacked_path_segments[idx];
const bool reversed_source = source_traversed_in_reverse[idx];
const bool reversed_target = target_traversed_in_reverse[idx];
auto leg_geometry = guidance::assembleGeometry(BaseAPI::facade,
path_data,
phantoms.source_phantom,
phantoms.target_phantom,
reversed_source,
reversed_target);
auto leg = guidance::assembleLeg(facade,
path_data,
leg_geometry,
phantoms.source_phantom,
phantoms.target_phantom,
reversed_target,
parameters.steps);
util::Log(logDEBUG) << "Assembling steps " << std::endl;
if (parameters.steps)
{
auto steps = guidance::assembleSteps(BaseAPI::facade,
path_data,
leg_geometry,
phantoms.source_phantom,
phantoms.target_phantom,
reversed_source,
reversed_target);
// Apply maneuver overrides before any other post
// processing is performed
guidance::applyOverrides(BaseAPI::facade, steps, leg_geometry);
// Collapse segregated steps before others
steps = guidance::collapseSegregatedTurnInstructions(std::move(steps));
/* Perform step-based post-processing.
*
* Using post-processing on basis of route-steps for a single leg at a time
* comes at the cost that we cannot count the correct exit for roundabouts.
* We can only emit the exit nr/intersections up to/starting at a part of the leg.
* If a roundabout is not terminated in a leg, we will end up with a
*enter-roundabout
* and exit-roundabout-nr where the exit nr is out of sync with the previous enter.
*
* | S |
* * *
* ----* * ----
* T
* ----* * ----
* V * *
* | |
* | |
*
* Coming from S via V to T, we end up with the legs S->V and V->T. V-T will say to
*take
* the second exit, even though counting from S it would be the third.
* For S, we only emit `roundabout` without an exit number, showing that we enter a
*roundabout
* to find a via point.
* The same exit will be emitted, though, if we should start routing at S, making
* the overall response consistent.
*
* CAUTION: order of post-processing steps is important
* - handleRoundabouts must be called before collapseTurnInstructions that
* expects post-processed roundabouts
*/
guidance::trimShortSegments(steps, leg_geometry);
leg.steps = guidance::handleRoundabouts(std::move(steps));
leg.steps = guidance::collapseTurnInstructions(std::move(leg.steps));
leg.steps = guidance::anticipateLaneChange(std::move(leg.steps));
leg.steps = guidance::buildIntersections(std::move(leg.steps));
leg.steps = guidance::suppressShortNameSegments(std::move(leg.steps));
leg.steps = guidance::assignRelativeLocations(std::move(leg.steps),
leg_geometry,
phantoms.source_phantom,
phantoms.target_phantom);
leg_geometry = guidance::resyncGeometry(std::move(leg_geometry), leg.steps);
}
leg_geometries.push_back(std::move(leg_geometry));
legs.push_back(std::move(leg));
}
return result;
}
boost::optional<std::vector<Coordinate>>
MakeOverview(const std::vector<guidance::LegGeometry> &leg_geometries) const
{
boost::optional<std::vector<Coordinate>> overview;
if (parameters.overview != RouteParameters::OverviewType::False)
{
const auto use_simplification =
parameters.overview == RouteParameters::OverviewType::Simplified;
BOOST_ASSERT(use_simplification ||
parameters.overview == RouteParameters::OverviewType::Full);
overview = guidance::assembleOverview(leg_geometries, use_simplification);
}
return overview;
}
}; };
} // ns api } // ns api

View File

@ -2,6 +2,7 @@
#define ENGINE_API_TABLE_HPP #define ENGINE_API_TABLE_HPP
#include "engine/api/base_api.hpp" #include "engine/api/base_api.hpp"
#include "engine/api/base_result.hpp"
#include "engine/api/json_factory.hpp" #include "engine/api/json_factory.hpp"
#include "engine/api/table_parameters.hpp" #include "engine/api/table_parameters.hpp"
@ -45,6 +46,126 @@ class TableAPI final : public BaseAPI
{ {
} }
virtual void
MakeResponse(const std::pair<std::vector<EdgeDuration>, std::vector<EdgeDistance>> &tables,
const std::vector<PhantomNode> &phantoms,
const std::vector<TableCellRef> &fallback_speed_cells,
osrm::engine::api::ResultT &response) const
{
if (response.is<flatbuffers::FlatBufferBuilder>())
{
auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
MakeResponse(tables, phantoms, fallback_speed_cells, fb_result);
}
else
{
auto &json_result = response.get<util::json::Object>();
MakeResponse(tables, phantoms, fallback_speed_cells, json_result);
}
}
virtual void
MakeResponse(const std::pair<std::vector<EdgeDuration>, std::vector<EdgeDistance>> &tables,
const std::vector<PhantomNode> &phantoms,
const std::vector<TableCellRef> &fallback_speed_cells,
flatbuffers::FlatBufferBuilder &fb_result) const
{
auto number_of_sources = parameters.sources.size();
auto number_of_destinations = parameters.destinations.size();
auto data_timestamp = facade.GetTimestamp();
flatbuffers::Offset<flatbuffers::String> data_version_string;
if (!data_timestamp.empty())
{
data_version_string = fb_result.CreateString(data_timestamp);
}
// symmetric case
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<fbresult::Waypoint>>> sources;
if (parameters.sources.empty())
{
if (!parameters.skip_waypoints)
{
sources = MakeWaypoints(fb_result, phantoms);
}
number_of_sources = phantoms.size();
}
else
{
if (!parameters.skip_waypoints)
{
sources = MakeWaypoints(fb_result, phantoms, parameters.sources);
}
}
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<fbresult::Waypoint>>>
destinations;
if (parameters.destinations.empty())
{
if (!parameters.skip_waypoints)
{
destinations = MakeWaypoints(fb_result, phantoms);
}
number_of_destinations = phantoms.size();
}
else
{
if (!parameters.skip_waypoints)
{
destinations = MakeWaypoints(fb_result, phantoms, parameters.destinations);
}
}
bool use_durations = parameters.annotations & TableParameters::AnnotationsType::Duration;
flatbuffers::Offset<flatbuffers::Vector<float>> durations;
if (use_durations)
{
durations = MakeDurationTable(fb_result, tables.first);
}
bool use_distances = parameters.annotations & TableParameters::AnnotationsType::Distance;
flatbuffers::Offset<flatbuffers::Vector<float>> distances;
if (use_distances)
{
distances = MakeDistanceTable(fb_result, tables.second);
}
bool have_speed_cells =
parameters.fallback_speed != INVALID_FALLBACK_SPEED && parameters.fallback_speed > 0;
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> speed_cells;
if (have_speed_cells)
{
speed_cells = MakeEstimatesTable(fb_result, fallback_speed_cells);
}
fbresult::TableBuilder table(fb_result);
table.add_destinations(destinations);
table.add_rows(number_of_sources);
table.add_cols(number_of_destinations);
if (use_durations)
{
table.add_durations(durations);
}
if (use_distances)
{
table.add_distances(distances);
}
if (have_speed_cells)
{
table.add_fallback_speed_cells(speed_cells);
}
auto table_buffer = table.Finish();
fbresult::FBResultBuilder response(fb_result);
if (!data_timestamp.empty())
{
response.add_data_version(data_version_string);
}
response.add_table(table_buffer);
response.add_waypoints(sources);
fb_result.Finish(response.Finish());
}
virtual void virtual void
MakeResponse(const std::pair<std::vector<EdgeDuration>, std::vector<EdgeDistance>> &tables, MakeResponse(const std::pair<std::vector<EdgeDuration>, std::vector<EdgeDistance>> &tables,
const std::vector<PhantomNode> &phantoms, const std::vector<PhantomNode> &phantoms,
@ -56,24 +177,36 @@ class TableAPI final : public BaseAPI
// symmetric case // symmetric case
if (parameters.sources.empty()) if (parameters.sources.empty())
{
if (!parameters.skip_waypoints)
{ {
response.values["sources"] = MakeWaypoints(phantoms); response.values["sources"] = MakeWaypoints(phantoms);
}
number_of_sources = phantoms.size(); number_of_sources = phantoms.size();
} }
else else
{
if (!parameters.skip_waypoints)
{ {
response.values["sources"] = MakeWaypoints(phantoms, parameters.sources); response.values["sources"] = MakeWaypoints(phantoms, parameters.sources);
} }
}
if (parameters.destinations.empty()) if (parameters.destinations.empty())
{
if (!parameters.skip_waypoints)
{ {
response.values["destinations"] = MakeWaypoints(phantoms); response.values["destinations"] = MakeWaypoints(phantoms);
}
number_of_destinations = phantoms.size(); number_of_destinations = phantoms.size();
} }
else else
{
if (!parameters.skip_waypoints)
{ {
response.values["destinations"] = MakeWaypoints(phantoms, parameters.destinations); response.values["destinations"] = MakeWaypoints(phantoms, parameters.destinations);
} }
}
if (parameters.annotations & TableParameters::AnnotationsType::Duration) if (parameters.annotations & TableParameters::AnnotationsType::Duration)
{ {
@ -96,6 +229,85 @@ class TableAPI final : public BaseAPI
} }
protected: protected:
virtual flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<fbresult::Waypoint>>>
MakeWaypoints(flatbuffers::FlatBufferBuilder &builder,
const std::vector<PhantomNode> &phantoms) const
{
std::vector<flatbuffers::Offset<fbresult::Waypoint>> waypoints;
waypoints.reserve(phantoms.size());
BOOST_ASSERT(phantoms.size() == parameters.coordinates.size());
boost::range::transform(
phantoms, std::back_inserter(waypoints), [this, &builder](const PhantomNode &phantom) {
return BaseAPI::MakeWaypoint(&builder, phantom)->Finish();
});
return builder.CreateVector(waypoints);
}
virtual flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<fbresult::Waypoint>>>
MakeWaypoints(flatbuffers::FlatBufferBuilder &builder,
const std::vector<PhantomNode> &phantoms,
const std::vector<std::size_t> &indices) const
{
std::vector<flatbuffers::Offset<fbresult::Waypoint>> waypoints;
waypoints.reserve(indices.size());
boost::range::transform(indices,
std::back_inserter(waypoints),
[this, &builder, phantoms](const std::size_t idx) {
BOOST_ASSERT(idx < phantoms.size());
return BaseAPI::MakeWaypoint(&builder, phantoms[idx])->Finish();
});
return builder.CreateVector(waypoints);
}
virtual flatbuffers::Offset<flatbuffers::Vector<float>>
MakeDurationTable(flatbuffers::FlatBufferBuilder &builder,
const std::vector<EdgeWeight> &values) const
{
std::vector<float> distance_table;
distance_table.resize(values.size());
std::transform(
values.begin(), values.end(), distance_table.begin(), [](const EdgeWeight duration) {
if (duration == MAXIMAL_EDGE_DURATION)
{
return 0.;
}
return duration / 10.;
});
return builder.CreateVector(distance_table);
}
virtual flatbuffers::Offset<flatbuffers::Vector<float>>
MakeDistanceTable(flatbuffers::FlatBufferBuilder &builder,
const std::vector<EdgeDistance> &values) const
{
std::vector<float> duration_table;
duration_table.resize(values.size());
std::transform(
values.begin(), values.end(), duration_table.begin(), [](const EdgeDistance distance) {
if (distance == INVALID_EDGE_DISTANCE)
{
return 0.;
}
return std::round(distance * 10) / 10.;
});
return builder.CreateVector(duration_table);
}
virtual flatbuffers::Offset<flatbuffers::Vector<uint32_t>>
MakeEstimatesTable(flatbuffers::FlatBufferBuilder &builder,
const std::vector<TableCellRef> &fallback_speed_cells) const
{
std::vector<uint32_t> fb_table;
fb_table.reserve(fallback_speed_cells.size());
std::for_each(
fallback_speed_cells.begin(), fallback_speed_cells.end(), [&](const auto &cell) {
fb_table.push_back(cell.row);
fb_table.push_back(cell.column);
});
return builder.CreateVector(fb_table);
}
virtual util::json::Array MakeWaypoints(const std::vector<PhantomNode> &phantoms) const virtual util::json::Array MakeWaypoints(const std::vector<PhantomNode> &phantoms) const
{ {
util::json::Array json_waypoints; util::json::Array json_waypoints;

View File

@ -24,7 +24,47 @@ class TripAPI final : public RouteAPI
: RouteAPI(facade_, parameters_), parameters(parameters_) : RouteAPI(facade_, parameters_), parameters(parameters_)
{ {
} }
void MakeResponse(const std::vector<std::vector<NodeID>> &sub_trips,
const std::vector<InternalRouteResult> &sub_routes,
const std::vector<PhantomNode> &phantoms,
osrm::engine::api::ResultT &response) const
{
BOOST_ASSERT(sub_trips.size() == sub_routes.size());
if (response.is<flatbuffers::FlatBufferBuilder>())
{
auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
MakeResponse(sub_trips, sub_routes, phantoms, fb_result);
}
else
{
auto &json_result = response.get<util::json::Object>();
MakeResponse(sub_trips, sub_routes, phantoms, json_result);
}
}
void MakeResponse(const std::vector<std::vector<NodeID>> &sub_trips,
const std::vector<InternalRouteResult> &sub_routes,
const std::vector<PhantomNode> &phantoms,
flatbuffers::FlatBufferBuilder &fb_result) const
{
auto data_timestamp = facade.GetTimestamp();
flatbuffers::Offset<flatbuffers::String> data_version_string;
if (!data_timestamp.empty())
{
data_version_string = fb_result.CreateString(data_timestamp);
}
auto response =
MakeFBResponse(sub_routes, fb_result, [this, &fb_result, &sub_trips, &phantoms]() {
return MakeWaypoints(fb_result, sub_trips, phantoms);
});
if (!data_timestamp.empty())
{
response->add_data_version(data_version_string);
}
fb_result.Finish(response->Finish());
}
void MakeResponse(const std::vector<std::vector<NodeID>> &sub_trips, void MakeResponse(const std::vector<std::vector<NodeID>> &sub_trips,
const std::vector<InternalRouteResult> &sub_routes, const std::vector<InternalRouteResult> &sub_routes,
const std::vector<PhantomNode> &phantoms, const std::vector<PhantomNode> &phantoms,
@ -33,7 +73,6 @@ class TripAPI final : public RouteAPI
auto number_of_routes = sub_trips.size(); auto number_of_routes = sub_trips.size();
util::json::Array routes; util::json::Array routes;
routes.values.reserve(number_of_routes); routes.values.reserve(number_of_routes);
BOOST_ASSERT(sub_trips.size() == sub_routes.size());
for (auto index : util::irange<std::size_t>(0UL, sub_trips.size())) for (auto index : util::irange<std::size_t>(0UL, sub_trips.size()))
{ {
auto route = MakeRoute(sub_routes[index].segment_end_coordinates, auto route = MakeRoute(sub_routes[index].segment_end_coordinates,
@ -42,7 +81,10 @@ class TripAPI final : public RouteAPI
sub_routes[index].target_traversed_in_reverse); sub_routes[index].target_traversed_in_reverse);
routes.values.push_back(std::move(route)); routes.values.push_back(std::move(route));
} }
if (!parameters.skip_waypoints)
{
response.values["waypoints"] = MakeWaypoints(sub_trips, phantoms); response.values["waypoints"] = MakeWaypoints(sub_trips, phantoms);
}
response.values["trips"] = std::move(routes); response.values["trips"] = std::move(routes);
response.values["code"] = "Ok"; response.values["code"] = "Ok";
} }
@ -50,15 +92,11 @@ class TripAPI final : public RouteAPI
protected: protected:
// FIXME this logic is a little backwards. We should change the output format of the // FIXME this logic is a little backwards. We should change the output format of the
// trip plugin routing algorithm to be easier to consume here. // trip plugin routing algorithm to be easier to consume here.
util::json::Array MakeWaypoints(const std::vector<std::vector<NodeID>> &sub_trips,
const std::vector<PhantomNode> &phantoms) const
{
util::json::Array waypoints;
waypoints.values.reserve(parameters.coordinates.size());
struct TripIndex struct TripIndex
{ {
TripIndex() = default; TripIndex() = default;
TripIndex(unsigned sub_trip_index_, unsigned point_index_) TripIndex(unsigned sub_trip_index_, unsigned point_index_)
: sub_trip_index(sub_trip_index_), point_index(point_index_) : sub_trip_index(sub_trip_index_), point_index(point_index_)
{ {
@ -74,16 +112,38 @@ class TripAPI final : public RouteAPI
} }
}; };
std::vector<TripIndex> input_idx_to_trip_idx(parameters.coordinates.size()); flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<fbresult::Waypoint>>>
for (auto sub_trip_index : util::irange<unsigned>(0u, sub_trips.size())) MakeWaypoints(flatbuffers::FlatBufferBuilder &fb_result,
const std::vector<std::vector<NodeID>> &sub_trips,
const std::vector<PhantomNode> &phantoms) const
{ {
for (auto point_index : util::irange<unsigned>(0u, sub_trips[sub_trip_index].size())) std::vector<flatbuffers::Offset<fbresult::Waypoint>> waypoints;
waypoints.reserve(parameters.coordinates.size());
auto input_idx_to_trip_idx = MakeTripIndices(sub_trips);
for (auto input_index : util::irange<std::size_t>(0UL, parameters.coordinates.size()))
{ {
input_idx_to_trip_idx[sub_trips[sub_trip_index][point_index]] = auto trip_index = input_idx_to_trip_idx[input_index];
TripIndex{sub_trip_index, point_index}; BOOST_ASSERT(!trip_index.NotUsed());
auto waypoint = BaseAPI::MakeWaypoint(&fb_result, phantoms[input_index]);
waypoint->add_waypoint_index(trip_index.point_index);
waypoint->add_trips_index(trip_index.sub_trip_index);
waypoints.push_back(waypoint->Finish());
} }
return fb_result.CreateVector(waypoints);
} }
util::json::Array MakeWaypoints(const std::vector<std::vector<NodeID>> &sub_trips,
const std::vector<PhantomNode> &phantoms) const
{
util::json::Array waypoints;
waypoints.values.reserve(parameters.coordinates.size());
auto input_idx_to_trip_idx = MakeTripIndices(sub_trips);
for (auto input_index : util::irange<std::size_t>(0UL, parameters.coordinates.size())) for (auto input_index : util::irange<std::size_t>(0UL, parameters.coordinates.size()))
{ {
auto trip_index = input_idx_to_trip_idx[input_index]; auto trip_index = input_idx_to_trip_idx[input_index];
@ -98,6 +158,20 @@ class TripAPI final : public RouteAPI
return waypoints; return waypoints;
} }
std::vector<TripIndex> MakeTripIndices(const std::vector<std::vector<NodeID>> &sub_trips) const
{
std::vector<TripIndex> input_idx_to_trip_idx(parameters.coordinates.size());
for (auto sub_trip_index : util::irange<unsigned>(0u, sub_trips.size()))
{
for (auto point_index : util::irange<unsigned>(0u, sub_trips[sub_trip_index].size()))
{
input_idx_to_trip_idx[sub_trips[sub_trip_index][point_index]] =
TripIndex{sub_trip_index, point_index};
}
}
return input_idx_to_trip_idx;
}
const TripParameters &parameters; const TripParameters &parameters;
}; };

View File

@ -33,7 +33,7 @@ class MMapMemoryAllocator : public ContiguousBlockAllocator
private: private:
storage::SharedDataIndex index; storage::SharedDataIndex index;
std::vector<boost::iostreams::mapped_file> mapped_memory_files; std::vector<boost::iostreams::mapped_file_source> mapped_memory_files;
std::string rtree_filename; std::string rtree_filename;
}; };

View File

@ -32,17 +32,13 @@ class EngineInterface
{ {
public: public:
virtual ~EngineInterface() = default; virtual ~EngineInterface() = default;
virtual Status Route(const api::RouteParameters &parameters, virtual Status Route(const api::RouteParameters &parameters, api::ResultT &result) const = 0;
util::json::Object &result) const = 0; virtual Status Table(const api::TableParameters &parameters, api::ResultT &result) const = 0;
virtual Status Table(const api::TableParameters &parameters,
util::json::Object &result) const = 0;
virtual Status Nearest(const api::NearestParameters &parameters, virtual Status Nearest(const api::NearestParameters &parameters,
util::json::Object &result) const = 0; api::ResultT &result) const = 0;
virtual Status Trip(const api::TripParameters &parameters, virtual Status Trip(const api::TripParameters &parameters, api::ResultT &result) const = 0;
util::json::Object &result) const = 0; virtual Status Match(const api::MatchParameters &parameters, api::ResultT &result) const = 0;
virtual Status Match(const api::MatchParameters &parameters, virtual Status Tile(const api::TileParameters &parameters, api::ResultT &result) const = 0;
util::json::Object &result) const = 0;
virtual Status Tile(const api::TileParameters &parameters, std::string &result) const = 0;
}; };
template <typename Algorithm> class Engine final : public EngineInterface template <typename Algorithm> class Engine final : public EngineInterface
@ -89,36 +85,32 @@ template <typename Algorithm> class Engine final : public EngineInterface
Engine &operator=(const Engine &) = delete; Engine &operator=(const Engine &) = delete;
virtual ~Engine() = default; virtual ~Engine() = default;
Status Route(const api::RouteParameters &params, Status Route(const api::RouteParameters &params, api::ResultT &result) const override final
util::json::Object &result) const override final
{ {
return route_plugin.HandleRequest(GetAlgorithms(params), params, result); return route_plugin.HandleRequest(GetAlgorithms(params), params, result);
} }
Status Table(const api::TableParameters &params, Status Table(const api::TableParameters &params, api::ResultT &result) const override final
util::json::Object &result) const override final
{ {
return table_plugin.HandleRequest(GetAlgorithms(params), params, result); return table_plugin.HandleRequest(GetAlgorithms(params), params, result);
} }
Status Nearest(const api::NearestParameters &params, Status Nearest(const api::NearestParameters &params, api::ResultT &result) const override final
util::json::Object &result) const override final
{ {
return nearest_plugin.HandleRequest(GetAlgorithms(params), params, result); return nearest_plugin.HandleRequest(GetAlgorithms(params), params, result);
} }
Status Trip(const api::TripParameters &params, util::json::Object &result) const override final Status Trip(const api::TripParameters &params, api::ResultT &result) const override final
{ {
return trip_plugin.HandleRequest(GetAlgorithms(params), params, result); return trip_plugin.HandleRequest(GetAlgorithms(params), params, result);
} }
Status Match(const api::MatchParameters &params, Status Match(const api::MatchParameters &params, api::ResultT &result) const override final
util::json::Object &result) const override final
{ {
return match_plugin.HandleRequest(GetAlgorithms(params), params, result); return match_plugin.HandleRequest(GetAlgorithms(params), params, result);
} }
Status Tile(const api::TileParameters &params, std::string &result) const override final Status Tile(const api::TileParameters &params, api::ResultT &result) const override final
{ {
return tile_plugin.HandleRequest(GetAlgorithms(params), params, result); return tile_plugin.HandleRequest(GetAlgorithms(params), params, result);
} }

View File

@ -32,7 +32,7 @@ class MatchPlugin : public BasePlugin
Status HandleRequest(const RoutingAlgorithmsInterface &algorithms, Status HandleRequest(const RoutingAlgorithmsInterface &algorithms,
const api::MatchParameters &parameters, const api::MatchParameters &parameters,
util::json::Object &json_result) const; osrm::engine::api::ResultT &json_result) const;
private: private:
const int max_locations_map_matching; const int max_locations_map_matching;

View File

@ -21,7 +21,7 @@ class NearestPlugin final : public BasePlugin
Status HandleRequest(const RoutingAlgorithmsInterface &algorithms, Status HandleRequest(const RoutingAlgorithmsInterface &algorithms,
const api::NearestParameters &params, const api::NearestParameters &params,
util::json::Object &result) const; osrm::engine::api::ResultT &result) const;
private: private:
const int max_results; const int max_results;

View File

@ -2,6 +2,8 @@
#define BASE_PLUGIN_HPP #define BASE_PLUGIN_HPP
#include "engine/api/base_parameters.hpp" #include "engine/api/base_parameters.hpp"
#include "engine/api/base_result.hpp"
#include "engine/api/flatbuffers/fbresult_generated.h"
#include "engine/datafacade/datafacade_base.hpp" #include "engine/datafacade/datafacade_base.hpp"
#include "engine/phantom_node.hpp" #include "engine/phantom_node.hpp"
#include "engine/routing_algorithms.hpp" #include "engine/routing_algorithms.hpp"
@ -39,7 +41,7 @@ class BasePlugin
bool CheckAlgorithms(const api::BaseParameters &params, bool CheckAlgorithms(const api::BaseParameters &params,
const RoutingAlgorithmsInterface &algorithms, const RoutingAlgorithmsInterface &algorithms,
util::json::Object &result) const osrm::engine::api::ResultT &result) const
{ {
if (algorithms.IsValid()) if (algorithms.IsValid())
{ {
@ -62,12 +64,38 @@ class BasePlugin
return false; return false;
} }
Status Error(const std::string &code, struct ErrorRenderer
const std::string &message, {
util::json::Object &json_result) const std::string code;
std::string message;
ErrorRenderer(std::string code, std::string message)
: code(std::move(code)), message(std::move(message)){};
void operator()(util::json::Object &json_result)
{ {
json_result.values["code"] = code; json_result.values["code"] = code;
json_result.values["message"] = message; json_result.values["message"] = message;
};
void operator()(flatbuffers::FlatBufferBuilder &fb_result)
{
auto error = api::fbresult::CreateErrorDirect(fb_result, code.c_str(), message.c_str());
api::fbresult::FBResultBuilder response(fb_result);
response.add_error(true);
response.add_code(error);
fb_result.Finish(response.Finish());
};
void operator()(std::string &str_result)
{
str_result = str(boost::format("code=%1% message=%2%") % code % message);
};
};
Status Error(const std::string &code,
const std::string &message,
osrm::engine::api::ResultT &result) const
{
mapbox::util::apply_visitor(ErrorRenderer(code, message), result);
return Status::Error; return Status::Error;
} }

View File

@ -22,7 +22,7 @@ class TablePlugin final : public BasePlugin
Status HandleRequest(const RoutingAlgorithmsInterface &algorithms, Status HandleRequest(const RoutingAlgorithmsInterface &algorithms,
const api::TableParameters &params, const api::TableParameters &params,
util::json::Object &result) const; osrm::engine::api::ResultT &result) const;
private: private:
const int max_locations_distance_table; const int max_locations_distance_table;

View File

@ -28,7 +28,7 @@ class TilePlugin final : public BasePlugin
public: public:
Status HandleRequest(const RoutingAlgorithmsInterface &algorithms, Status HandleRequest(const RoutingAlgorithmsInterface &algorithms,
const api::TileParameters &parameters, const api::TileParameters &parameters,
std::string &pbf_buffer) const; osrm::engine::api::ResultT &pbf_buffer) const;
}; };
} }
} }

View File

@ -40,7 +40,7 @@ class TripPlugin final : public BasePlugin
Status HandleRequest(const RoutingAlgorithmsInterface &algorithms, Status HandleRequest(const RoutingAlgorithmsInterface &algorithms,
const api::TripParameters &parameters, const api::TripParameters &parameters,
util::json::Object &json_result) const; osrm::engine::api::ResultT &json_result) const;
}; };
} }
} }

View File

@ -33,7 +33,7 @@ class ViaRoutePlugin final : public BasePlugin
Status HandleRequest(const RoutingAlgorithmsInterface &algorithms, Status HandleRequest(const RoutingAlgorithmsInterface &algorithms,
const api::RouteParameters &route_parameters, const api::RouteParameters &route_parameters,
util::json::Object &json_result) const; osrm::engine::api::ResultT &json_result) const;
}; };
} }
} }

View File

@ -192,17 +192,22 @@ void annotatePath(const FacadeT &facade,
const bool is_first_segment = unpacked_path.empty(); const bool is_first_segment = unpacked_path.empty();
const std::size_t start_index = std::size_t start_index = 0;
(is_first_segment ? ((start_traversed_in_reverse) if (is_first_segment)
? weight_vector.size() - {
phantom_node_pair.source_phantom.fwd_segment_position - 1 unsigned short segment_position = phantom_node_pair.source_phantom.fwd_segment_position;
: phantom_node_pair.source_phantom.fwd_segment_position) if (start_traversed_in_reverse)
: 0); {
segment_position = weight_vector.size() -
phantom_node_pair.source_phantom.fwd_segment_position - 1;
}
BOOST_ASSERT(segment_position >= 0);
start_index = static_cast<std::size_t>(segment_position);
}
const std::size_t end_index = weight_vector.size(); const std::size_t end_index = weight_vector.size();
bool is_left_hand_driving = facade.IsLeftHandDriving(node_id); bool is_left_hand_driving = facade.IsLeftHandDriving(node_id);
BOOST_ASSERT(start_index >= 0);
BOOST_ASSERT(start_index < end_index); BOOST_ASSERT(start_index < end_index);
for (std::size_t segment_idx = start_index; segment_idx < end_index; ++segment_idx) for (std::size_t segment_idx = start_index; segment_idx < end_index; ++segment_idx)
{ {

View File

@ -85,33 +85,6 @@ struct InternalExtractorEdge
DurationData duration_data; DurationData duration_data;
// coordinate of the source node // coordinate of the source node
util::Coordinate source_coordinate; util::Coordinate source_coordinate;
// necessary static util functions for stxxl's sorting
static InternalExtractorEdge min_osm_value()
{
return InternalExtractorEdge(
MIN_OSM_NODEID, MIN_OSM_NODEID, WeightData(), DurationData(), util::Coordinate());
}
static InternalExtractorEdge max_osm_value()
{
return InternalExtractorEdge(
MAX_OSM_NODEID, MAX_OSM_NODEID, WeightData(), DurationData(), util::Coordinate());
}
static InternalExtractorEdge min_internal_value()
{
auto v = min_osm_value();
v.result.source = 0;
v.result.target = 0;
return v;
}
static InternalExtractorEdge max_internal_value()
{
auto v = max_osm_value();
v.result.source = std::numeric_limits<NodeID>::max();
v.result.target = std::numeric_limits<NodeID>::max();
return v;
}
}; };
} }
} }

73
include/extractor/raster_source.hpp Normal file → Executable file
View File

@ -4,16 +4,21 @@
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
#include "util/exception.hpp" #include "util/exception.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/trim.hpp> #include <boost/algorithm/string/trim.hpp>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
#include <boost/foreach.hpp>
#include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_int.hpp> #include <boost/spirit/include/qi_int.hpp>
#include <storage/io.hpp> #include <storage/io.hpp>
#include <iterator> #include <iterator>
#include <string>
#include <unordered_map> #include <unordered_map>
using namespace std;
namespace osrm namespace osrm
{ {
@ -43,37 +48,31 @@ class RasterGrid
xdim = _xdim; xdim = _xdim;
ydim = _ydim; ydim = _ydim;
_data.reserve(ydim * xdim); _data.reserve(ydim * xdim);
BOOST_ASSERT(ydim * xdim <= _data.capacity());
// Construct FileReader
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(xdim * 11); // INT32_MAX = 2147483647 = 10 chars + 1 white space = 11
BOOST_ASSERT(xdim * 11 <= buffer.size());
BOOST_ASSERT(buffer.size() > 1);
file_reader.ReadInto(&buffer[0], buffer.size());
for (unsigned int y = 0; y < ydim; y++)
{
// read one line from file.
file_reader.ReadLine(&buffer[0], xdim * 11);
boost::algorithm::trim(buffer); boost::algorithm::trim(buffer);
auto itr = buffer.begin(); std::vector<std::string> result;
auto end = buffer.end(); boost::split(
result, buffer, boost::is_any_of(" \r\n\0"), boost::algorithm::token_compress_on);
bool r = false; unsigned int x = 0;
try for (const auto &s : result)
{ {
r = boost::spirit::qi::parse( if (x < xdim)
itr, end, +boost::spirit::qi::int_ % +boost::spirit::qi::space, _data); _data[(y * xdim) + x] = atoi(s.c_str());
++x;
} }
catch (std::exception const &ex) BOOST_ASSERT(x == xdim);
{
throw util::exception("Failed to read from raster source " + filepath.string() + ": " +
ex.what() + SOURCE_REF);
}
if (!r || itr != end)
{
throw util::exception("Failed to parse raster source: " + filepath.string() +
SOURCE_REF);
} }
} }
@ -143,8 +142,36 @@ class RasterContainer
RasterDatum GetRasterInterpolateFromSource(unsigned int source_id, double lon, double lat); RasterDatum GetRasterInterpolateFromSource(unsigned int source_id, double lon, double lat);
private: private:
};
// << singletone >> RasterCache
// The instance of RasterContainer is created for every threads osrm-extract uses.
// To avoid multiple load of same file on each RasterContainer,
// The LoadedSources and LoadedSourcePaths are separated to RasterCache class
// and handled as the singletone pattern to avoid duplicate creation.
class RasterCache
{
public:
// class method to get the instance
static RasterCache &getInstance()
{
if (NULL == g_instance)
{
g_instance = new RasterCache();
}
return *g_instance;
}
// get reference of cache
std::vector<RasterSource> &getLoadedSources() { return LoadedSources; }
std::unordered_map<std::string, int> &getLoadedSourcePaths() { return LoadedSourcePaths; }
private:
// constructor
RasterCache() = default;
// member
std::vector<RasterSource> LoadedSources; std::vector<RasterSource> LoadedSources;
std::unordered_map<std::string, int> LoadedSourcePaths; std::unordered_map<std::string, int> LoadedSourcePaths;
// the instance
static RasterCache *g_instance;
}; };
} }
} }

View File

@ -37,8 +37,11 @@ struct Engine final : public Nan::ObjectWrap
std::shared_ptr<osrm::OSRM> this_; std::shared_ptr<osrm::OSRM> this_;
}; };
} // ns node_osrm } // namespace node_osrm
NODE_MODULE(osrm, node_osrm::Engine::Init) #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
NAN_MODULE_WORKER_ENABLED(osrm, node_osrm::Engine::Init)
#pragma GCC diagnostic pop
#endif #endif

View File

@ -116,8 +116,8 @@ inline engine_config_ptr argumentsToEngineConfig(const Nan::FunctionCallbackInfo
if (args[0]->IsString()) if (args[0]->IsString())
{ {
engine_config->storage_config = osrm::StorageConfig( engine_config->storage_config =
*v8::String::Utf8Value(Nan::To<v8::String>(args[0]).ToLocalChecked())); osrm::StorageConfig(*Nan::Utf8String(Nan::To<v8::String>(args[0]).ToLocalChecked()));
engine_config->use_shared_memory = false; engine_config->use_shared_memory = false;
return engine_config; return engine_config;
} }
@ -155,7 +155,7 @@ inline engine_config_ptr argumentsToEngineConfig(const Nan::FunctionCallbackInfo
} }
engine_config->memory_file = engine_config->memory_file =
*v8::String::Utf8Value(Nan::To<v8::String>(memory_file).ToLocalChecked()); *Nan::Utf8String(Nan::To<v8::String>(memory_file).ToLocalChecked());
} }
auto dataset_name = params->Get(Nan::New("dataset_name").ToLocalChecked()); auto dataset_name = params->Get(Nan::New("dataset_name").ToLocalChecked());
@ -166,7 +166,7 @@ inline engine_config_ptr argumentsToEngineConfig(const Nan::FunctionCallbackInfo
if (dataset_name->IsString()) if (dataset_name->IsString())
{ {
engine_config->dataset_name = engine_config->dataset_name =
*v8::String::Utf8Value(Nan::To<v8::String>(dataset_name).ToLocalChecked()); *Nan::Utf8String(Nan::To<v8::String>(dataset_name).ToLocalChecked());
} }
else else
{ {
@ -178,7 +178,7 @@ inline engine_config_ptr argumentsToEngineConfig(const Nan::FunctionCallbackInfo
if (!path->IsUndefined()) if (!path->IsUndefined())
{ {
engine_config->storage_config = engine_config->storage_config =
osrm::StorageConfig(*v8::String::Utf8Value(Nan::To<v8::String>(path).ToLocalChecked())); osrm::StorageConfig(*Nan::Utf8String(Nan::To<v8::String>(path).ToLocalChecked()));
engine_config->use_shared_memory = false; engine_config->use_shared_memory = false;
} }
@ -221,15 +221,15 @@ inline engine_config_ptr argumentsToEngineConfig(const Nan::FunctionCallbackInfo
if (algorithm->IsString()) if (algorithm->IsString())
{ {
auto algorithm_str = Nan::To<v8::String>(algorithm).ToLocalChecked(); auto algorithm_str = Nan::To<v8::String>(algorithm).ToLocalChecked();
if (*v8::String::Utf8Value(algorithm_str) == std::string("CH")) if (*Nan::Utf8String(algorithm_str) == std::string("CH"))
{ {
engine_config->algorithm = osrm::EngineConfig::Algorithm::CH; engine_config->algorithm = osrm::EngineConfig::Algorithm::CH;
} }
else if (*v8::String::Utf8Value(algorithm_str) == std::string("CoreCH")) else if (*Nan::Utf8String(algorithm_str) == std::string("CoreCH"))
{ {
engine_config->algorithm = osrm::EngineConfig::Algorithm::CH; engine_config->algorithm = osrm::EngineConfig::Algorithm::CH;
} }
else if (*v8::String::Utf8Value(algorithm_str) == std::string("MLD")) else if (*Nan::Utf8String(algorithm_str) == std::string("MLD"))
{ {
engine_config->algorithm = osrm::EngineConfig::Algorithm::MLD; engine_config->algorithm = osrm::EngineConfig::Algorithm::MLD;
} }
@ -290,23 +290,22 @@ inline engine_config_ptr argumentsToEngineConfig(const Nan::FunctionCallbackInfo
} }
if (max_locations_trip->IsNumber()) if (max_locations_trip->IsNumber())
engine_config->max_locations_trip = static_cast<int>(max_locations_trip->NumberValue()); engine_config->max_locations_trip = Nan::To<int>(max_locations_trip).FromJust();
if (max_locations_viaroute->IsNumber()) if (max_locations_viaroute->IsNumber())
engine_config->max_locations_viaroute = engine_config->max_locations_viaroute = Nan::To<int>(max_locations_viaroute).FromJust();
static_cast<int>(max_locations_viaroute->NumberValue());
if (max_locations_distance_table->IsNumber()) if (max_locations_distance_table->IsNumber())
engine_config->max_locations_distance_table = engine_config->max_locations_distance_table =
static_cast<int>(max_locations_distance_table->NumberValue()); Nan::To<int>(max_locations_distance_table).FromJust();
if (max_locations_map_matching->IsNumber()) if (max_locations_map_matching->IsNumber())
engine_config->max_locations_map_matching = engine_config->max_locations_map_matching =
static_cast<int>(max_locations_map_matching->NumberValue()); Nan::To<int>(max_locations_map_matching).FromJust();
if (max_results_nearest->IsNumber()) if (max_results_nearest->IsNumber())
engine_config->max_results_nearest = static_cast<int>(max_results_nearest->NumberValue()); engine_config->max_results_nearest = Nan::To<int>(max_results_nearest).FromJust();
if (max_alternatives->IsNumber()) if (max_alternatives->IsNumber())
engine_config->max_alternatives = static_cast<int>(max_alternatives->NumberValue()); engine_config->max_alternatives = Nan::To<int>(max_alternatives).FromJust();
if (max_radius_map_matching->IsNumber()) if (max_radius_map_matching->IsNumber())
engine_config->max_radius_map_matching = engine_config->max_radius_map_matching =
static_cast<double>(max_radius_map_matching->NumberValue()); Nan::To<double>(max_radius_map_matching).FromJust();
return engine_config; return engine_config;
} }
@ -343,8 +342,8 @@ parseCoordinateArray(const v8::Local<v8::Array> &coordinates_array)
return resulting_coordinates; return resulting_coordinates;
} }
double lon = coordinate_pair->Get(0)->NumberValue(); double lon = Nan::To<double>(coordinate_pair->Get(0)).FromJust();
double lat = coordinate_pair->Get(1)->NumberValue(); double lat = Nan::To<double>(coordinate_pair->Get(1)).FromJust();
if (std::isnan(lon) || std::isnan(lat) || std::isinf(lon) || std::isinf(lat)) if (std::isnan(lon) || std::isnan(lat) || std::isinf(lon) || std::isinf(lat))
{ {
@ -430,7 +429,7 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
return false; return false;
} }
if (obj->Has(Nan::New("approaches").ToLocalChecked())) if (Nan::Has(obj, Nan::New("approaches").ToLocalChecked()).FromJust())
{ {
v8::Local<v8::Value> approaches = obj->Get(Nan::New("approaches").ToLocalChecked()); v8::Local<v8::Value> approaches = obj->Get(Nan::New("approaches").ToLocalChecked());
if (approaches.IsEmpty()) if (approaches.IsEmpty())
@ -487,7 +486,7 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
} }
} }
if (obj->Has(Nan::New("bearings").ToLocalChecked())) if (Nan::Has(obj, Nan::New("bearings").ToLocalChecked()).FromJust())
{ {
v8::Local<v8::Value> bearings = obj->Get(Nan::New("bearings").ToLocalChecked()); v8::Local<v8::Value> bearings = obj->Get(Nan::New("bearings").ToLocalChecked());
if (bearings.IsEmpty()) if (bearings.IsEmpty())
@ -528,8 +527,8 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
return false; return false;
} }
const auto bearing = static_cast<short>(bearing_pair->Get(0)->NumberValue()); const auto bearing = Nan::To<int>(bearing_pair->Get(0)).FromJust();
const auto range = static_cast<short>(bearing_pair->Get(1)->NumberValue()); const auto range = Nan::To<int>(bearing_pair->Get(1)).FromJust();
if (bearing < 0 || bearing > 360 || range < 0 || range > 180) if (bearing < 0 || bearing > 360 || range < 0 || range > 180)
{ {
@ -537,7 +536,8 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
return false; return false;
} }
params->bearings.push_back(osrm::Bearing{bearing, range}); params->bearings.push_back(
osrm::Bearing{static_cast<short>(bearing), static_cast<short>(range)});
} }
else else
{ {
@ -553,7 +553,7 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
} }
} }
if (obj->Has(Nan::New("hints").ToLocalChecked())) if (Nan::Has(obj, Nan::New("hints").ToLocalChecked()).FromJust())
{ {
v8::Local<v8::Value> hints = obj->Get(Nan::New("hints").ToLocalChecked()); v8::Local<v8::Value> hints = obj->Get(Nan::New("hints").ToLocalChecked());
if (hints.IsEmpty()) if (hints.IsEmpty())
@ -581,14 +581,13 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
if (hint->IsString()) if (hint->IsString())
{ {
if (hint->ToString()->Length() == 0) if (Nan::To<v8::String>(hint).ToLocalChecked()->Length() == 0)
{ {
Nan::ThrowError("Hint cannot be an empty string"); Nan::ThrowError("Hint cannot be an empty string");
return false; return false;
} }
params->hints.push_back( params->hints.push_back(osrm::engine::Hint::FromBase64(*Nan::Utf8String(hint)));
osrm::engine::Hint::FromBase64(*v8::String::Utf8Value(hint)));
} }
else if (hint->IsNull()) else if (hint->IsNull())
{ {
@ -602,7 +601,7 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
} }
} }
if (obj->Has(Nan::New("radiuses").ToLocalChecked())) if (Nan::Has(obj, Nan::New("radiuses").ToLocalChecked()).FromJust())
{ {
v8::Local<v8::Value> radiuses = obj->Get(Nan::New("radiuses").ToLocalChecked()); v8::Local<v8::Value> radiuses = obj->Get(Nan::New("radiuses").ToLocalChecked());
if (radiuses.IsEmpty()) if (radiuses.IsEmpty())
@ -632,9 +631,9 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
{ {
params->radiuses.emplace_back(); params->radiuses.emplace_back();
} }
else if (radius->IsNumber() && radius->NumberValue() >= 0) else if (radius->IsNumber() && Nan::To<double>(radius).FromJust() >= 0)
{ {
params->radiuses.push_back(static_cast<double>(radius->NumberValue())); params->radiuses.push_back(Nan::To<double>(radius).FromJust());
} }
else else
{ {
@ -644,7 +643,7 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
} }
} }
if (obj->Has(Nan::New("generate_hints").ToLocalChecked())) if (Nan::Has(obj, Nan::New("generate_hints").ToLocalChecked()).FromJust())
{ {
v8::Local<v8::Value> generate_hints = obj->Get(Nan::New("generate_hints").ToLocalChecked()); v8::Local<v8::Value> generate_hints = obj->Get(Nan::New("generate_hints").ToLocalChecked());
if (generate_hints.IsEmpty()) if (generate_hints.IsEmpty())
@ -656,10 +655,10 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
return false; return false;
} }
params->generate_hints = generate_hints->BooleanValue(); params->generate_hints = Nan::To<bool>(generate_hints).FromJust();
} }
if (obj->Has(Nan::New("exclude").ToLocalChecked())) if (Nan::Has(obj, Nan::New("exclude").ToLocalChecked()).FromJust())
{ {
v8::Local<v8::Value> exclude = obj->Get(Nan::New("exclude").ToLocalChecked()); v8::Local<v8::Value> exclude = obj->Get(Nan::New("exclude").ToLocalChecked());
if (exclude.IsEmpty()) if (exclude.IsEmpty())
@ -681,7 +680,7 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
if (class_name->IsString()) if (class_name->IsString())
{ {
std::string class_name_str = *v8::String::Utf8Value(class_name); std::string class_name_str = *Nan::Utf8String(class_name);
params->exclude.emplace_back(class_name_str); params->exclude.emplace_back(class_name_str);
} }
else else
@ -698,7 +697,7 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
template <typename ParamType> template <typename ParamType>
inline bool parseCommonParameters(const v8::Local<v8::Object> &obj, ParamType &params) inline bool parseCommonParameters(const v8::Local<v8::Object> &obj, ParamType &params)
{ {
if (obj->Has(Nan::New("steps").ToLocalChecked())) if (Nan::Has(obj, Nan::New("steps").ToLocalChecked()).FromJust())
{ {
auto steps = obj->Get(Nan::New("steps").ToLocalChecked()); auto steps = obj->Get(Nan::New("steps").ToLocalChecked());
if (steps.IsEmpty()) if (steps.IsEmpty())
@ -706,7 +705,7 @@ inline bool parseCommonParameters(const v8::Local<v8::Object> &obj, ParamType &p
if (steps->IsBoolean()) if (steps->IsBoolean())
{ {
params->steps = steps->BooleanValue(); params->steps = Nan::To<bool>(steps).FromJust();
} }
else else
{ {
@ -715,7 +714,7 @@ inline bool parseCommonParameters(const v8::Local<v8::Object> &obj, ParamType &p
} }
} }
if (obj->Has(Nan::New("annotations").ToLocalChecked())) if (Nan::Has(obj, Nan::New("annotations").ToLocalChecked()).FromJust())
{ {
auto annotations = obj->Get(Nan::New("annotations").ToLocalChecked()); auto annotations = obj->Get(Nan::New("annotations").ToLocalChecked());
if (annotations.IsEmpty()) if (annotations.IsEmpty())
@ -723,7 +722,7 @@ inline bool parseCommonParameters(const v8::Local<v8::Object> &obj, ParamType &p
if (annotations->IsBoolean()) if (annotations->IsBoolean())
{ {
params->annotations = annotations->BooleanValue(); params->annotations = Nan::To<bool>(annotations).FromJust();
} }
else if (annotations->IsArray()) else if (annotations->IsArray())
{ {
@ -778,7 +777,7 @@ inline bool parseCommonParameters(const v8::Local<v8::Object> &obj, ParamType &p
} }
} }
if (obj->Has(Nan::New("geometries").ToLocalChecked())) if (Nan::Has(obj, Nan::New("geometries").ToLocalChecked()).FromJust())
{ {
v8::Local<v8::Value> geometries = obj->Get(Nan::New("geometries").ToLocalChecked()); v8::Local<v8::Value> geometries = obj->Get(Nan::New("geometries").ToLocalChecked());
if (geometries.IsEmpty()) if (geometries.IsEmpty())
@ -812,7 +811,7 @@ inline bool parseCommonParameters(const v8::Local<v8::Object> &obj, ParamType &p
} }
} }
if (obj->Has(Nan::New("overview").ToLocalChecked())) if (Nan::Has(obj, Nan::New("overview").ToLocalChecked()).FromJust())
{ {
v8::Local<v8::Value> overview = obj->Get(Nan::New("overview").ToLocalChecked()); v8::Local<v8::Value> overview = obj->Get(Nan::New("overview").ToLocalChecked());
if (overview.IsEmpty()) if (overview.IsEmpty())
@ -857,7 +856,7 @@ argumentsToPluginParameters(const Nan::FunctionCallbackInfo<v8::Value> &args)
return {}; return {};
} }
v8::Local<v8::Object> obj = Nan::To<v8::Object>(args[1]).ToLocalChecked(); v8::Local<v8::Object> obj = Nan::To<v8::Object>(args[1]).ToLocalChecked();
if (obj->Has(Nan::New("format").ToLocalChecked())) if (Nan::Has(obj, Nan::New("format").ToLocalChecked()).FromJust())
{ {
v8::Local<v8::Value> format = obj->Get(Nan::New("format").ToLocalChecked()); v8::Local<v8::Value> format = obj->Get(Nan::New("format").ToLocalChecked());
@ -904,7 +903,7 @@ argumentsToRouteParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
v8::Local<v8::Object> obj = Nan::To<v8::Object>(args[0]).ToLocalChecked(); v8::Local<v8::Object> obj = Nan::To<v8::Object>(args[0]).ToLocalChecked();
if (obj->Has(Nan::New("continue_straight").ToLocalChecked())) if (Nan::Has(obj, Nan::New("continue_straight").ToLocalChecked()).FromJust())
{ {
auto value = obj->Get(Nan::New("continue_straight").ToLocalChecked()); auto value = obj->Get(Nan::New("continue_straight").ToLocalChecked());
if (value.IsEmpty()) if (value.IsEmpty())
@ -917,11 +916,11 @@ argumentsToRouteParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
} }
if (value->IsBoolean()) if (value->IsBoolean())
{ {
params->continue_straight = value->BooleanValue(); params->continue_straight = Nan::To<bool>(value).FromJust();
} }
} }
if (obj->Has(Nan::New("alternatives").ToLocalChecked())) if (Nan::Has(obj, Nan::New("alternatives").ToLocalChecked()).FromJust())
{ {
auto value = obj->Get(Nan::New("alternatives").ToLocalChecked()); auto value = obj->Get(Nan::New("alternatives").ToLocalChecked());
if (value.IsEmpty()) if (value.IsEmpty())
@ -929,13 +928,13 @@ argumentsToRouteParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
if (value->IsBoolean()) if (value->IsBoolean())
{ {
params->alternatives = value->BooleanValue(); params->alternatives = Nan::To<bool>(value).FromJust();
params->number_of_alternatives = value->BooleanValue() ? 1u : 0u; params->number_of_alternatives = Nan::To<bool>(value).FromJust() ? 1u : 0u;
} }
else if (value->IsNumber()) else if (value->IsNumber())
{ {
params->alternatives = value->BooleanValue(); params->alternatives = Nan::To<bool>(value).FromJust();
params->number_of_alternatives = static_cast<unsigned>(value->NumberValue()); params->number_of_alternatives = Nan::To<unsigned>(value).FromJust();
} }
else else
{ {
@ -944,7 +943,7 @@ argumentsToRouteParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
} }
} }
if (obj->Has(Nan::New("waypoints").ToLocalChecked())) if (Nan::Has(obj, Nan::New("waypoints").ToLocalChecked()).FromJust())
{ {
v8::Local<v8::Value> waypoints = obj->Get(Nan::New("waypoints").ToLocalChecked()); v8::Local<v8::Value> waypoints = obj->Get(Nan::New("waypoints").ToLocalChecked());
if (waypoints.IsEmpty()) if (waypoints.IsEmpty())
@ -994,7 +993,7 @@ argumentsToRouteParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
Nan::ThrowError("Waypoints must correspond with the index of an input coordinate"); Nan::ThrowError("Waypoints must correspond with the index of an input coordinate");
return route_parameters_ptr(); return route_parameters_ptr();
} }
params->waypoints.emplace_back(static_cast<unsigned>(waypoint_value->NumberValue())); params->waypoints.emplace_back(Nan::To<unsigned>(waypoint_value).FromJust());
} }
if (!params->waypoints.empty()) if (!params->waypoints.empty())
@ -1010,7 +1009,7 @@ argumentsToRouteParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
} }
} }
if (obj->Has(Nan::New("snapping").ToLocalChecked())) if (Nan::Has(obj, Nan::New("snapping").ToLocalChecked()).FromJust())
{ {
v8::Local<v8::Value> snapping = obj->Get(Nan::New("snapping").ToLocalChecked()); v8::Local<v8::Value> snapping = obj->Get(Nan::New("snapping").ToLocalChecked());
if (snapping.IsEmpty()) if (snapping.IsEmpty())
@ -1095,9 +1094,9 @@ argumentsToTileParameters(const Nan::FunctionCallbackInfo<v8::Value> &args, bool
return tile_parameters_ptr(); return tile_parameters_ptr();
} }
params->x = x->Uint32Value(); params->x = Nan::To<uint32_t>(x).FromJust();
params->y = y->Uint32Value(); params->y = Nan::To<uint32_t>(y).FromJust();
params->z = z->Uint32Value(); params->z = Nan::To<uint32_t>(z).FromJust();
if (!params->IsValid()) if (!params->IsValid())
{ {
@ -1121,7 +1120,7 @@ argumentsToNearestParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
if (obj.IsEmpty()) if (obj.IsEmpty())
return nearest_parameters_ptr(); return nearest_parameters_ptr();
if (obj->Has(Nan::New("number").ToLocalChecked())) if (Nan::Has(obj, Nan::New("number").ToLocalChecked()).FromJust())
{ {
v8::Local<v8::Value> number = obj->Get(Nan::New("number").ToLocalChecked()); v8::Local<v8::Value> number = obj->Get(Nan::New("number").ToLocalChecked());
@ -1132,7 +1131,7 @@ argumentsToNearestParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
} }
else else
{ {
unsigned number_value = static_cast<unsigned>(number->NumberValue()); unsigned number_value = Nan::To<unsigned>(number).FromJust();
if (number_value < 1) if (number_value < 1)
{ {
@ -1140,7 +1139,7 @@ argumentsToNearestParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
return nearest_parameters_ptr(); return nearest_parameters_ptr();
} }
params->number_of_results = static_cast<unsigned>(number->NumberValue()); params->number_of_results = Nan::To<unsigned>(number).FromJust();
} }
} }
@ -1160,7 +1159,7 @@ argumentsToTableParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
if (obj.IsEmpty()) if (obj.IsEmpty())
return table_parameters_ptr(); return table_parameters_ptr();
if (obj->Has(Nan::New("sources").ToLocalChecked())) if (Nan::Has(obj, Nan::New("sources").ToLocalChecked()).FromJust())
{ {
v8::Local<v8::Value> sources = obj->Get(Nan::New("sources").ToLocalChecked()); v8::Local<v8::Value> sources = obj->Get(Nan::New("sources").ToLocalChecked());
if (sources.IsEmpty()) if (sources.IsEmpty())
@ -1181,7 +1180,7 @@ argumentsToTableParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
if (source->IsUint32()) if (source->IsUint32())
{ {
size_t source_value = static_cast<size_t>(source->NumberValue()); size_t source_value = Nan::To<unsigned>(source).FromJust();
if (source_value > params->coordinates.size()) if (source_value > params->coordinates.size())
{ {
Nan::ThrowError( Nan::ThrowError(
@ -1189,7 +1188,7 @@ argumentsToTableParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
return table_parameters_ptr(); return table_parameters_ptr();
} }
params->sources.push_back(static_cast<size_t>(source->NumberValue())); params->sources.push_back(Nan::To<unsigned>(source).FromJust());
} }
else else
{ {
@ -1199,7 +1198,7 @@ argumentsToTableParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
} }
} }
if (obj->Has(Nan::New("destinations").ToLocalChecked())) if (Nan::Has(obj, Nan::New("destinations").ToLocalChecked()).FromJust())
{ {
v8::Local<v8::Value> destinations = obj->Get(Nan::New("destinations").ToLocalChecked()); v8::Local<v8::Value> destinations = obj->Get(Nan::New("destinations").ToLocalChecked());
if (destinations.IsEmpty()) if (destinations.IsEmpty())
@ -1220,7 +1219,7 @@ argumentsToTableParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
if (destination->IsUint32()) if (destination->IsUint32())
{ {
size_t destination_value = static_cast<size_t>(destination->NumberValue()); size_t destination_value = Nan::To<unsigned>(destination).FromJust();
if (destination_value > params->coordinates.size()) if (destination_value > params->coordinates.size())
{ {
Nan::ThrowError("Destination indices must be less than or equal to the number " Nan::ThrowError("Destination indices must be less than or equal to the number "
@ -1228,7 +1227,7 @@ argumentsToTableParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
return table_parameters_ptr(); return table_parameters_ptr();
} }
params->destinations.push_back(static_cast<size_t>(destination->NumberValue())); params->destinations.push_back(Nan::To<unsigned>(destination).FromJust());
} }
else else
{ {
@ -1238,7 +1237,7 @@ argumentsToTableParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
} }
} }
if (obj->Has(Nan::New("annotations").ToLocalChecked())) if (Nan::Has(obj, Nan::New("annotations").ToLocalChecked()).FromJust())
{ {
v8::Local<v8::Value> annotations = obj->Get(Nan::New("annotations").ToLocalChecked()); v8::Local<v8::Value> annotations = obj->Get(Nan::New("annotations").ToLocalChecked());
if (annotations.IsEmpty()) if (annotations.IsEmpty())
@ -1278,7 +1277,7 @@ argumentsToTableParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
} }
} }
if (obj->Has(Nan::New("fallback_speed").ToLocalChecked())) if (Nan::Has(obj, Nan::New("fallback_speed").ToLocalChecked()).FromJust())
{ {
auto fallback_speed = obj->Get(Nan::New("fallback_speed").ToLocalChecked()); auto fallback_speed = obj->Get(Nan::New("fallback_speed").ToLocalChecked());
@ -1287,16 +1286,16 @@ argumentsToTableParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
Nan::ThrowError("fallback_speed must be a number"); Nan::ThrowError("fallback_speed must be a number");
return table_parameters_ptr(); return table_parameters_ptr();
} }
else if (fallback_speed->NumberValue() <= 0) else if (Nan::To<double>(fallback_speed).FromJust() <= 0)
{ {
Nan::ThrowError("fallback_speed must be > 0"); Nan::ThrowError("fallback_speed must be > 0");
return table_parameters_ptr(); return table_parameters_ptr();
} }
params->fallback_speed = static_cast<double>(fallback_speed->NumberValue()); params->fallback_speed = Nan::To<double>(fallback_speed).FromJust();
} }
if (obj->Has(Nan::New("fallback_coordinate").ToLocalChecked())) if (Nan::Has(obj, Nan::New("fallback_coordinate").ToLocalChecked()).FromJust())
{ {
auto fallback_coordinate = obj->Get(Nan::New("fallback_coordinate").ToLocalChecked()); auto fallback_coordinate = obj->Get(Nan::New("fallback_coordinate").ToLocalChecked());
@ -1306,7 +1305,7 @@ argumentsToTableParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
return table_parameters_ptr(); return table_parameters_ptr();
} }
std::string fallback_coordinate_str = *v8::String::Utf8Value(fallback_coordinate); std::string fallback_coordinate_str = *Nan::Utf8String(fallback_coordinate);
if (fallback_coordinate_str == "snapped") if (fallback_coordinate_str == "snapped")
{ {
@ -1324,7 +1323,7 @@ argumentsToTableParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
} }
} }
if (obj->Has(Nan::New("scale_factor").ToLocalChecked())) if (Nan::Has(obj, Nan::New("scale_factor").ToLocalChecked()).FromJust())
{ {
auto scale_factor = obj->Get(Nan::New("scale_factor").ToLocalChecked()); auto scale_factor = obj->Get(Nan::New("scale_factor").ToLocalChecked());
@ -1333,13 +1332,13 @@ argumentsToTableParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
Nan::ThrowError("scale_factor must be a number"); Nan::ThrowError("scale_factor must be a number");
return table_parameters_ptr(); return table_parameters_ptr();
} }
else if (scale_factor->NumberValue() <= 0) else if (Nan::To<double>(scale_factor).FromJust() <= 0)
{ {
Nan::ThrowError("scale_factor must be > 0"); Nan::ThrowError("scale_factor must be > 0");
return table_parameters_ptr(); return table_parameters_ptr();
} }
params->scale_factor = static_cast<double>(scale_factor->NumberValue()); params->scale_factor = Nan::To<double>(scale_factor).FromJust();
} }
return params; return params;
@ -1362,7 +1361,7 @@ argumentsToTripParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
return trip_parameters_ptr(); return trip_parameters_ptr();
} }
if (obj->Has(Nan::New("roundtrip").ToLocalChecked())) if (Nan::Has(obj, Nan::New("roundtrip").ToLocalChecked()).FromJust())
{ {
auto roundtrip = obj->Get(Nan::New("roundtrip").ToLocalChecked()); auto roundtrip = obj->Get(Nan::New("roundtrip").ToLocalChecked());
if (roundtrip.IsEmpty()) if (roundtrip.IsEmpty())
@ -1370,7 +1369,7 @@ argumentsToTripParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
if (roundtrip->IsBoolean()) if (roundtrip->IsBoolean())
{ {
params->roundtrip = roundtrip->BooleanValue(); params->roundtrip = Nan::To<bool>(roundtrip).FromJust();
} }
else else
{ {
@ -1379,7 +1378,7 @@ argumentsToTripParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
} }
} }
if (obj->Has(Nan::New("source").ToLocalChecked())) if (Nan::Has(obj, Nan::New("source").ToLocalChecked()).FromJust())
{ {
v8::Local<v8::Value> source = obj->Get(Nan::New("source").ToLocalChecked()); v8::Local<v8::Value> source = obj->Get(Nan::New("source").ToLocalChecked());
if (source.IsEmpty()) if (source.IsEmpty())
@ -1391,7 +1390,7 @@ argumentsToTripParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
return trip_parameters_ptr(); return trip_parameters_ptr();
} }
std::string source_str = *v8::String::Utf8Value(source); std::string source_str = *Nan::Utf8String(source);
if (source_str == "first") if (source_str == "first")
{ {
@ -1408,7 +1407,7 @@ argumentsToTripParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
} }
} }
if (obj->Has(Nan::New("destination").ToLocalChecked())) if (Nan::Has(obj, Nan::New("destination").ToLocalChecked()).FromJust())
{ {
v8::Local<v8::Value> destination = obj->Get(Nan::New("destination").ToLocalChecked()); v8::Local<v8::Value> destination = obj->Get(Nan::New("destination").ToLocalChecked());
if (destination.IsEmpty()) if (destination.IsEmpty())
@ -1420,7 +1419,7 @@ argumentsToTripParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
return trip_parameters_ptr(); return trip_parameters_ptr();
} }
std::string destination_str = *v8::String::Utf8Value(destination); std::string destination_str = *Nan::Utf8String(destination);
if (destination_str == "last") if (destination_str == "last")
{ {
@ -1451,7 +1450,7 @@ argumentsToMatchParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
v8::Local<v8::Object> obj = Nan::To<v8::Object>(args[0]).ToLocalChecked(); v8::Local<v8::Object> obj = Nan::To<v8::Object>(args[0]).ToLocalChecked();
if (obj->Has(Nan::New("timestamps").ToLocalChecked())) if (Nan::Has(obj, Nan::New("timestamps").ToLocalChecked()).FromJust())
{ {
v8::Local<v8::Value> timestamps = obj->Get(Nan::New("timestamps").ToLocalChecked()); v8::Local<v8::Value> timestamps = obj->Get(Nan::New("timestamps").ToLocalChecked());
if (timestamps.IsEmpty()) if (timestamps.IsEmpty())
@ -1483,11 +1482,11 @@ argumentsToMatchParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
Nan::ThrowError("Timestamps array items must be numbers"); Nan::ThrowError("Timestamps array items must be numbers");
return match_parameters_ptr(); return match_parameters_ptr();
} }
params->timestamps.emplace_back(static_cast<std::size_t>(timestamp->NumberValue())); params->timestamps.emplace_back(Nan::To<unsigned>(timestamp).FromJust());
} }
} }
if (obj->Has(Nan::New("gaps").ToLocalChecked())) if (Nan::Has(obj, Nan::New("gaps").ToLocalChecked()).FromJust())
{ {
v8::Local<v8::Value> gaps = obj->Get(Nan::New("gaps").ToLocalChecked()); v8::Local<v8::Value> gaps = obj->Get(Nan::New("gaps").ToLocalChecked());
if (gaps.IsEmpty()) if (gaps.IsEmpty())
@ -1517,7 +1516,7 @@ argumentsToMatchParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
} }
} }
if (obj->Has(Nan::New("tidy").ToLocalChecked())) if (Nan::Has(obj, Nan::New("tidy").ToLocalChecked()).FromJust())
{ {
v8::Local<v8::Value> tidy = obj->Get(Nan::New("tidy").ToLocalChecked()); v8::Local<v8::Value> tidy = obj->Get(Nan::New("tidy").ToLocalChecked());
if (tidy.IsEmpty()) if (tidy.IsEmpty())
@ -1529,10 +1528,10 @@ argumentsToMatchParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
return match_parameters_ptr(); return match_parameters_ptr();
} }
params->tidy = tidy->BooleanValue(); params->tidy = Nan::To<bool>(tidy).FromJust();
} }
if (obj->Has(Nan::New("waypoints").ToLocalChecked())) if (Nan::Has(obj, Nan::New("waypoints").ToLocalChecked()).FromJust())
{ {
v8::Local<v8::Value> waypoints = obj->Get(Nan::New("waypoints").ToLocalChecked()); v8::Local<v8::Value> waypoints = obj->Get(Nan::New("waypoints").ToLocalChecked());
if (waypoints.IsEmpty()) if (waypoints.IsEmpty())
@ -1582,7 +1581,8 @@ argumentsToMatchParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
Nan::ThrowError("Waypoints must correspond with the index of an input coordinate"); Nan::ThrowError("Waypoints must correspond with the index of an input coordinate");
return match_parameters_ptr(); return match_parameters_ptr();
} }
params->waypoints.emplace_back(static_cast<unsigned>(waypoint_value->NumberValue())); params->waypoints.emplace_back(
static_cast<unsigned>(Nan::To<unsigned>(waypoint_value).FromJust()));
} }
} }

View File

@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef OSRM_HPP #ifndef OSRM_HPP
#define OSRM_HPP #define OSRM_HPP
#include "engine/api/base_result.hpp"
#include "osrm/osrm_fwd.hpp" #include "osrm/osrm_fwd.hpp"
#include "osrm/status.hpp" #include "osrm/status.hpp"
@ -83,7 +84,7 @@ class OSRM final
* \return Status indicating success for the query or failure * \return Status indicating success for the query or failure
* \see Status, RouteParameters and json::Object * \see Status, RouteParameters and json::Object
*/ */
Status Route(const RouteParameters &parameters, json::Object &result) const; Status Route(const RouteParameters &parameters, osrm::engine::api::ResultT &result) const;
/** /**
* Distance tables for coordinates. * Distance tables for coordinates.
@ -92,7 +93,7 @@ class OSRM final
* \return Status indicating success for the query or failure * \return Status indicating success for the query or failure
* \see Status, TableParameters and json::Object * \see Status, TableParameters and json::Object
*/ */
Status Table(const TableParameters &parameters, json::Object &result) const; Status Table(const TableParameters &parameters, osrm::engine::api::ResultT &result) const;
/** /**
* Nearest street segment for coordinate. * Nearest street segment for coordinate.
@ -101,7 +102,7 @@ class OSRM final
* \return Status indicating success for the query or failure * \return Status indicating success for the query or failure
* \see Status, NearestParameters and json::Object * \see Status, NearestParameters and json::Object
*/ */
Status Nearest(const NearestParameters &parameters, json::Object &result) const; Status Nearest(const NearestParameters &parameters, osrm::engine::api::ResultT &result) const;
/** /**
* Trip: shortest round trip between coordinates. * Trip: shortest round trip between coordinates.
@ -110,7 +111,7 @@ class OSRM final
* \return Status indicating success for the query or failure * \return Status indicating success for the query or failure
* \see Status, TripParameters and json::Object * \see Status, TripParameters and json::Object
*/ */
Status Trip(const TripParameters &parameters, json::Object &result) const; Status Trip(const TripParameters &parameters, osrm::engine::api::ResultT &result) const;
/** /**
* Match: snaps noisy coordinate traces to the road network * Match: snaps noisy coordinate traces to the road network
@ -119,7 +120,7 @@ class OSRM final
* \return Status indicating success for the query or failure * \return Status indicating success for the query or failure
* \see Status, MatchParameters and json::Object * \see Status, MatchParameters and json::Object
*/ */
Status Match(const MatchParameters &parameters, json::Object &result) const; Status Match(const MatchParameters &parameters, osrm::engine::api::ResultT &result) const;
/** /**
* Tile: vector tiles with internal graph representation * Tile: vector tiles with internal graph representation
@ -128,7 +129,7 @@ class OSRM final
* \return Status indicating success for the query or failure * \return Status indicating success for the query or failure
* \see Status, TileParameters and json::Object * \see Status, TileParameters and json::Object
*/ */
Status Tile(const TileParameters &parameters, std::string &result) const; Status Tile(const TileParameters &parameters, osrm::engine::api::ResultT &result) const;
private: private:
std::unique_ptr<engine::EngineInterface> engine_; std::unique_ptr<engine::EngineInterface> engine_;

View File

@ -152,6 +152,10 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
qi::lit("generate_hints=") > qi::lit("generate_hints=") >
qi::bool_[ph::bind(&engine::api::BaseParameters::generate_hints, qi::_r1) = qi::_1]; qi::bool_[ph::bind(&engine::api::BaseParameters::generate_hints, qi::_r1) = qi::_1];
skip_waypoints_rule =
qi::lit("skip_waypoints=") >
qi::bool_[ph::bind(&engine::api::BaseParameters::skip_waypoints, qi::_r1) = qi::_1];
bearings_rule = bearings_rule =
qi::lit("bearings=") > qi::lit("bearings=") >
(-(qi::short_ > ',' > qi::short_))[ph::bind(add_bearing, qi::_r1, qi::_1)] % ';'; (-(qi::short_ > ',' > qi::short_))[ph::bind(add_bearing, qi::_r1, qi::_1)] % ';';
@ -169,6 +173,12 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
qi::lit("snapping=") > qi::lit("snapping=") >
snapping_type[ph::bind(&engine::api::BaseParameters::snapping, qi::_r1) = qi::_1]; snapping_type[ph::bind(&engine::api::BaseParameters::snapping, qi::_r1) = qi::_1];
format_type.add(".json", engine::api::BaseParameters::OutputFormatType::JSON)(
".flatbuffers", engine::api::BaseParameters::OutputFormatType::FLATBUFFERS);
format_rule =
-format_type[ph::bind(&engine::api::BaseParameters::format, qi::_r1) = qi::_1];
exclude_rule = qi::lit("exclude=") > exclude_rule = qi::lit("exclude=") >
(qi::as_string[+qi::char_("a-zA-Z0-9")] % (qi::as_string[+qi::char_("a-zA-Z0-9")] %
',')[ph::bind(&engine::api::BaseParameters::exclude, qi::_r1) = qi::_1]; ',')[ph::bind(&engine::api::BaseParameters::exclude, qi::_r1) = qi::_1];
@ -177,6 +187,7 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
| hints_rule(qi::_r1) // | hints_rule(qi::_r1) //
| bearings_rule(qi::_r1) // | bearings_rule(qi::_r1) //
| generate_hints_rule(qi::_r1) // | generate_hints_rule(qi::_r1) //
| skip_waypoints_rule(qi::_r1) //
| approach_rule(qi::_r1) // | approach_rule(qi::_r1) //
| exclude_rule(qi::_r1) // | exclude_rule(qi::_r1) //
| snapping_rule(qi::_r1); | snapping_rule(qi::_r1);
@ -185,6 +196,9 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
protected: protected:
qi::rule<Iterator, Signature> base_rule; qi::rule<Iterator, Signature> base_rule;
qi::rule<Iterator, Signature> query_rule; qi::rule<Iterator, Signature> query_rule;
qi::rule<Iterator, Signature> format_rule;
qi::symbols<char, engine::api::BaseParameters::OutputFormatType> format_type;
qi::real_parser<double, json_policy> double_; qi::real_parser<double, json_policy> double_;
@ -194,6 +208,7 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
qi::rule<Iterator, Signature> hints_rule; qi::rule<Iterator, Signature> hints_rule;
qi::rule<Iterator, Signature> generate_hints_rule; qi::rule<Iterator, Signature> generate_hints_rule;
qi::rule<Iterator, Signature> skip_waypoints_rule;
qi::rule<Iterator, Signature> approach_rule; qi::rule<Iterator, Signature> approach_rule;
qi::rule<Iterator, Signature> exclude_rule; qi::rule<Iterator, Signature> exclude_rule;

View File

@ -46,7 +46,7 @@ struct MatchParametersGrammar final : public RouteParametersGrammar<Iterator, Si
"ignore", engine::api::MatchParameters::GapsType::Ignore); "ignore", engine::api::MatchParameters::GapsType::Ignore);
root_rule = root_rule =
BaseGrammar::query_rule(qi::_r1) > -qi::lit(".json") > BaseGrammar::query_rule(qi::_r1) > BaseGrammar::format_rule(qi::_r1) >
-('?' > (timestamps_rule(qi::_r1) | BaseGrammar::base_rule(qi::_r1) | -('?' > (timestamps_rule(qi::_r1) | BaseGrammar::base_rule(qi::_r1) |
(qi::lit("gaps=") > (qi::lit("gaps=") >
gaps_type[ph::bind(&engine::api::MatchParameters::gaps, qi::_r1) = qi::_1]) | gaps_type[ph::bind(&engine::api::MatchParameters::gaps, qi::_r1) = qi::_1]) |

View File

@ -32,7 +32,7 @@ struct NearestParametersGrammar final : public BaseParametersGrammar<Iterator, S
qi::uint_)[ph::bind(&engine::api::NearestParameters::number_of_results, qi::uint_)[ph::bind(&engine::api::NearestParameters::number_of_results,
qi::_r1) = qi::_1]; qi::_r1) = qi::_1];
root_rule = BaseGrammar::query_rule(qi::_r1) > -qi::lit(".json") > root_rule = BaseGrammar::query_rule(qi::_r1) > BaseGrammar::format_rule(qi::_r1) >
-('?' > (nearest_rule(qi::_r1) | BaseGrammar::base_rule(qi::_r1)) % '&'); -('?' > (nearest_rule(qi::_r1) | BaseGrammar::base_rule(qi::_r1)) % '&');
} }

View File

@ -42,7 +42,7 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
qi::bool_[ph::bind(&engine::api::RouteParameters::continue_straight, qi::_r1) = qi::bool_[ph::bind(&engine::api::RouteParameters::continue_straight, qi::_r1) =
qi::_1])); qi::_1]));
root_rule = query_rule(qi::_r1) > -qi::lit(".json") > root_rule = query_rule(qi::_r1) > BaseGrammar::format_rule(qi::_r1) >
-('?' > (route_rule(qi::_r1) | base_rule(qi::_r1)) % '&'); -('?' > (route_rule(qi::_r1) | base_rule(qi::_r1)) % '&');
} }

View File

@ -62,7 +62,7 @@ struct TableParametersGrammar : public BaseParametersGrammar<Iterator, Signature
table_rule = destinations_rule(qi::_r1) | sources_rule(qi::_r1); table_rule = destinations_rule(qi::_r1) | sources_rule(qi::_r1);
root_rule = BaseGrammar::query_rule(qi::_r1) > -qi::lit(".json") > root_rule = BaseGrammar::query_rule(qi::_r1) > BaseGrammar::format_rule(qi::_r1) >
-('?' > (table_rule(qi::_r1) | base_rule(qi::_r1) | scale_factor_rule(qi::_r1) | -('?' > (table_rule(qi::_r1) | base_rule(qi::_r1) | scale_factor_rule(qi::_r1) |
fallback_speed_rule(qi::_r1) | fallback_speed_rule(qi::_r1) |
(qi::lit("fallback_coordinate=") > (qi::lit("fallback_coordinate=") >

View File

@ -45,7 +45,7 @@ struct TripParametersGrammar final : public RouteParametersGrammar<Iterator, Sig
qi::lit("destination=") > qi::lit("destination=") >
destination_type[ph::bind(&engine::api::TripParameters::destination, qi::_r1) = qi::_1]; destination_type[ph::bind(&engine::api::TripParameters::destination, qi::_r1) = qi::_1];
root_rule = BaseGrammar::query_rule(qi::_r1) > -qi::lit(".json") > root_rule = BaseGrammar::query_rule(qi::_r1) > BaseGrammar::format_rule(qi::_r1) >
-('?' > (roundtrip_rule(qi::_r1) | source_rule(qi::_r1) | -('?' > (roundtrip_rule(qi::_r1) | source_rule(qi::_r1) |
destination_rule(qi::_r1) | BaseGrammar::base_rule(qi::_r1)) % destination_rule(qi::_r1) | BaseGrammar::base_rule(qi::_r1)) %
'&'); '&');

View File

@ -52,11 +52,17 @@ class Connection : public std::enable_shared_from_this<Connection>
/// Handle completion of a write operation. /// Handle completion of a write operation.
void handle_write(const boost::system::error_code &e); void handle_write(const boost::system::error_code &e);
/// Handle read timeout
void handle_timeout(boost::system::error_code);
void handle_shutdown();
std::vector<char> compress_buffers(const std::vector<char> &uncompressed_data, std::vector<char> compress_buffers(const std::vector<char> &uncompressed_data,
const http::compression_type compression_type); const http::compression_type compression_type);
boost::asio::io_service::strand strand; boost::asio::io_service::strand strand;
boost::asio::ip::tcp::socket TCP_socket; boost::asio::ip::tcp::socket TCP_socket;
boost::asio::deadline_timer timer;
RequestHandler &request_handler; RequestHandler &request_handler;
RequestParser request_parser; RequestParser request_parser;
boost::array<char, 8192> incoming_data_buffer; boost::array<char, 8192> incoming_data_buffer;
@ -65,6 +71,10 @@ class Connection : public std::enable_shared_from_this<Connection>
std::vector<char> compressed_output; std::vector<char> compressed_output;
// Header compression_header; // Header compression_header;
std::vector<boost::asio::const_buffer> output_buffer; std::vector<boost::asio::const_buffer> output_buffer;
// Keep alive support
bool keep_alive = false;
short processed_requests = 512;
short keepalive_timeout = 5; // In seconds
}; };
} }
} }

View File

@ -17,6 +17,7 @@ struct request
std::string uri; std::string uri;
std::string referrer; std::string referrer;
std::string agent; std::string agent;
std::string connection;
boost::asio::ip::address endpoint; boost::asio::ip::address endpoint;
}; };
} }

View File

@ -61,7 +61,6 @@ class RequestParser
header_line_start, header_line_start,
header_lws, header_lws,
header_name, header_name,
space_before_header_value,
header_value, header_value,
expecting_newline_2, expecting_newline_2,
expecting_newline_3 expecting_newline_3

View File

@ -20,13 +20,11 @@ namespace service
class BaseService class BaseService
{ {
public: public:
using ResultT = mapbox::util::variant<util::json::Object, std::string>;
BaseService(OSRM &routing_machine) : routing_machine(routing_machine) {} BaseService(OSRM &routing_machine) : routing_machine(routing_machine) {}
virtual ~BaseService() = default; virtual ~BaseService() = default;
virtual engine::Status virtual engine::Status
RunQuery(std::size_t prefix_length, std::string &query, ResultT &result) = 0; RunQuery(std::size_t prefix_length, std::string &query, osrm::engine::api::ResultT &result) = 0;
virtual unsigned GetVersion() = 0; virtual unsigned GetVersion() = 0;

View File

@ -22,8 +22,9 @@ class MatchService final : public BaseService
public: public:
MatchService(OSRM &routing_machine) : BaseService(routing_machine) {} MatchService(OSRM &routing_machine) : BaseService(routing_machine) {}
engine::Status engine::Status RunQuery(std::size_t prefix_length,
RunQuery(std::size_t prefix_length, std::string &query, ResultT &result) final override; std::string &query,
osrm::engine::api::ResultT &result) final override;
unsigned GetVersion() final override { return 1; } unsigned GetVersion() final override { return 1; }
}; };

View File

@ -22,8 +22,9 @@ class NearestService final : public BaseService
public: public:
NearestService(OSRM &routing_machine) : BaseService(routing_machine) {} NearestService(OSRM &routing_machine) : BaseService(routing_machine) {}
engine::Status engine::Status RunQuery(std::size_t prefix_length,
RunQuery(std::size_t prefix_length, std::string &query, ResultT &result) final override; std::string &query,
osrm::engine::api::ResultT &result) final override;
unsigned GetVersion() final override { return 1; } unsigned GetVersion() final override { return 1; }
}; };

View File

@ -22,8 +22,9 @@ class RouteService final : public BaseService
public: public:
RouteService(OSRM &routing_machine) : BaseService(routing_machine) {} RouteService(OSRM &routing_machine) : BaseService(routing_machine) {}
engine::Status engine::Status RunQuery(std::size_t prefix_length,
RunQuery(std::size_t prefix_length, std::string &query, ResultT &result) final override; std::string &query,
osrm::engine::api::ResultT &result) final override;
unsigned GetVersion() final override { return 1; } unsigned GetVersion() final override { return 1; }
}; };

View File

@ -22,8 +22,9 @@ class TableService final : public BaseService
public: public:
TableService(OSRM &routing_machine) : BaseService(routing_machine) {} TableService(OSRM &routing_machine) : BaseService(routing_machine) {}
engine::Status engine::Status RunQuery(std::size_t prefix_length,
RunQuery(std::size_t prefix_length, std::string &query, ResultT &result) final override; std::string &query,
osrm::engine::api::ResultT &result) final override;
unsigned GetVersion() final override { return 1; } unsigned GetVersion() final override { return 1; }
}; };

View File

@ -22,8 +22,9 @@ class TileService final : public BaseService
public: public:
TileService(OSRM &routing_machine) : BaseService(routing_machine) {} TileService(OSRM &routing_machine) : BaseService(routing_machine) {}
engine::Status engine::Status RunQuery(std::size_t prefix_length,
RunQuery(std::size_t prefix_length, std::string &query, ResultT &result) final override; std::string &query,
osrm::engine::api::ResultT &result) final override;
unsigned GetVersion() final override { return 1; } unsigned GetVersion() final override { return 1; }
}; };

View File

@ -22,8 +22,9 @@ class TripService final : public BaseService
public: public:
TripService(OSRM &routing_machine) : BaseService(routing_machine) {} TripService(OSRM &routing_machine) : BaseService(routing_machine) {}
engine::Status engine::Status RunQuery(std::size_t prefix_length,
RunQuery(std::size_t prefix_length, std::string &query, ResultT &result) final override; std::string &query,
osrm::engine::api::ResultT &result) final override;
unsigned GetVersion() final override { return 1; } unsigned GetVersion() final override { return 1; }
}; };

View File

@ -3,6 +3,7 @@
#include "server/service/base_service.hpp" #include "server/service/base_service.hpp"
#include "engine/api/base_api.hpp"
#include "osrm/osrm.hpp" #include "osrm/osrm.hpp"
#include <unordered_map> #include <unordered_map>
@ -28,14 +29,14 @@ class ServiceHandlerInterface
public: public:
virtual ~ServiceHandlerInterface() {} virtual ~ServiceHandlerInterface() {}
virtual engine::Status RunQuery(api::ParsedURL parsed_url, virtual engine::Status RunQuery(api::ParsedURL parsed_url,
service::BaseService::ResultT &result) = 0; osrm::engine::api::ResultT &result) = 0;
}; };
class ServiceHandler final : public ServiceHandlerInterface class ServiceHandler final : public ServiceHandlerInterface
{ {
public: public:
ServiceHandler(osrm::EngineConfig &config); ServiceHandler(osrm::EngineConfig &config);
using ResultT = service::BaseService::ResultT; using ResultT = osrm::engine::api::ResultT;
virtual engine::Status RunQuery(api::ParsedURL parsed_url, ResultT &result) override; virtual engine::Status RunQuery(api::ParsedURL parsed_url, ResultT &result) override;

35
include/storage/io.hpp Normal file → Executable file
View File

@ -10,6 +10,7 @@
#include "util/log.hpp" #include "util/log.hpp"
#include "util/version.hpp" #include "util/version.hpp"
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
#include <boost/iostreams/device/array.hpp> #include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/seek.hpp> #include <boost/iostreams/seek.hpp>
@ -60,29 +61,27 @@ class FileReader
std::size_t GetSize() std::size_t GetSize()
{ {
const boost::filesystem::ifstream::pos_type position = input_stream.tellg(); const boost::filesystem::path path(filepath);
input_stream.seekg(0, std::ios::end); try
const boost::filesystem::ifstream::pos_type file_size = input_stream.tellg();
if (file_size == boost::filesystem::ifstream::pos_type(-1))
{ {
throw util::RuntimeError("Unable to determine file size for " + return std::size_t(boost::filesystem::file_size(path)) -
std::string(filepath.string()), ((fingerprint == FingerprintFlag::VerifyFingerprint) ? sizeof(util::FingerPrint)
ErrorCode::FileIOError, : 0);
SOURCE_REF, }
std::strerror(errno)); catch (const boost::filesystem::filesystem_error &ex)
{
std::cout << ex.what() << std::endl;
throw;
}
} }
// restore the current position /* Read one line */
input_stream.seekg(position, std::ios::beg); template <typename T> void ReadLine(T *dest, const std::size_t count)
if (fingerprint == FingerprintFlag::VerifyFingerprint)
{ {
return std::size_t(file_size) - sizeof(util::FingerPrint); if (0 < count)
}
else
{ {
return file_size; memset(dest, 0, count * sizeof(T));
input_stream.getline(reinterpret_cast<char *>(dest), count * sizeof(T));
} }
} }

View File

@ -17,10 +17,6 @@
#include <cstdint> #include <cstdint>
#include <tuple> #include <tuple>
#if USE_STXXL_LIBRARY
#include <stxxl/vector>
#endif
namespace osrm namespace osrm
{ {
namespace storage namespace storage
@ -134,24 +130,6 @@ inline void write(storage::tar::FileWriter &writer,
writer.WriteStreaming<T>(name, vec.begin(), vec.size()); writer.WriteStreaming<T>(name, vec.begin(), vec.size());
} }
#if USE_STXXL_LIBRARY
template <typename T>
inline void read(storage::tar::FileReader &reader, const std::string &name, stxxl::vector<T> &vec)
{
auto size = reader.ReadElementCount64(name);
vec.reserve(size);
reader.ReadStreaming<T>(name, std::back_inserter(vec), size);
}
template <typename T>
inline void
write(storage::tar::FileWriter &writer, const std::string &name, const stxxl::vector<T> &vec)
{
writer.WriteElementCount64(name, vec.size());
writer.WriteStreaming<T>(name, vec.begin(), vec.size());
}
#endif
template <typename T> void read(io::BufferReader &reader, std::vector<T> &data) template <typename T> void read(io::BufferReader &reader, std::vector<T> &data)
{ {
const auto count = reader.ReadElementCount64(); const auto count = reader.ReadElementCount64();

View File

@ -99,8 +99,8 @@ class BaseDataLayout
} }
} }
virtual inline void *GetBlockPtr(void *base_ptr, const std::string &name) const = 0; virtual void *GetBlockPtr(void *base_ptr, const std::string &name) const = 0;
virtual inline std::uint64_t GetSizeOfLayout() const = 0; virtual std::uint64_t GetSizeOfLayout() const = 0;
protected: protected:
const Block &GetBlock(const std::string &name) const const Block &GetBlock(const std::string &name) const

View File

@ -17,6 +17,8 @@
#include <boost/spirit/include/phoenix.hpp> #include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/qi.hpp>
#include <exception>
#include <stdexcept>
#include <vector> #include <vector>
namespace osrm namespace osrm
@ -80,7 +82,9 @@ template <typename Key, typename Value> struct CSVFilesParser
return LookupTable<Key, Value>{lookup}; return LookupTable<Key, Value>{lookup};
} }
catch (const tbb::captured_exception &e) catch (const std::exception &e)
// TBB should capture to std::exception_ptr and automatically rethrow in this thread.
// https://software.intel.com/en-us/node/506317
{ {
throw util::exception(e.what() + SOURCE_REF); throw util::exception(e.what() + SOURCE_REF);
} }
@ -122,7 +126,7 @@ template <typename Key, typename Value> struct CSVFilesParser
util::Log() << "Loaded " << filename << " with " << result.size() << "values"; util::Log() << "Loaded " << filename << " with " << result.size() << "values";
return std::move(result); return result;
} }
catch (const boost::exception &e) catch (const boost::exception &e)
{ {

View File

@ -7,29 +7,11 @@
#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
{ {
inline void DumpSTXXLStats()
{
#if USE_STXXL_LIBRARY
#if STXXL_VERSION_MAJOR > 1 || (STXXL_VERSION_MAJOR == 1 && STXXL_VERSION_MINOR >= 4)
auto manager = stxxl::block_manager::get_instance();
util::Log() << "STXXL: peak bytes used: " << manager->get_maximum_allocation();
util::Log() << "STXXL: total disk allocated: " << manager->get_total_bytes();
#else
#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";
#endif
#endif
}
inline void DumpMemoryStats() inline void DumpMemoryStats()
{ {
#ifndef _WIN32 #ifndef _WIN32

View File

@ -19,10 +19,6 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#if USE_STXXL_LIBRARY
#include <stxxl/vector>
#endif
namespace osrm namespace osrm
{ {
namespace util namespace util
@ -253,16 +249,10 @@ 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,
ExternalVector<DataT>, std::vector<DataT>,
std::vector<DataT>>::type; std::vector<DataT>>::type;
template <typename DataT, storage::Ownership Ownership> template <typename DataT, storage::Ownership Ownership>

10
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "osrm", "name": "osrm",
"version": "5.20.0-latest.1", "version": "5.22.0-customsnapping.2",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -1740,6 +1740,7 @@
"resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
"integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"inherits": "~2.0.0" "inherits": "~2.0.0"
} }
@ -5567,6 +5568,7 @@
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
"integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"graceful-fs": "^4.1.2", "graceful-fs": "^4.1.2",
"inherits": "~2.0.0", "inherits": "~2.0.0",
@ -7646,9 +7648,9 @@
"dev": true "dev": true
}, },
"nan": { "nan": {
"version": "2.11.1", "version": "2.14.1",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz",
"integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==" "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw=="
}, },
"natural-compare": { "natural-compare": {
"version": "1.4.0", "version": "1.4.0",

View File

@ -5,7 +5,7 @@
"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": {
"mkdirp": "^0.5.1", "mkdirp": "^0.5.1",
"nan": "^2.11.1", "nan": "^2.14.1",
"node-cmake": "^2.3.2", "node-cmake": "^2.3.2",
"node-pre-gyp": "^0.12.0", "node-pre-gyp": "^0.12.0",
"rimraf": "^2.5.4" "rimraf": "^2.5.4"

View File

@ -56,7 +56,13 @@ function setup()
'private', 'private',
'agricultural', 'agricultural',
'forestry', 'forestry',
'delivery' 'delivery',
-- When a way is tagged with `use_sidepath` a parallel way suitable for
-- cyclists is mapped and must be used instead (by law). This tag is
-- used on ways that normally may be used by cyclists, but not when
-- a signposted parallel cycleway is available. For purposes of routing
-- cyclists, this value should be treated as 'no access for bicycles'.
'use_sidepath'
}, },
restricted_access_tag_list = Set { }, restricted_access_tag_list = Set { },

View File

@ -39,11 +39,11 @@ function setup()
cardinal_directions = false, cardinal_directions = false,
-- Size of the vehicle, to be limited by physical restriction of the way -- Size of the vehicle, to be limited by physical restriction of the way
vehicle_height = 2.5, -- in meters, 2.5m is the height of van vehicle_height = 2.0, -- in meters, 2.0m is the height slightly above biggest SUVs
vehicle_width = 1.9, -- in meters, ways with narrow tag are considered narrower than 2.2m vehicle_width = 1.9, -- in meters, ways with narrow tag are considered narrower than 2.2m
-- Size of the vehicle, to be limited mostly by legal restriction of the way -- Size of the vehicle, to be limited mostly by legal restriction of the way
vehicle_length = 4.8, -- in meters, 4.8m is the length of large or familly car vehicle_length = 4.8, -- in meters, 4.8m is the length of large or family car
vehicle_weight = 2000, -- in kilograms vehicle_weight = 2000, -- in kilograms
-- a list of suffixes to suppress in name change instructions. The suffixes also include common substrings of each other -- a list of suffixes to suppress in name change instructions. The suffixes also include common substrings of each other

View File

@ -38,7 +38,7 @@ local way = {
local result = {} local result = {}
-- call the way function -- call the way function
Debug.way_function(way,result) Debug.process_way(way,result)
-- print input and output -- print input and output
pprint(way) pprint(way)

View File

@ -10,7 +10,7 @@ local pprint = require('lib/pprint')
-- globals that are normally set from C++ -- globals that are normally set from C++
-- should match values defined in include/extractor/guidance/road_classification.hpp -- should match values defined in include/extractor/road_classification.hpp
road_priority_class = { road_priority_class = {
motorway = 0, motorway = 0,
trunk = 2, trunk = 2,

View File

@ -15,7 +15,7 @@ local pprint = require('lib/pprint')
-- profiles code modifies this table -- profiles code modifies this table
properties = {} properties = {}
-- should match values defined in include/extractor/guidance/road_classification.hpp -- should match values defined in include/extractor/road_classification.hpp
road_priority_class = { road_priority_class = {
motorway = 0, motorway = 0,
trunk = 2, trunk = 2,

View File

@ -18,11 +18,3 @@ sudo apt-get update -qq --yes || true
sudo apt-get install -qq --yes --force-yes g++-4.8-arm-linux-gnueabihf g++-4.8-multilib-arm-linux-gnueabihf gcc-4.8-arm-linux-gnueabihf gcc-4.8-multilib-arm-linux-gnueabihf sudo apt-get install -qq --yes --force-yes g++-4.8-arm-linux-gnueabihf g++-4.8-multilib-arm-linux-gnueabihf gcc-4.8-arm-linux-gnueabihf gcc-4.8-multilib-arm-linux-gnueabihf
sudo apt-get install -qq --yes --force-yes libexpat1-dev:armhf zlib1g-dev:armhf libbz2-dev:armhf libboost-date-time-dev:armhf libboost-filesystem-dev:armhf libboost-iostreams-dev:armhf libboost-program-options-dev:armhf libboost-regex-dev:armhf libboost-system-dev:armhf libboost-thread-dev:armhf libtbb-dev:armhf libboost-test-dev:armhf sudo apt-get install -qq --yes --force-yes libexpat1-dev:armhf zlib1g-dev:armhf libbz2-dev:armhf libboost-date-time-dev:armhf libboost-filesystem-dev:armhf libboost-iostreams-dev:armhf libboost-program-options-dev:armhf libboost-regex-dev:armhf libboost-system-dev:armhf libboost-thread-dev:armhf libtbb-dev:armhf libboost-test-dev:armhf
## build libstxxl1v5:armhf from sources, no package in trusty
if [ $UBUNTU_RELEASE == trusty ] ; then
( cd /tmp && wget http://sourceforge.net/projects/stxxl/files/stxxl/1.4.1/stxxl-1.4.1.tar.gz && tar xf stxxl-1.4.1.tar.gz )
( cd /tmp/stxxl-1.4.1 && mkdir build && cd build && CC=arm-linux-gnueabihf-gcc-4.8 CXX=arm-linux-gnueabihf-g++-4.8 cmake .. && make && sudo make install )
else
sudo apt-get install -qq --yes --force-yes libstxxl1v5:armhf
fi

View File

@ -3,4 +3,4 @@
sudo dpkg --add-architecture i386 sudo dpkg --add-architecture i386
sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test && ( sudo apt-get update -qq --yes || true ) sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test && ( sudo apt-get update -qq --yes || true )
sudo apt-get install -qq --yes --force-yes g++-7-multilib libxml2-dev:i386 libexpat1-dev:i386 libzip-dev:i386 libbz2-dev:i386 libstxxl-dev:i386 libtbb-dev:i386 lua5.2:i386 liblua5.2-dev:i386 libboost-date-time-dev:i386 libboost-filesystem-dev:i386 libboost-iostreams-dev:i386 libboost-program-options-dev:i386 libboost-regex-dev:i386 libboost-system-dev:i386 libboost-thread-dev:i386 libboost-test-dev:i386 sudo apt-get install -qq --yes --force-yes g++-7-multilib libxml2-dev:i386 libexpat1-dev:i386 libzip-dev:i386 libbz2-dev:i386 libtbb-dev:i386 lua5.2:i386 liblua5.2-dev:i386 libboost-date-time-dev:i386 libboost-filesystem-dev:i386 libboost-iostreams-dev:i386 libboost-program-options-dev:i386 libboost-regex-dev:i386 libboost-system-dev:i386 libboost-thread-dev:i386 libboost-test-dev:i386

View File

@ -214,9 +214,11 @@ int main(int argc, const char *argv[]) try
auto NUM = 100; auto NUM = 100;
for (int i = 0; i < NUM; ++i) for (int i = 0; i < NUM; ++i)
{ {
json::Object result; engine::api::ResultT result = json::Object();
const auto rc = osrm.Match(params, result); const auto rc = osrm.Match(params, result);
if (rc != Status::Ok || result.values.at("matchings").get<json::Array>().values.size() != 1) auto &json_result = result.get<json::Object>();
if (rc != Status::Ok ||
json_result.values.at("matchings").get<json::Array>().values.size() != 1)
{ {
return EXIT_FAILURE; return EXIT_FAILURE;
} }

View File

@ -36,7 +36,12 @@
#include <boost/assert.hpp> #include <boost/assert.hpp>
#if TBB_VERSION_MAJOR == 2020
#include <tbb/global_control.h>
#else
#include <tbb/task_scheduler_init.h> #include <tbb/task_scheduler_init.h>
#endif
namespace osrm namespace osrm
{ {
namespace contractor namespace contractor
@ -44,8 +49,13 @@ namespace contractor
int Contractor::Run() int Contractor::Run()
{ {
#if TBB_VERSION_MAJOR == 2020
tbb::global_control gc(tbb::global_control::max_allowed_parallelism,
config.requested_num_threads);
#else
tbb::task_scheduler_init init(config.requested_num_threads); tbb::task_scheduler_init init(config.requested_num_threads);
BOOST_ASSERT(init.is_active()); BOOST_ASSERT(init.is_active());
#endif
if (config.core_factor != 1.0) if (config.core_factor != 1.0)
{ {

View File

@ -21,7 +21,11 @@
#include <boost/assert.hpp> #include <boost/assert.hpp>
#if TBB_VERSION_MAJOR == 2020
#include <tbb/global_control.h>
#else
#include <tbb/task_scheduler_init.h> #include <tbb/task_scheduler_init.h>
#endif
namespace osrm namespace osrm
{ {
@ -118,8 +122,13 @@ std::vector<CellMetric> customizeFilteredMetrics(const partitioner::MultiLevelEd
int Customizer::Run(const CustomizationConfig &config) int Customizer::Run(const CustomizationConfig &config)
{ {
#if TBB_VERSION_MAJOR == 2020
tbb::global_control gc(tbb::global_control::max_allowed_parallelism,
config.requested_num_threads);
#else
tbb::task_scheduler_init init(config.requested_num_threads); tbb::task_scheduler_init init(config.requested_num_threads);
BOOST_ASSERT(init.is_active()); BOOST_ASSERT(init.is_active());
#endif
TIMER_START(loading_data); TIMER_START(loading_data);

View File

@ -20,7 +20,6 @@
#include <vector> #include <vector>
namespace TurnType = osrm::guidance::TurnType; namespace TurnType = osrm::guidance::TurnType;
namespace DirectionModifier = osrm::guidance::DirectionModifier;
using TurnInstruction = osrm::guidance::TurnInstruction; using TurnInstruction = osrm::guidance::TurnInstruction;
namespace osrm namespace osrm
@ -34,18 +33,6 @@ namespace json
namespace detail namespace detail
{ {
// Check whether to include a modifier in the result of the API
inline bool isValidModifier(const guidance::StepManeuver maneuver)
{
return (maneuver.waypoint_type == guidance::WaypointType::None ||
maneuver.instruction.direction_modifier != DirectionModifier::UTurn);
}
inline bool hasValidLanes(const guidance::IntermediateIntersection &intersection)
{
return intersection.lanes.lanes_in_turn > 0;
}
inline util::json::Array toJSON(const extractor::TurnLaneType::Mask lane_type) inline util::json::Array toJSON(const extractor::TurnLaneType::Mask lane_type)
{ {
util::json::Array result; util::json::Array result;

View File

@ -52,11 +52,11 @@ MMapMemoryAllocator::MMapMemoryAllocator(const storage::StorageConfig &config)
{ {
std::unique_ptr<storage::BaseDataLayout> layout = std::unique_ptr<storage::BaseDataLayout> layout =
std::make_unique<storage::TarDataLayout>(); std::make_unique<storage::TarDataLayout>();
boost::iostreams::mapped_file mapped_memory_file; boost::iostreams::mapped_file_source mapped_memory_file;
util::mmapFile<char>(file.second, mapped_memory_file); auto data = util::mmapFile<char>(file.second, mapped_memory_file).data();
mapped_memory_files.push_back(std::move(mapped_memory_file)); mapped_memory_files.push_back(std::move(mapped_memory_file));
storage::populateLayoutFromFile(file.second, *layout); storage::populateLayoutFromFile(file.second, *layout);
allocated_regions.push_back({mapped_memory_file.data(), std::move(layout)}); allocated_regions.push_back({const_cast<char *>(data), std::move(layout)});
} }
} }

View File

@ -112,16 +112,16 @@ void filterCandidates(const std::vector<util::Coordinate> &coordinates,
Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms, Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
const api::MatchParameters &parameters, const api::MatchParameters &parameters,
util::json::Object &json_result) const osrm::engine::api::ResultT &result) const
{ {
if (!algorithms.HasMapMatching()) if (!algorithms.HasMapMatching())
{ {
return Error("NotImplemented", return Error("NotImplemented",
"Map matching is not implemented for the chosen search algorithm.", "Map matching is not implemented for the chosen search algorithm.",
json_result); result);
} }
if (!CheckAlgorithms(parameters, algorithms, json_result)) if (!CheckAlgorithms(parameters, algorithms, result))
return Status::Error; return Status::Error;
const auto &facade = algorithms.GetFacade(); const auto &facade = algorithms.GetFacade();
@ -132,12 +132,12 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
if (max_locations_map_matching > 0 && if (max_locations_map_matching > 0 &&
static_cast<int>(parameters.coordinates.size()) > max_locations_map_matching) static_cast<int>(parameters.coordinates.size()) > max_locations_map_matching)
{ {
return Error("TooBig", "Too many trace coordinates", json_result); return Error("TooBig", "Too many trace coordinates", result);
} }
if (!CheckAllCoordinates(parameters.coordinates)) if (!CheckAllCoordinates(parameters.coordinates))
{ {
return Error("InvalidValue", "Invalid coordinate value.", json_result); return Error("InvalidValue", "Invalid coordinate value.", result);
} }
if (max_radius_map_matching > 0 && std::any_of(parameters.radiuses.begin(), if (max_radius_map_matching > 0 && std::any_of(parameters.radiuses.begin(),
@ -148,7 +148,7 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
return *radius > max_radius_map_matching; return *radius > max_radius_map_matching;
})) }))
{ {
return Error("TooBig", "Radius search size is too large for map matching.", json_result); return Error("TooBig", "Radius search size is too large for map matching.", result);
} }
// Check for same or increasing timestamps. Impl. note: Incontrast to `sort(first, // Check for same or increasing timestamps. Impl. note: Incontrast to `sort(first,
@ -158,8 +158,7 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
if (!time_increases_monotonically) if (!time_increases_monotonically)
{ {
return Error( return Error("InvalidValue", "Timestamps need to be monotonically increasing.", result);
"InvalidValue", "Timestamps need to be monotonically increasing.", json_result);
} }
SubMatchingList sub_matchings; SubMatchingList sub_matchings;
@ -180,9 +179,8 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
(tidied.parameters.waypoints[0] != 0 || (tidied.parameters.waypoints[0] != 0 ||
tidied.parameters.waypoints.back() != (tidied.parameters.coordinates.size() - 1))) tidied.parameters.waypoints.back() != (tidied.parameters.coordinates.size() - 1)))
{ {
return Error("InvalidValue", return Error(
"First and last coordinates must be specified as waypoints.", "InvalidValue", "First and last coordinates must be specified as waypoints.", result);
json_result);
} }
// assuming radius is the standard deviation of a normal distribution // assuming radius is the standard deviation of a normal distribution
@ -225,7 +223,7 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
{ {
return Error("NoSegment", return Error("NoSegment",
std::string("Could not find a matching segment for any coordinate."), std::string("Could not find a matching segment for any coordinate."),
json_result); result);
} }
// call the actual map matching // call the actual map matching
@ -238,13 +236,13 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
if (sub_matchings.size() == 0) if (sub_matchings.size() == 0)
{ {
return Error("NoMatch", "Could not match the trace.", json_result); return Error("NoMatch", "Could not match the trace.", result);
} }
// trace was split, we don't support the waypoints parameter across multiple match objects // trace was split, we don't support the waypoints parameter across multiple match objects
if (sub_matchings.size() > 1 && !parameters.waypoints.empty()) if (sub_matchings.size() > 1 && !parameters.waypoints.empty())
{ {
return Error("NoMatch", "Could not match the trace with the given waypoints.", json_result); return Error("NoMatch", "Could not match the trace with the given waypoints.", result);
} }
// Error: Check if user-supplied waypoints can be found in the resulting matches // Error: Check if user-supplied waypoints can be found in the resulting matches
@ -260,8 +258,7 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
} }
if (!tidied_waypoints.empty()) if (!tidied_waypoints.empty())
{ {
return Error( return Error("NoMatch", "Requested waypoint parameter could not be matched.", result);
"NoMatch", "Requested waypoint parameter could not be matched.", json_result);
} }
} }
// we haven't errored yet, only allow leg collapsing if it was originally requested // we haven't errored yet, only allow leg collapsing if it was originally requested
@ -313,7 +310,7 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
} }
api::MatchAPI match_api{facade, parameters, tidied}; api::MatchAPI match_api{facade, parameters, tidied};
match_api.MakeResponse(sub_matchings, sub_routes, json_result); match_api.MakeResponse(sub_matchings, sub_routes, result);
return Status::Ok; return Status::Ok;
} }

View File

@ -21,11 +21,11 @@ NearestPlugin::NearestPlugin(const int max_results_) : max_results{max_results_}
Status NearestPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms, Status NearestPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
const api::NearestParameters &params, const api::NearestParameters &params,
util::json::Object &json_result) const osrm::engine::api::ResultT &result) const
{ {
BOOST_ASSERT(params.IsValid()); BOOST_ASSERT(params.IsValid());
if (!CheckAlgorithms(params, algorithms, json_result)) if (!CheckAlgorithms(params, algorithms, result))
return Status::Error; return Status::Error;
const auto &facade = algorithms.GetFacade(); const auto &facade = algorithms.GetFacade();
@ -36,27 +36,27 @@ Status NearestPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms
return Error("TooBig", return Error("TooBig",
"Number of results " + std::to_string(params.number_of_results) + "Number of results " + std::to_string(params.number_of_results) +
" is higher than current maximum (" + std::to_string(max_results) + ")", " is higher than current maximum (" + std::to_string(max_results) + ")",
json_result); result);
} }
if (!CheckAllCoordinates(params.coordinates)) if (!CheckAllCoordinates(params.coordinates))
return Error("InvalidOptions", "Coordinates are invalid", json_result); return Error("InvalidOptions", "Coordinates are invalid", result);
if (params.coordinates.size() != 1) if (params.coordinates.size() != 1)
{ {
return Error("InvalidOptions", "Only one input coordinate is supported", json_result); return Error("InvalidOptions", "Only one input coordinate is supported", result);
} }
auto phantom_nodes = GetPhantomNodes(facade, params, params.number_of_results); auto phantom_nodes = GetPhantomNodes(facade, params, params.number_of_results);
if (phantom_nodes.front().size() == 0) if (phantom_nodes.front().size() == 0)
{ {
return Error("NoSegment", "Could not find a matching segments for coordinate", json_result); return Error("NoSegment", "Could not find a matching segments for coordinate", result);
} }
BOOST_ASSERT(phantom_nodes.front().size() > 0); BOOST_ASSERT(phantom_nodes.front().size() > 0);
api::NearestAPI nearest_api(facade, params); api::NearestAPI nearest_api(facade, params);
nearest_api.MakeResponse(phantom_nodes, json_result); nearest_api.MakeResponse(phantom_nodes, result);
return Status::Ok; return Status::Ok;
} }

View File

@ -31,7 +31,7 @@ TablePlugin::TablePlugin(const int max_locations_distance_table)
Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms, Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
const api::TableParameters &params, const api::TableParameters &params,
util::json::Object &result) const osrm::engine::api::ResultT &result) const
{ {
if (!algorithms.HasManyToManySearch()) if (!algorithms.HasManyToManySearch())
{ {

View File

@ -665,10 +665,11 @@ void encodeVectorTile(const DataFacadeBase &facade,
Status TilePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms, Status TilePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
const api::TileParameters &parameters, const api::TileParameters &parameters,
std::string &pbf_buffer) const osrm::engine::api::ResultT &result) const
{ {
BOOST_ASSERT(parameters.IsValid()); BOOST_ASSERT(parameters.IsValid());
auto &pbf_buffer = result.get<std::string>();
const auto &facade = algorithms.GetFacade(); const auto &facade = algorithms.GetFacade();
auto edges = getEdges(facade, parameters.x, parameters.y, parameters.z); auto edges = getEdges(facade, parameters.x, parameters.y, parameters.z);
auto segregated_nodes = getSegregatedNodes(facade, edges); auto segregated_nodes = getSegregatedNodes(facade, edges);

View File

@ -144,19 +144,19 @@ void ManipulateTableForFSE(const std::size_t source_id,
Status TripPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms, Status TripPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
const api::TripParameters &parameters, const api::TripParameters &parameters,
util::json::Object &json_result) const osrm::engine::api::ResultT &result) const
{ {
if (!algorithms.HasShortestPathSearch()) if (!algorithms.HasShortestPathSearch())
{ {
return Error("NotImplemented", return Error("NotImplemented",
"Shortest path search is not implemented for the chosen search algorithm.", "Shortest path search is not implemented for the chosen search algorithm.",
json_result); result);
} }
if (!algorithms.HasManyToManySearch()) if (!algorithms.HasManyToManySearch())
{ {
return Error("NotImplemented", return Error("NotImplemented",
"Many to many search is not implemented for the chosen search algorithm.", "Many to many search is not implemented for the chosen search algorithm.",
json_result); result);
} }
BOOST_ASSERT(parameters.IsValid()); BOOST_ASSERT(parameters.IsValid());
@ -177,21 +177,21 @@ Status TripPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
bool fixed_end = (destination_id == number_of_locations - 1); bool fixed_end = (destination_id == number_of_locations - 1);
if (!IsSupportedParameterCombination(fixed_start, fixed_end, parameters.roundtrip)) if (!IsSupportedParameterCombination(fixed_start, fixed_end, parameters.roundtrip))
{ {
return Error("NotImplemented", "This request is not supported", json_result); return Error("NotImplemented", "This request is not supported", result);
} }
// enforce maximum number of locations for performance reasons // enforce maximum number of locations for performance reasons
if (max_locations_trip > 0 && static_cast<int>(number_of_locations) > max_locations_trip) if (max_locations_trip > 0 && static_cast<int>(number_of_locations) > max_locations_trip)
{ {
return Error("TooBig", "Too many trip coordinates", json_result); return Error("TooBig", "Too many trip coordinates", result);
} }
if (!CheckAllCoordinates(parameters.coordinates)) if (!CheckAllCoordinates(parameters.coordinates))
{ {
return Error("InvalidValue", "Invalid coordinate value.", json_result); return Error("InvalidValue", "Invalid coordinate value.", result);
} }
if (!CheckAlgorithms(parameters, algorithms, json_result)) if (!CheckAlgorithms(parameters, algorithms, result))
return Status::Error; return Status::Error;
const auto &facade = algorithms.GetFacade(); const auto &facade = algorithms.GetFacade();
@ -201,14 +201,14 @@ Status TripPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
return Error("NoSegment", return Error("NoSegment",
std::string("Could not find a matching segment for coordinate ") + std::string("Could not find a matching segment for coordinate ") +
std::to_string(phantom_node_pairs.size()), std::to_string(phantom_node_pairs.size()),
json_result); result);
} }
BOOST_ASSERT(phantom_node_pairs.size() == number_of_locations); BOOST_ASSERT(phantom_node_pairs.size() == number_of_locations);
if (fixed_start && fixed_end && (source_id >= parameters.coordinates.size() || if (fixed_start && fixed_end && (source_id >= parameters.coordinates.size() ||
destination_id >= parameters.coordinates.size())) destination_id >= parameters.coordinates.size()))
{ {
return Error("InvalidValue", "Invalid source or destination value.", json_result); return Error("InvalidValue", "Invalid source or destination value.", result);
} }
auto snapped_phantoms = SnapPhantomNodes(phantom_node_pairs); auto snapped_phantoms = SnapPhantomNodes(phantom_node_pairs);
@ -231,7 +231,7 @@ Status TripPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
if (!IsStronglyConnectedComponent(result_duration_table)) if (!IsStronglyConnectedComponent(result_duration_table))
{ {
return Error("NoTrips", "No trip visiting all destinations possible.", json_result); return Error("NoTrips", "No trip visiting all destinations possible.", result);
} }
if (fixed_start && fixed_end) if (fixed_start && fixed_end)
@ -275,7 +275,7 @@ Status TripPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
const std::vector<std::vector<NodeID>> trips = {duration_trip}; const std::vector<std::vector<NodeID>> trips = {duration_trip};
const std::vector<InternalRouteResult> routes = {route}; const std::vector<InternalRouteResult> routes = {route};
api::TripAPI trip_api{facade, parameters}; api::TripAPI trip_api{facade, parameters};
trip_api.MakeResponse(trips, routes, snapped_phantoms, json_result); trip_api.MakeResponse(trips, routes, snapped_phantoms, result);
return Status::Ok; return Status::Ok;
} }

View File

@ -28,7 +28,7 @@ ViaRoutePlugin::ViaRoutePlugin(int max_locations_viaroute, int max_alternatives)
Status ViaRoutePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms, Status ViaRoutePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
const api::RouteParameters &route_parameters, const api::RouteParameters &route_parameters,
util::json::Object &json_result) const osrm::engine::api::ResultT &result) const
{ {
BOOST_ASSERT(route_parameters.IsValid()); BOOST_ASSERT(route_parameters.IsValid());
@ -37,7 +37,7 @@ Status ViaRoutePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithm
return Error("NotImplemented", return Error("NotImplemented",
"Shortest path search is not implemented for the chosen search algorithm. " "Shortest path search is not implemented for the chosen search algorithm. "
"Only two coordinates supported.", "Only two coordinates supported.",
json_result); result);
} }
if (!algorithms.HasDirectShortestPathSearch() && !algorithms.HasShortestPathSearch()) if (!algorithms.HasDirectShortestPathSearch() && !algorithms.HasShortestPathSearch())
@ -45,7 +45,7 @@ Status ViaRoutePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithm
return Error( return Error(
"NotImplemented", "NotImplemented",
"Direct shortest path search is not implemented for the chosen search algorithm.", "Direct shortest path search is not implemented for the chosen search algorithm.",
json_result); result);
} }
if (max_locations_viaroute > 0 && if (max_locations_viaroute > 0 &&
@ -55,7 +55,7 @@ Status ViaRoutePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithm
"Number of entries " + std::to_string(route_parameters.coordinates.size()) + "Number of entries " + std::to_string(route_parameters.coordinates.size()) +
" is higher than current maximum (" + " is higher than current maximum (" +
std::to_string(max_locations_viaroute) + ")", std::to_string(max_locations_viaroute) + ")",
json_result); result);
} }
// Takes care of alternatives=n and alternatives=true // Takes care of alternatives=n and alternatives=true
@ -65,12 +65,12 @@ Status ViaRoutePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithm
return Error("TooBig", return Error("TooBig",
"Requested number of alternatives is higher than current maximum (" + "Requested number of alternatives is higher than current maximum (" +
std::to_string(max_alternatives) + ")", std::to_string(max_alternatives) + ")",
json_result); result);
} }
if (!CheckAllCoordinates(route_parameters.coordinates)) if (!CheckAllCoordinates(route_parameters.coordinates))
{ {
return Error("InvalidValue", "Invalid coordinate value.", json_result); return Error("InvalidValue", "Invalid coordinate value.", result);
} }
// Error: first and last points should be waypoints // Error: first and last points should be waypoints
@ -78,12 +78,11 @@ Status ViaRoutePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithm
(route_parameters.waypoints[0] != 0 || (route_parameters.waypoints[0] != 0 ||
route_parameters.waypoints.back() != (route_parameters.coordinates.size() - 1))) route_parameters.waypoints.back() != (route_parameters.coordinates.size() - 1)))
{ {
return Error("InvalidValue", return Error(
"First and last coordinates must be specified as waypoints.", "InvalidValue", "First and last coordinates must be specified as waypoints.", result);
json_result);
} }
if (!CheckAlgorithms(route_parameters, algorithms, json_result)) if (!CheckAlgorithms(route_parameters, algorithms, result))
return Status::Error; return Status::Error;
const auto &facade = algorithms.GetFacade(); const auto &facade = algorithms.GetFacade();
@ -93,7 +92,7 @@ Status ViaRoutePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithm
return Error("NoSegment", return Error("NoSegment",
std::string("Could not find a matching segment for coordinate ") + std::string("Could not find a matching segment for coordinate ") +
std::to_string(phantom_node_pairs.size()), std::to_string(phantom_node_pairs.size()),
json_result); result);
} }
BOOST_ASSERT(phantom_node_pairs.size() == route_parameters.coordinates.size()); BOOST_ASSERT(phantom_node_pairs.size() == route_parameters.coordinates.size());
@ -162,7 +161,7 @@ Status ViaRoutePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithm
} }
} }
route_api.MakeResponse(routes, start_end_nodes, json_result); route_api.MakeResponse(routes, start_end_nodes, result);
} }
else else
{ {
@ -175,11 +174,11 @@ Status ViaRoutePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithm
if (not_in_same_component) if (not_in_same_component)
{ {
return Error("NoRoute", "Impossible route between points", json_result); return Error("NoRoute", "Impossible route between points", result);
} }
else else
{ {
return Error("NoRoute", "No route found between points", json_result); return Error("NoRoute", "No route found between points", result);
} }
} }

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