Merges node-osrm into repository
Build with cmake .. -DCMAKE_BUILD_TYPE=Release -DENABLE_NODE_BINDINGS=On -DENABLE_MASON=On
This commit is contained in:
parent
ff238c2724
commit
2351b5a084
10
.gitignore
vendored
10
.gitignore
vendored
@ -46,7 +46,8 @@ Thumbs.db
|
||||
#######################
|
||||
/build/
|
||||
/example/build/
|
||||
/test/data/monaco*
|
||||
/test/data/berlin*
|
||||
/test/bindings/node/data/berlin*
|
||||
/cmake/postinst
|
||||
|
||||
# Eclipse related files #
|
||||
@ -86,7 +87,7 @@ stxxl.errlog
|
||||
/test/cache
|
||||
/test/speeds.csv
|
||||
/test/penalties.csv
|
||||
/test/data/monaco.*
|
||||
/test/data/berlin.*
|
||||
node_modules
|
||||
|
||||
# Deprecated config file #
|
||||
@ -96,4 +97,7 @@ node_modules
|
||||
*.swp
|
||||
|
||||
# local lua debugging file
|
||||
debug.lua
|
||||
debug.lua
|
||||
|
||||
# node-osrm artifacts
|
||||
lib/binding
|
||||
|
10
.npmignore
Normal file
10
.npmignore
Normal file
@ -0,0 +1,10 @@
|
||||
*
|
||||
!README.md
|
||||
!CHANGELOG.md
|
||||
!CONTRIBUTING.MD
|
||||
!LICENCE.TXT
|
||||
!package.json
|
||||
!example
|
||||
!lib/*.js
|
||||
!profiles/*
|
||||
!profiles/lib/*
|
21
.travis.yml
21
.travis.yml
@ -58,7 +58,7 @@ matrix:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['libstdc++-5-dev']
|
||||
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_SANITIZER=ON
|
||||
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_SANITIZER=ON ENABLE_NODE_BINDINGS=ON
|
||||
|
||||
# Release Builds
|
||||
- os: linux
|
||||
@ -67,7 +67,7 @@ matrix:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['libstdc++-5-dev']
|
||||
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON RUN_CLANG_FORMAT=ON ENABLE_LTO=ON
|
||||
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON RUN_CLANG_FORMAT=ON ENABLE_LTO=ON ENABLE_NODE_BINDINGS=ON
|
||||
|
||||
- os: linux
|
||||
compiler: "gcc-6-release"
|
||||
@ -81,7 +81,7 @@ matrix:
|
||||
compiler: "gcc-6-release-i686"
|
||||
env: >
|
||||
TARGET_ARCH='i686' CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release'
|
||||
CFLAGS='-m32 -msse2 -mfpmath=sse' CXXFLAGS='-m32 -msse2 -mfpmath=sse' CHECK_HEADERS=yes
|
||||
CFLAGS='-m32 -msse2 -mfpmath=sse' CXXFLAGS='-m32 -msse2 -mfpmath=sse'
|
||||
|
||||
- os: linux
|
||||
compiler: "gcc-4.9-release"
|
||||
@ -142,7 +142,7 @@ before_install:
|
||||
- echo "Using ${JOBS} jobs"
|
||||
- source ./scripts/install_node.sh 4
|
||||
- npm install -g "npm@>=3" # Upgrade to npm >v2 to reduce size of downloaded dependencies
|
||||
- npm install
|
||||
- npm install --ignore-scripts
|
||||
# Bootstrap cmake to be able to run mason
|
||||
- CMAKE_URL="https://mason-binaries.s3.amazonaws.com/${TRAVIS_OS_NAME}-x86_64/cmake/${CMAKE_VERSION}.tar.gz"
|
||||
- CMAKE_DIR="mason_packages/${TRAVIS_OS_NAME}-x86_64/cmake/${CMAKE_VERSION}"
|
||||
@ -173,7 +173,7 @@ install:
|
||||
- export OSRM_BUILD_DIR="$(pwd)/build-osrm"
|
||||
- mkdir ${OSRM_BUILD_DIR} && pushd ${OSRM_BUILD_DIR}
|
||||
- export CC=${CCOMPILER} CXX=${CXXCOMPILER}
|
||||
- cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DENABLE_MASON=${ENABLE_MASON:-OFF} -DENABLE_ASSERTIONS=${ENABLE_ASSERTIONS:-OFF} -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS:-OFF} -DENABLE_COVERAGE=${ENABLE_COVERAGE:-OFF} -DENABLE_SANITIZER=${ENABLE_SANITIZER:-OFF} -DBUILD_TOOLS=ON -DENABLE_CCACHE=ON
|
||||
- cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DENABLE_MASON=${ENABLE_MASON:-OFF} -DENABLE_ASSERTIONS=${ENABLE_ASSERTIONS:-OFF} -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS:-OFF} -DENABLE_COVERAGE=${ENABLE_COVERAGE:-OFF} -DENABLE_SANITIZER=${ENABLE_SANITIZER:-OFF} -DBUILD_TOOLS=ON -DENABLE_CCACHE=ON -DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF}
|
||||
- echo "travis_fold:start:MAKE"
|
||||
- make --jobs=${JOBS}
|
||||
- make tests --jobs=${JOBS}
|
||||
@ -185,7 +185,6 @@ install:
|
||||
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
|
||||
sudo ldconfig
|
||||
fi
|
||||
- if [[ ${CHECK_HEADERS} == yes ]] ; then make check-headers ; fi
|
||||
- popd
|
||||
- mkdir example/build && pushd example/build
|
||||
- cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
|
||||
@ -196,7 +195,7 @@ install:
|
||||
script:
|
||||
- if [[ $TARGET_ARCH == armhf ]] ; then echo "Skip tests for $TARGET_ARCH" && exit 0 ; fi
|
||||
- make -C test/data benchmark
|
||||
- ./example/build/osrm-example test/data/monaco_CH.osrm
|
||||
- ./example/build/osrm-example test/data/berlin_CH.osrm
|
||||
# All tests assume to be run from the build directory
|
||||
- pushd ${OSRM_BUILD_DIR}
|
||||
- ./unit_tests/library-tests
|
||||
@ -213,3 +212,11 @@ after_success:
|
||||
if [ -n "${ENABLE_COVERAGE}" ]; then
|
||||
bash <(curl -s https://codecov.io/bash)
|
||||
fi
|
||||
|
||||
- |
|
||||
if [ -n "${ENABLE_NODE_BINDINGS}" ]; then
|
||||
nvm install 4
|
||||
nvm use 4
|
||||
source ./scripts/travis/build.sh
|
||||
./scripts/travis/publish.sh
|
||||
fi
|
||||
|
@ -1,5 +1,7 @@
|
||||
# 5.7.0
|
||||
- Changes from 5.6
|
||||
- NodeJs Bindings
|
||||
- Merged https://github.com/Project-OSRM/node-osrm into repository. Build via `cmake .. -DCMAKE_BUILD_TYPE=Release -DENABLE_NODE_BINDINGS=On -DENABLE_MASON=On`.
|
||||
- Internals
|
||||
- Shared memory notification via conditional variables on Linux or semaphore queue on OS X and Windows with a limit of 128 OSRM Engine instances
|
||||
- Files
|
||||
|
@ -24,6 +24,7 @@ option(ENABLE_SANITIZER "Use memory sanitizer for Debug build" OFF)
|
||||
option(ENABLE_LTO "Use LTO if available" OFF)
|
||||
option(ENABLE_FUZZING "Fuzz testing using LLVM's libFuzzer" OFF)
|
||||
option(ENABLE_GOLD_LINKER "Use GNU gold linker if available" ON)
|
||||
option(ENABLE_NODE_BINDINGS "Build NodeJs bindings" OFF)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
|
||||
@ -800,6 +801,11 @@ add_custom_target(uninstall
|
||||
add_subdirectory(unit_tests)
|
||||
add_subdirectory(src/benchmarks)
|
||||
|
||||
if (ENABLE_NODE_BINDINGS)
|
||||
add_subdirectory(src/nodejs)
|
||||
endif()
|
||||
|
||||
|
||||
if (ENABLE_FUZZING)
|
||||
# Requires libosrm being built with sanitizers; make configurable and default to ubsan
|
||||
set(FUZZ_SANITIZER "undefined" CACHE STRING "Sanitizer to be used for Fuzz testing")
|
||||
@ -815,18 +821,21 @@ if (ENABLE_FUZZING)
|
||||
endif ()
|
||||
|
||||
|
||||
## add headers sanity check target that includes all headers independently
|
||||
set(check_headers_dir "${PROJECT_BINARY_DIR}/check-headers")
|
||||
file(GLOB_RECURSE headers_to_check
|
||||
${PROJECT_BINARY_DIR}/*.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/*.hpp)
|
||||
foreach(header ${headers_to_check})
|
||||
get_filename_component(filename ${header} NAME_WE)
|
||||
set(filename "${check_headers_dir}/${filename}.cpp")
|
||||
if (NOT EXISTS ${filename})
|
||||
file(WRITE ${filename} "#include \"${header}\"\n")
|
||||
endif()
|
||||
list(APPEND sources ${filename})
|
||||
endforeach()
|
||||
add_library(check-headers STATIC EXCLUDE_FROM_ALL ${sources})
|
||||
set_target_properties(check-headers PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${check_headers_dir})
|
||||
# add headers sanity check target that includes all headers independently
|
||||
# make sure we have all deps for the nodejs sub project's includes (nan, node)
|
||||
if (ENABLE_NODE_BINDINGS)
|
||||
set(check_headers_dir "${PROJECT_BINARY_DIR}/check-headers")
|
||||
file(GLOB_RECURSE headers_to_check
|
||||
${PROJECT_BINARY_DIR}/*.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/*.hpp)
|
||||
foreach(header ${headers_to_check})
|
||||
get_filename_component(filename ${header} NAME_WE)
|
||||
set(filename "${check_headers_dir}/${filename}.cpp")
|
||||
if (NOT EXISTS ${filename})
|
||||
file(WRITE ${filename} "#include \"${header}\"\n")
|
||||
endif()
|
||||
list(APPEND sources ${filename})
|
||||
endforeach()
|
||||
add_library(check-headers STATIC EXCLUDE_FROM_ALL ${sources})
|
||||
set_target_properties(check-headers PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${check_headers_dir})
|
||||
endif()
|
||||
|
@ -133,12 +133,12 @@ unit_tests\%Configuration%\server-tests.exe
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||
|
||||
ECHO running library-tests.exe ...
|
||||
SET test_region=monaco
|
||||
SET test_region=berlin
|
||||
SET test_osm=%test_region%.osm.pbf
|
||||
SET test_osm_ch=%test_region%_CH.osm.pbf
|
||||
SET test_osm_corech=%test_region%_CoreCH.osm.pbf
|
||||
SET test_osm_mld=%test_region%_MLD.osm.pbf
|
||||
IF NOT EXIST %test_osm% powershell Invoke-WebRequest https://s3.amazonaws.com/mapbox/osrm/testing/monaco.osm.pbf -OutFile %test_osm%
|
||||
IF NOT EXIST %test_osm% powershell Invoke-WebRequest https://s3.amazonaws.com/mapbox/osrm/testing/berlin.osm.pbf -OutFile %test_osm%
|
||||
COPY %test_osm% %test_osm_ch%
|
||||
COPY %test_osm% %test_osm_corech%
|
||||
COPY %test_osm% %test_osm_mld%
|
||||
|
587
cmake/nodejs/FindNodeJS.cmake
Normal file
587
cmake/nodejs/FindNodeJS.cmake
Normal file
@ -0,0 +1,587 @@
|
||||
# Copyright (c) 2015, Colin Taylor
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# FindNodeJS.cmake CMake module vendored from the node-cmake project (v1.2).
|
||||
|
||||
# This script uses CMake 3.1+ features
|
||||
if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 3.1.0)
|
||||
message(FATAL_ERROR "FindNodeJS.cmake uses CMake 3.1+ features")
|
||||
endif()
|
||||
|
||||
# Force a build type to be set (ignored on config based generators)
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build type" FORCE)
|
||||
endif()
|
||||
|
||||
# Capture module information
|
||||
set(NodeJS_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
|
||||
get_filename_component(NodeJS_MODULE_NAME ${NodeJS_MODULE_PATH} NAME)
|
||||
|
||||
# Allow users to specify the installed location of the Node.js package
|
||||
set(NodeJS_ROOT_DIR "" CACHE PATH
|
||||
"The root directory of the node.js installed package")
|
||||
|
||||
# Allow users to specify that downloaded sources should be used
|
||||
option(NodeJS_DOWNLOAD "Download the required source files" Off)
|
||||
|
||||
# Allow users to force downloading of node packages
|
||||
option(NodeJS_FORCE_DOWNLOAD "Download the source files every time" Off)
|
||||
|
||||
# Allow users to force archive extraction
|
||||
option(NodeJS_FORCE_EXTRACT "Extract the archive every time" Off)
|
||||
|
||||
# Make libc++ the default when compiling with clang
|
||||
option(NodeJS_USE_CLANG_STDLIB "Use libc++ when compiling with clang" On)
|
||||
if(APPLE)
|
||||
set(NodeJS_USE_CLANG_STDLIB On CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
# Allow users to specify that the executable should be downloaded
|
||||
option(NodeJS_DOWNLOAD_EXECUTABLE
|
||||
"Download matching executable if available" Off
|
||||
)
|
||||
endif()
|
||||
|
||||
# Try to find the node.js executable
|
||||
# The node executable under linux may not be the correct program
|
||||
find_program(NodeJS_EXECUTABLE
|
||||
NAMES node
|
||||
PATHS ${NodeJS_ROOT_DIR}
|
||||
PATH_SUFFIXES nodejs node
|
||||
)
|
||||
set(NodeJS_VALIDATE_EXECUTABLE 1)
|
||||
if(NodeJS_EXECUTABLE)
|
||||
execute_process(
|
||||
COMMAND ${NodeJS_EXECUTABLE} --version
|
||||
RESULT_VARIABLE NodeJS_VALIDATE_EXECUTABLE
|
||||
OUTPUT_VARIABLE NodeJS_INSTALLED_VERSION
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
execute_process(
|
||||
COMMAND ${NodeJS_EXECUTABLE} -p "process.platform"
|
||||
OUTPUT_VARIABLE NodeJS_INSTALLED_PLATFORM
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
execute_process(
|
||||
COMMAND ${NodeJS_EXECUTABLE} -p "process.arch"
|
||||
OUTPUT_VARIABLE NodeJS_INSTALLED_ARCH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
endif()
|
||||
|
||||
# If node isn't the node.js binary, try the nodejs binary
|
||||
if(NOT NodeJS_VALIDATE_EXECUTABLE EQUAL 0)
|
||||
find_program(NodeJS_EXECUTABLE
|
||||
NAMES nodejs
|
||||
PATHS ${NodeJS_ROOT_DIR}
|
||||
PATH_SUFFIXES nodejs node
|
||||
)
|
||||
set(NodeJS_VALIDATE_EXECUTABLE 1)
|
||||
if(NodeJS_EXECUTABLE)
|
||||
execute_process(
|
||||
COMMAND ${NodeJS_EXECUTABLE} --version
|
||||
RESULT_VARIABLE NodeJS_VALIDATE_EXECUTABLE
|
||||
OUTPUT_VARIABLE NodeJS_INSTALLED_VERSION
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT NodeJS_VALIDATE_EXECUTABLE EQUAL 0)
|
||||
message(WARNING "Node.js executable could not be found. \
|
||||
Set NodeJS_ROOT_DIR to the installed location of the executable or \
|
||||
install Node.js to its default location.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Determine if a variant is set in the components
|
||||
list(APPEND NodeJS_OTHER_COMPONENTS
|
||||
X64 IA32 ARM WIN32 LINUX DARWIN
|
||||
)
|
||||
set(NodeJS_COMPONENTS_CONTAINS_VARIANT False)
|
||||
foreach(NodeJS_COMPONENT ${NodeJS_FIND_COMPONENTS})
|
||||
list(FIND NodeJS_OTHER_COMPONENTS ${NodeJS_COMPONENT} NodeJS_OTHER_INDEX)
|
||||
if(NodeJS_OTHER_INDEX EQUAL -1)
|
||||
set(NodeJS_COMPONENTS_CONTAINS_VARIANT True)
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Get the targeted version of Node.js (or one of its derivatives)
|
||||
if(NOT NodeJS_VERSION)
|
||||
if(NodeJS_FIND_VERSION)
|
||||
set(NodeJS_VERSION ${NodeJS_FIND_VERSION})
|
||||
elseif(NodeJS_INSTALLED_VERSION AND NOT NodeJS_COMPONENTS_CONTAINS_VARIANT)
|
||||
string(SUBSTRING ${NodeJS_INSTALLED_VERSION} 1 -1 NodeJS_VERSION)
|
||||
else()
|
||||
message(FATAL_ERROR "Node.js version is not set. Set the VERSION \
|
||||
property of the find_package command to the required version of the \
|
||||
Node.js sources")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Determine the target platform for the compiled module
|
||||
# Uses several mechanisms in order:
|
||||
#
|
||||
# 1. CMake cache (allows overriding on the command line)
|
||||
# 2. Node architecture when binary is available
|
||||
# 3. CMake architecture
|
||||
#
|
||||
set(NodeJS_PLATFORM "" CACHE STRING "Target node.js platform for module")
|
||||
if(NOT NodeJS_PLATFORM)
|
||||
if(NodeJS_EXECUTABLE)
|
||||
set(NodeJS_PLATFORM ${NodeJS_INSTALLED_PLATFORM})
|
||||
elseif(WIN32)
|
||||
set(NodeJS_PLATFORM "win32")
|
||||
elseif(UNIX)
|
||||
if(APPLE)
|
||||
set(NodeJS_PLATFORM "darwin")
|
||||
else()
|
||||
set(NodeJS_PLATFORM "linux")
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "Node.js platform is not set. Add the platform \
|
||||
to the find_package components section or set NodeJS_PLATFORM in the \
|
||||
cache.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Convenience variables for the platform type
|
||||
if(NodeJS_PLATFORM STREQUAL "win32")
|
||||
set(NodeJS_PLATFORM_WIN32 True)
|
||||
set(NodeJS_PLATFORM_LINUX False)
|
||||
set(NodeJS_PLATFORM_DARWIN False)
|
||||
elseif(NodeJS_PLATFORM STREQUAL "linux")
|
||||
set(NodeJS_PLATFORM_WIN32 False)
|
||||
set(NodeJS_PLATFORM_LINUX True)
|
||||
set(NodeJS_PLATFORM_DARWIN False)
|
||||
elseif(NodeJS_PLATFORM STREQUAL "darwin")
|
||||
set(NodeJS_PLATFORM_WIN32 False)
|
||||
set(NodeJS_PLATFORM_LINUX False)
|
||||
set(NodeJS_PLATFORM_DARWIN True)
|
||||
endif()
|
||||
|
||||
# Determine the target architecture for the compiled module
|
||||
# Uses several mechanisms in order:
|
||||
#
|
||||
# 1. CMake cache (allows overriding on the command line)
|
||||
# 2. Node architecture when binary is available
|
||||
# 3. Compiler architecture under MSVC
|
||||
#
|
||||
set(NodeJS_ARCH "" CACHE STRING "Target node.js architecture for module")
|
||||
if(NOT NodeJS_ARCH)
|
||||
if(NodeJS_EXECUTABLE)
|
||||
set(NodeJS_ARCH ${NodeJS_INSTALLED_ARCH})
|
||||
elseif(MSVC)
|
||||
if(CMAKE_CL_64)
|
||||
set(NodeJS_ARCH "x64")
|
||||
else()
|
||||
set(NodeJS_ARCH "ia32")
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "Node.js architecture is not set. Add the \
|
||||
architecture to the find_package components section or set NodeJS_ARCH \
|
||||
in the cache.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Convenience variables for the architecture
|
||||
if(NodeJS_ARCH STREQUAL "x64")
|
||||
set(NodeJS_ARCH_X64 True)
|
||||
set(NodeJS_ARCH_IA32 False)
|
||||
set(NodeJS_ARCH_ARM False)
|
||||
elseif(NodeJS_ARCH STREQUAL "ia32")
|
||||
set(NodeJS_ARCH_X64 False)
|
||||
set(NodeJS_ARCH_IA32 True)
|
||||
set(NodeJS_ARCH_ARM False)
|
||||
elseif(NodeJS_ARCH STREQUAL "arm")
|
||||
set(NodeJS_ARCH_X64 False)
|
||||
set(NodeJS_ARCH_IA32 False)
|
||||
set(NodeJS_ARCH_ARM True)
|
||||
endif()
|
||||
|
||||
# Include helper functions
|
||||
include(util/NodeJSUtil)
|
||||
|
||||
# Default variant name
|
||||
# Used by the installed header comparison below
|
||||
set(NodeJS_DEFAULT_VARIANT_NAME "node.js")
|
||||
|
||||
# Variables for Node.js artifacts across variants
|
||||
# Specify all of these variables for each new variant
|
||||
set(NodeJS_VARIANT_NAME "") # The printable name of the variant
|
||||
set(NodeJS_VARIANT_BASE "") # A file name safe version of the variant
|
||||
set(NodeJS_URL "") # The URL for the artifacts
|
||||
set(NodeJS_SOURCE_PATH "") # The URL path of the source archive
|
||||
set(NodeJS_CHECKSUM_PATH "") # The URL path of the checksum file
|
||||
set(NodeJS_CHECKSUM_TYPE "") # The checksum type (algorithm)
|
||||
set(NodeJS_WIN32_LIBRARY_PATH "") # The URL path of the windows library
|
||||
set(NodeJS_WIN32_BINARY_PATH "") # The URL path of the windows executable
|
||||
set(NodeJS_WIN32_LIBRARY_NAME "") # The name of the windows library
|
||||
set(NodeJS_WIN32_BINARY_NAME "") # The name of the windows executable
|
||||
|
||||
set(NodeJS_DEFAULT_INCLUDE True) # Enable default include behavior
|
||||
set(NodeJS_DEFAULT_LIBS True) # Include the default libraries
|
||||
set(NodeJS_HAS_WIN32_PREFIX True) # Does the variant use library prefixes
|
||||
set(NodeJS_HAS_WIN32_BINARY True) # Does the variant have win32 executables
|
||||
set(NodeJS_HAS_OPENSSL True) # Does the variant include openssl headers
|
||||
set(NodeJS_HEADER_VERSION 0.12.7) # Version after header-only archives start
|
||||
set(NodeJS_SHA256_VERSION 0.7.0) # Version after sha256 checksums start
|
||||
set(NodeJS_PREFIX_VERSION 0.12.7) # Version after windows prefixing starts
|
||||
set(NodeJS_CXX11R_VERSION 0.12.7) # Version after c++11 is required
|
||||
set(NodeJS_SOURCE_INCLUDE True) # Use the include paths from a source archive
|
||||
set(NodeJS_HEADER_INCLUDE False) # Use the include paths from a header archive
|
||||
set(NodeJS_INCLUDE_PATHS "") # Set of header dirs inside the source archive
|
||||
set(NodeJS_LIBRARIES "") # The set of libraries to link with addon
|
||||
set(NodeJS_WIN32_DELAYLOAD "") # Set of executables to delayload on windows
|
||||
|
||||
# NodeJS variants
|
||||
# Selects download target based on configured component
|
||||
# Include NodeJS last to provide default configurations when omitted
|
||||
file(
|
||||
GLOB NodeJS_SUPPORTED_VARIANTS
|
||||
RELATIVE ${CMAKE_CURRENT_LIST_DIR}/variants
|
||||
${CMAKE_CURRENT_LIST_DIR}/variants/*
|
||||
)
|
||||
foreach(NodeJS_SUPPORTED_VARIANT ${NodeJS_SUPPORTED_VARIANTS})
|
||||
get_filename_component(NodeJS_SUPPORTED_VARIANT_NAME
|
||||
${NodeJS_SUPPORTED_VARIANT} NAME_WE
|
||||
)
|
||||
if(NOT NodeJS_SUPPORTED_VARIANT_NAME STREQUAL "NodeJS")
|
||||
include(variants/${NodeJS_SUPPORTED_VARIANT_NAME})
|
||||
endif()
|
||||
endforeach()
|
||||
include(variants/NodeJS)
|
||||
|
||||
# Populate version variables, including version components
|
||||
set(NodeJS_VERSION_STRING "v${NodeJS_VERSION}")
|
||||
|
||||
# Populate the remaining version variables
|
||||
string(REPLACE "." ";" NodeJS_VERSION_PARTS ${NodeJS_VERSION})
|
||||
list(GET NodeJS_VERSION_PARTS 0 NodeJS_VERSION_MAJOR)
|
||||
list(GET NodeJS_VERSION_PARTS 1 NodeJS_VERSION_MINOR)
|
||||
list(GET NodeJS_VERSION_PARTS 2 NodeJS_VERSION_PATCH)
|
||||
|
||||
# If the version we're looking for is the version that is installed,
|
||||
# try finding the required headers. Don't do this under windows (where
|
||||
# headers are not part of the installed content), when the user has
|
||||
# specified that headers should be downloaded or when using a variant other
|
||||
# than the default
|
||||
if((NOT NodeJS_PLATFORM_WIN32) AND (NOT NodeJS_DOWNLOAD) AND
|
||||
NodeJS_VARIANT_NAME STREQUAL NodeJS_DEFAULT_VARIANT_NAME AND
|
||||
NodeJS_INSTALLED_VERSION STREQUAL NodeJS_VERSION_STRING AND
|
||||
NodeJS_INSTALLED_PLATFORM STREQUAL NodeJS_PLATFORM AND
|
||||
NodeJS_INSTALLED_ARCH STREQUAL NodeJS_ARCH)
|
||||
# node.h is really generic and too easy for cmake to find the wrong
|
||||
# file, so use the directory as a guard, and then just tack it on to
|
||||
# the actual path
|
||||
#
|
||||
# Specifically ran into this under OSX, where python contains a node.h
|
||||
# that gets found instead
|
||||
find_path(NodeJS_INCLUDE_PARENT node/node.h)
|
||||
set(NodeJS_INCLUDE_DIRS ${NodeJS_INCLUDE_PARENT}/node)
|
||||
|
||||
# Under all systems that support this, there are no libraries required
|
||||
# for linking (symbols are resolved via the main executable at runtime)
|
||||
set(NodeJS_LIBRARIES "")
|
||||
|
||||
# Otherwise, headers and required libraries must be downloaded to the project
|
||||
# to supplement what is installed
|
||||
else()
|
||||
# Create a folder for downloaded artifacts
|
||||
set(NodeJS_DOWNLOAD_PATH
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${NodeJS_VARIANT_BASE}
|
||||
)
|
||||
set(NodeJS_DOWNLOAD_PATH ${NodeJS_DOWNLOAD_PATH}-${NodeJS_VERSION_STRING})
|
||||
file(MAKE_DIRECTORY ${NodeJS_DOWNLOAD_PATH})
|
||||
|
||||
# Download the checksum file for validating all other downloads
|
||||
# Conveniently, if this doesn't download correctly, the setup fails
|
||||
# due to checksum failures
|
||||
set(NodeJS_CHECKSUM_FILE ${NodeJS_DOWNLOAD_PATH}/CHECKSUM)
|
||||
nodejs_download(
|
||||
${NodeJS_URL}/${NodeJS_CHECKSUM_PATH}
|
||||
${NodeJS_CHECKSUM_FILE}
|
||||
${NodeJS_FORCE_DOWNLOAD}
|
||||
)
|
||||
file(READ ${NodeJS_CHECKSUM_FILE} NodeJS_CHECKSUM_DATA)
|
||||
|
||||
# Download and extract the main source archive
|
||||
set(NodeJS_SOURCE_FILE ${NodeJS_DOWNLOAD_PATH}/headers.tar.gz)
|
||||
nodejs_checksum(
|
||||
${NodeJS_CHECKSUM_DATA} ${NodeJS_SOURCE_PATH} NodeJS_SOURCE_CHECKSUM
|
||||
)
|
||||
nodejs_download(
|
||||
${NodeJS_URL}/${NodeJS_SOURCE_PATH}
|
||||
${NodeJS_SOURCE_FILE}
|
||||
${NodeJS_SOURCE_CHECKSUM}
|
||||
${NodeJS_CHECKSUM_TYPE}
|
||||
${NodeJS_FORCE_DOWNLOAD}
|
||||
)
|
||||
set(NodeJS_HEADER_PATH ${NodeJS_DOWNLOAD_PATH}/src)
|
||||
nodejs_extract(
|
||||
${NodeJS_SOURCE_FILE}
|
||||
${NodeJS_HEADER_PATH}
|
||||
${NodeJS_FORCE_EXTRACT}
|
||||
)
|
||||
|
||||
# Populate include directories from the extracted source archive
|
||||
foreach(NodeJS_HEADER_BASE ${NodeJS_INCLUDE_PATHS})
|
||||
set(NodeJS_INCLUDE_DIR ${NodeJS_HEADER_PATH}/${NodeJS_HEADER_BASE})
|
||||
if(NOT EXISTS ${NodeJS_INCLUDE_DIR})
|
||||
message(FATAL_ERROR "Include does not exist: ${NodeJS_INCLUDE_DIR}")
|
||||
endif()
|
||||
list(APPEND NodeJS_INCLUDE_DIRS ${NodeJS_INCLUDE_DIR})
|
||||
endforeach()
|
||||
|
||||
# Download required library files when targeting windows
|
||||
if(NodeJS_PLATFORM_WIN32)
|
||||
# Download the windows library
|
||||
set(NodeJS_WIN32_LIBRARY_FILE
|
||||
${NodeJS_DOWNLOAD_PATH}/lib/${NodeJS_ARCH}
|
||||
)
|
||||
set(NodeJS_WIN32_LIBRARY_FILE
|
||||
${NodeJS_WIN32_LIBRARY_FILE}/${NodeJS_WIN32_LIBRARY_NAME}
|
||||
)
|
||||
nodejs_checksum(
|
||||
${NodeJS_CHECKSUM_DATA} ${NodeJS_WIN32_LIBRARY_PATH}
|
||||
NodeJS_WIN32_LIBRARY_CHECKSUM
|
||||
)
|
||||
nodejs_download(
|
||||
${NodeJS_URL}/${NodeJS_WIN32_LIBRARY_PATH}
|
||||
${NodeJS_WIN32_LIBRARY_FILE}
|
||||
${NodeJS_WIN32_LIBRARY_CHECKSUM}
|
||||
${NodeJS_CHECKSUM_TYPE}
|
||||
${NodeJS_FORCE_DOWNLOAD}
|
||||
)
|
||||
list(APPEND NodeJS_LIBRARIES ${NodeJS_WIN32_LIBRARY_FILE})
|
||||
|
||||
# If provided, download the windows executable
|
||||
if(NodeJS_WIN32_BINARY_PATH AND
|
||||
NodeJS_DOWNLOAD_EXECUTABLE)
|
||||
set(NodeJS_WIN32_BINARY_FILE
|
||||
${NodeJS_DOWNLOAD_PATH}/lib/${NodeJS_ARCH}
|
||||
)
|
||||
set(NodeJS_WIN32_BINARY_FILE
|
||||
${NodeJS_WIN32_BINARY_FILE}/${NodeJS_WIN32_BINARY_NAME}
|
||||
)
|
||||
nodejs_checksum(
|
||||
${NodeJS_CHECKSUM_DATA} ${NodeJS_WIN32_BINARY_PATH}
|
||||
NodeJS_WIN32_BINARY_CHECKSUM
|
||||
)
|
||||
nodejs_download(
|
||||
${NodeJS_URL}/${NodeJS_WIN32_BINARY_PATH}
|
||||
${NodeJS_WIN32_BINARY_FILE}
|
||||
${NodeJS_WIN32_BINARY_CHECKSUM}
|
||||
${NodeJS_CHECKSUM_TYPE}
|
||||
${NodeJS_FORCE_DOWNLOAD}
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Support windows delay loading
|
||||
if(NodeJS_PLATFORM_WIN32)
|
||||
list(APPEND NodeJS_LINK_FLAGS /IGNORE:4199)
|
||||
set(NodeJS_WIN32_DELAYLOAD_CONDITION "")
|
||||
foreach(NodeJS_WIN32_DELAYLOAD_BINARY ${NodeJS_WIN32_DELAYLOAD})
|
||||
list(APPEND NodeJS_LINK_FLAGS
|
||||
/DELAYLOAD:${NodeJS_WIN32_DELAYLOAD_BINARY}
|
||||
)
|
||||
list(APPEND NodeJS_WIN32_DELAYLOAD_CONDITION
|
||||
"_stricmp(info->szDll, \"${NodeJS_WIN32_DELAYLOAD_BINARY}\") != 0"
|
||||
)
|
||||
endforeach()
|
||||
string(REPLACE ";" " &&\n "
|
||||
NodeJS_WIN32_DELAYLOAD_CONDITION
|
||||
"${NodeJS_WIN32_DELAYLOAD_CONDITION}"
|
||||
)
|
||||
configure_file(
|
||||
${NodeJS_MODULE_PATH}/src/win_delay_load_hook.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/win_delay_load_hook.c @ONLY
|
||||
)
|
||||
list(APPEND NodeJS_ADDITIONAL_SOURCES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/win_delay_load_hook.c
|
||||
)
|
||||
endif()
|
||||
|
||||
# Allow undefined symbols on OSX
|
||||
if(NodeJS_PLATFORM_DARWIN)
|
||||
list(APPEND NodeJS_LINK_FLAGS "-undefined dynamic_lookup")
|
||||
endif()
|
||||
|
||||
# Use libc++ when clang is the compiler by default
|
||||
if(NodeJS_USE_CLANG_STDLIB AND CMAKE_CXX_COMPILER_ID MATCHES ".*Clang.*")
|
||||
list(APPEND NodeJS_COMPILE_OPTIONS -stdlib=libc++)
|
||||
endif()
|
||||
|
||||
# Require c++11 support after a specific point, but only if the user hasn't
|
||||
# specified an override
|
||||
if(NOT NodeJS_CXX_STANDARD)
|
||||
if(NodeJS_VERSION VERSION_GREATER NodeJS_CXX11R_VERSION)
|
||||
set(NodeJS_CXX_STANDARD 11)
|
||||
else()
|
||||
set(NodeJS_CXX_STANDARD 98)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Set required definitions
|
||||
list(APPEND NodeJS_DEFINITIONS BUILDING_NODE_EXTENSION)
|
||||
if(NodeJS_PLATFORM_DARWIN)
|
||||
list(APPEND NodeJS_DEFINITIONS _DARWIN_USE_64_BIT_INODE=1)
|
||||
endif()
|
||||
if(NOT NodeJS_PLATFORM_WIN32)
|
||||
list(APPEND NodeJS_DEFINITIONS
|
||||
_LARGEFILE_SOURCE
|
||||
_FILE_OFFSET_BITS=64
|
||||
)
|
||||
endif()
|
||||
|
||||
function(add_nodejs_module NAME)
|
||||
# Build a shared library for the module
|
||||
add_library(${NAME} SHARED ${ARGN} ${NodeJS_ADDITIONAL_SOURCES})
|
||||
|
||||
# Include required headers
|
||||
# Find and include Nan as well (always available as its a
|
||||
# dependency of this module)
|
||||
nodejs_find_module_fallback(nan ${CMAKE_CURRENT_SOURCE_DIR} NAN_PATH)
|
||||
target_include_directories(${NAME}
|
||||
PUBLIC ${NodeJS_INCLUDE_DIRS}
|
||||
PUBLIC ${NAN_PATH}
|
||||
)
|
||||
|
||||
# Set module properties
|
||||
# This ensures proper naming of the module library across all platforms
|
||||
get_target_property(COMPILE_OPTIONS ${NAME} COMPILE_OPTIONS)
|
||||
if(NOT COMPILE_OPTIONS)
|
||||
set(COMPILE_OPTIONS "")
|
||||
endif()
|
||||
set(COMPILE_OPTIONS ${COMPILE_OPTIONS} ${NodeJS_COMPILE_OPTIONS})
|
||||
get_target_property(LINK_FLAGS ${NAME} LINK_FLAGS)
|
||||
if(NOT LINK_FLAGS)
|
||||
set(LINK_FLAGS "")
|
||||
endif()
|
||||
foreach(NodeJS_LINK_FLAG ${NodeJS_LINK_FLAGS})
|
||||
set(LINK_FLAGS "${LINK_FLAGS} ${NodeJS_LINK_FLAG}")
|
||||
endforeach()
|
||||
set_target_properties(${NAME} PROPERTIES
|
||||
PREFIX ""
|
||||
SUFFIX ".node"
|
||||
MACOSX_RPATH ON
|
||||
POSITION_INDEPENDENT_CODE TRUE
|
||||
COMPILE_OPTIONS "${COMPILE_OPTIONS}"
|
||||
LINK_FLAGS "${LINK_FLAGS}"
|
||||
CXX_STANDARD_REQUIRED TRUE
|
||||
CXX_STANDARD ${NodeJS_CXX_STANDARD}
|
||||
)
|
||||
|
||||
# Output the module in a per build type directory
|
||||
# This makes builds consistent with visual studio and other generators
|
||||
# that build by configuration
|
||||
if(NOT CMAKE_CONFIGURATION_TYPES)
|
||||
set_property(TARGET ${NAME} PROPERTY LIBRARY_OUTPUT_DIRECTORY
|
||||
${CMAKE_BUILD_TYPE}
|
||||
)
|
||||
endif()
|
||||
|
||||
# Set any required complier flags
|
||||
# Mostly used under windows
|
||||
target_compile_definitions(${NAME} PRIVATE ${NodeJS_DEFINITIONS})
|
||||
|
||||
# Link against required NodeJS libraries
|
||||
target_link_libraries(${NAME} ${NodeJS_LIBRARIES})
|
||||
endfunction()
|
||||
|
||||
# Write out the configuration for node scripts
|
||||
configure_file(
|
||||
${NodeJS_MODULE_PATH}/build.json.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/build.json @ONLY
|
||||
)
|
||||
|
||||
# Make sure we haven't violated the version-to-standard mapping
|
||||
if(NodeJS_VERSION VERSION_GREATER NodeJS_CXX11R_VERSION AND
|
||||
NodeJS_CXX_STANDARD EQUAL 98)
|
||||
message(FATAL_ERROR "${NodeJS_VARIANT_NAME} ${NodeJS_VERSION} \
|
||||
requires C++11 or newer to build")
|
||||
endif()
|
||||
|
||||
# This is a find_package file, handle the standard invocation
|
||||
include(FindPackageHandleStandardArgs)
|
||||
set(NodeJS_TARGET "${NodeJS_VARIANT_NAME} ${NodeJS_PLATFORM}/${NodeJS_ARCH}")
|
||||
find_package_handle_standard_args(NodeJS
|
||||
FOUND_VAR NodeJS_FOUND
|
||||
REQUIRED_VARS NodeJS_TARGET NodeJS_INCLUDE_DIRS
|
||||
VERSION_VAR NodeJS_VERSION
|
||||
)
|
||||
|
||||
# Mark variables that users shouldn't modify
|
||||
mark_as_advanced(
|
||||
NodeJS_VALIDATE_EXECUTABLE
|
||||
NodeJS_OTHER_COMPONENTS
|
||||
NodeJS_COMPONENTS_CONTAINS_VARIANT
|
||||
NodeJS_COMPONENT
|
||||
NodeJS_OTHER_INDEX
|
||||
NodeJS_VERSION_STRING
|
||||
NodeJS_VERSION_MAJOR
|
||||
NodeJS_VERSION_MINOR
|
||||
NodeJS_VERSION_PATCH
|
||||
NodeJS_VERSION_TWEAK
|
||||
NodeJS_PLATFORM
|
||||
NodeJS_PLATFORM_WIN32
|
||||
NodeJS_PLATFORM_LINUX
|
||||
NodeJS_PLATFORM_DARWIN
|
||||
NodeJS_ARCH
|
||||
NodeJS_ARCH_X64
|
||||
NodeJS_ARCH_IA32
|
||||
NodeJS_ARCH_ARM
|
||||
NodeJS_DEFAULT_VARIANT_NAME
|
||||
NodeJS_VARIANT_BASE
|
||||
NodeJS_VARIANT_NAME
|
||||
NodeJS_URL
|
||||
NodeJS_SOURCE_PATH
|
||||
NodeJS_CHECKSUM_PATH
|
||||
NodeJS_CHECKSUM_TYPE
|
||||
NodeJS_WIN32_LIBRARY_PATH
|
||||
NodeJS_WIN32_BINARY_PATH
|
||||
NodeJS_WIN32_LIBRARY_NAME
|
||||
NodeJS_WIN32_BINARY_NAME
|
||||
NodeJS_DEFAULT_INCLUDE
|
||||
NodeJS_DEFAULT_LIBS
|
||||
NodeJS_HAS_WIN32_BINARY
|
||||
NodeJS_HEADER_VERSION
|
||||
NodeJS_SHA256_VERISON
|
||||
NodeJS_PREFIX_VERSION
|
||||
NodeJS_SOURCE_INCLUDE
|
||||
NodeJS_HEADER_INCLUDE
|
||||
NodeJS_INCLUDE_PATHS
|
||||
NodeJS_WIN32_DELAYLOAD
|
||||
NodeJS_DOWNLOAD_PATH
|
||||
NodeJS_CHECKSUM_FILE
|
||||
NodeJS_CHECKSUM_DATA
|
||||
NodeJS_SOURCE_FILE
|
||||
NodeJS_SOURCE_CHECKSUM
|
||||
NodeJS_HEADER_PATH
|
||||
NodeJS_HEADER_BASE
|
||||
NodeJS_INCLUDE_DIR
|
||||
NodeJS_WIN32_LIBRARY_FILE
|
||||
NodeJS_WIN32_LIBRARY_CHECKSUM
|
||||
NodeJS_WIN32_BINARY_FILE
|
||||
NodeJS_WIN32_BINARY_CHECKSUM
|
||||
NodeJS_NAN_PATH
|
||||
NodeJS_LINK_FLAGS
|
||||
NodeJS_COMPILE_OPTIONS
|
||||
NodeJS_ADDITIONAL_SOURCES
|
||||
NodeJS_WIN32_DELAYLOAD_CONDITION
|
||||
NodeJS_WIN32_DELAYLOAD_BINARY
|
||||
NodeJS_TARGET
|
||||
)
|
10
cmake/nodejs/build.json.in
Normal file
10
cmake/nodejs/build.json.in
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"build_type": "@CMAKE_BUILD_TYPE@",
|
||||
"generator": "@CMAKE_GENERATOR@",
|
||||
"toolset": "@CMAKE_GENERATOR_TOOLSET@",
|
||||
"platform": "@CMAKE_GENERATOR_PLATFORM@",
|
||||
"variant": "@NodeJS_VARIANT_BASE@",
|
||||
"version": "@NodeJS_VERSION@",
|
||||
"download": "@NodeJS_DOWNLOAD@",
|
||||
"standard": "@NodeJS_CXX_STANDARD@"
|
||||
}
|
28
cmake/nodejs/util/Github.cmake
Normal file
28
cmake/nodejs/util/Github.cmake
Normal file
@ -0,0 +1,28 @@
|
||||
set(GITHUB_API_TOKEN $ENV{GITHUB_API_TOKEN})
|
||||
|
||||
set(GITHUB_AUTH "")
|
||||
if(GITHUB_API_TOKEN)
|
||||
set(GITHUB_AUTH "?access_token=${GITHUB_API_TOKEN}")
|
||||
endif()
|
||||
|
||||
set(GITHUB_API_URL "https://api.github.com")
|
||||
|
||||
function(github_get_rate_limit VAR)
|
||||
set(RATE_LIMIT_FILE ${CMAKE_CURRENT_BINARY_DIR}/GITHUBRATE)
|
||||
set(RATE_LIMIT_URL ${GITHUB_API_URL}/rate_limit${GITHUB_AUTH})
|
||||
nodejs_download(
|
||||
${RATE_LIMIT_URL}
|
||||
${RATE_LIMIT_FILE}
|
||||
ON
|
||||
)
|
||||
file(READ ${RATE_LIMIT_FILE} RATE_LIMIT_DATA)
|
||||
string(REGEX MATCH "\"remaining\": ([0-9]+),"
|
||||
RATE_LIMIT_MATCH ${RATE_LIMIT_DATA})
|
||||
set(${VAR} ${CMAKE_MATCH_1} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
mark_as_advanced(
|
||||
GITHUB_AUTH
|
||||
GITHUB_API_TOKEN
|
||||
GITHUB_API_URL
|
||||
)
|
166
cmake/nodejs/util/NodeJSUtil.cmake
Normal file
166
cmake/nodejs/util/NodeJSUtil.cmake
Normal file
@ -0,0 +1,166 @@
|
||||
function(nodejs_check_file FILE)
|
||||
set(MESSAGE "File ${FILE} does not exist or is empty")
|
||||
if(ARGC GREATER 1)
|
||||
set(MESSAGE ${ARGV1})
|
||||
endif()
|
||||
|
||||
# Make sure the file has contents
|
||||
file(READ ${FILE} FILE_CONTENT LIMIT 1 HEX)
|
||||
if(NOT FILE_CONTENT)
|
||||
file(REMOVE ${FILE})
|
||||
message(FATAL_ERROR ${MESSAGE})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(nodejs_download URL FILE)
|
||||
# Function optionally takes a checksum and a checksum type, and
|
||||
# a force value
|
||||
# Either can be specified without the other, but checksum must come first
|
||||
if(ARGC GREATER 2)
|
||||
set(CHECKSUM ${ARGV2})
|
||||
if(CHECKSUM STREQUAL "On" OR CHECKSUM STREQUAL "ON" OR
|
||||
CHECKSUM STREQUAL "True" OR CHECKSUM STREQUAL "TRUE" OR
|
||||
CHECKSUM STREQUAL "Off" OR CHECKSUM STREQUAL "OFF" OR
|
||||
CHECKSUM STREQUAL "False" OR CHECKSUM STREQUAL "FALSE")
|
||||
set(FORCE ${CHECKSUM})
|
||||
unset(CHECKSUM)
|
||||
elseif(ARGC GREATER 3)
|
||||
set(TYPE ${ARGV3})
|
||||
else()
|
||||
message(FATAL_ERROR "Checksum type must be specified")
|
||||
endif()
|
||||
elseif(ARGC GREATER 4)
|
||||
set(CHECKSUM ${ARGV2})
|
||||
set(TYPE ${ARGV3})
|
||||
set(FORCE ${ARGV4})
|
||||
endif()
|
||||
|
||||
# If the file exists, no need to download it again unless its being forced
|
||||
if(NOT FORCE AND EXISTS ${FILE})
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Download the file
|
||||
message(STATUS "Downloading: ${URL}")
|
||||
file(DOWNLOAD
|
||||
${URL}
|
||||
${FILE}
|
||||
SHOW_PROGRESS
|
||||
)
|
||||
|
||||
# Make sure the file has contents
|
||||
nodejs_check_file(${FILE} "Unable to download ${URL}")
|
||||
|
||||
# If a checksum is provided, validate the downloaded file
|
||||
if(CHECKSUM)
|
||||
message(STATUS "Validating: ${FILE}")
|
||||
file(${TYPE} ${FILE} DOWNLOAD_CHECKSUM)
|
||||
message(STATUS "Checksum: ${CHECKSUM}")
|
||||
message(STATUS "Download: ${DOWNLOAD_CHECKSUM}")
|
||||
if(NOT CHECKSUM STREQUAL DOWNLOAD_CHECKSUM)
|
||||
file(REMOVE ${FILE})
|
||||
message(FATAL_ERROR "Validation failure: ${FILE}")
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(nodejs_checksum DATA FILE VAR)
|
||||
string(REGEX MATCH "([A-Fa-f0-9]+)[\t ]+${FILE}" CHECKSUM_MATCH ${DATA})
|
||||
if(CMAKE_MATCH_1)
|
||||
set(${VAR} ${CMAKE_MATCH_1} PARENT_SCOPE)
|
||||
else()
|
||||
message(FATAL_ERROR "Unable to extract file checksum")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(nodejs_extract FILE DIR)
|
||||
# Function optionally takes a force value
|
||||
if(ARGC GREATER 2)
|
||||
set(FORCE ${ARGV2})
|
||||
endif()
|
||||
|
||||
# If the archvie has been extracted, no need to extract again unless it
|
||||
# is being forced
|
||||
if(NOT FORCE AND EXISTS ${DIR})
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Make a temporary directory for extracting the output
|
||||
set(EXTRACT_DIR ${CMAKE_CURRENT_BINARY_DIR}/extract)
|
||||
if(EXISTS ${EXTRACT_DIR})
|
||||
file(REMOVE_RECURSE ${EXTRACT_DIR})
|
||||
endif()
|
||||
file(MAKE_DIRECTORY ${EXTRACT_DIR})
|
||||
|
||||
# Extract the archive
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar xfz ${FILE}
|
||||
WORKING_DIRECTORY ${EXTRACT_DIR}
|
||||
)
|
||||
|
||||
# If only one element is extracted, the archive contained a nested
|
||||
# folder; use the inner folder as the extracted folder
|
||||
file(GLOB EXTRACT_CHILDREN ${EXTRACT_DIR}/*)
|
||||
list(LENGTH EXTRACT_CHILDREN NUM_CHILDREN)
|
||||
set(TARGET_DIR ${EXTRACT_DIR})
|
||||
if(NUM_CHILDREN EQUAL 1)
|
||||
list(GET EXTRACT_CHILDREN 0 TARGET_DIR)
|
||||
endif()
|
||||
|
||||
# Move the folder to the target path
|
||||
if(EXISTS ${DIR})
|
||||
file(REMOVE_RECURSE ${DIR})
|
||||
endif()
|
||||
file(RENAME ${TARGET_DIR} ${DIR})
|
||||
|
||||
# Make sure to clean up the extraction folder when the inner folder
|
||||
# is used
|
||||
file(REMOVE_RECURSE ${EXTRACT_DIR})
|
||||
endfunction()
|
||||
|
||||
function(nodejs_find_module NAME BASE PATH)
|
||||
# Find a node module using the same search path that require uses
|
||||
# without needing a node binary
|
||||
set(ROOT ${BASE})
|
||||
set(DRIVE "^[A-Za-z]?:?/$")
|
||||
|
||||
# Walk up the directory tree until at the root
|
||||
while(NOT ROOT MATCHES ${DRIVE} AND NOT
|
||||
EXISTS ${ROOT}/node_modules/${NAME})
|
||||
get_filename_component(ROOT ${ROOT} DIRECTORY)
|
||||
endwhile()
|
||||
|
||||
# Operate like the CMake find_* functions, returning NOTFOUND if the
|
||||
# module can't be found
|
||||
if(ROOT MATCHES ${DRIVE})
|
||||
set(${PATH} ${NAME}-NOTFOUND PARENT_SCOPE)
|
||||
else()
|
||||
set(${PATH} ${ROOT}/node_modules/${NAME} PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
macro(nodejs_find_module_fallback NAME BASE PATH)
|
||||
# Look in the provided path first
|
||||
# If the module isn't found, try searching from the module
|
||||
nodejs_find_module(${NAME} ${BASE} ${PATH})
|
||||
if(NOT ${PATH})
|
||||
nodejs_find_module(${NAME} ${NodeJS_MODULE_PATH} ${PATH})
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
function(nodejs_get_version URL VAR)
|
||||
set(NWJS_LATEST_RELEASE_URL
|
||||
"${NWJS_URL_BASE}/latest/${NodeJS_CHECKSUM_PATH}")
|
||||
set(VERSION_FILE ${CMAKE_CURRENT_BINARY_DIR}/VERSION)
|
||||
nodejs_download(
|
||||
${URL}
|
||||
${VERSION_FILE}
|
||||
ON
|
||||
)
|
||||
nodejs_check_file(${VERSION_FILE})
|
||||
file(READ ${VERSION_FILE} VERSION_DATA)
|
||||
string(REGEX MATCH "v([0-9]+\.[0-9]+\.[0-9]+)"
|
||||
VERSION_MATCH ${VERSION_DATA}
|
||||
)
|
||||
set(${VAR} ${CMAKE_MATCH_1} PARENT_SCOPE)
|
||||
endfunction()
|
81
cmake/nodejs/variants/Electron.cmake
Normal file
81
cmake/nodejs/variants/Electron.cmake
Normal file
@ -0,0 +1,81 @@
|
||||
set(ELECTRON_VARIANT_BASE "electron")
|
||||
set(ELECTRON_WIN32_BINARY_NAME "${ELECTRON_VARIANT_BASE}.exe")
|
||||
list(APPEND NodeJS_WIN32_DELAYLOAD ${ELECTRON_WIN32_BINARY_NAME})
|
||||
|
||||
if(NodeJS_FIND_REQUIRED_ELECTRON OR
|
||||
NodeJS_VARIANT STREQUAL ${ELECTRON_VARIANT_BASE})
|
||||
if(NodeJS_VERSION STREQUAL "latest")
|
||||
include(util/Github)
|
||||
github_get_rate_limit(GITHUB_RATE_LIMIT)
|
||||
|
||||
# Handle determining the latest release
|
||||
# Very complicated, due to electron not following the "latest"
|
||||
# convention of other variants
|
||||
set(ELECTRON_LATEST_RELEASE_FILE ${CMAKE_CURRENT_BINARY_DIR}/ELECTRON)
|
||||
set(ELECTRON_LATEST_RELEASE_URL
|
||||
${GITHUB_API_URL}/repos/atom/electron/releases/latest${GITHUB_AUTH}
|
||||
)
|
||||
if(GITHUB_RATE_LIMIT GREATER 0)
|
||||
nodejs_download(
|
||||
${ELECTRON_LATEST_RELEASE_URL}
|
||||
${ELECTRON_LATEST_RELEASE_FILE}
|
||||
ON
|
||||
)
|
||||
endif()
|
||||
nodejs_check_file(
|
||||
${ELECTRON_LATEST_RELEASE_FILE}
|
||||
"Releases file could not be downloaded, likely \
|
||||
because github rate limit was exceeded. Wait until the limit \
|
||||
passes or set GITHUB_API_TOKEN in your environment to a valid \
|
||||
github developer token."
|
||||
)
|
||||
file(READ ${ELECTRON_LATEST_RELEASE_FILE} ELECTRON_LATEST_RELEASE_DATA)
|
||||
string(REGEX MATCH "\"tag_name\"\: \"v([0-9]+\.[0-9]+\.[0-9]+)\""
|
||||
ELECTRON_LATEST_RELEASE_MATCH ${ELECTRON_LATEST_RELEASE_DATA})
|
||||
set(NodeJS_VERSION ${CMAKE_MATCH_1})
|
||||
endif()
|
||||
|
||||
set(NodeJS_VARIANT_NAME "Electron.js")
|
||||
|
||||
# SHASUMS of any kind is inaccessible prior to 0.16.0
|
||||
if(NodeJS_VERSION VERSION_LESS 0.16.0)
|
||||
message(FATAL_ERROR "Electron is only supported for versions >= 0.16.0")
|
||||
endif()
|
||||
|
||||
# Electron switched to IOJS after 0.25.0
|
||||
# Probably needs to be bounded on the upper side if/when they switch
|
||||
# back to node mainline due to iojs-node merge
|
||||
set(NodeJS_VARIANT_BASE "node")
|
||||
if(NodeJS_VERSION VERSION_GREATER 0.25.0)
|
||||
set(NodeJS_VARIANT_BASE "iojs")
|
||||
endif()
|
||||
|
||||
# Url is hard to get, because it will immediately resolve to a CDN
|
||||
# Extracted from the electron website
|
||||
set(NodeJS_URL
|
||||
"https://atom.io/download/atom-shell/v${NodeJS_VERSION}"
|
||||
)
|
||||
|
||||
# Headers become available for IOJS base ONLY!
|
||||
# Variant base switch above handles this
|
||||
set(NodeJS_HEADER_VERSION 0.30.1)
|
||||
|
||||
# Header only archive uses source style paths
|
||||
set(NodeJS_DEFAULT_INCLUDE False)
|
||||
|
||||
# Hard to determine, but versions seem to start at 16, and SHA256 is
|
||||
# available
|
||||
set(NodeJS_SHA256_VERSION 0.15.9)
|
||||
|
||||
# C++11 and Prefixing start after the IOJS switch
|
||||
# Will carry forward after node mainline so no need for upper bound (whew)
|
||||
set(NodeJS_PREFIX_VERSION 0.25.0)
|
||||
set(NodeJS_CXX11R_VERSION 0.25.0)
|
||||
|
||||
# The executable is not provided on the CDN
|
||||
# In theory, I could support a BINARY_URL to get this from github
|
||||
set(NodeJS_HAS_WIN32_BINARY False)
|
||||
|
||||
# OpenSSL isn't included in the headers
|
||||
set(NodeJS_HAS_OPENSSL False)
|
||||
endif()
|
25
cmake/nodejs/variants/IOJS.cmake
Normal file
25
cmake/nodejs/variants/IOJS.cmake
Normal file
@ -0,0 +1,25 @@
|
||||
set(IOJS_URL_BASE "https://iojs.org/dist")
|
||||
set(IOJS_VARIANT_BASE "iojs")
|
||||
set(IOJS_WIN32_BINARY_NAME "${IOJS_VARIANT_BASE}.exe")
|
||||
list(APPEND NodeJS_WIN32_DELAYLOAD ${IOJS_WIN32_BINARY_NAME})
|
||||
|
||||
if(NodeJS_FIND_REQUIRED_IOJS OR NodeJS_VARIANT STREQUAL ${IOJS_VARIANT_BASE})
|
||||
if(NodeJS_VERSION STREQUAL "latest")
|
||||
set(IOJS_LATEST_RELEASE_URL
|
||||
"${IOJS_URL_BASE}/latest/SHASUMS256.txt")
|
||||
nodejs_get_version(${IOJS_LATEST_RELEASE_URL} NodeJS_VERSION)
|
||||
endif()
|
||||
|
||||
set(NodeJS_VARIANT_NAME "io.js")
|
||||
set(NodeJS_VARIANT_BASE ${IOJS_VARIANT_BASE})
|
||||
set(NodeJS_URL "${IOJS_URL_BASE}/v${NodeJS_VERSION}")
|
||||
set(NodeJS_HEADER_VERSION 2.3.1)
|
||||
set(NodeJS_WIN32_BINARY_NAME "${IOJS_WIN32_BINARY_NAME}")
|
||||
endif()
|
||||
|
||||
mark_as_advanced(
|
||||
IOJS_URL_BASE
|
||||
IOJS_VARIANT_BASE
|
||||
IOJS_WIN32_BINARY_NAME
|
||||
IOJS_LATEST_RELEASE_URL
|
||||
)
|
30
cmake/nodejs/variants/NWJS.cmake
Normal file
30
cmake/nodejs/variants/NWJS.cmake
Normal file
@ -0,0 +1,30 @@
|
||||
set(NWJS_URL_BASE "http://dl.nwjs.io")
|
||||
set(NWJS_VARIANT_BASE "nw")
|
||||
set(NWJS_WIN32_BINARY_NAME "${NWJS_VARIANT_BASE}.exe")
|
||||
list(APPEND NodeJS_WIN32_DELAYLOAD ${NWJS_WIN32_BINARY_NAME})
|
||||
|
||||
if(NodeJS_FIND_REQUIRED_NWJS OR NodeJS_VARIANT STREQUAL ${NWJS_VARIANT_BASE})
|
||||
set(NodeJS_CHECKSUM_PATH "MD5SUMS")
|
||||
set(NodeJS_CHECKSUM_TYPE "MD5")
|
||||
|
||||
if(NodeJS_VERSION STREQUAL "latest")
|
||||
set(NWJS_LATEST_RELEASE_URL
|
||||
"${NWJS_URL_BASE}/latest/${NodeJS_CHECKSUM_PATH}")
|
||||
nodejs_get_version(${NWJS_LATEST_RELEASE_URL} NodeJS_VERSION)
|
||||
endif()
|
||||
|
||||
set(NodeJS_VARIANT_NAME "nw.js")
|
||||
set(NodeJS_VARIANT_BASE ${NWJS_VARIANT_BASE})
|
||||
set(NodeJS_URL "${NWJS_URL_BASE}/v${NodeJS_VERSION}")
|
||||
set(NodeJS_SOURCE_PATH "nw-headers-v${NodeJS_VERSION}.tar.gz")
|
||||
set(NodeJS_DEFAULT_INCLUDE False)
|
||||
set(NodeJS_HAS_WIN32_PREFIX False)
|
||||
set(NodeJS_HAS_WIN32_BINARY False)
|
||||
endif()
|
||||
|
||||
mark_as_advanced(
|
||||
NWJS_URL_BASE
|
||||
NWJS_VARIANT_BASE
|
||||
NWJS_WIN32_BINARY_NAME
|
||||
NWJS_LATEST_RELEASE_URL
|
||||
)
|
131
cmake/nodejs/variants/NodeJS.cmake
Normal file
131
cmake/nodejs/variants/NodeJS.cmake
Normal file
@ -0,0 +1,131 @@
|
||||
set(NodeJS_URL_BASE http://nodejs.org/dist)
|
||||
set(NodeJS_DEFAULT_VARIANT_BASE "node")
|
||||
set(NodeJS_DEFAULT_WIN32_BINARY_NAME "${NodeJS_DEFAULT_VARIANT_BASE}.exe")
|
||||
list(APPEND NodeJS_WIN32_DELAYLOAD ${NodeJS_DEFAULT_WIN32_BINARY_NAME})
|
||||
|
||||
if(NodeJS_VERSION STREQUAL "latest")
|
||||
set(NodeJS_LATEST_RELEASE_URL
|
||||
"${NodeJS_URL_BASE}/latest/SHASUMS256.txt")
|
||||
nodejs_get_version(${NodeJS_LATEST_RELEASE_URL} NodeJS_VERSION)
|
||||
endif()
|
||||
|
||||
if(NOT NodeJS_VARIANT_NAME)
|
||||
set(NodeJS_VARIANT_NAME ${NodeJS_DEFAULT_VARIANT_NAME})
|
||||
endif()
|
||||
if(NOT NodeJS_VARIANT_BASE)
|
||||
set(NodeJS_VARIANT_BASE ${NodeJS_DEFAULT_VARIANT_BASE})
|
||||
endif()
|
||||
if(NOT NodeJS_URL)
|
||||
set(NodeJS_URL "${NodeJS_URL_BASE}/v${NodeJS_VERSION}")
|
||||
endif()
|
||||
|
||||
if(NOT NodeJS_SOURCE_PATH)
|
||||
set(NodeJS_SOURCE_PATH "${NodeJS_VARIANT_BASE}-v${NodeJS_VERSION}")
|
||||
# Use the headers archive when its available
|
||||
if(NodeJS_VERSION VERSION_GREATER ${NodeJS_HEADER_VERSION})
|
||||
set(NodeJS_SOURCE_PATH "${NodeJS_SOURCE_PATH}-headers")
|
||||
endif()
|
||||
set(NodeJS_SOURCE_PATH "${NodeJS_SOURCE_PATH}.tar.gz")
|
||||
endif()
|
||||
|
||||
if(NodeJS_DEFAULT_INCLUDE AND
|
||||
NodeJS_VERSION VERSION_GREATER ${NodeJS_HEADER_VERSION})
|
||||
set(NodeJS_SOURCE_INCLUDE False)
|
||||
set(NodeJS_HEADER_INCLUDE True)
|
||||
endif()
|
||||
|
||||
if(NodeJS_SOURCE_INCLUDE)
|
||||
list(APPEND NodeJS_INCLUDE_PATHS
|
||||
src
|
||||
deps/uv/include
|
||||
deps/v8/include
|
||||
deps/zlib
|
||||
)
|
||||
# OpenSSL is an optional header
|
||||
if(NodeJS_HAS_OPENSSL)
|
||||
list(APPEND NodeJS_INCLUDE_PATHS
|
||||
deps/openssl/openssl/include
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
if(NodeJS_HEADER_INCLUDE)
|
||||
set(NodeJS_INCLUDE_PATHS include/node)
|
||||
endif()
|
||||
|
||||
if(NOT NodeJS_CHECKSUM_TYPE)
|
||||
# Use SHA256 when available
|
||||
if(NodeJS_VERSION VERSION_GREATER ${NodeJS_SHA256_VERSION})
|
||||
set(NodeJS_CHECKSUM_TYPE "SHA256")
|
||||
else()
|
||||
set(NodeJS_CHECKSUM_TYPE "SHA1")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT NodeJS_CHECKSUM_PATH)
|
||||
set(NodeJS_CHECKSUM_PATH "SHASUMS")
|
||||
if(NodeJS_CHECKSUM_TYPE STREQUAL "SHA256")
|
||||
set(NodeJS_CHECKSUM_PATH "${NodeJS_CHECKSUM_PATH}256")
|
||||
endif()
|
||||
set(NodeJS_CHECKSUM_PATH "${NodeJS_CHECKSUM_PATH}.txt")
|
||||
endif()
|
||||
|
||||
# Library and binary are based on variant base
|
||||
if(NOT NodeJS_WIN32_LIBRARY_NAME)
|
||||
set(NodeJS_WIN32_LIBRARY_NAME ${NodeJS_VARIANT_BASE}.lib)
|
||||
endif()
|
||||
if(NOT NodeJS_WIN32_BINARY_NAME)
|
||||
set(NodeJS_WIN32_BINARY_NAME ${NodeJS_VARIANT_BASE}.exe)
|
||||
endif()
|
||||
|
||||
if(NOT NodeJS_WIN32_LIBRARY_PATH)
|
||||
# The library location is prefixed after a specific version
|
||||
if(NodeJS_HAS_WIN32_PREFIX AND
|
||||
NodeJS_VERSION VERSION_GREATER ${NodeJS_PREFIX_VERSION})
|
||||
set(NodeJS_WIN32_LIBRARY_PATH "win-")
|
||||
if(NodeJS_ARCH_IA32)
|
||||
set(NodeJS_WIN32_LIBRARY_PATH "${NodeJS_WIN32_LIBRARY_PATH}x86/")
|
||||
endif()
|
||||
endif()
|
||||
# 64-bit versions are prefixed
|
||||
if(NodeJS_ARCH_X64)
|
||||
set(NodeJS_WIN32_LIBRARY_PATH "${NodeJS_WIN32_LIBRARY_PATH}x64/")
|
||||
endif()
|
||||
set(NodeJS_WIN32_LIBRARY_PATH
|
||||
"${NodeJS_WIN32_LIBRARY_PATH}${NodeJS_WIN32_LIBRARY_NAME}"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NodeJS_HAS_WIN32_BINARY AND NOT NodeJS_WIN32_BINARY_PATH)
|
||||
# The executable location is prefixed after a specific version
|
||||
if(NodeJS_HAS_WIN32_PREFIX AND
|
||||
NodeJS_VERSION VERSION_GREATER ${NodeJS_PREFIX_VERSION})
|
||||
set(NodeJS_WIN32_BINARY_PATH "win-")
|
||||
if(NodeJS_ARCH_IA32)
|
||||
set(NodeJS_WIN32_BINARY_PATH "${NodeJS_WIN32_BINARY_PATH}x86/")
|
||||
endif()
|
||||
endif()
|
||||
# 64-bit versions are prefixed
|
||||
if(NodeJS_ARCH_X64)
|
||||
set(NodeJS_WIN32_BINARY_PATH "${NodeJS_WIN32_BINARY_PATH}x64/")
|
||||
endif()
|
||||
set(NodeJS_WIN32_BINARY_PATH
|
||||
"${NodeJS_WIN32_BINARY_PATH}${NodeJS_WIN32_BINARY_NAME}"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Specify windows libraries
|
||||
# XXX: This may need to be version/variant specific in the future
|
||||
if(NodeJS_DEFAULT_LIBS AND NodeJS_PLATFORM_WIN32)
|
||||
list(APPEND NodeJS_LIBRARIES
|
||||
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib
|
||||
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib
|
||||
odbc32.lib DelayImp.lib
|
||||
)
|
||||
endif()
|
||||
|
||||
mark_as_advanced(
|
||||
NodeJS_URL_BASE
|
||||
NodeJS_DEFAULT_VARIANT_BASE
|
||||
NodeJS_DEFAULT_WIN32_BINARY_NAME
|
||||
NodeJS_LATEST_RELEASE_URL
|
||||
)
|
333
docs/bindings/node/api.md
Normal file
333
docs/bindings/node/api.md
Normal file
@ -0,0 +1,333 @@
|
||||
# OSRM
|
||||
|
||||
The `OSRM` method is the main constructor for creating an OSRM instance. An OSRM instance requires a `.osrm` network,
|
||||
which is prepared by the OSRM Backend C++ library.
|
||||
|
||||
You can create such a `.osrm` file by running the OSRM binaries we ship in `node_modules/osrm/lib/binding/` and default
|
||||
profiles (e.g. for setting speeds and determining road types to route on) in `node_modules/osrm/profiles/`:
|
||||
|
||||
node_modules/osrm/lib/binding/osrm-extract data.osm.pbf -p node_modules/osrm/profiles/car.lua
|
||||
node_modules/osrm/lib/binding/osrm-contract data.osrm
|
||||
|
||||
Consult the [osrm-backend](https://github.com/Project-OSRM/osrm-backend) documentation or further details.
|
||||
|
||||
Once you have a complete `network.osrm` file, you can calculate networks in javascript with this library using the
|
||||
methods below. To create an OSRM instance with your network you need to construct an instance like this:
|
||||
|
||||
```javascript
|
||||
var osrm = new OSRM('network.osrm');
|
||||
```
|
||||
|
||||
#### Methods
|
||||
|
||||
| Service | Description |
|
||||
| -------------------------- | --------------------------------------------------------- |
|
||||
| [`osrm.route`](#route) | shortest path between given coordinates |
|
||||
| [`osrm.nearest`](#nearest) | returns the nearest street segment for a given coordinate |
|
||||
| [`osrm.table`](#table) | computes distance tables for given coordinates |
|
||||
| [`osrm.match`](#match) | matches given coordinates to the road network |
|
||||
| [`osrm.trip`](#trip) | Compute the shortest trip between given coordinates |
|
||||
| [`osrm.tile`](#tile) | Return vector tiles containing debugging info |
|
||||
|
||||
#### General Options
|
||||
|
||||
Each OSRM method (except for `OSRM.tile()`) has set of general options as well as unique options, outlined below.
|
||||
|
||||
| Option | Values | Description | Format |
|
||||
| --------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ |
|
||||
| coordinates | `array` of `coordinate` elements: `[{coordinate}, ...]` | The coordinates this request will use. | `array` with `[{lon},{lat}]` values, in decimal degrees |
|
||||
| bearings | `array` of `bearing` elements: `[{bearing}, ...]` | Limits the search to segments with given bearing in degrees towards true north in clockwise direction. | `null` or `array` with `[{value},{range}]` `integer 0 .. 360,integer 0 .. 180` |
|
||||
| radiuses | `array` of `radius` elements: `[{radius}, ...]` | Limits the search to given radius in meters. | `null` or `double >= 0` or `unlimited` (default) |
|
||||
| hints | `array` of `hint` elements: `[{hint}, ...]` | Hint to derive position in street network. | Base64 `string` |
|
||||
| generate\_hints | `true` (default) or `false` | Adds a Hint to the response which can be used in subsequent requests, see `hints` parameter. | `Boolean` |
|
||||
|
||||
## route
|
||||
|
||||
Returns the fastest route between two or more coordinates while visiting the waypoints in order.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- `options` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Object literal containing parameters for the route query.
|
||||
- `options.alternatives` **\[[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)]** Search for alternative routes and return as well. _Please note that even if an alternative route is requested, a result cannot be guaranteed._ (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 leg. (optional, default `false`)
|
||||
- `options.annotations` **\[[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)] or \[[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)<[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)>]** Return annotations for each route leg for duration, nodes, distance, weight, datasources and/or speed. Annotations can be `false` or `true` (no/full annotations) or an array of strings with `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed`. (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.overview` **\[[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`). (optional, default `simplified`)
|
||||
- `options.continue_straight` **\[[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)]** Forces the route to keep going straight at waypoints and don't do a uturn even if it would be faster. Default value depends on the profile. `null`/`true`/`false`
|
||||
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
|
||||
|
||||
**Examples**
|
||||
|
||||
```javascript
|
||||
var osrm = new OSRM("berlin-latest.osrm");
|
||||
osrm.route({coordinates: [[13.438640,52.519930], [13.415852, 52.513191]]}, function(err, result) {
|
||||
if(err) throw err;
|
||||
console.log(result.waypoints); // array of Waypoint objects representing all waypoints in order
|
||||
console.log(result.routes); // array of Route objects ordered by descending recommendation rank
|
||||
});
|
||||
```
|
||||
|
||||
Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** An array of [Waypoint](#waypoint) objects representing all waypoints in order AND an array of [`Route`](#route) objects ordered by descending recommendation rank.
|
||||
|
||||
## nearest
|
||||
|
||||
Snaps a coordinate to the street network and returns the nearest n matches.
|
||||
|
||||
Note: `coordinates` in the general options only supports a single `{longitude},{latitude}` entry.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- `options` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Object literal containing parameters for the nearest query.
|
||||
- `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`)
|
||||
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
|
||||
|
||||
**Examples**
|
||||
|
||||
```javascript
|
||||
var osrm = new OSRM('network.osrm');
|
||||
var options = {
|
||||
coordinates: [[13.388860,52.517037]],
|
||||
number: 3,
|
||||
bearings: [[0,20]]
|
||||
};
|
||||
osrm.nearest(options, function(err, response) {
|
||||
console.log(response.waypoints); // array of Waypoint objects
|
||||
});
|
||||
```
|
||||
|
||||
Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** containing `waypoints`.
|
||||
**`waypoints`**: array of [`Ẁaypoint`](#waypoint) objects sorted by distance to the input coordinate.
|
||||
Each object has an additional `distance` property, which is the distance in meters to the supplied
|
||||
input coordinate.
|
||||
|
||||
## table
|
||||
|
||||
Computes duration tables for the given locations. Allows for both symmetric and asymmetric tables.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- `options` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Object literal containing parameters for the table query.
|
||||
- `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
|
||||
location with given index as source. Default is to use all.
|
||||
- `options.destinations` **\[[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)]** An array of `index` elements (`0 <= integer < #coordinates`) to use location with given index as destination. Default is to use all.
|
||||
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
|
||||
|
||||
**Examples**
|
||||
|
||||
```javascript
|
||||
var osrm = new OSRM('network.osrm');
|
||||
var options = {
|
||||
coordinates: [
|
||||
[13.388860,52.517037],
|
||||
[13.397634,52.529407],
|
||||
[13.428555,52.523219]
|
||||
]
|
||||
};
|
||||
osrm.table(options, function(err, response) {
|
||||
console.log(response.durations); // array of arrays, matrix in row-major order
|
||||
console.log(response.sources); // array of Waypoint objects
|
||||
console.log(response.destinations); // array of Waypoint objects
|
||||
});
|
||||
```
|
||||
|
||||
Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** containing `durations`, `sources`, and `destinations`.
|
||||
**`durations`**: array of arrays that stores the matrix in row-major order. `durations[i][j]`
|
||||
gives the travel time from the i-th waypoint to the j-th waypoint. Values are given in seconds.
|
||||
**`sources`**: array of [`Ẁaypoint`](#waypoint) objects describing all sources in order.
|
||||
**`destinations`**: array of [`Ẁaypoint`](#waypoint) objects describing all destinations in order.
|
||||
|
||||
## tile
|
||||
|
||||
This generates [Mapbox Vector Tiles](https://mapbox.com/vector-tiles) that can be viewed with a
|
||||
vector-tile capable slippy-map viewer. The tiles contain road geometries and metadata that can
|
||||
be used to examine the routing graph. The tiles are generated directly from the data in-memory,
|
||||
so are in sync with actual routing results, and let you examine which roads are actually routable,
|
||||
and what weights they have applied.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- `ZXY` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)** an array consisting of `x`, `y`, and `z` values representing tile coordinates like
|
||||
[wiki.openstreetmap.org/wiki/Slippy_map_tilenames](https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames)
|
||||
and are supported by vector tile viewers like [Mapbox GL JS]\(<https://www.mapbox.com/mapbox-gl-js/api/>.
|
||||
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
|
||||
|
||||
**Examples**
|
||||
|
||||
```javascript
|
||||
var osrm = new OSRM('network.osrm');
|
||||
osrm.tile([0, 0, 0], function(err, response) {
|
||||
if (err) throw err;
|
||||
fs.writeFileSync('./tile.vector.pbf', response); // write the buffer to a file
|
||||
});
|
||||
```
|
||||
|
||||
Returns **[Buffer](https://nodejs.org/api/buffer.html)** contains a Protocol Buffer encoded vector tile.
|
||||
|
||||
## match
|
||||
|
||||
Map matching matches given GPS points to the road network in the most plausible way.
|
||||
Please note the request might result multiple sub-traces. Large jumps in the timestamps
|
||||
(>60s) or improbable transitions lead to trace splits if a complete matching could
|
||||
not be found. The algorithm might not be able to match all points. Outliers are removed
|
||||
if they can not be matched successfully.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- `options` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Object literal containing parameters for the match query.
|
||||
- `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` **\[[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)] or \[[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)<[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)>]** Return annotations for each route leg for duration, nodes, distance, weight, datasources and/or speed. Annotations can be `false` or `true` (no/full annotations) or an array of strings with `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed`. (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.overview` **\[[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** Add overview geometry either `full`, `simplified`
|
||||
according to highest zoom level it could be display on, or not at all (`false`). (optional, default `simplified`)
|
||||
- `options.timestamps` **\[[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>]** Timestamp of the input location (integers, UNIX-like timestamp).
|
||||
- `options.radiuses` **\[[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)]** Standard deviation of GPS precision used for map matching.
|
||||
If applicable use GPS accuracy (`double >= 0`, default `5m`).
|
||||
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
|
||||
|
||||
**Examples**
|
||||
|
||||
```javascript
|
||||
var osrm = new OSRM('network.osrm');
|
||||
var options = {
|
||||
coordinates: [[13.393252,52.542648],[13.39478,52.543079],[13.397389,52.542107]],
|
||||
timestamps: [1424684612, 1424684616, 1424684620]
|
||||
};
|
||||
osrm.match(options, function(err, response) {
|
||||
if (err) throw err;
|
||||
console.log(response.tracepoints); // array of Waypoint objects
|
||||
console.log(response.matchings); // array of Route objects
|
||||
});
|
||||
```
|
||||
|
||||
Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** containing `tracepoints` and `matchings`.
|
||||
**`tracepoints`** Array of [`Ẁaypoint`](#waypoint) objects representing all points of the trace in order.
|
||||
If the trace point was ommited by map matching because it is an outlier, the entry will be null. Each
|
||||
`Waypoint` object includes two additional properties, 1) `matchings_index`: Index to the
|
||||
[`Route`](#route) object in matchings the sub-trace was matched to, 2) `waypoint_index`: Index of
|
||||
the waypoint inside the matched route.
|
||||
**`matchings`** is an array of [`Route`](#route) objects that
|
||||
assemble the trace. Each `Route` object has an additional `confidence` property, which is the confidence of
|
||||
the matching. float value between `0` and `1`. `1` is very confident that the matching is correct.
|
||||
|
||||
## trip
|
||||
|
||||
The trip plugin solves the Traveling Salesman Problem using a greedy heuristic (farthest-insertion algorithm). The returned path does not have to be the fastest path, as TSP is NP-hard it is only an approximation. Note that all input coordinates have to be connected for the trip service to work.
|
||||
|
||||
**Parameters**
|
||||
- `options` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Object literal containing parameters for the trip query.
|
||||
- `options.roundtrip` **\[[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)]** Return route is a roundtrip. (optional, default `true`)
|
||||
- `options.source` **\[[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** Return route starts at `any` coordinate. Can also be `first`. (optional, default `any`)
|
||||
- `options.destination` **\[[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** Return route ends at `any` coordinate. Can also be `last`. (optional, default `any`)
|
||||
- `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` **\[[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)] or \[[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)<[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)>]** Return annotations for each route leg for duration, nodes, distance, weight, datasources and/or speed. Annotations can be `false` or `true` (no/full annotations) or an array of strings with `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed`. (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.overview` **\[[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** Add overview geometry either `full`, `simplified` (optional, default `simplified`)
|
||||
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
|
||||
|
||||
**Fixing Start and End Points**
|
||||
|
||||
It is possible to explicitly set the start or end coordinate of the trip. When source is set to `first`, the first coordinate is used as start coordinate of the trip in the output. When destination is set to `last`, the last coordinate will be used as destination of the trip in the returned output. If you specify `any`, any of the coordinates can be used as the first or last coordinate in the output.
|
||||
|
||||
However, if `source=any&destination=any` the returned round-trip will still start at the first input coordinate by default.
|
||||
|
||||
Currently, not all combinations of `roundtrip`, `source` and `destination` are supported.
|
||||
Right now, the following combinations are possible:
|
||||
|
||||
| roundtrip | source | destination | supported |
|
||||
| :-- | :-- | :-- | :-- |
|
||||
| true | first | last | **yes** |
|
||||
| true | first | any | **yes** |
|
||||
| true | any | last | **yes** |
|
||||
| true | any | any | **yes** |
|
||||
| false | first | last | **yes** |
|
||||
| false | first | any | no |
|
||||
| false | any | last | no |
|
||||
| false | any | any | no |
|
||||
|
||||
**Examples**
|
||||
|
||||
Roundtrip Request
|
||||
```javascript
|
||||
var osrm = new OSRM('network.osrm');
|
||||
var options = {
|
||||
coordinates: [
|
||||
[13.36761474609375, 52.51663871100423],
|
||||
[13.374481201171875, 52.506191342034576]
|
||||
]
|
||||
}
|
||||
osrm.trip(options, function(err, response) {
|
||||
if (err) throw err;
|
||||
console.log(response.waypoints); // array of Waypoint objects
|
||||
console.log(response.trips); // array of Route objects
|
||||
});
|
||||
```
|
||||
|
||||
Non Roundtrip Request
|
||||
```javascript
|
||||
var osrm = new OSRM('network.osrm');
|
||||
var options = {
|
||||
coordinates: [
|
||||
[13.36761474609375, 52.51663871100423],
|
||||
[13.374481201171875, 52.506191342034576]
|
||||
],
|
||||
source: "first",
|
||||
destination: "last",
|
||||
roundtrip: false
|
||||
}
|
||||
osrm.trip(options, function(err, response) {
|
||||
if (err) throw err;
|
||||
console.log(response.waypoints); // array of Waypoint objects
|
||||
console.log(response.trips); // array of Route objects
|
||||
});
|
||||
```
|
||||
|
||||
Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** containing `waypoints` and `trips`.
|
||||
**`waypoints`**: an array of [`Ẁaypoint`](#waypoint) objects representing all waypoints in input order.
|
||||
Each Waypoint object has the following additional properties, 1) `trips_index`: index to trips of the
|
||||
sub-trip the point was matched to, and 2) `waypoint_index`: index of the point in the trip.
|
||||
**`trips`**: an array of [`Route`](#route) objects that assemble the trace.
|
||||
|
||||
# Responses
|
||||
|
||||
Responses
|
||||
|
||||
## Route
|
||||
|
||||
Represents a route through (potentially multiple) waypoints.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- `exteral` **documentation** in [`osrm-backend`](https://github.com/Project-OSRM/osrm-backend/blob/master/docs/http.md#route)
|
||||
|
||||
## RouteLeg
|
||||
|
||||
Represents a route between two waypoints.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- `exteral` **documentation** in [`osrm-backend`](https://github.com/Project-OSRM/osrm-backend/blob/master/docs/http.md#routeleg)
|
||||
|
||||
## RouteStep
|
||||
|
||||
A step consists of a maneuver such as a turn or merge, followed by a distance of travel along a single way to the subsequent step.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- `exteral` **documentation** in [`osrm-backend`](https://github.com/Project-OSRM/osrm-backend/blob/master/docs/http.md#routestep)
|
||||
|
||||
## StepManeuver
|
||||
|
||||
**Parameters**
|
||||
|
||||
- `exteral` **documentation** in [`osrm-backend`](https://github.com/Project-OSRM/osrm-backend/blob/master/docs/http.md#stepmanuever)
|
||||
|
||||
## Waypoint
|
||||
|
||||
Object used to describe waypoint on a route.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- `exteral` **documentation** in [`osrm-backend`](https://github.com/Project-OSRM/osrm-backend/blob/master/docs/http.md#waypoint)
|
86
docs/bindings/node/releasing.md
Normal file
86
docs/bindings/node/releasing.md
Normal file
@ -0,0 +1,86 @@
|
||||
# Releasing
|
||||
|
||||
Releasing a new version of `node-osrm` is mostly automated using Travis CI.
|
||||
|
||||
The version of `node-osrm` is locked to the same version as `osrm-backend`. Every `node-osrm` should have a `osrm-backend` release of the same version. Of course, only release a `node-osrm` after the release has been tagged in `osrm-backend`.
|
||||
|
||||
These steps all happen on `master`. After the release is out, create a branch using the MAJOR.MINOR version of the release to document code changes made for that version.
|
||||
|
||||
### Steps to release
|
||||
|
||||
1. Update the `osrm_release` field in `package.json` to the corresonding git tag in `osrm-backend.`
|
||||
|
||||
Confirm the desired OSRM branch and commit to `master`.
|
||||
|
||||
1. Bump node-osrm version
|
||||
|
||||
Update the `CHANGELOG.md` and the `package.json` version if needed.
|
||||
|
||||
1. Check that Travis CI [builds are passing](https://travis-ci.org/Project-OSRM/node-osrm) for the latest commit on `master`.
|
||||
|
||||
1. Publishing binaries
|
||||
|
||||
If travis builds are passing then it's time to publish binaries by committing with a message containing `[publish binary]`. Use an empty commit for this.
|
||||
|
||||
```
|
||||
git commit --allow-empty -m "[publish binary] vMAJOR.MINOR.PATCH"
|
||||
```
|
||||
|
||||
1. Test
|
||||
|
||||
Locally you can now test binaries. Cleanup, re-install, and run the tests like:
|
||||
|
||||
```
|
||||
make clean
|
||||
npm install # will pull remote binaries
|
||||
npm ls # confirm deps are correct
|
||||
make test
|
||||
```
|
||||
|
||||
1. Tag
|
||||
|
||||
Once binaries are published for Linux and OS X then its time to tag a new release and add the changelog to the tag:
|
||||
|
||||
```
|
||||
git tag vMAJOR.MINOR.PATCH -a
|
||||
git push --tags
|
||||
```
|
||||
|
||||
1. Publish node-osrm. **we only do this for stable releases**
|
||||
|
||||
First ensure your local `node-pre-gyp` is up to date:
|
||||
|
||||
```
|
||||
npm ls
|
||||
```
|
||||
|
||||
This is important because it is bundled during packaging.
|
||||
|
||||
If you see any errors then do:
|
||||
|
||||
```
|
||||
rm -rf node_modules/node-pre-gyp
|
||||
npm install node-pre-gyp
|
||||
```
|
||||
|
||||
Now we're ready to publish `node-osrm` to <https://www.npmjs.org/package/osrm>:
|
||||
|
||||
```
|
||||
npm publish
|
||||
```
|
||||
|
||||
Dependent apps can now pull from the npm registry like:
|
||||
|
||||
```
|
||||
"dependencies": {
|
||||
"osrm": "^MAJOR.MINOR.PATCH"
|
||||
}
|
||||
```
|
||||
|
||||
Or can still pull from the github tag like:
|
||||
|
||||
```
|
||||
"dependencies": {
|
||||
"osrm": "https://github.com/Project-OSRM/node-osrm/archive/vMAJOR.MINOR.PATCH.tar.gz"
|
||||
}
|
||||
```
|
@ -46,12 +46,6 @@ You should see the compiled binaries in `build/unit_tests`, you can then run eac
|
||||
./engine-tests
|
||||
```
|
||||
|
||||
For `library-tests` you will need to provide a path to the test data:
|
||||
|
||||
```
|
||||
./library-tests ../../test/data/monaco.osrm
|
||||
```
|
||||
|
||||
## Cucumber
|
||||
|
||||
For a general introduction on cucumber in our testsuite, have a look at [the wiki](https://github.com/Project-OSRM/osrm-backend/wiki/Cucumber-Test-Suite).
|
||||
|
@ -39,9 +39,9 @@ int main(int argc, const char *argv[])
|
||||
// The following shows how to use the Route service; configure this service
|
||||
RouteParameters params;
|
||||
|
||||
// Route in monaco
|
||||
params.coordinates.push_back({util::FloatLongitude{7.419758}, util::FloatLatitude{43.731142}});
|
||||
params.coordinates.push_back({util::FloatLongitude{7.419505}, util::FloatLatitude{43.736825}});
|
||||
// Route in Berlin: Alexanderplatz to Hackescher Markt
|
||||
params.coordinates.push_back({util::FloatLongitude{13.414307}, util::FloatLatitude{52.521835}});
|
||||
params.coordinates.push_back({util::FloatLongitude{13.402290}, util::FloatLatitude{52.523728}});
|
||||
|
||||
// Response is in JSON format
|
||||
json::Object result;
|
||||
@ -59,7 +59,7 @@ int main(int argc, const char *argv[])
|
||||
const auto duration = route.values["duration"].get<json::Number>().value;
|
||||
|
||||
// Warn users if extract does not contain the default Berlin coordinates from above
|
||||
if (distance == 0 or duration == 0)
|
||||
if (distance == 0 || duration == 0)
|
||||
{
|
||||
std::cout << "Note: distance or duration is zero. ";
|
||||
std::cout << "You are probably doing a query outside of the OSM extract.\n\n";
|
||||
|
32
example/example.js
Normal file
32
example/example.js
Normal file
@ -0,0 +1,32 @@
|
||||
process.env.UV_THREADPOOL_SIZE = Math.ceil(require('os').cpus().length * 1.5);
|
||||
|
||||
var express = require('express');
|
||||
var OSRM = require('..');
|
||||
var path = require('path');
|
||||
|
||||
var app = express();
|
||||
var osrm = new OSRM(path.join(__dirname,"../test/data/berlin_CH.osrm"));
|
||||
|
||||
// Accepts a query like:
|
||||
// http://localhost:8888?start=13.414307,52.521835&end=13.402290,52.523728
|
||||
app.get('/', function(req, res) {
|
||||
if (!req.query.start || !req.query.end) {
|
||||
return res.json({"error":"invalid start and end query"});
|
||||
}
|
||||
var coordinates = [];
|
||||
var start = req.query.start.split(',');
|
||||
coordinates.push([+start[0],+start[1]]);
|
||||
var end = req.query.end.split(',');
|
||||
coordinates.push([+end[0],+end[1]]);
|
||||
var query = {
|
||||
coordinates: coordinates,
|
||||
alternateRoute: req.query.alternatives !== 'false'
|
||||
};
|
||||
osrm.route(query, function(err, result) {
|
||||
if (err) return res.json({"error":err.message});
|
||||
return res.json(result);
|
||||
});
|
||||
});
|
||||
|
||||
console.log('Listening on port: ' + 8888);
|
||||
app.listen(8888);
|
65
include/nodejs/json_v8_renderer.hpp
Normal file
65
include/nodejs/json_v8_renderer.hpp
Normal file
@ -0,0 +1,65 @@
|
||||
#ifndef OSRM_BINDINGS_NODE_JSON_V8_RENDERER_HPP
|
||||
#define OSRM_BINDINGS_NODE_JSON_V8_RENDERER_HPP
|
||||
|
||||
#include "osrm/json_container.hpp"
|
||||
|
||||
#include <nan.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace node_osrm
|
||||
{
|
||||
|
||||
struct V8Renderer
|
||||
{
|
||||
explicit V8Renderer(v8::Local<v8::Value> &_out) : out(_out) {}
|
||||
|
||||
void operator()(const osrm::json::String &string) const
|
||||
{
|
||||
out = Nan::New(std::cref(string.value)).ToLocalChecked();
|
||||
}
|
||||
|
||||
void operator()(const osrm::json::Number &number) const { out = Nan::New(number.value); }
|
||||
|
||||
void operator()(const osrm::json::Object &object) const
|
||||
{
|
||||
v8::Local<v8::Object> obj = Nan::New<v8::Object>();
|
||||
for (const auto &keyValue : object.values)
|
||||
{
|
||||
v8::Local<v8::Value> child;
|
||||
mapbox::util::apply_visitor(V8Renderer(child), keyValue.second);
|
||||
obj->Set(Nan::New(keyValue.first).ToLocalChecked(), child);
|
||||
}
|
||||
out = obj;
|
||||
}
|
||||
|
||||
void operator()(const osrm::json::Array &array) const
|
||||
{
|
||||
v8::Local<v8::Array> a = Nan::New<v8::Array>(array.values.size());
|
||||
for (auto i = 0u; i < array.values.size(); ++i)
|
||||
{
|
||||
v8::Local<v8::Value> child;
|
||||
mapbox::util::apply_visitor(V8Renderer(child), array.values[i]);
|
||||
a->Set(i, child);
|
||||
}
|
||||
out = a;
|
||||
}
|
||||
|
||||
void operator()(const osrm::json::True &) const { out = Nan::New(true); }
|
||||
|
||||
void operator()(const osrm::json::False &) const { out = Nan::New(false); }
|
||||
|
||||
void operator()(const osrm::json::Null &) const { out = Nan::Null(); }
|
||||
|
||||
private:
|
||||
v8::Local<v8::Value> &out;
|
||||
};
|
||||
|
||||
inline void renderToV8(v8::Local<v8::Value> &out, const osrm::json::Object &object)
|
||||
{
|
||||
osrm::json::Value value = object;
|
||||
mapbox::util::apply_visitor(V8Renderer(out), value);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // JSON_V8_RENDERER_HPP
|
41
include/nodejs/node_osrm.hpp
Normal file
41
include/nodejs/node_osrm.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef OSRM_BINDINGS_NODE_HPP
|
||||
#define OSRM_BINDINGS_NODE_HPP
|
||||
|
||||
#include "osrm/osrm_fwd.hpp"
|
||||
|
||||
#include <nan.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace node_osrm
|
||||
{
|
||||
|
||||
struct Engine final : public Nan::ObjectWrap
|
||||
{
|
||||
using Base = Nan::ObjectWrap;
|
||||
|
||||
static NAN_MODULE_INIT(Init);
|
||||
|
||||
static NAN_METHOD(New);
|
||||
|
||||
static NAN_METHOD(route);
|
||||
static NAN_METHOD(nearest);
|
||||
static NAN_METHOD(table);
|
||||
static NAN_METHOD(tile);
|
||||
static NAN_METHOD(match);
|
||||
static NAN_METHOD(trip);
|
||||
|
||||
Engine(osrm::EngineConfig &config);
|
||||
|
||||
// Thread-safe singleton accessor
|
||||
static Nan::Persistent<v8::Function> &constructor();
|
||||
|
||||
// Ref-counted OSRM alive even after shutdown until last callback is done
|
||||
std::shared_ptr<osrm::OSRM> this_;
|
||||
};
|
||||
|
||||
} // ns node_osrm
|
||||
|
||||
NODE_MODULE(osrm, node_osrm::Engine::Init)
|
||||
|
||||
#endif
|
922
include/nodejs/node_osrm_support.hpp
Normal file
922
include/nodejs/node_osrm_support.hpp
Normal file
@ -0,0 +1,922 @@
|
||||
#ifndef OSRM_BINDINGS_NODE_SUPPORT_HPP
|
||||
#define OSRM_BINDINGS_NODE_SUPPORT_HPP
|
||||
|
||||
#include "nodejs/json_v8_renderer.hpp"
|
||||
|
||||
#include "osrm/bearing.hpp"
|
||||
#include "osrm/coordinate.hpp"
|
||||
#include "osrm/engine_config.hpp"
|
||||
#include "osrm/json_container.hpp"
|
||||
#include "osrm/match_parameters.hpp"
|
||||
#include "osrm/nearest_parameters.hpp"
|
||||
#include "osrm/osrm.hpp"
|
||||
#include "osrm/route_parameters.hpp"
|
||||
#include "osrm/status.hpp"
|
||||
#include "osrm/storage_config.hpp"
|
||||
#include "osrm/table_parameters.hpp"
|
||||
#include "osrm/tile_parameters.hpp"
|
||||
#include "osrm/trip_parameters.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/make_unique.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace node_osrm
|
||||
{
|
||||
|
||||
using engine_config_ptr = std::unique_ptr<osrm::EngineConfig>;
|
||||
using route_parameters_ptr = std::unique_ptr<osrm::RouteParameters>;
|
||||
using trip_parameters_ptr = std::unique_ptr<osrm::TripParameters>;
|
||||
using tile_parameters_ptr = std::unique_ptr<osrm::TileParameters>;
|
||||
using match_parameters_ptr = std::unique_ptr<osrm::MatchParameters>;
|
||||
using nearest_parameters_ptr = std::unique_ptr<osrm::NearestParameters>;
|
||||
using table_parameters_ptr = std::unique_ptr<osrm::TableParameters>;
|
||||
|
||||
template <typename ResultT> inline v8::Local<v8::Value> render(const ResultT &result);
|
||||
|
||||
template <> v8::Local<v8::Value> inline render(const std::string &result)
|
||||
{
|
||||
return Nan::CopyBuffer(result.data(), result.size()).ToLocalChecked();
|
||||
}
|
||||
|
||||
template <> v8::Local<v8::Value> inline render(const osrm::json::Object &result)
|
||||
{
|
||||
v8::Local<v8::Value> value;
|
||||
renderToV8(value, result);
|
||||
return value;
|
||||
}
|
||||
|
||||
inline void ParseResult(const osrm::Status &result_status, osrm::json::Object &result)
|
||||
{
|
||||
const auto code_iter = result.values.find("code");
|
||||
const auto end_iter = result.values.end();
|
||||
|
||||
BOOST_ASSERT(code_iter != end_iter);
|
||||
|
||||
if (result_status == osrm::Status::Error)
|
||||
{
|
||||
throw std::logic_error(code_iter->second.get<osrm::json::String>().value.c_str());
|
||||
}
|
||||
|
||||
result.values.erase(code_iter);
|
||||
const auto message_iter = result.values.find("message");
|
||||
if (message_iter != end_iter)
|
||||
{
|
||||
result.values.erase(message_iter);
|
||||
}
|
||||
}
|
||||
|
||||
inline void ParseResult(const osrm::Status &result_status, const std::string & /*unused*/) {}
|
||||
|
||||
inline engine_config_ptr argumentsToEngineConfig(const Nan::FunctionCallbackInfo<v8::Value> &args)
|
||||
{
|
||||
Nan::HandleScope scope;
|
||||
auto engine_config = boost::make_unique<osrm::EngineConfig>();
|
||||
|
||||
if (args.Length() == 0)
|
||||
{
|
||||
return engine_config;
|
||||
}
|
||||
else if (args.Length() > 1)
|
||||
{
|
||||
Nan::ThrowError("Only accepts one parameter");
|
||||
return engine_config_ptr();
|
||||
}
|
||||
|
||||
BOOST_ASSERT(args.Length() == 1);
|
||||
|
||||
if (args[0]->IsString())
|
||||
{
|
||||
engine_config->storage_config = osrm::StorageConfig(
|
||||
*v8::String::Utf8Value(Nan::To<v8::String>(args[0]).ToLocalChecked()));
|
||||
engine_config->use_shared_memory = false;
|
||||
return engine_config;
|
||||
}
|
||||
else if (!args[0]->IsObject())
|
||||
{
|
||||
Nan::ThrowError("Parameter must be a path or options object");
|
||||
return engine_config_ptr();
|
||||
}
|
||||
|
||||
BOOST_ASSERT(args[0]->IsObject());
|
||||
auto params = Nan::To<v8::Object>(args[0]).ToLocalChecked();
|
||||
|
||||
auto path = params->Get(Nan::New("path").ToLocalChecked());
|
||||
auto shared_memory = params->Get(Nan::New("shared_memory").ToLocalChecked());
|
||||
if (!path->IsUndefined())
|
||||
{
|
||||
engine_config->storage_config =
|
||||
osrm::StorageConfig(*v8::String::Utf8Value(Nan::To<v8::String>(path).ToLocalChecked()));
|
||||
}
|
||||
if (!shared_memory->IsUndefined())
|
||||
{
|
||||
if (shared_memory->IsBoolean())
|
||||
{
|
||||
engine_config->use_shared_memory = Nan::To<bool>(shared_memory).FromJust();
|
||||
}
|
||||
else
|
||||
{
|
||||
Nan::ThrowError("Shared_memory option must be a boolean");
|
||||
return engine_config_ptr();
|
||||
}
|
||||
}
|
||||
|
||||
if (path->IsUndefined() && !engine_config->use_shared_memory)
|
||||
{
|
||||
Nan::ThrowError("Shared_memory must be enabled if no path is "
|
||||
"specified");
|
||||
return engine_config_ptr();
|
||||
}
|
||||
|
||||
return engine_config;
|
||||
}
|
||||
|
||||
inline boost::optional<std::vector<osrm::Coordinate>>
|
||||
parseCoordinateArray(const v8::Local<v8::Array> &coordinates_array)
|
||||
{
|
||||
Nan::HandleScope scope;
|
||||
boost::optional<std::vector<osrm::Coordinate>> resulting_coordinates;
|
||||
std::vector<osrm::Coordinate> temp_coordinates;
|
||||
|
||||
for (uint32_t i = 0; i < coordinates_array->Length(); ++i)
|
||||
{
|
||||
v8::Local<v8::Value> coordinate = coordinates_array->Get(i);
|
||||
|
||||
if (!coordinate->IsArray())
|
||||
{
|
||||
Nan::ThrowError("Coordinates must be an array of (lon/lat) pairs");
|
||||
return resulting_coordinates;
|
||||
}
|
||||
|
||||
v8::Local<v8::Array> coordinate_pair = v8::Local<v8::Array>::Cast(coordinate);
|
||||
if (coordinate_pair->Length() != 2)
|
||||
{
|
||||
Nan::ThrowError("Coordinates must be an array of (lon/lat) pairs");
|
||||
return resulting_coordinates;
|
||||
}
|
||||
|
||||
if (!coordinate_pair->Get(0)->IsNumber() || !coordinate_pair->Get(1)->IsNumber())
|
||||
{
|
||||
Nan::ThrowError("Each member of a coordinate pair must be a number");
|
||||
return resulting_coordinates;
|
||||
}
|
||||
|
||||
double lon = coordinate_pair->Get(0)->NumberValue();
|
||||
double lat = coordinate_pair->Get(1)->NumberValue();
|
||||
|
||||
if (std::isnan(lon) || std::isnan(lat) || std::isinf(lon) || std::isinf(lat))
|
||||
{
|
||||
Nan::ThrowError("Lng/Lat coordinates must be valid numbers");
|
||||
return resulting_coordinates;
|
||||
}
|
||||
|
||||
if (lon > 180 || lon < -180 || lat > 90 || lat < -90)
|
||||
{
|
||||
Nan::ThrowError("Lng/Lat coordinates must be within world bounds "
|
||||
"(-180 < lng < 180, -90 < lat < 90)");
|
||||
return resulting_coordinates;
|
||||
}
|
||||
|
||||
temp_coordinates.emplace_back(osrm::util::FloatLongitude{std::move(lon)},
|
||||
osrm::util::FloatLatitude{std::move(lat)});
|
||||
}
|
||||
|
||||
resulting_coordinates = boost::make_optional(std::move(temp_coordinates));
|
||||
return resulting_coordinates;
|
||||
}
|
||||
|
||||
// Parses all the non-service specific parameters
|
||||
template <typename ParamType>
|
||||
inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
|
||||
ParamType ¶ms,
|
||||
bool requires_multiple_coordinates)
|
||||
{
|
||||
Nan::HandleScope scope;
|
||||
|
||||
if (args.Length() < 2)
|
||||
{
|
||||
Nan::ThrowTypeError("Two arguments required");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!args[0]->IsObject())
|
||||
{
|
||||
Nan::ThrowTypeError("First arg must be an object");
|
||||
return false;
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> obj = Nan::To<v8::Object>(args[0]).ToLocalChecked();
|
||||
|
||||
v8::Local<v8::Value> coordinates = obj->Get(Nan::New("coordinates").ToLocalChecked());
|
||||
if (coordinates->IsUndefined())
|
||||
{
|
||||
Nan::ThrowError("Must provide a coordinates property");
|
||||
return false;
|
||||
}
|
||||
else if (coordinates->IsArray())
|
||||
{
|
||||
auto coordinates_array = v8::Local<v8::Array>::Cast(coordinates);
|
||||
if (coordinates_array->Length() < 2 && requires_multiple_coordinates)
|
||||
{
|
||||
Nan::ThrowError("At least two coordinates must be provided");
|
||||
return false;
|
||||
}
|
||||
else if (!requires_multiple_coordinates && coordinates_array->Length() != 1)
|
||||
{
|
||||
Nan::ThrowError("Exactly one coordinate pair must be provided");
|
||||
return false;
|
||||
}
|
||||
auto maybe_coordinates = parseCoordinateArray(coordinates_array);
|
||||
if (maybe_coordinates)
|
||||
{
|
||||
std::copy(maybe_coordinates->begin(),
|
||||
maybe_coordinates->end(),
|
||||
std::back_inserter(params->coordinates));
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!coordinates->IsUndefined())
|
||||
{
|
||||
BOOST_ASSERT(!coordinates->IsArray());
|
||||
Nan::ThrowError("Coordinates must be an array of (lon/lat) pairs");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (obj->Has(Nan::New("bearings").ToLocalChecked()))
|
||||
{
|
||||
v8::Local<v8::Value> bearings = obj->Get(Nan::New("bearings").ToLocalChecked());
|
||||
|
||||
if (!bearings->IsArray())
|
||||
{
|
||||
Nan::ThrowError("Bearings must be an array of arrays of numbers");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto bearings_array = v8::Local<v8::Array>::Cast(bearings);
|
||||
|
||||
if (bearings_array->Length() != params->coordinates.size())
|
||||
{
|
||||
Nan::ThrowError("Bearings array must have the same length as coordinates array");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < bearings_array->Length(); ++i)
|
||||
{
|
||||
v8::Local<v8::Value> bearing_raw = bearings_array->Get(i);
|
||||
|
||||
if (bearing_raw->IsNull())
|
||||
{
|
||||
params->bearings.emplace_back();
|
||||
}
|
||||
else if (bearing_raw->IsArray())
|
||||
{
|
||||
auto bearing_pair = v8::Local<v8::Array>::Cast(bearing_raw);
|
||||
if (bearing_pair->Length() == 2)
|
||||
{
|
||||
if (!bearing_pair->Get(0)->IsNumber() || !bearing_pair->Get(1)->IsNumber())
|
||||
{
|
||||
Nan::ThrowError("Bearing values need to be numbers in range 0..360");
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto bearing = static_cast<short>(bearing_pair->Get(0)->NumberValue());
|
||||
const auto range = static_cast<short>(bearing_pair->Get(1)->NumberValue());
|
||||
|
||||
if (bearing < 0 || bearing > 360 || range < 0 || range > 180)
|
||||
{
|
||||
Nan::ThrowError("Bearing values need to be in range 0..360, 0..180");
|
||||
return false;
|
||||
}
|
||||
|
||||
params->bearings.push_back(osrm::Bearing{bearing, range});
|
||||
}
|
||||
else
|
||||
{
|
||||
Nan::ThrowError("Bearing must be an array of [bearing, range] or null");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Nan::ThrowError("Bearing must be an array of [bearing, range] or null");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (obj->Has(Nan::New("hints").ToLocalChecked()))
|
||||
{
|
||||
v8::Local<v8::Value> hints = obj->Get(Nan::New("hints").ToLocalChecked());
|
||||
|
||||
if (!hints->IsArray())
|
||||
{
|
||||
Nan::ThrowError("Hints must be an array of strings/null");
|
||||
return false;
|
||||
}
|
||||
|
||||
v8::Local<v8::Array> hints_array = v8::Local<v8::Array>::Cast(hints);
|
||||
|
||||
if (hints_array->Length() != params->coordinates.size())
|
||||
{
|
||||
Nan::ThrowError("Hints array must have the same length as coordinates array");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < hints_array->Length(); ++i)
|
||||
{
|
||||
v8::Local<v8::Value> hint = hints_array->Get(i);
|
||||
if (hint->IsString())
|
||||
{
|
||||
if (hint->ToString()->Length() == 0)
|
||||
{
|
||||
Nan::ThrowError("Hint cannot be an empty string");
|
||||
return false;
|
||||
}
|
||||
|
||||
params->hints.push_back(
|
||||
osrm::engine::Hint::FromBase64(*v8::String::Utf8Value(hint)));
|
||||
}
|
||||
else if (hint->IsNull())
|
||||
{
|
||||
params->hints.emplace_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
Nan::ThrowError("Hint must be null or string");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (obj->Has(Nan::New("radiuses").ToLocalChecked()))
|
||||
{
|
||||
v8::Local<v8::Value> radiuses = obj->Get(Nan::New("radiuses").ToLocalChecked());
|
||||
|
||||
if (!radiuses->IsArray())
|
||||
{
|
||||
Nan::ThrowError("Radiuses must be an array of non-negative doubles or null");
|
||||
return false;
|
||||
}
|
||||
|
||||
v8::Local<v8::Array> radiuses_array = v8::Local<v8::Array>::Cast(radiuses);
|
||||
|
||||
if (radiuses_array->Length() != params->coordinates.size())
|
||||
{
|
||||
Nan::ThrowError("Radiuses array must have the same length as coordinates array");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < radiuses_array->Length(); ++i)
|
||||
{
|
||||
v8::Local<v8::Value> radius = radiuses_array->Get(i);
|
||||
if (radius->IsNull())
|
||||
{
|
||||
params->radiuses.emplace_back();
|
||||
}
|
||||
else if (radius->IsNumber() && radius->NumberValue() >= 0)
|
||||
{
|
||||
params->radiuses.push_back(static_cast<double>(radius->NumberValue()));
|
||||
}
|
||||
else
|
||||
{
|
||||
Nan::ThrowError("Radius must be non-negative double or null");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (obj->Has(Nan::New("generate_hints").ToLocalChecked()))
|
||||
{
|
||||
v8::Local<v8::Value> generate_hints = obj->Get(Nan::New("generate_hints").ToLocalChecked());
|
||||
|
||||
if (!generate_hints->IsBoolean())
|
||||
{
|
||||
Nan::ThrowError("generate_hints must be of type Boolean");
|
||||
return false;
|
||||
}
|
||||
|
||||
params->generate_hints = generate_hints->BooleanValue();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename ParamType>
|
||||
inline bool parseCommonParameters(const v8::Local<v8::Object> &obj, ParamType ¶ms)
|
||||
{
|
||||
if (obj->Has(Nan::New("steps").ToLocalChecked()))
|
||||
{
|
||||
auto steps = obj->Get(Nan::New("steps").ToLocalChecked());
|
||||
if (steps->IsBoolean())
|
||||
{
|
||||
params->steps = steps->BooleanValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
Nan::ThrowError("'steps' param must be a boolean");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (obj->Has(Nan::New("annotations").ToLocalChecked()))
|
||||
{
|
||||
auto annotations = obj->Get(Nan::New("annotations").ToLocalChecked());
|
||||
if (annotations->IsBoolean())
|
||||
{
|
||||
params->annotations = annotations->BooleanValue();
|
||||
}
|
||||
else if (annotations->IsArray())
|
||||
{
|
||||
v8::Local<v8::Array> annotations_array = v8::Local<v8::Array>::Cast(annotations);
|
||||
for (std::size_t i = 0; i < annotations_array->Length(); i++)
|
||||
{
|
||||
const Nan::Utf8String annotations_utf8str(annotations_array->Get(i));
|
||||
std::string annotations_str{*annotations_utf8str,
|
||||
*annotations_utf8str + annotations_utf8str.length()};
|
||||
|
||||
if (annotations_str == "duration")
|
||||
{
|
||||
params->annotations_type =
|
||||
params->annotations_type | osrm::RouteParameters::AnnotationsType::Duration;
|
||||
}
|
||||
else if (annotations_str == "nodes")
|
||||
{
|
||||
params->annotations_type =
|
||||
params->annotations_type | osrm::RouteParameters::AnnotationsType::Nodes;
|
||||
}
|
||||
else if (annotations_str == "distance")
|
||||
{
|
||||
params->annotations_type =
|
||||
params->annotations_type | osrm::RouteParameters::AnnotationsType::Distance;
|
||||
}
|
||||
else if (annotations_str == "weight")
|
||||
{
|
||||
params->annotations_type =
|
||||
params->annotations_type | osrm::RouteParameters::AnnotationsType::Weight;
|
||||
}
|
||||
else if (annotations_str == "datasources")
|
||||
{
|
||||
params->annotations_type = params->annotations_type |
|
||||
osrm::RouteParameters::AnnotationsType::Datasources;
|
||||
}
|
||||
else if (annotations_str == "speed")
|
||||
{
|
||||
params->annotations_type =
|
||||
params->annotations_type | osrm::RouteParameters::AnnotationsType::Speed;
|
||||
}
|
||||
else
|
||||
{
|
||||
Nan::ThrowError("this 'annotations' param is not supported");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Nan::ThrowError("this 'annotations' param is not supported");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (obj->Has(Nan::New("geometries").ToLocalChecked()))
|
||||
{
|
||||
v8::Local<v8::Value> geometries = obj->Get(Nan::New("geometries").ToLocalChecked());
|
||||
|
||||
if (!geometries->IsString())
|
||||
{
|
||||
Nan::ThrowError("Geometries must be a string: [polyline, polyline6, geojson]");
|
||||
return false;
|
||||
}
|
||||
const Nan::Utf8String geometries_utf8str(geometries);
|
||||
std::string geometries_str{*geometries_utf8str,
|
||||
*geometries_utf8str + geometries_utf8str.length()};
|
||||
|
||||
if (geometries_str == "polyline")
|
||||
{
|
||||
params->geometries = osrm::RouteParameters::GeometriesType::Polyline;
|
||||
}
|
||||
else if (geometries_str == "polyline6")
|
||||
{
|
||||
params->geometries = osrm::RouteParameters::GeometriesType::Polyline6;
|
||||
}
|
||||
else if (geometries_str == "geojson")
|
||||
{
|
||||
params->geometries = osrm::RouteParameters::GeometriesType::GeoJSON;
|
||||
}
|
||||
else
|
||||
{
|
||||
Nan::ThrowError("'geometries' param must be one of [polyline, polyline6, geojson]");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (obj->Has(Nan::New("overview").ToLocalChecked()))
|
||||
{
|
||||
v8::Local<v8::Value> overview = obj->Get(Nan::New("overview").ToLocalChecked());
|
||||
|
||||
if (!overview->IsString())
|
||||
{
|
||||
Nan::ThrowError("Overview must be a string: [simplified, full, false]");
|
||||
return false;
|
||||
}
|
||||
|
||||
const Nan::Utf8String overview_utf8str(overview);
|
||||
std::string overview_str{*overview_utf8str, *overview_utf8str + overview_utf8str.length()};
|
||||
|
||||
if (overview_str == "simplified")
|
||||
{
|
||||
params->overview = osrm::RouteParameters::OverviewType::Simplified;
|
||||
}
|
||||
else if (overview_str == "full")
|
||||
{
|
||||
params->overview = osrm::RouteParameters::OverviewType::Full;
|
||||
}
|
||||
else if (overview_str == "false")
|
||||
{
|
||||
params->overview = osrm::RouteParameters::OverviewType::False;
|
||||
}
|
||||
else
|
||||
{
|
||||
Nan::ThrowError("'overview' param must be one of [simplified, full, false]");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline route_parameters_ptr
|
||||
argumentsToRouteParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
|
||||
bool requires_multiple_coordinates)
|
||||
{
|
||||
route_parameters_ptr params = boost::make_unique<osrm::RouteParameters>();
|
||||
bool has_base_params = argumentsToParameter(args, params, requires_multiple_coordinates);
|
||||
if (!has_base_params)
|
||||
return route_parameters_ptr();
|
||||
|
||||
v8::Local<v8::Object> obj = Nan::To<v8::Object>(args[0]).ToLocalChecked();
|
||||
|
||||
if (obj->Has(Nan::New("continue_straight").ToLocalChecked()))
|
||||
{
|
||||
auto value = obj->Get(Nan::New("continue_straight").ToLocalChecked());
|
||||
if (!value->IsBoolean() && !value->IsNull())
|
||||
{
|
||||
Nan::ThrowError("'continue_straight' parama must be boolean or null");
|
||||
}
|
||||
if (value->IsBoolean())
|
||||
{
|
||||
params->continue_straight = value->BooleanValue();
|
||||
}
|
||||
}
|
||||
|
||||
if (obj->Has(Nan::New("alternatives").ToLocalChecked()))
|
||||
{
|
||||
auto value = obj->Get(Nan::New("alternatives").ToLocalChecked());
|
||||
if (!value->IsBoolean())
|
||||
{
|
||||
Nan::ThrowError("'alternatives' parama must be boolean");
|
||||
}
|
||||
params->alternatives = value->BooleanValue();
|
||||
}
|
||||
|
||||
bool parsedSuccessfully = parseCommonParameters(obj, params);
|
||||
if (!parsedSuccessfully)
|
||||
{
|
||||
return route_parameters_ptr();
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
inline tile_parameters_ptr
|
||||
argumentsToTileParameters(const Nan::FunctionCallbackInfo<v8::Value> &args, bool /*unused*/)
|
||||
{
|
||||
tile_parameters_ptr params = boost::make_unique<osrm::TileParameters>();
|
||||
|
||||
if (args.Length() < 2)
|
||||
{
|
||||
Nan::ThrowTypeError("Coordinate object and callback required");
|
||||
return tile_parameters_ptr();
|
||||
}
|
||||
|
||||
if (!args[0]->IsArray())
|
||||
{
|
||||
Nan::ThrowTypeError("Parameter must be an array [x, y, z]");
|
||||
return tile_parameters_ptr();
|
||||
}
|
||||
|
||||
v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(args[0]);
|
||||
|
||||
if (array->Length() != 3)
|
||||
{
|
||||
Nan::ThrowTypeError("Parameter must be an array [x, y, z]");
|
||||
return tile_parameters_ptr();
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> x = array->Get(0);
|
||||
v8::Local<v8::Value> y = array->Get(1);
|
||||
v8::Local<v8::Value> z = array->Get(2);
|
||||
|
||||
if (!x->IsUint32() && !x->IsUndefined())
|
||||
{
|
||||
Nan::ThrowError("Tile x coordinate must be unsigned interger");
|
||||
return tile_parameters_ptr();
|
||||
}
|
||||
if (!y->IsUint32() && !y->IsUndefined())
|
||||
{
|
||||
Nan::ThrowError("Tile y coordinate must be unsigned interger");
|
||||
return tile_parameters_ptr();
|
||||
}
|
||||
if (!z->IsUint32() && !z->IsUndefined())
|
||||
{
|
||||
Nan::ThrowError("Tile z coordinate must be unsigned interger");
|
||||
return tile_parameters_ptr();
|
||||
}
|
||||
|
||||
params->x = x->Uint32Value();
|
||||
params->y = y->Uint32Value();
|
||||
params->z = z->Uint32Value();
|
||||
|
||||
if (!params->IsValid())
|
||||
{
|
||||
Nan::ThrowError("Invalid tile coordinates");
|
||||
return tile_parameters_ptr();
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
inline nearest_parameters_ptr
|
||||
argumentsToNearestParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
|
||||
bool requires_multiple_coordinates)
|
||||
{
|
||||
nearest_parameters_ptr params = boost::make_unique<osrm::NearestParameters>();
|
||||
bool has_base_params = argumentsToParameter(args, params, requires_multiple_coordinates);
|
||||
if (!has_base_params)
|
||||
return nearest_parameters_ptr();
|
||||
|
||||
v8::Local<v8::Object> obj = Nan::To<v8::Object>(args[0]).ToLocalChecked();
|
||||
|
||||
if (obj->Has(Nan::New("number").ToLocalChecked()))
|
||||
{
|
||||
v8::Local<v8::Value> number = obj->Get(Nan::New("number").ToLocalChecked());
|
||||
|
||||
if (!number->IsUint32())
|
||||
{
|
||||
Nan::ThrowError("Number must be an integer greater than or equal to 1");
|
||||
return nearest_parameters_ptr();
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned number_value = static_cast<unsigned>(number->NumberValue());
|
||||
|
||||
if (number_value < 1)
|
||||
{
|
||||
Nan::ThrowError("Number must be an integer greater than or equal to 1");
|
||||
return nearest_parameters_ptr();
|
||||
}
|
||||
|
||||
params->number_of_results = static_cast<unsigned>(number->NumberValue());
|
||||
}
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
inline table_parameters_ptr
|
||||
argumentsToTableParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
|
||||
bool requires_multiple_coordinates)
|
||||
{
|
||||
table_parameters_ptr params = boost::make_unique<osrm::TableParameters>();
|
||||
bool has_base_params = argumentsToParameter(args, params, requires_multiple_coordinates);
|
||||
if (!has_base_params)
|
||||
return table_parameters_ptr();
|
||||
|
||||
v8::Local<v8::Object> obj = Nan::To<v8::Object>(args[0]).ToLocalChecked();
|
||||
|
||||
if (obj->Has(Nan::New("sources").ToLocalChecked()))
|
||||
{
|
||||
v8::Local<v8::Value> sources = obj->Get(Nan::New("sources").ToLocalChecked());
|
||||
|
||||
if (!sources->IsArray())
|
||||
{
|
||||
Nan::ThrowError("Sources must be an array of indices (or undefined)");
|
||||
return table_parameters_ptr();
|
||||
}
|
||||
|
||||
v8::Local<v8::Array> sources_array = v8::Local<v8::Array>::Cast(sources);
|
||||
for (uint32_t i = 0; i < sources_array->Length(); ++i)
|
||||
{
|
||||
v8::Local<v8::Value> source = sources_array->Get(i);
|
||||
if (source->IsUint32())
|
||||
{
|
||||
size_t source_value = static_cast<size_t>(source->NumberValue());
|
||||
if (source_value > params->coordinates.size())
|
||||
{
|
||||
Nan::ThrowError(
|
||||
"Source indices must be less than or equal to the number of coordinates");
|
||||
return table_parameters_ptr();
|
||||
}
|
||||
|
||||
params->sources.push_back(static_cast<size_t>(source->NumberValue()));
|
||||
}
|
||||
else
|
||||
{
|
||||
Nan::ThrowError("Source must be an integer");
|
||||
return table_parameters_ptr();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (obj->Has(Nan::New("destinations").ToLocalChecked()))
|
||||
{
|
||||
v8::Local<v8::Value> destinations = obj->Get(Nan::New("destinations").ToLocalChecked());
|
||||
|
||||
if (!destinations->IsArray())
|
||||
{
|
||||
Nan::ThrowError("Destinations must be an array of indices (or undefined)");
|
||||
return table_parameters_ptr();
|
||||
}
|
||||
|
||||
v8::Local<v8::Array> destinations_array = v8::Local<v8::Array>::Cast(destinations);
|
||||
for (uint32_t i = 0; i < destinations_array->Length(); ++i)
|
||||
{
|
||||
v8::Local<v8::Value> destination = destinations_array->Get(i);
|
||||
if (destination->IsUint32())
|
||||
{
|
||||
size_t destination_value = static_cast<size_t>(destination->NumberValue());
|
||||
if (destination_value > params->coordinates.size())
|
||||
{
|
||||
Nan::ThrowError("Destination indices must be less than or equal to the number "
|
||||
"of coordinates");
|
||||
return table_parameters_ptr();
|
||||
}
|
||||
|
||||
params->destinations.push_back(static_cast<size_t>(destination->NumberValue()));
|
||||
}
|
||||
else
|
||||
{
|
||||
Nan::ThrowError("Destination must be an integer");
|
||||
return table_parameters_ptr();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
inline trip_parameters_ptr
|
||||
argumentsToTripParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
|
||||
bool requires_multiple_coordinates)
|
||||
{
|
||||
trip_parameters_ptr params = boost::make_unique<osrm::TripParameters>();
|
||||
bool has_base_params = argumentsToParameter(args, params, requires_multiple_coordinates);
|
||||
if (!has_base_params)
|
||||
return trip_parameters_ptr();
|
||||
|
||||
v8::Local<v8::Object> obj = Nan::To<v8::Object>(args[0]).ToLocalChecked();
|
||||
|
||||
bool parsedSuccessfully = parseCommonParameters(obj, params);
|
||||
if (!parsedSuccessfully)
|
||||
{
|
||||
return trip_parameters_ptr();
|
||||
}
|
||||
|
||||
if (obj->Has(Nan::New("roundtrip").ToLocalChecked()))
|
||||
{
|
||||
auto roundtrip = obj->Get(Nan::New("roundtrip").ToLocalChecked());
|
||||
if (roundtrip->IsBoolean())
|
||||
{
|
||||
params->roundtrip = roundtrip->BooleanValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
Nan::ThrowError("'roundtrip' param must be a boolean");
|
||||
return trip_parameters_ptr();
|
||||
}
|
||||
}
|
||||
|
||||
if (obj->Has(Nan::New("source").ToLocalChecked()))
|
||||
{
|
||||
v8::Local<v8::Value> source = obj->Get(Nan::New("source").ToLocalChecked());
|
||||
|
||||
if (!source->IsString())
|
||||
{
|
||||
Nan::ThrowError("Source must be a string: [any, first]");
|
||||
return trip_parameters_ptr();
|
||||
}
|
||||
|
||||
std::string source_str = *v8::String::Utf8Value(source);
|
||||
|
||||
if (source_str == "first")
|
||||
{
|
||||
params->source = osrm::TripParameters::SourceType::First;
|
||||
}
|
||||
else if (source_str == "any")
|
||||
{
|
||||
params->source = osrm::TripParameters::SourceType::Any;
|
||||
}
|
||||
else
|
||||
{
|
||||
Nan::ThrowError("'source' param must be one of [any, first]");
|
||||
return trip_parameters_ptr();
|
||||
}
|
||||
}
|
||||
|
||||
if (obj->Has(Nan::New("destination").ToLocalChecked()))
|
||||
{
|
||||
v8::Local<v8::Value> destination = obj->Get(Nan::New("destination").ToLocalChecked());
|
||||
|
||||
if (!destination->IsString())
|
||||
{
|
||||
Nan::ThrowError("Destination must be a string: [any, last]");
|
||||
return trip_parameters_ptr();
|
||||
}
|
||||
|
||||
std::string destination_str = *v8::String::Utf8Value(destination);
|
||||
|
||||
if (destination_str == "last")
|
||||
{
|
||||
params->destination = osrm::TripParameters::DestinationType::Last;
|
||||
}
|
||||
else if (destination_str == "any")
|
||||
{
|
||||
params->destination = osrm::TripParameters::DestinationType::Any;
|
||||
}
|
||||
else
|
||||
{
|
||||
Nan::ThrowError("'destination' param must be one of [any, last]");
|
||||
return trip_parameters_ptr();
|
||||
}
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
inline match_parameters_ptr
|
||||
argumentsToMatchParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
|
||||
bool requires_multiple_coordinates)
|
||||
{
|
||||
match_parameters_ptr params = boost::make_unique<osrm::MatchParameters>();
|
||||
bool has_base_params = argumentsToParameter(args, params, requires_multiple_coordinates);
|
||||
if (!has_base_params)
|
||||
return match_parameters_ptr();
|
||||
|
||||
v8::Local<v8::Object> obj = Nan::To<v8::Object>(args[0]).ToLocalChecked();
|
||||
|
||||
if (obj->Has(Nan::New("timestamps").ToLocalChecked()))
|
||||
{
|
||||
v8::Local<v8::Value> timestamps = obj->Get(Nan::New("timestamps").ToLocalChecked());
|
||||
|
||||
if (!timestamps->IsArray())
|
||||
{
|
||||
Nan::ThrowError("Timestamps must be an array of integers (or undefined)");
|
||||
return match_parameters_ptr();
|
||||
}
|
||||
|
||||
v8::Local<v8::Array> timestamps_array = v8::Local<v8::Array>::Cast(timestamps);
|
||||
|
||||
if (params->coordinates.size() != timestamps_array->Length())
|
||||
{
|
||||
Nan::ThrowError("Timestamp array must have the same size as the coordinates "
|
||||
"array");
|
||||
return match_parameters_ptr();
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < timestamps_array->Length(); ++i)
|
||||
{
|
||||
v8::Local<v8::Value> timestamp = timestamps_array->Get(i);
|
||||
if (!timestamp->IsNumber())
|
||||
{
|
||||
Nan::ThrowError("Timestamps array items must be numbers");
|
||||
return match_parameters_ptr();
|
||||
}
|
||||
params->timestamps.emplace_back(static_cast<unsigned>(timestamp->NumberValue()));
|
||||
}
|
||||
}
|
||||
|
||||
bool parsedSuccessfully = parseCommonParameters(obj, params);
|
||||
if (!parsedSuccessfully)
|
||||
{
|
||||
return match_parameters_ptr();
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
} // ns node_osrm
|
||||
|
||||
#endif
|
0
lib/binding/.gitkeep
Normal file
0
lib/binding/.gitkeep
Normal file
2
lib/index.js
Normal file
2
lib/index.js
Normal file
@ -0,0 +1,2 @@
|
||||
var OSRM = module.exports = require('./binding/node-osrm.node').OSRM;
|
||||
OSRM.version = require('../package.json').version;
|
28
package.json
28
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "osrm-backend-test-suite",
|
||||
"version": "0.0.0",
|
||||
"name": "osrm",
|
||||
"version": "5.7.0",
|
||||
"private": true,
|
||||
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.",
|
||||
"dependencies": {
|
||||
@ -12,7 +12,11 @@
|
||||
"polyline": "^0.2.0",
|
||||
"request": "^2.69.0",
|
||||
"rimraf": "^2.5.4",
|
||||
"xmlbuilder": "^4.2.1"
|
||||
"xmlbuilder": "^4.2.1",
|
||||
|
||||
"nan": "^2.1.0",
|
||||
"node-cmake": "^1.2.1",
|
||||
"node-pre-gyp": "~0.6.30"
|
||||
},
|
||||
"bin": {
|
||||
"cucumber": "./node_modules/cucumber/bin/cucumber.js"
|
||||
@ -28,7 +32,10 @@
|
||||
"test": "npm run lint && node ./node_modules/cucumber/bin/cucumber.js features/ -p verify && node ./node_modules/cucumber/bin/cucumber.js features/ -p mld",
|
||||
"clean-test": "rm -rf test/cache",
|
||||
"cucumber": "./node_modules/cucumber/bin/cucumber.js",
|
||||
"build-api-docs": "./scripts/build_api_docs.sh"
|
||||
"build-api-docs": "./scripts/build_api_docs.sh",
|
||||
|
||||
"preinstall": "npm install node-pre-gyp",
|
||||
"install": "node-pre-gyp install --fallback-to-build=false"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -45,6 +52,17 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"docbox": "^1.0.2",
|
||||
"eslint": "^2.4.0"
|
||||
"eslint": "^2.4.0",
|
||||
|
||||
"aws-sdk": "~2.0.31",
|
||||
"tape": "^4.2.2"
|
||||
},
|
||||
"main": "lib/index.js",
|
||||
"binary": {
|
||||
"module_name": "node-osrm",
|
||||
"module_path": "./lib/binding/",
|
||||
"host": "https://mapbox-node-binary.s3.amazonaws.com",
|
||||
"remote_path": "./{name}/v{version}/{configuration}/",
|
||||
"package_name": "{node_abi}-{platform}-{arch}.tar.gz"
|
||||
}
|
||||
}
|
||||
|
@ -51,8 +51,8 @@ else if (process.argv.length > 2 && process.argv[2] == "dc")
|
||||
}
|
||||
else if (process.argv.length > 2)
|
||||
{
|
||||
let monaco_poly_path = process.argv[2];
|
||||
let poly_data = fs.readFileSync(monaco_poly_path, 'utf-8');
|
||||
let poly_path = process.argv[2];
|
||||
let poly_data = fs.readFileSync(poly_path, 'utf-8');
|
||||
|
||||
// lets assume there is only one ring
|
||||
// cut of name and ring number and the two END statements
|
||||
|
99
scripts/travis/build.sh
Executable file
99
scripts/travis/build.sh
Executable file
@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eu
|
||||
set -o pipefail
|
||||
|
||||
# defaults
|
||||
export ENABLE_COVERAGE=${ENABLE_COVERAGE:-"Off"}
|
||||
export BUILD_TYPE=${BUILD_TYPE:-"Release"}
|
||||
export NODE=${NODE:-4}
|
||||
|
||||
export CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
export DEPS_DIR="$(pwd)/deps"
|
||||
export PATH=${DEPS_DIR}/bin:${PATH}
|
||||
mkdir -p ${DEPS_DIR}
|
||||
|
||||
export CLANG_VERSION="${CLANG_VERSION:-4.0.0}"
|
||||
export CCACHE_VERSION=3.3.1
|
||||
export CMAKE_VERSION=3.7.2
|
||||
|
||||
source ${CURRENT_DIR}/travis_helper.sh
|
||||
|
||||
# ensure we start inside the root directory (two level up)
|
||||
cd ${CURRENT_DIR}/../../
|
||||
|
||||
if [[ ! $(which wget) ]]; then
|
||||
echo "echo wget must be installed";
|
||||
exit 1;
|
||||
fi;
|
||||
|
||||
SYSTEM_NAME=$(uname -s)
|
||||
if [[ "${SYSTEM_NAME}" == "Darwin" ]]; then
|
||||
OS_NAME="osx"
|
||||
elif [[ "${SYSTEM_NAME}" == "Linux" ]]; then
|
||||
OS_NAME="linux"
|
||||
fi
|
||||
|
||||
# FIXME This should be replaced by proper calls to mason but we currently have a chicken-egg problem
|
||||
# since we rely on osrm-backend to ship mason for us. Once we merged this into osrm-backend this will not be needed.
|
||||
CMAKE_URL="https://s3.amazonaws.com/mason-binaries/${OS_NAME}-x86_64/cmake/${CMAKE_VERSION}.tar.gz"
|
||||
echo "Downloading cmake from ${CMAKE_URL} ..."
|
||||
wget --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C ${DEPS_DIR} || exit 1
|
||||
CCACHE_URL="https://s3.amazonaws.com/mason-binaries/${OS_NAME}-x86_64/ccache/${CCACHE_VERSION}.tar.gz"
|
||||
echo "Downloading ccache from ${CCACHE_URL} ..."
|
||||
wget --quiet -O - ${CCACHE_URL} | tar --strip-components=1 -xz -C ${DEPS_DIR} || exit 1
|
||||
# install clang for linux but use the xcode version on OSX
|
||||
if [[ "${OS_NAME}" != "osx" ]]; then
|
||||
CLANG_URL="https://s3.amazonaws.com/mason-binaries/${OS_NAME}-x86_64/clang++/${CLANG_VERSION}.tar.gz"
|
||||
echo "Downloading clang from ${CLANG_URL} ..."
|
||||
wget --quiet -O - ${CLANG_URL} | tar --strip-components=1 -xz -C ${DEPS_DIR} || exit 1
|
||||
export CCOMPILER='clang'
|
||||
export CXXCOMPILER='clang++'
|
||||
export CC='clang'
|
||||
export CXX='clang++'
|
||||
fi
|
||||
|
||||
if [[ "${OS_NAME}" == "osx" ]]; then
|
||||
if [[ -f /etc/sysctl.conf ]] && [[ $(grep shmmax /etc/sysctl.conf) ]]; then
|
||||
echo "Note: found shmmax setting in /etc/sysctl.conf, not modifying"
|
||||
else
|
||||
echo "WARNING: Did not find shmmax setting in /etc/sysctl.conf, adding now (requires sudo and restarting)..."
|
||||
sudo sysctl -w kern.sysv.shmmax=4294967296
|
||||
sudo sysctl -w kern.sysv.shmall=1048576
|
||||
sudo sysctl -w kern.sysv.shmseg=128
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
echo "Now build node-osrm and dependencies"
|
||||
export VERBOSE=1
|
||||
if [[ "${ENABLE_COVERAGE}" == "On" ]]; then
|
||||
mapbox_time "make" make -j4 coverage
|
||||
else
|
||||
mkdir -p build
|
||||
pushd build
|
||||
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DENABLE_NODE_BINDINGS=On -DENABLE_MASON=On
|
||||
mapbox_time "make" make -j4
|
||||
popd
|
||||
fi
|
||||
|
||||
## run tests, with backtrace support
|
||||
#if [[ "${OS_NAME}" == "linux" ]]; then
|
||||
# ulimit -c unlimited -S
|
||||
# RESULT=0
|
||||
# mapbox_time "make-test" make tests || RESULT=$?
|
||||
# for i in $(find ./ -maxdepth 1 -name 'core*' -print);
|
||||
# do gdb $(which node) $i -ex "thread apply all bt" -ex "set pagination 0" -batch;
|
||||
# done;
|
||||
# if [[ ${RESULT} != 0 ]]; then exit $RESULT; fi
|
||||
#else
|
||||
# # todo: coredump support on OS X
|
||||
# RESULT=0
|
||||
# mapbox_time "make-test" make tests || RESULT=$?
|
||||
# if [[ ${RESULT} != 0 ]]; then exit $RESULT; fi
|
||||
#fi
|
||||
|
||||
|
||||
set +eu
|
||||
set +o pipefail
|
27
scripts/travis/is_pr_merge.sh
Executable file
27
scripts/travis/is_pr_merge.sh
Executable file
@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu pipefail
|
||||
|
||||
: '
|
||||
|
||||
This script is designed to detect if a gitsha represents a normal
|
||||
push commit (to any branch) or whether it represents travis attempting
|
||||
to merge between the origin and the upstream branch.
|
||||
|
||||
For more details see: https://docs.travis-ci.com/user/pull-requests
|
||||
|
||||
'
|
||||
|
||||
# Get the commit message via git log
|
||||
# This should always be the exact text the developer provided
|
||||
COMMIT_LOG=$(git log --format=%B --no-merges -n 1 | tr -d '\n')
|
||||
|
||||
# Get the commit message via git show
|
||||
# If the gitsha represents a merge then this will
|
||||
# look something like "Merge e3b1981 into 615d2a3"
|
||||
# Otherwise it will be the same as the "git log" output
|
||||
COMMIT_SHOW=$(git show -s --format=%B | tr -d '\n')
|
||||
|
||||
if [[ "${COMMIT_LOG}" != "${COMMIT_SHOW}" ]]; then
|
||||
echo true
|
||||
fi
|
51
scripts/travis/publish.sh
Executable file
51
scripts/travis/publish.sh
Executable file
@ -0,0 +1,51 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
set -o pipefail
|
||||
|
||||
# should be set for debug builds
|
||||
export NPM_FLAGS=${NPM_FLAGS:-}
|
||||
|
||||
echo "node version is:"
|
||||
which node
|
||||
node -v
|
||||
|
||||
echo "dumping binary meta..."
|
||||
./node_modules/.bin/node-pre-gyp reveal ${NPM_FLAGS}
|
||||
|
||||
# enforce that binary has proper ORIGIN flags so that
|
||||
# it can portably find libtbb.so in the same directory
|
||||
if [[ $(uname -s) == 'Linux' ]]; then
|
||||
readelf -d ./lib/binding/node-osrm.node > readelf-output.txt
|
||||
if grep -q 'Flags: ORIGIN' readelf-output.txt; then
|
||||
echo "Found ORIGIN flag in readelf output"
|
||||
cat readelf-output.txt
|
||||
else
|
||||
echo "*** Error: Could not found ORIGIN flag in readelf output"
|
||||
cat readelf-output.txt
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "determining publishing status..."
|
||||
|
||||
if [[ $(./scripts/travis/is_pr_merge.sh) ]]; then
|
||||
echo "Skipping publishing because this is a PR merge commit"
|
||||
else
|
||||
echo "This is a push commit, continuing to package..."
|
||||
./node_modules/.bin/node-pre-gyp package ${NPM_FLAGS}
|
||||
|
||||
export COMMIT_MESSAGE=$(git log --format=%B --no-merges | head -n 1 | tr -d '\n')
|
||||
echo "Commit message: ${COMMIT_MESSAGE}"
|
||||
|
||||
if [[ ${COMMIT_MESSAGE} =~ "[publish binary]" ]]; then
|
||||
echo "Publishing"
|
||||
./node_modules/.bin/node-pre-gyp publish ${NPM_FLAGS}
|
||||
elif [[ ${COMMIT_MESSAGE} =~ "[republish binary]" ]]; then
|
||||
echo "*** Error: Republishing is disallowed for this repository"
|
||||
exit 1
|
||||
#./node_modules/.bin/node-pre-gyp unpublish publish ${NPM_FLAGS}
|
||||
else
|
||||
echo "Skipping publishing"
|
||||
fi;
|
||||
fi
|
75
scripts/travis/travis_helper.sh
Normal file
75
scripts/travis/travis_helper.sh
Normal file
@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# This script is sourced, so do not set -e or -o pipefail here. Doing so would
|
||||
# bleed into Travis' wrapper script, which messes with their workflow, e.g.
|
||||
# preventing after_failure scripts to be triggered.
|
||||
|
||||
function mapbox_time_start {
|
||||
local name=$1
|
||||
mapbox_timer_name=$name
|
||||
|
||||
mapbox_fold start $name
|
||||
|
||||
mapbox_timer_id=$(printf %08x $(( RANDOM * RANDOM )))
|
||||
eval "mapbox_start_time_$mapbox_timer_id=$(mapbox_nanoseconds)"
|
||||
echo -en "travis_time:start:$mapbox_timer_id\n"
|
||||
}
|
||||
|
||||
function mapbox_time_finish {
|
||||
local name=${1:-$mapbox_timer_name}
|
||||
local timer_id=${2:-$mapbox_timer_id}
|
||||
local timer_start="mapbox_start_time_$timer_id"
|
||||
eval local start_time=\${$timer_start}
|
||||
local end_time=$(mapbox_nanoseconds)
|
||||
local duration=$(($end_time-$start_time))
|
||||
echo -en "travis_time:end:$timer_id:start=$start_time,finish=$end_time,duration=$duration\n"
|
||||
}
|
||||
|
||||
function mapbox_time {
|
||||
local name=$1 ; shift
|
||||
mapbox_time_start $name
|
||||
local timer_id=$mapbox_timer_id
|
||||
echo "\$ $@"
|
||||
# note: we capture the return code here
|
||||
# so that we can ensure mapbox_time_finish is called
|
||||
# and an error is trickled up correctly
|
||||
local RESULT=0
|
||||
$@ || RESULT=$?
|
||||
mapbox_time_finish $name $timer_id
|
||||
if [[ ${RESULT} != 0 ]]; then
|
||||
echo "$name failed with ${RESULT}"
|
||||
# note: we use false here instead of exit this this script is sourced
|
||||
# and exit would abort the shell which we don't want
|
||||
false
|
||||
else
|
||||
mapbox_fold end $name
|
||||
fi
|
||||
}
|
||||
|
||||
function mapbox_fold {
|
||||
local action=$1
|
||||
local name=$2
|
||||
local ANSI_CLEAR="\e[0m"
|
||||
echo -en "travis_fold:${action}:${name}\r${ANSI_CLEAR}"
|
||||
}
|
||||
|
||||
function mapbox_nanoseconds {
|
||||
local cmd="date"
|
||||
local format="+%s%N"
|
||||
local os=$(uname -s)
|
||||
|
||||
if hash gdate > /dev/null 2>&1; then
|
||||
cmd="gdate" # use gdate if available
|
||||
elif [[ "$os" = Darwin ]]; then
|
||||
format="+%s000000000" # fallback to second precision on darwin (does not support %N)
|
||||
fi
|
||||
|
||||
$cmd -u $format
|
||||
}
|
||||
|
||||
export JOBS
|
||||
export -f mapbox_fold
|
||||
export -f mapbox_nanoseconds
|
||||
export -f mapbox_time
|
||||
export -f mapbox_time_start
|
||||
export -f mapbox_time_finish
|
@ -36,7 +36,7 @@ int main(int argc, const char *argv[]) try
|
||||
// Routing machine with several services (such as Route, Table, Nearest, Trip, Match)
|
||||
OSRM osrm{config};
|
||||
|
||||
// Route in monaco
|
||||
// Match traces to the road network in our Berlin test dataset
|
||||
MatchParameters params;
|
||||
params.overview = RouteParameters::OverviewType::False;
|
||||
params.steps = false;
|
||||
@ -45,170 +45,123 @@ int main(int argc, const char *argv[]) try
|
||||
using osrm::util::FloatLatitude;
|
||||
using osrm::util::FloatLongitude;
|
||||
|
||||
// Grab trace, or: go to geojson.io, create linestring.
|
||||
// Extract coordinates: jq '.features[].geometry.coordinates[]' coordinates.json
|
||||
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.422176599502563}, FloatLatitude{43.73754595167546}});
|
||||
FloatCoordinate{FloatLongitude{13.410401344299316}, FloatLatitude{52.522749270442254}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.421715259552002}, FloatLatitude{43.73744517900973}});
|
||||
FloatCoordinate{FloatLongitude{13.410615921020508}, FloatLatitude{52.52284066124772}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.421489953994752}, FloatLatitude{43.73738316497729}});
|
||||
FloatCoordinate{FloatLongitude{13.410787582397461}, FloatLatitude{52.522932051863044}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.421286106109619}, FloatLatitude{43.737274640266}});
|
||||
FloatCoordinate{FloatLongitude{13.411259651184082}, FloatLatitude{52.52333677944541}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.420910596847533}, FloatLatitude{43.73714285999499}});
|
||||
FloatCoordinate{FloatLongitude{13.411538600921629}, FloatLatitude{52.52341511338546}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.420696020126342}, FloatLatitude{43.73699557581948}});
|
||||
FloatCoordinate{FloatLongitude{13.411903381347656}, FloatLatitude{52.52374150329884}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.42049217224121}, FloatLatitude{43.73690255404829}});
|
||||
FloatCoordinate{FloatLongitude{13.412246704101562}, FloatLatitude{52.523950391570665}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.420309782028198}, FloatLatitude{43.73672426191624}});
|
||||
FloatCoordinate{FloatLongitude{13.410637378692625}, FloatLatitude{52.52398955801103}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.420159578323363}, FloatLatitude{43.7366622471372}});
|
||||
FloatCoordinate{FloatLongitude{13.409242630004881}, FloatLatitude{52.52413316799366}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.420148849487305}, FloatLatitude{43.736623487867654}});
|
||||
FloatCoordinate{FloatLongitude{13.407998085021973}, FloatLatitude{52.52448566323317}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.419934272766113}, FloatLatitude{43.73647620241466}});
|
||||
FloatCoordinate{FloatLongitude{13.40705394744873}, FloatLatitude{52.52474676899426}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.419805526733398}, FloatLatitude{43.736228141885455}});
|
||||
FloatCoordinate{FloatLongitude{13.406410217285156}, FloatLatitude{52.5249948180297}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.419601678848267}, FloatLatitude{43.736142870841206}});
|
||||
FloatCoordinate{FloatLongitude{13.406989574432373}, FloatLatitude{52.525686736883024}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.419376373291015}, FloatLatitude{43.735956824504974}});
|
||||
FloatCoordinate{FloatLongitude{13.407375812530518}, FloatLatitude{52.52628726139225}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.419247627258301}, FloatLatitude{43.73574752168583}});
|
||||
FloatCoordinate{FloatLongitude{13.406217098236084}, FloatLatitude{52.52663973934549}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.419043779373169}, FloatLatitude{43.73566224995717}});
|
||||
FloatCoordinate{FloatLongitude{13.405036926269531}, FloatLatitude{52.52696610529863}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.418732643127442}, FloatLatitude{43.735406434042645}});
|
||||
FloatCoordinate{FloatLongitude{13.404350280761717}, FloatLatitude{52.52717497823596}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.418657541275024}, FloatLatitude{43.735321161828274}});
|
||||
FloatCoordinate{FloatLongitude{13.404221534729004}, FloatLatitude{52.5265222470087}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.418593168258667}, FloatLatitude{43.73521263337983}});
|
||||
FloatCoordinate{FloatLongitude{13.40383529663086}, FloatLatitude{52.526039219655445}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.418367862701416}, FloatLatitude{43.73508084857086}});
|
||||
FloatCoordinate{FloatLongitude{13.402740955352783}, FloatLatitude{52.526300316181675}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.418346405029297}, FloatLatitude{43.73484828643578}});
|
||||
FloatCoordinate{FloatLongitude{13.401474952697754}, FloatLatitude{52.52666584871098}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.4180567264556885}, FloatLatitude{43.734437424456566}});
|
||||
FloatCoordinate{FloatLongitude{13.400874137878418}, FloatLatitude{52.527370795712564}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.417809963226318}, FloatLatitude{43.73414284243448}});
|
||||
FloatCoordinate{FloatLongitude{13.400616645812988}, FloatLatitude{52.52780159108807}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.417863607406615}, FloatLatitude{43.73375523230292}});
|
||||
FloatCoordinate{FloatLongitude{13.399865627288817}, FloatLatitude{52.52756661231615}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.417809963226318}, FloatLatitude{43.73386376339265}});
|
||||
FloatCoordinate{FloatLongitude{13.399114608764648}, FloatLatitude{52.52744912245876}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.417895793914795}, FloatLatitude{43.73365445325776}});
|
||||
FloatCoordinate{FloatLongitude{13.39802026748657}, FloatLatitude{52.527266359833675}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.418067455291747}, FloatLatitude{43.73343739012297}});
|
||||
FloatCoordinate{FloatLongitude{13.398470878601072}, FloatLatitude{52.52648308282661}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.41803526878357}, FloatLatitude{43.73319706930599}});
|
||||
FloatCoordinate{FloatLongitude{13.398964405059813}, FloatLatitude{52.52538647154948}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.418024539947509}, FloatLatitude{43.73295674752463}});
|
||||
FloatCoordinate{FloatLongitude{13.398363590240479}, FloatLatitude{52.52542563670941}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.417906522750854}, FloatLatitude{43.73284821479115}});
|
||||
FloatCoordinate{FloatLongitude{13.39780569076538}, FloatLatitude{52.525347306354654}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.417917251586914}, FloatLatitude{43.7327551865773}});
|
||||
FloatCoordinate{FloatLongitude{13.397247791290283}, FloatLatitude{52.525190645226104}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.417434453964233}, FloatLatitude{43.73281720540258}});
|
||||
FloatCoordinate{FloatLongitude{13.396217823028564}, FloatLatitude{52.52494259729653}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.4173808097839355}, FloatLatitude{43.73307303237796}});
|
||||
FloatCoordinate{FloatLongitude{13.395531177520752}, FloatLatitude{52.52452482919627}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.41750955581665}, FloatLatitude{43.73328234454499}});
|
||||
FloatCoordinate{FloatLongitude{13.39482307434082}, FloatLatitude{52.524472607904364}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.417563199996948}, FloatLatitude{43.73352266501975}});
|
||||
FloatCoordinate{FloatLongitude{13.39359998703003}, FloatLatitude{52.5246814926995}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.41750955581665}, FloatLatitude{43.733770736756355}});
|
||||
FloatCoordinate{FloatLongitude{13.392891883850098}, FloatLatitude{52.52490343170594}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.417466640472412}, FloatLatitude{43.73409632935116}});
|
||||
FloatCoordinate{FloatLongitude{13.392398357391357}, FloatLatitude{52.5239765025348}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.417230606079102}, FloatLatitude{43.73428238146768}});
|
||||
FloatCoordinate{FloatLongitude{13.391926288604736}, FloatLatitude{52.52310177678706}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.41724133491516}, FloatLatitude{43.73405756842078}});
|
||||
FloatCoordinate{FloatLongitude{13.39184045791626}, FloatLatitude{52.52222703362077}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.4169838428497314}, FloatLatitude{43.73449168940785}});
|
||||
FloatCoordinate{FloatLongitude{13.39184045791626}, FloatLatitude{52.521169485041774}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.41701602935791}, FloatLatitude{43.734615723397525}});
|
||||
FloatCoordinate{FloatLongitude{13.39184045791626}, FloatLatitude{52.52039915585348}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.41704821586609}, FloatLatitude{43.73487929477265}});
|
||||
FloatCoordinate{FloatLongitude{13.39205503463745}, FloatLatitude{52.519681040207885}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.41725206375122}, FloatLatitude{43.734949063471895}});
|
||||
FloatCoordinate{FloatLongitude{13.392269611358643}, FloatLatitude{52.51900208371135}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.4173808097839355}, FloatLatitude{43.73533666587628}});
|
||||
FloatCoordinate{FloatLongitude{13.392527103424072}, FloatLatitude{52.51812725890996}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.41750955581665}, FloatLatitude{43.735623490040375}});
|
||||
FloatCoordinate{FloatLongitude{13.392677307128904}, FloatLatitude{52.51750050804369}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.417799234390259}, FloatLatitude{43.73577852955704}});
|
||||
FloatCoordinate{FloatLongitude{13.393385410308838}, FloatLatitude{52.51735687637764}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.4180781841278085}, FloatLatitude{43.735972328388435}});
|
||||
FloatCoordinate{FloatLongitude{13.394951820373535}, FloatLatitude{52.517474393230245}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.41850733757019}, FloatLatitude{43.73608860738618}});
|
||||
FloatCoordinate{FloatLongitude{13.396711349487305}, FloatLatitude{52.51735687637764}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.418850660324096}, FloatLatitude{43.736228141885455}});
|
||||
FloatCoordinate{FloatLongitude{13.398127555847168}, FloatLatitude{52.517696368649815}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.419086694717407}, FloatLatitude{43.73636767605958}});
|
||||
FloatCoordinate{FloatLongitude{13.399629592895508}, FloatLatitude{52.51773554066627}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.419333457946777}, FloatLatitude{43.73664674343239}});
|
||||
FloatCoordinate{FloatLongitude{13.400981426239014}, FloatLatitude{52.51829700239765}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.419633865356444}, FloatLatitude{43.73676302112054}});
|
||||
FloatCoordinate{FloatLongitude{13.403105735778809}, FloatLatitude{52.51887151395141}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.419784069061279}, FloatLatitude{43.737096349241845}});
|
||||
FloatCoordinate{FloatLongitude{13.40355634689331}, FloatLatitude{52.51966798345114}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.420030832290649}, FloatLatitude{43.73720487427631}});
|
||||
FloatCoordinate{FloatLongitude{13.404908180236816}, FloatLatitude{52.52007274110608}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.419601678848267}, FloatLatitude{43.73708084564945}});
|
||||
FloatCoordinate{FloatLongitude{13.40555191040039}, FloatLatitude{52.520529721073366}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.419333457946777}, FloatLatitude{43.73708084564945}});
|
||||
FloatCoordinate{FloatLongitude{13.407869338989258}, FloatLatitude{52.52144366674759}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.419043779373169}, FloatLatitude{43.737158363571325}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.418915033340454}, FloatLatitude{43.737305647346446}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.41848587989807}, FloatLatitude{43.7374916894919}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.418271303176879}, FloatLatitude{43.73746843425534}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.417960166931152}, FloatLatitude{43.73744517900973}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.417885065078735}, FloatLatitude{43.737212626056944}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.417563199996948}, FloatLatitude{43.73703433484817}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.4173057079315186}, FloatLatitude{43.73692580950463}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.417144775390625}, FloatLatitude{43.7367707729584}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.416973114013672}, FloatLatitude{43.73653821738638}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.416855096817017}, FloatLatitude{43.73639868360965}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.4167799949646}, FloatLatitude{43.736142870841206}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.41675853729248}, FloatLatitude{43.735848297208605}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.416619062423706}, FloatLatitude{43.73567000193752}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.416543960571288}, FloatLatitude{43.735406434042645}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.416479587554932}, FloatLatitude{43.73529790574875}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.416415214538574}, FloatLatitude{43.73515061703527}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.416350841522218}, FloatLatitude{43.73490255101476}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.416340112686156}, FloatLatitude{43.73475526132885}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.416222095489501}, FloatLatitude{43.73446068087028}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.416243553161621}, FloatLatitude{43.73430563794159}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.416050434112548}, FloatLatitude{43.73403431185051}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.415814399719239}, FloatLatitude{43.73382500231174}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.415750026702881}, FloatLatitude{43.73354592178871}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.415513992309569}, FloatLatitude{43.73347615145474}});
|
||||
params.coordinates.push_back(
|
||||
FloatCoordinate{FloatLongitude{7.415342330932617}, FloatLatitude{43.733251335381205}});
|
||||
FloatCoordinate{FloatLongitude{13.408942222595215}, FloatLatitude{52.52203119321206}});
|
||||
|
||||
TIMER_START(routes);
|
||||
auto NUM = 100;
|
||||
|
54
src/nodejs/CMakeLists.txt
Normal file
54
src/nodejs/CMakeLists.txt
Normal file
@ -0,0 +1,54 @@
|
||||
# node-cmake requires CMake 3.1 features; for the osrm project we only
|
||||
# require CMake 2.8.11 so that we can build e.g. on Trusty by default.
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
|
||||
message(STATUS "Building node-osrm")
|
||||
|
||||
set(BINDING_DIR "${PROJECT_SOURCE_DIR}/lib/binding")
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/nodejs")
|
||||
include(FindNodeJS)
|
||||
|
||||
set(NodeJS_CXX_STANDARD 14 CACHE INTERNAL "Use C++14" FORCE)
|
||||
set(NodeJS_DOWNLOAD ON CACHE INTERNAL "Download node.js sources" FORCE)
|
||||
set(NodeJS_USE_CLANG_STDLIB OFF CACHE BOOL "Don't use libc++ by default" FORCE)
|
||||
|
||||
find_package(NodeJS REQUIRED)
|
||||
add_nodejs_module(node-osrm node_osrm.cpp)
|
||||
target_link_libraries(node-osrm osrm)
|
||||
|
||||
# node-osrm artifacts in ${BINDING_DIR} to depend targets on
|
||||
set(ARTIFACTS "")
|
||||
|
||||
set(OSRM_BINARIES osrm-extract osrm-contract osrm-routed osrm-datastore osrm-components)
|
||||
foreach(binary ${OSRM_BINARIES})
|
||||
add_custom_command(OUTPUT ${BINDING_DIR}/${binary}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${binary}> ${BINDING_DIR}
|
||||
DEPENDS ${binary} ${BINDING_DIR})
|
||||
list(APPEND ARTIFACTS "${BINDING_DIR}/${binary}")
|
||||
endforeach(binary)
|
||||
|
||||
# For mason-enabled builds we copy over tbb's shared objects for packaging.
|
||||
# TODO: consider using statically linked tbb library (for node-osrm only!)
|
||||
if (ENABLE_MASON)
|
||||
foreach(libpath ${MASON_PACKAGE_tbb_LIBRARY_DIRS})
|
||||
file(GLOB TBBGlob ${libpath}/*.*)
|
||||
foreach(filepath ${TBBGlob})
|
||||
get_filename_component(filename ${filepath} NAME)
|
||||
add_custom_command(OUTPUT "${BINDING_DIR}/${filename}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${filepath} ${BINDING_DIR}
|
||||
DEPENDS ${filepath} ${BINDING_DIR})
|
||||
list(APPEND ARTIFACTS "${BINDING_DIR}/${filename}")
|
||||
endforeach()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
|
||||
add_custom_command(OUTPUT ${BINDING_DIR}/node-osrm.node
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:node-osrm> ${BINDING_DIR}
|
||||
DEPENDS node-osrm ${BINDING_DIR})
|
||||
list(APPEND ARTIFACTS "${BINDING_DIR}/node-osrm.node")
|
||||
|
||||
|
||||
message(STATUS "node-osrm artifacts will be copied to: ${BINDING_DIR}")
|
||||
add_custom_target(copy_artifacts ALL DEPENDS ${ARTIFACTS})
|
507
src/nodejs/node_osrm.cpp
Normal file
507
src/nodejs/node_osrm.cpp
Normal file
@ -0,0 +1,507 @@
|
||||
#include "osrm/engine_config.hpp"
|
||||
#include "osrm/osrm.hpp"
|
||||
|
||||
#include "osrm/match_parameters.hpp"
|
||||
#include "osrm/nearest_parameters.hpp"
|
||||
#include "osrm/route_parameters.hpp"
|
||||
#include "osrm/table_parameters.hpp"
|
||||
#include "osrm/tile_parameters.hpp"
|
||||
#include "osrm/trip_parameters.hpp"
|
||||
|
||||
#include <exception>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "nodejs/node_osrm.hpp"
|
||||
#include "nodejs/node_osrm_support.hpp"
|
||||
|
||||
namespace node_osrm
|
||||
{
|
||||
|
||||
Engine::Engine(osrm::EngineConfig &config) : Base(), this_(std::make_shared<osrm::OSRM>(config)) {}
|
||||
|
||||
Nan::Persistent<v8::Function> &Engine::constructor()
|
||||
{
|
||||
static Nan::Persistent<v8::Function> init;
|
||||
return init;
|
||||
}
|
||||
|
||||
NAN_MODULE_INIT(Engine::Init)
|
||||
{
|
||||
const auto whoami = Nan::New("OSRM").ToLocalChecked();
|
||||
|
||||
auto fnTp = Nan::New<v8::FunctionTemplate>(New);
|
||||
fnTp->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
fnTp->SetClassName(whoami);
|
||||
|
||||
SetPrototypeMethod(fnTp, "route", route);
|
||||
SetPrototypeMethod(fnTp, "nearest", nearest);
|
||||
SetPrototypeMethod(fnTp, "table", table);
|
||||
SetPrototypeMethod(fnTp, "tile", tile);
|
||||
SetPrototypeMethod(fnTp, "match", match);
|
||||
SetPrototypeMethod(fnTp, "trip", trip);
|
||||
|
||||
const auto fn = Nan::GetFunction(fnTp).ToLocalChecked();
|
||||
|
||||
constructor().Reset(fn);
|
||||
|
||||
Nan::Set(target, whoami, fn);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* The `OSRM` method is the main constructor for creating an OSRM instance. An OSRM instance
|
||||
* requires a `.osrm` network,
|
||||
* which is prepared by the OSRM Backend C++ library. Once you have a complete `network.osrm` file,
|
||||
* you can calculate
|
||||
* networks in javascript with this library using the methods below. To create an OSRM instance with
|
||||
* your network
|
||||
* you need to construct an instance like this:
|
||||
*
|
||||
* ```javascript
|
||||
* var osrm = new OSRM('network.osrm');
|
||||
* ```
|
||||
*
|
||||
* #### Methods
|
||||
*
|
||||
* | Service | Description |
|
||||
* |-----------------------------|-----------------------------------------------------------|
|
||||
* | [`osrm.route`](#route) | shortest path between given coordinates |
|
||||
* | [`osrm.nearest`](#nearest) | returns the nearest street segment for a given coordinate |
|
||||
* | [`osrm.table`](#table) | computes distance tables for given coordinates |
|
||||
* | [`osrm.match`](#match) | matches given coordinates to the road network |
|
||||
* | [`osrm.trip`](#trip) | computes the shortest trip between given coordinates |
|
||||
* | [`osrm.tile`](#tile) | Return vector tiles containing debugging info |
|
||||
*
|
||||
* #### General Options
|
||||
*
|
||||
* Each OSRM method (except for `OSRM.tile()`) has set of general options as well as unique options,
|
||||
* outlined below.
|
||||
*
|
||||
* | Option | Values | Description
|
||||
* | Format |
|
||||
* | ----------- | ------------------------------------------------------- |
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* | ------------------------------------------------------------------------------ |
|
||||
* | coordinates | `array` of `coordinate` elements: `[{coordinate}, ...]` | The coordinates this
|
||||
* request will use. | `array` with
|
||||
* `[{lon},{lat}]` values, in decimal degrees |
|
||||
* | bearings | `array` of `bearing` elements: `[{bearing}, ...]` | Limits the search to
|
||||
* segments with given bearing in degrees towards true north in clockwise direction. | `null` or
|
||||
* `array` with `[{value},{range}]` `integer 0 .. 360,integer 0 .. 180` |
|
||||
* | radiuses | `array` of `radius` elements: `[{radius}, ...]` | Limits the search to
|
||||
* given radius in meters. | `null` or
|
||||
* `double >= 0` or `unlimited` (default) |
|
||||
* | hints | `array` of `hint` elements: `[{hint}, ...]` | Hint to derive position
|
||||
* in street network. | Base64 `string`
|
||||
* |
|
||||
*
|
||||
* @class OSRM
|
||||
*
|
||||
*/
|
||||
NAN_METHOD(Engine::New)
|
||||
{
|
||||
if (info.IsConstructCall())
|
||||
{
|
||||
try
|
||||
{
|
||||
auto config = argumentsToEngineConfig(info);
|
||||
if (!config)
|
||||
return;
|
||||
|
||||
auto *const self = new Engine(*config);
|
||||
self->Wrap(info.This());
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
return Nan::ThrowTypeError(ex.what());
|
||||
}
|
||||
|
||||
info.GetReturnValue().Set(info.This());
|
||||
}
|
||||
else
|
||||
{
|
||||
return Nan::ThrowTypeError(
|
||||
"Cannot call constructor as function, you need to use 'new' keyword");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ParameterParser, typename ServiceMemFn>
|
||||
inline void async(const Nan::FunctionCallbackInfo<v8::Value> &info,
|
||||
ParameterParser argsToParams,
|
||||
ServiceMemFn service,
|
||||
bool requires_multiple_coordinates)
|
||||
{
|
||||
auto params = argsToParams(info, requires_multiple_coordinates);
|
||||
if (!params)
|
||||
return;
|
||||
|
||||
BOOST_ASSERT(params->IsValid());
|
||||
|
||||
if (!info[info.Length() - 1]->IsFunction())
|
||||
return Nan::ThrowTypeError("last argument must be a callback function");
|
||||
|
||||
auto *const self = Nan::ObjectWrap::Unwrap<Engine>(info.Holder());
|
||||
using ParamPtr = decltype(params);
|
||||
|
||||
struct Worker final : Nan::AsyncWorker
|
||||
{
|
||||
using Base = Nan::AsyncWorker;
|
||||
|
||||
Worker(std::shared_ptr<osrm::OSRM> osrm_,
|
||||
ParamPtr params_,
|
||||
ServiceMemFn service,
|
||||
Nan::Callback *callback)
|
||||
: Base(callback), osrm{std::move(osrm_)}, service{std::move(service)},
|
||||
params{std::move(params_)}
|
||||
{
|
||||
}
|
||||
|
||||
void Execute() override try
|
||||
{
|
||||
const auto status = ((*osrm).*(service))(*params, result);
|
||||
ParseResult(status, result);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
SetErrorMessage(e.what());
|
||||
}
|
||||
|
||||
void HandleOKCallback() override
|
||||
{
|
||||
Nan::HandleScope scope;
|
||||
|
||||
const constexpr auto argc = 2u;
|
||||
v8::Local<v8::Value> argv[argc] = {Nan::Null(), render(result)};
|
||||
|
||||
callback->Call(argc, argv);
|
||||
}
|
||||
|
||||
// Keeps the OSRM object alive even after shutdown until we're done with callback
|
||||
std::shared_ptr<osrm::OSRM> osrm;
|
||||
ServiceMemFn service;
|
||||
const ParamPtr params;
|
||||
|
||||
// All services return json::Object .. except for Tile!
|
||||
using ObjectOrString =
|
||||
typename std::conditional<std::is_same<ParamPtr, tile_parameters_ptr>::value,
|
||||
std::string,
|
||||
osrm::json::Object>::type;
|
||||
|
||||
ObjectOrString result;
|
||||
};
|
||||
|
||||
auto *callback = new Nan::Callback{info[info.Length() - 1].As<v8::Function>()};
|
||||
Nan::AsyncQueueWorker(new Worker{self->this_, std::move(params), service, callback});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fastest route between two or more coordinates while visiting the waypoints in order.
|
||||
*
|
||||
* @name route
|
||||
* @memberof OSRM
|
||||
* @param {Object} options Object literal containing parameters for the route query.
|
||||
* @param {Boolean} [options.alternatives=false] Search for alternative routes and return as well.
|
||||
* *Please note that even if an alternative route is requested, a result cannot be guaranteed.*
|
||||
* @param {Boolean} [options.steps=false] Return route steps for each route leg.
|
||||
* @param {Boolean} or {Array} [options.annotations=false] Return annotations for each route leg.
|
||||
* Can be `false`, `true` or an array with strings of `duration`, `nodes`, `distance`, `weight`,
|
||||
* `datasources`, `speed`.
|
||||
* @param {String} [options.geometries=polyline] Returned route geometry format (influences overview
|
||||
* and per step). Can also be `geojson`.
|
||||
* @param {String} [options.overview=simplified] Add overview geometry either `full`, `simplified`
|
||||
* according to highest zoom level it could be display on, or not at all (`false`).
|
||||
* @param {Boolean} [options.continue_straight] Forces the route to keep going straight at waypoints
|
||||
* and don't do a uturn even if it would be faster. Default value depends on the profile.
|
||||
* `null`/`true`/`false`
|
||||
* @param {Function} callback
|
||||
*
|
||||
* @returns {Object} An array of [Waypoint](#waypoint) objects representing all waypoints in order
|
||||
* AND an array of [`Route`](#route) objects ordered by descending recommendation rank.
|
||||
*
|
||||
* @example
|
||||
* var osrm = new OSRM("berlin-latest.osrm");
|
||||
* osrm.route({coordinates: [[52.519930,13.438640], [52.513191,13.415852]]}, function(err, result) {
|
||||
* if(err) throw err;
|
||||
* console.log(result.waypoints); // array of Waypoint objects representing all waypoints in order
|
||||
* console.log(result.routes); // array of Route objects ordered by descending recommendation rank
|
||||
* });
|
||||
*/
|
||||
NAN_METHOD(Engine::route) //
|
||||
{
|
||||
async(info, &argumentsToRouteParameter, &osrm::OSRM::Route, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Snaps a coordinate to the street network and returns the nearest n matches.
|
||||
*
|
||||
* Note: `coordinates` in the general options only supports a single `{longitude},{latitude}` entry.
|
||||
*
|
||||
* @name nearest
|
||||
* @memberof OSRM
|
||||
* @param {Object} options - Object literal containing parameters for the nearest query.
|
||||
* @param {Number} [options.number=1] Number of nearest segments that should be returned.
|
||||
* Must be an integer greater than or equal to `1`.
|
||||
* @param {Function} callback
|
||||
*
|
||||
* @returns {Object} containing `waypoints`.
|
||||
* **`waypoints`**: array of [`Ẁaypoint`](#waypoint) objects sorted by distance to the input
|
||||
* coordinate.
|
||||
* Each object has an additional `distance` property, which is the distance in meters to the
|
||||
* supplied
|
||||
* input coordinate.
|
||||
*
|
||||
* @example
|
||||
* var osrm = new OSRM('network.osrm');
|
||||
* var options = {
|
||||
* coordinates: [[13.388860,52.517037]],
|
||||
* number: 3,
|
||||
* bearings: [[0,20]]
|
||||
* };
|
||||
* osrm.nearest(options, function(err, response) {
|
||||
* console.log(response.waypoints); // array of Waypoint objects
|
||||
* });
|
||||
*/
|
||||
NAN_METHOD(Engine::nearest) //
|
||||
{
|
||||
async(info, &argumentsToNearestParameter, &osrm::OSRM::Nearest, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes duration tables for the given locations. Allows for both symmetric and asymmetric
|
||||
* tables.
|
||||
*
|
||||
* @name table
|
||||
* @memberof OSRM
|
||||
* @param {Object} options - Object literal containing parameters for the table query.
|
||||
* @param {Array} [options.sources] An array of `index` elements (`0 <= integer < #coordinates`) to
|
||||
* use
|
||||
* location with given index as source. Default is to use all.
|
||||
* @param {Array} [options.destinations] An array of `index` elements (`0 <= integer <
|
||||
* #coordinates`) to use location with given index as destination. Default is to use all.
|
||||
* @param {Function} callback
|
||||
*
|
||||
* @returns {Object} containing `durations`, `sources`, and `destinations`.
|
||||
* **`durations`**: array of arrays that stores the matrix in row-major order. `durations[i][j]`
|
||||
* gives the travel time from the i-th waypoint to the j-th waypoint. Values are given in seconds.
|
||||
* **`sources`**: array of [`Ẁaypoint`](#waypoint) objects describing all sources in order.
|
||||
* **`destinations`**: array of [`Ẁaypoint`](#waypoint) objects describing all destinations in
|
||||
* order.
|
||||
*
|
||||
* @example
|
||||
* var osrm = new OSRM('network.osrm');
|
||||
* var options = {
|
||||
* coordinates: [
|
||||
* [13.388860,52.517037],
|
||||
* [13.397634,52.529407],
|
||||
* [13.428555,52.523219]
|
||||
* ]
|
||||
* };
|
||||
* osrm.table(options, function(err, response) {
|
||||
* console.log(response.durations); // array of arrays, matrix in row-major order
|
||||
* console.log(response.sources); // array of Waypoint objects
|
||||
* console.log(response.destinations); // array of Waypoint objects
|
||||
* });
|
||||
*/
|
||||
NAN_METHOD(Engine::table) //
|
||||
{
|
||||
async(info, &argumentsToTableParameter, &osrm::OSRM::Table, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* This generates [Mapbox Vector Tiles](https://mapbox.com/vector-tiles) that can be viewed with a
|
||||
* vector-tile capable slippy-map viewer. The tiles contain road geometries and metadata that can
|
||||
* be used to examine the routing graph. The tiles are generated directly from the data in-memory,
|
||||
* so are in sync with actual routing results, and let you examine which roads are actually
|
||||
* routable,
|
||||
* and what weights they have applied.
|
||||
*
|
||||
* @name tile
|
||||
* @memberof OSRM
|
||||
* @param {Array} ZXY - an array consisting of `x`, `y`, and `z` values representing tile
|
||||
* coordinates like
|
||||
* [wiki.openstreetmap.org/wiki/Slippy_map_tilenames](https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames)
|
||||
* and are supported by vector tile viewers like [Mapbox GL
|
||||
* JS](https://www.mapbox.com/mapbox-gl-js/api/.
|
||||
* @param {Function} callback
|
||||
*
|
||||
* @returns {Buffer} contains a Protocol Buffer encoded vector tile.
|
||||
*
|
||||
* @example
|
||||
* var osrm = new OSRM('network.osrm');
|
||||
* osrm.tile([0, 0, 0], function(err, response) {
|
||||
* if (err) throw err;
|
||||
* fs.writeFileSync('./tile.vector.pbf', response); // write the buffer to a file
|
||||
* });
|
||||
*/
|
||||
NAN_METHOD(Engine::tile)
|
||||
{
|
||||
async(info, &argumentsToTileParameters, &osrm::OSRM::Tile, {/*unused*/});
|
||||
}
|
||||
|
||||
/**
|
||||
* Map matching matches given GPS points to the road network in the most plausible way.
|
||||
* Please note the request might result multiple sub-traces. Large jumps in the timestamps
|
||||
* (>60s) or improbable transitions lead to trace splits if a complete matching could
|
||||
* not be found. The algorithm might not be able to match all points. Outliers are removed
|
||||
* if they can not be matched successfully.
|
||||
*
|
||||
* @name match
|
||||
* @memberof OSRM
|
||||
* @param {Object} options - Object literal containing parameters for the match query.
|
||||
* @param {Boolean} [options.steps=false] Return route steps for each route.
|
||||
* @param {Boolean} or {Array} [options.annotations=false] Return annotations for each route leg.
|
||||
* Can be `false`, `true` or an array with strings of `duration`, `nodes`, `distance`, `weight`,
|
||||
* `datasources`, `speed`.
|
||||
* @param {String} [options.geometries=polyline] Returned route geometry format (influences overview
|
||||
* and per step). Can also be `geojson`.
|
||||
* @param {String} [options.overview=simplified] Add overview geometry either `full`, `simplified`
|
||||
* according to highest zoom level it could be display on, or not at all (`false`).
|
||||
* @param {Array<Number>} [options.timestamps] Timestamp of the input location (integers, UNIX-like
|
||||
* timestamp).
|
||||
* @param {Array} [options.radiuses] Standard deviation of GPS precision used for map matching.
|
||||
* If applicable use GPS accuracy (`double >= 0`, default `5m`).
|
||||
* @param {Function} callback
|
||||
*
|
||||
* @returns {Object} containing `tracepoints` and `matchings`.
|
||||
* **`tracepoints`** Array of [`Ẁaypoint`](#waypoint) objects representing all points of the trace
|
||||
* in order.
|
||||
* If the trace point was ommited by map matching because it is an outlier, the entry will be null.
|
||||
* Each
|
||||
* `Waypoint` object includes two additional properties, 1) `matchings_index`: Index to the
|
||||
* [`Route`](#route) object in matchings the sub-trace was matched to, 2) `waypoint_index`: Index of
|
||||
* the waypoint inside the matched route.
|
||||
* **`matchings`** is an array of [`Route`](#route) objects that
|
||||
* assemble the trace. Each `Route` object has an additional `confidence` property, which is the
|
||||
* confidence of
|
||||
* the matching. float value between `0` and `1`. `1` is very confident that the matching is
|
||||
* correct.
|
||||
*
|
||||
* @example
|
||||
* var osrm = new OSRM('network.osrm');
|
||||
* var options = {
|
||||
* coordinates: [[13.393252,52.542648],[13.39478,52.543079],[13.397389,52.542107]],
|
||||
* timestamps: [1424684612, 1424684616, 1424684620]
|
||||
* };
|
||||
* osrm.match(options, function(err, response) {
|
||||
* if (err) throw err;
|
||||
* console.log(response.tracepoints); // array of Waypoint objects
|
||||
* console.log(response.matchings); // array of Route objects
|
||||
* });
|
||||
*
|
||||
*/
|
||||
NAN_METHOD(Engine::match) //
|
||||
{
|
||||
async(info, &argumentsToMatchParameter, &osrm::OSRM::Match, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* The trip plugin solves the Traveling Salesman Problem using a greedy heuristic
|
||||
* (farthest-insertion algorithm) for 10 or * more waypoints and uses brute force for less than 10
|
||||
* waypoints. The returned path does not have to be the shortest path, * as TSP is NP-hard it is
|
||||
* only an approximation.
|
||||
* Note that all input coordinates have to be connected for the trip service to work.
|
||||
*
|
||||
* @name trip
|
||||
* @memberof OSRM
|
||||
* @param {Object} options - Object literal containing parameters for the trip query.
|
||||
* @param {Boolean} [options.steps=false] Return route steps for each route.
|
||||
* @param {Boolean} or {Array} [options.annotations=false] Return annotations for each route leg.
|
||||
* Can be `false`, `true` or an array with strings of `duration`, `nodes`, `distance`, `weight`,
|
||||
* `datasources`, `speed`.
|
||||
* @param {String} [options.geometries=polyline] Returned route geometry format (influences overview
|
||||
* and per step). Can also be `geojson`.
|
||||
* @param {String} [options.overview=simplified] Add overview geometry either `full`, `simplified`
|
||||
* @param {Function} callback
|
||||
* @param {Boolean} [options.roundtrip=true] Return route is a roundtrip.
|
||||
* @param {String} [options.source=any] Return route starts at `any` or `first` coordinate.
|
||||
* @param {String} [options.destination=any] Return route ends at `any` or `last` coordinate.
|
||||
*
|
||||
* @returns {Object} containing `waypoints` and `trips`.
|
||||
* **`waypoints`**: an array of [`Waypoint`](#waypoint) objects representing all waypoints in input
|
||||
* order.
|
||||
* Each Waypoint object has the following additional properties, 1) `trips_index`: index to trips of
|
||||
* the
|
||||
* sub-trip the point was matched to, and 2) `waypoint_index`: index of the point in the trip.
|
||||
* **`trips`**: an array of [`Route`](#route) objects that assemble the trace.
|
||||
*
|
||||
* @example
|
||||
* var osrm = new OSRM('network.osrm');
|
||||
* var options = {
|
||||
* coordinates: [
|
||||
* [13.36761474609375, 52.51663871100423],
|
||||
* [13.374481201171875, 52.506191342034576]
|
||||
* ]
|
||||
* }
|
||||
* osrm.trip(options, function(err, response) {
|
||||
* if (err) throw err;
|
||||
* console.log(response.waypoints); // array of Waypoint objects
|
||||
* console.log(response.trips); // array of Route objects
|
||||
* });
|
||||
*/
|
||||
NAN_METHOD(Engine::trip) //
|
||||
{
|
||||
async(info, &argumentsToTripParameter, &osrm::OSRM::Trip, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Responses
|
||||
* @class Responses
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a route through (potentially multiple) waypoints.
|
||||
*
|
||||
* @name Route
|
||||
* @memberof Responses
|
||||
*
|
||||
* @param {documentation} exteral in
|
||||
* [`osrm-backend`](https://github.com/Project-OSRM/osrm-backend/blob/master/docs/http.md#route)
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a route between two waypoints.
|
||||
*
|
||||
* @name RouteLeg
|
||||
* @memberof Responses
|
||||
*
|
||||
* @param {documentation} exteral in
|
||||
* [`osrm-backend`](https://github.com/Project-OSRM/osrm-backend/blob/master/docs/http.md#routeleg)
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* A step consists of a maneuver such as a turn or merge, followed by a distance of travel along a
|
||||
* single way to the subsequent step.
|
||||
*
|
||||
* @name RouteStep
|
||||
* @memberof Responses
|
||||
*
|
||||
* @param {documentation} exteral in
|
||||
* [`osrm-backend`](https://github.com/Project-OSRM/osrm-backend/blob/master/docs/http.md#routestep)
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @name StepManeuver
|
||||
* @memberof Responses
|
||||
*
|
||||
* @param {documentation} exteral in
|
||||
* [`osrm-backend`](https://github.com/Project-OSRM/osrm-backend/blob/master/docs/http.md#stepmaneuver)
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Object used to describe waypoint on a route.
|
||||
*
|
||||
* @name Waypoint
|
||||
* @memberof Responses
|
||||
*
|
||||
* @param {documentation} exteral in
|
||||
* [`osrm-backend`](https://github.com/Project-OSRM/osrm-backend/blob/master/docs/http.md#waypoint)
|
||||
*
|
||||
*/
|
||||
|
||||
} // namespace node_osrm
|
@ -1,4 +1,4 @@
|
||||
DATA_NAME:=monaco
|
||||
DATA_NAME:=berlin
|
||||
DATA_URL:=https://s3.amazonaws.com/mapbox/osrm/testing/$(DATA_NAME).osm.pbf
|
||||
DATA_POLY_URL:=https://s3.amazonaws.com/mapbox/osrm/testing/$(DATA_NAME).poly
|
||||
OSRM_BUILD_DIR?=../../build
|
||||
|
@ -1,2 +1,2 @@
|
||||
2b8dd9343d5e615afc9c67bcc7028a63 monaco.osm.pbf
|
||||
b0788991ab3791d53c1c20b6281f81ad monaco.poly
|
||||
54707104e9f411d1a3032c00fb1276c6 berlin.osm.pbf
|
||||
031d988f23fc2a30371c9ef8d2a49bae berlin.poly
|
||||
|
58
test/nodejs/index.js
Normal file
58
test/nodejs/index.js
Normal file
@ -0,0 +1,58 @@
|
||||
var OSRM = require('../../');
|
||||
var test = require('tape');
|
||||
var berlin_path = require('./osrm-data-path').data_path;
|
||||
|
||||
test('constructor: throws if new keyword is not used', function(assert) {
|
||||
assert.plan(1);
|
||||
assert.throws(function() { OSRM(); },
|
||||
/Cannot call constructor as function, you need to use 'new' keyword/);
|
||||
});
|
||||
|
||||
test('constructor: uses defaults with no parameter', function(assert) {
|
||||
assert.plan(1);
|
||||
var osrm = new OSRM();
|
||||
assert.ok(osrm);
|
||||
});
|
||||
|
||||
test('constructor: does not accept more than one parameter', function(assert) {
|
||||
assert.plan(1);
|
||||
assert.throws(function() { new OSRM({}, {}); },
|
||||
/Only accepts one parameter/);
|
||||
});
|
||||
|
||||
test('constructor: throws if necessary files do not exist', function(assert) {
|
||||
assert.plan(1);
|
||||
assert.throws(function() { new OSRM("missing.osrm"); },
|
||||
/Invalid file paths/);
|
||||
});
|
||||
|
||||
test('constructor: takes a shared memory argument', function(assert) {
|
||||
assert.plan(1);
|
||||
var osrm = new OSRM({path: berlin_path, shared_memory: false});
|
||||
assert.ok(osrm);
|
||||
});
|
||||
|
||||
test('constructor: throws if shared_memory==false with no path defined', function(assert) {
|
||||
assert.plan(1);
|
||||
assert.throws(function() { var osrm = new OSRM({shared_memory: false}); },
|
||||
/Shared_memory must be enabled if no path is specified/);
|
||||
});
|
||||
|
||||
test('constructor: throws if given a non-bool shared_memory option', function(assert) {
|
||||
assert.plan(1);
|
||||
assert.throws(function() { var osrm = new OSRM({path: berlin_path, shared_memory: "a"}); },
|
||||
/Shared_memory option must be a boolean/);
|
||||
});
|
||||
|
||||
test('constructor: throws if given a non-string/obj argument', function(assert) {
|
||||
assert.plan(1);
|
||||
assert.throws(function() { var osrm = new OSRM(true); },
|
||||
/Parameter must be a path or options object/);
|
||||
});
|
||||
|
||||
require('./route.js');
|
||||
require('./trip.js');
|
||||
require('./match.js');
|
||||
require('./tile.js');
|
||||
require('./table.js');
|
||||
require('./nearest.js');
|
195
test/nodejs/match.js
Normal file
195
test/nodejs/match.js
Normal file
@ -0,0 +1,195 @@
|
||||
var OSRM = require('../../');
|
||||
var test = require('tape');
|
||||
var berlin_path = require('./osrm-data-path').data_path;
|
||||
|
||||
test('match: match in Berlin', function(assert) {
|
||||
assert.plan(5);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.393252,52.542648],[13.39478,52.543079],[13.397389,52.542107]],
|
||||
timestamps: [1424684612, 1424684616, 1424684620]
|
||||
};
|
||||
osrm.match(options, function(err, response) {
|
||||
assert.ifError(err);
|
||||
assert.equal(response.matchings.length, 1);
|
||||
assert.ok(response.matchings.every(function(m) {
|
||||
return !!m.distance && !!m.duration && Array.isArray(m.legs) && !!m.geometry && m.confidence > 0;
|
||||
}))
|
||||
assert.equal(response.tracepoints.length, 3);
|
||||
assert.ok(response.tracepoints.every(function(t) {
|
||||
return !!t.hint && !isNaN(t.matchings_index) && !isNaN(t.waypoint_index) && !!t.name;
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
test('match: match in Berlin without timestamps', function(assert) {
|
||||
assert.plan(3);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.393252,52.542648],[13.39478,52.543079],[13.397389,52.542107]]
|
||||
};
|
||||
osrm.match(options, function(err, response) {
|
||||
assert.ifError(err);
|
||||
assert.equal(response.tracepoints.length, 3);
|
||||
assert.equal(response.matchings.length, 1);
|
||||
});
|
||||
});
|
||||
|
||||
test('match: match in Berlin without geometry compression', function(assert) {
|
||||
assert.plan(4);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.393252,52.542648],[13.39478,52.543079],[13.397389,52.542107]],
|
||||
geometries: 'geojson'
|
||||
};
|
||||
osrm.match(options, function(err, response) {
|
||||
assert.ifError(err);
|
||||
assert.equal(response.matchings.length, 1);
|
||||
assert.ok(response.matchings[0].geometry instanceof Object);
|
||||
assert.ok(Array.isArray(response.matchings[0].geometry.coordinates));
|
||||
});
|
||||
});
|
||||
|
||||
test('match: match in Berlin with geometry compression', function(assert) {
|
||||
assert.plan(3);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.393252,52.542648],[13.39478,52.543079],[13.397389,52.542107]]
|
||||
};
|
||||
osrm.match(options, function(err, response) {
|
||||
assert.ifError(err);
|
||||
assert.equal(response.matchings.length, 1);
|
||||
assert.equal('string', typeof response.matchings[0].geometry);
|
||||
});
|
||||
});
|
||||
|
||||
test('match: match in Berlin with speed annotations options', function(assert) {
|
||||
assert.plan(12);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.393252,52.542648],[13.39478,52.543079],[13.397389,52.542107]],
|
||||
timestamps: [1424684612, 1424684616, 1424684620],
|
||||
radiuses: [4.07, 4.07, 4.07],
|
||||
steps: true,
|
||||
annotations: ['speed'],
|
||||
overview: 'false',
|
||||
geometries: 'geojson'
|
||||
};
|
||||
osrm.match(options, function(err, response) {
|
||||
assert.ifError(err);
|
||||
assert.equal(response.matchings.length, 1);
|
||||
assert.ok(response.matchings[0].confidence > 0, 'has confidence');
|
||||
assert.ok(response.matchings[0].legs.every((l) => {return l.steps.length > 0; }), 'every leg has steps');
|
||||
assert.ok(response.matchings[0].legs.every((l) => {return l.annotation; }), 'every leg has annotations');
|
||||
assert.ok(response.matchings[0].legs.every((l) => {return l.annotation.speed; }), 'every leg has annotations for speed');
|
||||
assert.notOk(response.matchings[0].legs.every((l) => {return l.annotation.weight; }), 'has no annotations for weight')
|
||||
assert.notOk(response.matchings[0].legs.every((l) => {return l.annotation.datasources; }), 'has no annotations for datasources')
|
||||
assert.notOk(response.matchings[0].legs.every((l) => {return l.annotation.duration; }), 'has no annotations for duration')
|
||||
assert.notOk(response.matchings[0].legs.every((l) => {return l.annotation.distance; }), 'has no annotations for distance')
|
||||
assert.notOk(response.matchings[0].legs.every((l) => {return l.annotation.nodes; }), 'has no annotations for nodes')
|
||||
assert.equal(undefined, response.matchings[0].geometry);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('match: match in Berlin with several (duration, distance, nodes) annotations options', function(assert) {
|
||||
assert.plan(12);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.393252,52.542648],[13.39478,52.543079],[13.397389,52.542107]],
|
||||
timestamps: [1424684612, 1424684616, 1424684620],
|
||||
radiuses: [4.07, 4.07, 4.07],
|
||||
steps: true,
|
||||
annotations: ['duration','distance','nodes'],
|
||||
overview: 'false',
|
||||
geometries: 'geojson'
|
||||
};
|
||||
osrm.match(options, function(err, response) {
|
||||
assert.ifError(err);
|
||||
assert.equal(response.matchings.length, 1);
|
||||
assert.ok(response.matchings[0].confidence > 0, 'has confidence');
|
||||
assert.ok(response.matchings[0].legs.every((l) => {return l.steps.length > 0; }), 'every leg has steps');
|
||||
assert.ok(response.matchings[0].legs.every((l) => {return l.annotation; }), 'every leg has annotations');
|
||||
assert.ok(response.matchings[0].legs.every((l) => {return l.annotation.distance; }), 'every leg has annotations for distance');
|
||||
assert.ok(response.matchings[0].legs.every((l) => {return l.annotation.duration; }), 'every leg has annotations for durations');
|
||||
assert.ok(response.matchings[0].legs.every((l) => {return l.annotation.nodes; }), 'every leg has annotations for nodes');
|
||||
assert.notOk(response.matchings[0].legs.every((l) => {return l.annotation.weight; }), 'has no annotations for weight')
|
||||
assert.notOk(response.matchings[0].legs.every((l) => {return l.annotation.datasources; }), 'has no annotations for datasources')
|
||||
assert.notOk(response.matchings[0].legs.every((l) => {return l.annotation.speed; }), 'has no annotations for speed')
|
||||
assert.equal(undefined, response.matchings[0].geometry);
|
||||
});
|
||||
});
|
||||
|
||||
test('match: match in Berlin with all options', function(assert) {
|
||||
assert.plan(8);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.393252,52.542648],[13.39478,52.543079],[13.397389,52.542107]],
|
||||
timestamps: [1424684612, 1424684616, 1424684620],
|
||||
radiuses: [4.07, 4.07, 4.07],
|
||||
steps: true,
|
||||
annotations: true,
|
||||
overview: 'false',
|
||||
geometries: 'geojson'
|
||||
};
|
||||
osrm.match(options, function(err, response) {
|
||||
assert.ifError(err);
|
||||
assert.equal(response.matchings.length, 1);
|
||||
assert.ok(response.matchings[0].confidence > 0, 'has confidence');
|
||||
assert.ok(response.matchings[0].legs.every((l) => {return l.steps.length > 0; }), 'every leg has steps');
|
||||
assert.ok(response.matchings[0].legs.every((l) => {return l.annotation; }), 'every leg has annotations');
|
||||
assert.ok(response.matchings[0].legs.every((l) => {return l.annotation.distance; }), 'every leg has annotations for distance');
|
||||
assert.ok(response.matchings[0].legs.every((l) => {return l.annotation.duration; }), 'every leg has annotations for durations');
|
||||
assert.equal(undefined, response.matchings[0].geometry);
|
||||
});
|
||||
});
|
||||
|
||||
test('match: throws on missing arguments', function(assert) {
|
||||
assert.plan(1);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
assert.throws(function() { osrm.match({}) },
|
||||
/Two arguments required/);
|
||||
});
|
||||
|
||||
test('match: throws on non-object arg', function(assert) {
|
||||
assert.plan(1);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
assert.throws(function() { osrm.match(null, function(err, response) {}) },
|
||||
/First arg must be an object/);
|
||||
});
|
||||
|
||||
test('match: throws on invalid coordinates param', function(assert) {
|
||||
assert.plan(4);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: ''
|
||||
};
|
||||
assert.throws(function() { osrm.match(options, function(err, response) {}) },
|
||||
/Coordinates must be an array of \(lon\/lat\) pairs/);
|
||||
options.coordinates = [[13.393252,52.542648]];
|
||||
assert.throws(function() { osrm.match(options, function(err, response) {}) },
|
||||
/At least two coordinates must be provided/);
|
||||
options.coordinates = [13.393252,52.542648];
|
||||
assert.throws(function() { osrm.match(options, function(err, response) {}) },
|
||||
/Coordinates must be an array of \(lon\/lat\) pairs/);
|
||||
options.coordinates = [[13.393252],[52.542648]];
|
||||
assert.throws(function() { osrm.match(options, function(err, response) {}) },
|
||||
/Coordinates must be an array of \(lon\/lat\) pairs/);
|
||||
});
|
||||
|
||||
test('match: throws on invalid timestamps param', function(assert) {
|
||||
assert.plan(3);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.393252,52.542648],[13.39478,52.543079],[13.397389,52.542107]],
|
||||
timestamps: 'timestamps'
|
||||
};
|
||||
assert.throws(function() { osrm.match(options, function(err, response) {}) },
|
||||
/Timestamps must be an array of integers \(or undefined\)/);
|
||||
options.timestamps = ['invalid', 'timestamp', 'array'];
|
||||
assert.throws(function() { osrm.match(options, function(err, response) {}) },
|
||||
/Timestamps array items must be numbers/);
|
||||
options.timestamps = [1424684612, 1424684616];
|
||||
assert.throws(function() { osrm.match(options, function(err, response) {}) },
|
||||
/Timestamp array must have the same size as the coordinates array/);
|
||||
});
|
51
test/nodejs/nearest.js
Normal file
51
test/nodejs/nearest.js
Normal file
@ -0,0 +1,51 @@
|
||||
var OSRM = require('../../');
|
||||
var test = require('tape');
|
||||
var berlin_path = require('./osrm-data-path').data_path;
|
||||
|
||||
test('nearest', function(assert) {
|
||||
assert.plan(4);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
osrm.nearest({
|
||||
coordinates: [[13.333086, 52.4224]]
|
||||
}, function(err, result) {
|
||||
assert.ifError(err);
|
||||
assert.equal(result.waypoints.length, 1);
|
||||
assert.equal(result.waypoints[0].location.length, 2);
|
||||
assert.ok(result.waypoints[0].hasOwnProperty('name'));
|
||||
});
|
||||
});
|
||||
|
||||
test('nearest: can ask for multiple nearest pts', function(assert) {
|
||||
assert.plan(2);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
osrm.nearest({
|
||||
coordinates: [[13.333086, 52.4224]],
|
||||
number: 3
|
||||
}, function(err, result) {
|
||||
assert.ifError(err);
|
||||
assert.equal(result.waypoints.length, 3);
|
||||
});
|
||||
});
|
||||
|
||||
test('nearest: throws on invalid args', function(assert) {
|
||||
assert.plan(6);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {};
|
||||
assert.throws(function() { osrm.nearest(options); },
|
||||
/Two arguments required/);
|
||||
assert.throws(function() { osrm.nearest(null, function(err, res) {}); },
|
||||
/First arg must be an object/);
|
||||
options.coordinates = [52.4224];
|
||||
assert.throws(function() { osrm.nearest(options, function(err, res) {}); },
|
||||
/Coordinates must be an array of /);
|
||||
options.coordinates = [[13.333086, 52.4224],[13.333086, 52.5224]];
|
||||
assert.throws(function() { osrm.nearest(options, function(err, res) {}); },
|
||||
/Exactly one coordinate pair must be provided/);
|
||||
options.coordinates = [[13.333086, 52.4224]];
|
||||
options.number = 3.14159;
|
||||
assert.throws(function() { osrm.nearest(options, function(err, res) {}); },
|
||||
/Number must be an integer greater than or equal to 1/);
|
||||
options.number = 0;
|
||||
assert.throws(function() { osrm.nearest(options, function(err, res) {}); },
|
||||
/Number must be an integer greater than or equal to 1/);
|
||||
});
|
8
test/nodejs/osrm-data-path.js
Normal file
8
test/nodejs/osrm-data-path.js
Normal file
@ -0,0 +1,8 @@
|
||||
var path = require('path');
|
||||
|
||||
if (process.env.OSRM_DATA_PATH !== undefined) {
|
||||
exports.data_path = path.join(path.resolve(process.env.OSRM_DATA_PATH), "berlin_CH.osrm");
|
||||
console.log('Setting custom data path to ' + exports.data_path);
|
||||
} else {
|
||||
exports.data_path = path.resolve(path.join(__dirname, "../data/berlin_CH.osrm"));
|
||||
}
|
471
test/nodejs/route.js
Normal file
471
test/nodejs/route.js
Normal file
@ -0,0 +1,471 @@
|
||||
var OSRM = require('../../');
|
||||
var test = require('tape');
|
||||
var berlin_path = require('./osrm-data-path').data_path;
|
||||
|
||||
test('route: routes Berlin', function(assert) {
|
||||
assert.plan(5);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
osrm.route({coordinates: [[13.43864,52.51993],[13.415852,52.513191]]}, function(err, route) {
|
||||
assert.ifError(err);
|
||||
assert.ok(route.waypoints);
|
||||
assert.ok(route.routes);
|
||||
assert.ok(route.routes.length);
|
||||
assert.ok(route.routes[0].geometry);
|
||||
});
|
||||
});
|
||||
|
||||
test('route: throws with too few or invalid args', function(assert) {
|
||||
assert.plan(3);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
assert.throws(function() { osrm.route({coordinates: [[13.43864,52.51993],[13.415852,52.513191]]}) },
|
||||
/Two arguments required/);
|
||||
assert.throws(function() { osrm.route(null, function(err, route) {}) },
|
||||
/First arg must be an object/);
|
||||
assert.throws(function() { osrm.route({coordinates: [[13.43864,52.51993],[13.415852,52.513191]]}, true)},
|
||||
/last argument must be a callback function/);
|
||||
});
|
||||
|
||||
test('route: provides no alternatives by default, but when requested', function(assert) {
|
||||
assert.plan(6);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {coordinates: [[13.302383,52.490516], [13.418427,52.522070]]};
|
||||
|
||||
osrm.route(options, function(err, route) {
|
||||
assert.ifError(err);
|
||||
assert.ok(route.routes);
|
||||
assert.equal(route.routes.length, 1);
|
||||
});
|
||||
options.alternatives = true;
|
||||
osrm.route(options, function(err, route) {
|
||||
assert.ifError(err);
|
||||
assert.ok(route.routes);
|
||||
assert.equal(route.routes.length, 2);
|
||||
});
|
||||
});
|
||||
|
||||
test('route: throws with bad params', function(assert) {
|
||||
assert.plan(11);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
assert.throws(function () { osrm.route({coordinates: []}, function(err) {}) });
|
||||
assert.throws(function() { osrm.route({}, function(err, route) {}) },
|
||||
/Must provide a coordinates property/);
|
||||
assert.throws(function() { osrm.route({coordinates: null}, function(err, route) {}) },
|
||||
/Coordinates must be an array of \(lon\/lat\) pairs/);
|
||||
assert.throws(function() { osrm.route({coordinates: [13.438640, 52.519930]}, function(err, route) {}) },
|
||||
/Coordinates must be an array of \(lon\/lat\) pairs/);
|
||||
assert.throws(function() { osrm.route({coordinates: [[true, '52.519930'], [13.438640, 52.519930]]}, function(err, route) {}) },
|
||||
/Each member of a coordinate pair must be a number/);
|
||||
assert.throws(function() { osrm.route({coordinates: [[213.43864,252.51993],[413.415852,552.513191]]}, function(err, route) {}) },
|
||||
/Lng\/Lat coordinates must be within world bounds \(-180 < lng < 180, -90 < lat < 90\)/);
|
||||
assert.throws(function() { osrm.route({coordinates: [[13.438640], [52.519930]]}, function(err, route) {}) },
|
||||
/Coordinates must be an array of \(lon\/lat\) pairs/);
|
||||
assert.throws(function() { osrm.route({coordinates: [[13.43864,52.51993],[13.415852,52.513191]], hints: null}, function(err, route) {}) },
|
||||
/Hints must be an array of strings\/null/);
|
||||
assert.throws(function() { osrm.route({coordinates: [[13.43864,52.51993],[13.415852,52.513191]], steps: null}, function(err, route) {}) });
|
||||
assert.throws(function() { osrm.route({coordinates: [[13.43864,52.51993],[13.415852,52.513191]], annotations: null}, function(err, route) {}) });
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
alternateRoute: false,
|
||||
hints: [13.438640, 52.519930]
|
||||
};
|
||||
assert.throws(function() { osrm.route(options, function(err, route) {}) },
|
||||
/Hint must be null or string/);
|
||||
});
|
||||
|
||||
test('route: routes Berlin using shared memory', function(assert) {
|
||||
assert.plan(2);
|
||||
var osrm = new OSRM();
|
||||
osrm.route({coordinates: [[13.43864,52.51993],[13.415852,52.513191]]}, function(err, route) {
|
||||
assert.ifError(err);
|
||||
assert.ok(Array.isArray(route.routes));
|
||||
});
|
||||
});
|
||||
|
||||
test('route: routes Berlin with geometry compression', function(assert) {
|
||||
assert.plan(2);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
};
|
||||
osrm.route(options, function(err, route) {
|
||||
assert.ifError(err);
|
||||
assert.equal('string', typeof route.routes[0].geometry);
|
||||
});
|
||||
});
|
||||
|
||||
test('route: routes Berlin without geometry compression', function(assert) {
|
||||
assert.plan(4);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
geometries: 'geojson'
|
||||
};
|
||||
osrm.route(options, function(err, route) {
|
||||
assert.ifError(err);
|
||||
assert.ok(Array.isArray(route.routes));
|
||||
assert.ok(Array.isArray(route.routes[0].geometry.coordinates));
|
||||
assert.equal(route.routes[0].geometry.type, 'LineString');
|
||||
});
|
||||
});
|
||||
|
||||
test('Test polyline6 geometries option', function(assert) {
|
||||
assert.plan(6);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
continue_straight: false,
|
||||
overview: 'false',
|
||||
geometries: 'polyline6',
|
||||
steps: true
|
||||
};
|
||||
osrm.route(options, function(err, first) {
|
||||
assert.ifError(err);
|
||||
assert.ok(first.routes);
|
||||
assert.equal(first.routes.length, 1);
|
||||
assert.notOk(first.routes[0].geometry);
|
||||
assert.ok(first.routes[0].legs[0]);
|
||||
assert.equal(typeof first.routes[0].legs[0].steps[0].geometry, 'string');
|
||||
});
|
||||
});
|
||||
|
||||
test('route: routes Berlin with speed annotations options', function(assert) {
|
||||
assert.plan(17);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
continue_straight: false,
|
||||
overview: 'false',
|
||||
geometries: 'polyline',
|
||||
steps: true,
|
||||
annotations: ['speed']
|
||||
};
|
||||
osrm.route(options, function(err, first) {
|
||||
assert.ifError(err);
|
||||
assert.ok(first.routes);
|
||||
assert.ok(first.routes[0].legs.every(function(l) { return Array.isArray(l.steps) && l.steps.length > 0; }));
|
||||
assert.equal(first.routes.length, 1);
|
||||
assert.notOk(first.routes[0].geometry);
|
||||
assert.ok(first.routes[0].legs[0]);
|
||||
assert.ok(first.routes[0].legs.every(l => { return l.steps.length > 0; }), 'every leg has steps');
|
||||
assert.ok(first.routes[0].legs.every(l => { return l.annotation;}), 'every leg has annotations');
|
||||
assert.ok(first.routes[0].legs.every(l => { return l.annotation.speed;}), 'every leg has annotations for speed');
|
||||
assert.notOk(first.routes[0].legs.every(l => { return l.annotation.weight; }), 'has no annotations for weight')
|
||||
assert.notOk(first.routes[0].legs.every(l => { return l.annotation.datasources; }), 'has no annotations for datasources')
|
||||
assert.notOk(first.routes[0].legs.every(l => { return l.annotation.duration; }), 'has no annotations for duration')
|
||||
assert.notOk(first.routes[0].legs.every(l => { return l.annotation.distance; }), 'has no annotations for distance')
|
||||
assert.notOk(first.routes[0].legs.every(l => { return l.annotation.nodes; }), 'has no annotations for nodes')
|
||||
|
||||
options.overview = 'full';
|
||||
osrm.route(options, function(err, full) {
|
||||
assert.ifError(err);
|
||||
options.overview = 'simplified';
|
||||
osrm.route(options, function(err, simplified) {
|
||||
assert.ifError(err);
|
||||
assert.notEqual(full.routes[0].geometry, simplified.routes[0].geometry);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('route: routes Berlin with several (duration, distance, nodes) annotations options', function(assert) {
|
||||
assert.plan(17);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
continue_straight: false,
|
||||
overview: 'false',
|
||||
geometries: 'polyline',
|
||||
steps: true,
|
||||
annotations: ['duration','distance','nodes']
|
||||
};
|
||||
osrm.route(options, function(err, first) {
|
||||
assert.ifError(err);
|
||||
assert.ok(first.routes);
|
||||
assert.ok(first.routes[0].legs.every(function(l) { return Array.isArray(l.steps) && l.steps.length > 0; }));
|
||||
assert.equal(first.routes.length, 1);
|
||||
assert.notOk(first.routes[0].geometry);
|
||||
assert.ok(first.routes[0].legs[0]);
|
||||
assert.ok(first.routes[0].legs.every(l => { return l.steps.length > 0; }), 'every leg has steps');
|
||||
assert.ok(first.routes[0].legs.every(l => { return l.annotation;}), 'every leg has annotations');
|
||||
assert.ok(first.routes[0].legs.every(l => { return l.annotation.distance;}), 'every leg has annotations for distance');
|
||||
assert.ok(first.routes[0].legs.every(l => { return l.annotation.duration;}), 'every leg has annotations for durations');
|
||||
assert.ok(first.routes[0].legs.every(l => { return l.annotation.nodes;}), 'every leg has annotations for nodes');
|
||||
assert.notOk(first.routes[0].legs.every(l => { return l.annotation.weight; }), 'has no annotations for weight')
|
||||
assert.notOk(first.routes[0].legs.every(l => { return l.annotation.datasources; }), 'has no annotations for datasources')
|
||||
assert.notOk(first.routes[0].legs.every(l => { return l.annotation.speed; }), 'has no annotations for speed')
|
||||
|
||||
options.overview = 'full';
|
||||
osrm.route(options, function(err, full) {
|
||||
assert.ifError(err);
|
||||
options.overview = 'simplified';
|
||||
osrm.route(options, function(err, simplified) {
|
||||
assert.ifError(err);
|
||||
assert.notEqual(full.routes[0].geometry, simplified.routes[0].geometry);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('route: routes Berlin with options', function(assert) {
|
||||
assert.plan(11);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
continue_straight: false,
|
||||
overview: 'false',
|
||||
geometries: 'polyline',
|
||||
steps: true,
|
||||
annotations: true
|
||||
};
|
||||
osrm.route(options, function(err, first) {
|
||||
assert.ifError(err);
|
||||
assert.ok(first.routes);
|
||||
assert.ok(first.routes[0].legs.every(function(l) { return Array.isArray(l.steps) && l.steps.length > 0; }));
|
||||
assert.equal(first.routes.length, 1);
|
||||
assert.notOk(first.routes[0].geometry);
|
||||
assert.ok(first.routes[0].legs[0]);
|
||||
assert.ok(first.routes[0].legs.every(l => { return l.steps.length > 0; }), 'every leg has steps');
|
||||
assert.ok(first.routes[0].legs.every(l => { return l.annotation;}), 'every leg has annotations');
|
||||
|
||||
options.overview = 'full';
|
||||
osrm.route(options, function(err, full) {
|
||||
assert.ifError(err);
|
||||
options.overview = 'simplified';
|
||||
osrm.route(options, function(err, simplified) {
|
||||
assert.ifError(err);
|
||||
assert.notEqual(full.routes[0].geometry, simplified.routes[0].geometry);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('route: routes Berlin with options', function(assert) {
|
||||
assert.plan(11);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
continue_straight: false,
|
||||
overview: 'false',
|
||||
geometries: 'polyline',
|
||||
steps: true,
|
||||
annotations: true
|
||||
};
|
||||
osrm.route(options, function(err, first) {
|
||||
assert.ifError(err);
|
||||
assert.ok(first.routes);
|
||||
assert.ok(first.routes[0].legs.every(function(l) { return Array.isArray(l.steps) && l.steps.length > 0; }));
|
||||
assert.equal(first.routes.length, 1);
|
||||
assert.notOk(first.routes[0].geometry);
|
||||
assert.ok(first.routes[0].legs[0]);
|
||||
assert.ok(first.routes[0].legs.every(l => { return l.steps.length > 0; }), 'every leg has steps');
|
||||
assert.ok(first.routes[0].legs.every(l => { return l.annotation;}), 'every leg has annotations');
|
||||
|
||||
options.overview = 'full';
|
||||
osrm.route(options, function(err, full) {
|
||||
assert.ifError(err);
|
||||
options.overview = 'simplified';
|
||||
osrm.route(options, function(err, simplified) {
|
||||
assert.ifError(err);
|
||||
assert.notEqual(full.routes[0].geometry, simplified.routes[0].geometry);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('route: invalid route options', function(assert) {
|
||||
assert.plan(8);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
assert.throws(function() { osrm.route({
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
continue_straight: []
|
||||
}, function(err, route) {}); },
|
||||
/must be boolean/);
|
||||
assert.throws(function() { osrm.route({
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
alternatives: []
|
||||
}, function(err, route) {}); },
|
||||
/must be boolean/);
|
||||
assert.throws(function() { osrm.route({
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
geometries: true
|
||||
}, function(err, route) {}); },
|
||||
/Geometries must be a string: \[polyline, polyline6, geojson\]/);
|
||||
assert.throws(function() { osrm.route({
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
overview: false
|
||||
}, function(err, route) {}); },
|
||||
/Overview must be a string: \[simplified, full, false\]/);
|
||||
assert.throws(function() { osrm.route({
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
overview: false
|
||||
}, function(err, route) {}); },
|
||||
/Overview must be a string: \[simplified, full, false\]/);
|
||||
assert.throws(function() { osrm.route({
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
overview: 'maybe'
|
||||
}, function(err, route) {}); },
|
||||
/'overview' param must be one of \[simplified, full, false\]/);
|
||||
assert.throws(function() { osrm.route({
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
geometries: 'maybe'
|
||||
}, function(err, route) {}); },
|
||||
/'geometries' param must be one of \[polyline, polyline6, geojson\]/);
|
||||
assert.throws(function() { osrm.route({
|
||||
coordinates: [[NaN, -NaN],[Infinity, -Infinity]]
|
||||
}, function(err, route) {}); },
|
||||
/Lng\/Lat coordinates must be valid numbers/);
|
||||
});
|
||||
|
||||
test('route: integer bearing values no longer supported', function(assert) {
|
||||
assert.plan(1);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
bearings: [200, 250],
|
||||
};
|
||||
assert.throws(function() { osrm.route(options, function(err, route) {}); },
|
||||
/Bearing must be an array of \[bearing, range\] or null/);
|
||||
});
|
||||
|
||||
test('route: valid bearing values', function(assert) {
|
||||
assert.plan(4);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
bearings: [[200, 180], [250, 180]],
|
||||
};
|
||||
osrm.route(options, function(err, route) {
|
||||
assert.ifError(err);
|
||||
assert.ok(route.routes[0]);
|
||||
});
|
||||
options.bearings = [null, [360, 180]];
|
||||
osrm.route(options, function(err, route) {
|
||||
assert.ifError(err);
|
||||
assert.ok(route.routes[0]);
|
||||
});
|
||||
});
|
||||
|
||||
test('route: invalid bearing values', function(assert) {
|
||||
assert.plan(6);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
assert.throws(function() { osrm.route({
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
bearings: [[400, 180], [-250, 180]],
|
||||
}, function(err, route) {}) },
|
||||
/Bearing values need to be in range 0..360, 0..180/);
|
||||
assert.throws(function() { osrm.route({
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
bearings: [[200], [250, 180]],
|
||||
}, function(err, route) {}) },
|
||||
/Bearing must be an array of/);
|
||||
assert.throws(function() { osrm.route({
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
bearings: [[400, 109], [100, 720]],
|
||||
}, function(err, route) {}) },
|
||||
/Bearing values need to be in range 0..360, 0..180/);
|
||||
assert.throws(function() { osrm.route({
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
bearings: 400,
|
||||
}, function(err, route) {}) },
|
||||
/Bearings must be an array of arrays of numbers/);
|
||||
assert.throws(function() { osrm.route({
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
bearings: [[100, 100]],
|
||||
}, function(err, route) {}) },
|
||||
/Bearings array must have the same length as coordinates array/);
|
||||
assert.throws(function() { osrm.route({
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
bearings: [Infinity, Infinity],
|
||||
}, function(err, route) {}) },
|
||||
/Bearing must be an array of \[bearing, range\] or null/);
|
||||
});
|
||||
|
||||
test('route: routes Berlin with hints', function(assert) {
|
||||
assert.plan(5);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]]
|
||||
};
|
||||
osrm.route(options, function(err, first) {
|
||||
assert.ifError(err);
|
||||
assert.ok(first.waypoints);
|
||||
var hints = first.waypoints.map(function(wp) { return wp.hint; });
|
||||
assert.ok(hints.every(function(h) { return typeof h === 'string'; }));
|
||||
|
||||
options.hints = hints;
|
||||
|
||||
osrm.route(options, function(err, second) {
|
||||
assert.ifError(err);
|
||||
assert.deepEqual(first, second);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('route: routes Berlin with null hints', function(assert) {
|
||||
assert.plan(1);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
hints: [null, null]
|
||||
};
|
||||
osrm.route(options, function(err, route) {
|
||||
assert.ifError(err);
|
||||
});
|
||||
});
|
||||
|
||||
test('route: throws on bad hints', function(assert) {
|
||||
assert.plan(2);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
assert.throws(function() { osrm.route({
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
hints: ['', '']
|
||||
}, function(err, route) {})}, /Hint cannot be an empty string/);
|
||||
assert.throws(function() { osrm.route({
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
hints: [null]
|
||||
}, function(err, route) {})}, /Hints array must have the same length as coordinates array/);
|
||||
});
|
||||
|
||||
test('route: routes Berlin with valid radius values', function(assert) {
|
||||
assert.plan(3);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
radiuses: [100, 100]
|
||||
};
|
||||
osrm.route(options, function(err, route) {
|
||||
assert.ifError(err);
|
||||
});
|
||||
options.radiuses = [null, null];
|
||||
osrm.route(options, function(err, route) {
|
||||
assert.ifError(err);
|
||||
});
|
||||
options.radiuses = [100, null];
|
||||
osrm.route(options, function(err, route) {
|
||||
assert.ifError(err);
|
||||
});
|
||||
});
|
||||
|
||||
test('route: throws on bad radiuses', function(assert) {
|
||||
assert.plan(3);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
radiuses: [10, 10]
|
||||
};
|
||||
assert.throws(function() { osrm.route({
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
radiuses: 10
|
||||
}, function(err, route) {}) },
|
||||
/Radiuses must be an array of non-negative doubles or null/);
|
||||
assert.throws(function() { osrm.route({
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
radiuses: ['magic', 'numbers']
|
||||
}, function(err, route) {}) },
|
||||
/Radius must be non-negative double or null/);
|
||||
assert.throws(function() { osrm.route({
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
radiuses: [10]
|
||||
}, function(err, route) {}) },
|
||||
/Radiuses array must have the same length as coordinates array/);
|
||||
});
|
161
test/nodejs/table.js
Normal file
161
test/nodejs/table.js
Normal file
@ -0,0 +1,161 @@
|
||||
var OSRM = require('../../');
|
||||
var test = require('tape');
|
||||
var berlin_path = require('./osrm-data-path').data_path;
|
||||
|
||||
test('table: distance table in Berlin', function(assert) {
|
||||
assert.plan(9);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]]
|
||||
};
|
||||
osrm.table(options, function(err, table) {
|
||||
assert.ifError(err);
|
||||
assert.ok(Array.isArray(table.durations), 'result must be an array');
|
||||
var row_count = table.durations.length;
|
||||
for (var i = 0; i < row_count; ++i) {
|
||||
var column = table.durations[i];
|
||||
var column_count = column.length;
|
||||
assert.equal(row_count, column_count);
|
||||
for (var j = 0; j < column_count; ++j) {
|
||||
if (i == j) {
|
||||
// check that diagonal is zero
|
||||
assert.equal(0, column[j], 'diagonal must be zero');
|
||||
} else {
|
||||
// everything else is non-zero
|
||||
assert.notEqual(0, column[j], 'other entries must be non-zero');
|
||||
}
|
||||
}
|
||||
}
|
||||
assert.equal(options.coordinates.length, row_count);
|
||||
});
|
||||
});
|
||||
|
||||
test('table: distance table in Berlin with sources/destinations', function(assert) {
|
||||
assert.plan(6);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
sources: [0],
|
||||
destinations: [0,1]
|
||||
};
|
||||
osrm.table(options, function(err, table) {
|
||||
assert.ifError(err);
|
||||
assert.ok(Array.isArray(table.durations), 'result must be an array');
|
||||
var row_count = table.durations.length;
|
||||
for (var i = 0; i < row_count; ++i) {
|
||||
var column = table.durations[i];
|
||||
var column_count = column.length;
|
||||
assert.equal(options.destinations.length, column_count);
|
||||
for (var j = 0; j < column_count; ++j) {
|
||||
if (i == j) {
|
||||
// check that diagonal is zero
|
||||
assert.equal(0, column[j], 'diagonal must be zero');
|
||||
} else {
|
||||
// everything else is non-zero
|
||||
assert.notEqual(0, column[j], 'other entries must be non-zero');
|
||||
}
|
||||
}
|
||||
}
|
||||
assert.equal(options.sources.length, row_count);
|
||||
});
|
||||
});
|
||||
|
||||
test('table: throws on invalid arguments', function(assert) {
|
||||
assert.plan(14);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {};
|
||||
assert.throws(function() { osrm.table(options); },
|
||||
/Two arguments required/);
|
||||
options.coordinates = null;
|
||||
assert.throws(function() { osrm.table(options, function() {}); },
|
||||
/Coordinates must be an array of \(lon\/lat\) pairs/);
|
||||
options.coordinates = [[13.393252,52.542648]];
|
||||
assert.throws(function() { osrm.table(options, function(err, response) {}) },
|
||||
/At least two coordinates must be provided/);
|
||||
options.coordinates = [13.393252,52.542648];
|
||||
assert.throws(function() { osrm.table(options, function(err, response) {}) },
|
||||
/Coordinates must be an array of \(lon\/lat\) pairs/);
|
||||
options.coordinates = [[13.393252],[52.542648]];
|
||||
assert.throws(function() { osrm.table(options, function(err, response) {}) },
|
||||
/Coordinates must be an array of \(lon\/lat\) pairs/);
|
||||
|
||||
options.coordinates = [[13.393252,52.542648],[13.393252,52.542648]];
|
||||
options.sources = true;
|
||||
assert.throws(function() { osrm.table(options, function(err, response) {}) },
|
||||
/Sources must be an array of indices \(or undefined\)/);
|
||||
options.sources = [0, 4];
|
||||
assert.throws(function() { osrm.table(options, function(err, response) {}) },
|
||||
/Source indices must be less than or equal to the number of coordinates/);
|
||||
options.sources = [0.3, 1.1];
|
||||
assert.throws(function() { osrm.table(options, function(err, response) {}) },
|
||||
/Source must be an integer/);
|
||||
|
||||
options.destinations = true;
|
||||
delete options.sources;
|
||||
assert.throws(function() { osrm.table(options, function(err, response) {}) },
|
||||
/Destinations must be an array of indices \(or undefined\)/);
|
||||
options.destinations = [0, 4];
|
||||
assert.throws(function() { osrm.table(options, function(err, response) {}) },
|
||||
/Destination indices must be less than or equal to the number of coordinates/);
|
||||
options.destinations = [0.3, 1.1];
|
||||
assert.throws(function() { osrm.table(options, function(err, response) {}) },
|
||||
/Destination must be an integer/);
|
||||
|
||||
// does not throw: the following two have been changed in OSRM v5
|
||||
options.sources = [0, 1];
|
||||
delete options.destinations;
|
||||
assert.doesNotThrow(function() { osrm.table(options, function(err, response) {}) },
|
||||
/Both sources and destinations need to be specified/);
|
||||
options.destinations = [0, 1];
|
||||
assert.doesNotThrow(function() { osrm.table(options, function(err, response) {}) },
|
||||
/You can either specify sources and destinations, or coordinates/);
|
||||
|
||||
assert.throws(function() { osrm.route({coordinates: [[13.43864,52.51993],[13.415852,52.513191]], generate_hints: null}, function(err, route) {}) },
|
||||
/generate_hints must be of type Boolean/);
|
||||
});
|
||||
|
||||
test('table: throws on invalid arguments', function(assert) {
|
||||
assert.plan(1);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
assert.throws(function() { osrm.table(null, function() {}); },
|
||||
/First arg must be an object/);
|
||||
});
|
||||
|
||||
test('table: distance table in Berlin with hints', function(assert) {
|
||||
assert.plan(5);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
generate_hints: true // true is default but be explicit here
|
||||
};
|
||||
osrm.table(options, function(err, table) {
|
||||
console.log(table);
|
||||
assert.ifError(err);
|
||||
|
||||
function assertHasHints(waypoint) {
|
||||
assert.notStrictEqual(waypoint.hint, undefined);
|
||||
}
|
||||
|
||||
table.sources.map(assertHasHints);
|
||||
table.destinations.map(assertHasHints);
|
||||
});
|
||||
});
|
||||
|
||||
test('table: distance table in Berlin without hints', function(assert) {
|
||||
assert.plan(5);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
generate_hints: false // true is default
|
||||
};
|
||||
osrm.table(options, function(err, table) {
|
||||
assert.ifError(err);
|
||||
|
||||
function assertHasNoHints(waypoint) {
|
||||
assert.strictEqual(waypoint.hint, undefined);
|
||||
}
|
||||
|
||||
table.sources.map(assertHasNoHints);
|
||||
table.destinations.map(assertHasNoHints);
|
||||
});
|
||||
});
|
23
test/nodejs/tile.js
Normal file
23
test/nodejs/tile.js
Normal file
@ -0,0 +1,23 @@
|
||||
var OSRM = require('../../');
|
||||
var test = require('tape');
|
||||
var berlin_path = "test/data/berlin-latest.osrm";
|
||||
|
||||
test.test('tile check size coarse', function(assert) {
|
||||
assert.plan(2);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
osrm.tile([17603, 10747, 15], function(err, result) {
|
||||
assert.ifError(err);
|
||||
assert.ok(result.length > 35000);
|
||||
});
|
||||
});
|
||||
|
||||
// FIXME the size of the tile that is returned depends on the architecture
|
||||
// See issue #3343 in osrm-backend
|
||||
test.skip('tile', function(assert) {
|
||||
assert.plan(2);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
osrm.tile([17603, 10747, 15], function(err, result) {
|
||||
assert.ifError(err);
|
||||
assert.equal(result.length, 35970);
|
||||
});
|
||||
});
|
333
test/nodejs/trip.js
Normal file
333
test/nodejs/trip.js
Normal file
@ -0,0 +1,333 @@
|
||||
var OSRM = require('../../');
|
||||
var test = require('tape');
|
||||
var berlin_path = require('./osrm-data-path').data_path;
|
||||
|
||||
test('trip: trip in Berlin', function(assert) {
|
||||
assert.plan(2);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
osrm.trip({coordinates: [[13.36761474609375,52.51663871100423],[13.374481201171875,52.506191342034576]]}, function(err, trip) {
|
||||
assert.ifError(err);
|
||||
for (t = 0; t < trip.trips.length; t++) {
|
||||
assert.ok(trip.trips[t].geometry);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('trip: trip with many locations in Berlin', function(assert) {
|
||||
assert.plan(4);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var opts = {coordinates: [[13.36761474609375,52.51663871100423],[13.374481201171875,52.506191342034576],[13.404693603515625,52.50535544522142],[13.388900756835938,52.50159371284434],[13.386840820312498,52.518727886767266],[13.4088134765625,52.528754547664185],[13.41156005859375,52.51705655410405],[13.420486450195312,52.512042174642346],[13.413619995117188,52.50368360390624],[13.36212158203125,52.504101570196205],[13.35113525390625,52.52248815280757],[13.36761474609375,52.53460237630516],[13.383407592773438,52.53710835019913],[13.392333984375,52.536690697815736],[13.42529296875,52.532931647583325],[13.399200439453125,52.52415927884915],[13.390960693359375,52.51956352925745],[13.375167846679688,52.533349335723294],[13.37860107421875,52.520399155853454],[13.355255126953125,52.52081696319122],[13.385467529296875,52.5143405029259],[13.398857116699219,52.513086884218325],[13.399200439453125,52.50744515744915],[13.409500122070312,52.49783165855699],[13.424949645996094,52.500339730516934],[13.440055847167969,52.50786308797268],[13.428382873535156,52.511624283857785],[13.437652587890625,52.50451953251202],[13.443145751953125,52.5199813445422],[13.431129455566406,52.52520370034151],[13.418426513671875,52.52896341209634],[13.429069519042969,52.517474393230245],[13.418083190917969,52.528127948407935],[13.405036926269531,52.52833681581998],[13.384437561035156,52.53084314728766],[13.374481201171875,52.53084314728766],[13.3978271484375,52.532305107923925],[13.418769836425781,52.526039219655445],[13.441085815429688,52.51642978796417],[13.448638916015625,52.51601193890388],[13.44623565673828,52.50535544522142],[13.430442810058594,52.502638670794546],[13.358688354492188,52.520190250694526],[13.358001708984375,52.531887409851336],[13.367271423339842,52.528545682238736],[13.387870788574219,52.52958999943304],[13.406410217285156,52.53961418106945],[13.399543762207031,52.50556442091497],[13.374824523925781,52.50389258754797],[13.386154174804688,52.51099744023003],[13.40229034423828,52.49657756892365]]
|
||||
};
|
||||
osrm.trip(opts, function(err, trip) {
|
||||
assert.ifError(err);
|
||||
for (t = 0; t < trip.trips.length; t++) {
|
||||
assert.ok(trip.trips[t].geometry);
|
||||
}
|
||||
assert.equal(opts.coordinates.length, trip.waypoints.length);
|
||||
var indexMap = trip.waypoints.map(function(wp, i) {
|
||||
return [i, wp.waypoint_index];
|
||||
});
|
||||
assert.ok(!indexMap.every(function(tuple) { return tuple[0] === tuple[1]; }));
|
||||
});
|
||||
});
|
||||
|
||||
test('trip: throws with too few or invalid args', function(assert) {
|
||||
assert.plan(2);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
assert.throws(function() { osrm.trip({coordinates: [[13.43864,52.51993],[13.415852,52.513191]]}) },
|
||||
/Two arguments required/);
|
||||
assert.throws(function() { osrm.trip(null, function(err, trip) {}) },
|
||||
/First arg must be an object/);
|
||||
});
|
||||
|
||||
test('trip: throws with bad params', function(assert) {
|
||||
assert.plan(14);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
assert.throws(function () { osrm.trip({coordinates: []}, function(err) {}) });
|
||||
assert.throws(function() { osrm.trip({}, function(err, trip) {}) },
|
||||
/Must provide a coordinates property/);
|
||||
assert.throws(function() { osrm.trip({
|
||||
coordinates: null
|
||||
}, function(err, trip) {}) },
|
||||
/Coordinates must be an array of \(lon\/lat\) pairs/);
|
||||
assert.throws(function() { osrm.trip({
|
||||
coordinates: [13.438640, 52.519930]
|
||||
}, function(err, trip) {}) },
|
||||
/Coordinates must be an array of \(lon\/lat\) pairs/);
|
||||
assert.throws(function() { osrm.trip({
|
||||
coordinates: [[13.438640], [52.519930]]
|
||||
}, function(err, trip) {}) },
|
||||
/Coordinates must be an array of \(lon\/lat\) pairs/);
|
||||
assert.throws(function() { osrm.trip({
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
hints: null
|
||||
}, function(err, trip) {}) },
|
||||
/Hints must be an array of strings\/null/);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
printInstructions: false,
|
||||
hints: [13.438640, 52.519930]
|
||||
};
|
||||
assert.throws(function() { osrm.trip(options, function(err, trip) {}); },
|
||||
/Hint must be null or string/);
|
||||
options.hints = [null];
|
||||
assert.throws(function() { osrm.trip(options, function(err, trip) {}); },
|
||||
/Hints array must have the same length as coordinates array/);
|
||||
delete options.hints;
|
||||
options.geometries = 'false';
|
||||
assert.throws(function() { osrm.trip(options, function(err, trip) {}); },
|
||||
/'geometries' param must be one of \[polyline, polyline6, geojson\]/);
|
||||
delete options.geometries;
|
||||
options.source = false;
|
||||
assert.throws(function() { osrm.trip(options, function(err, trip) {}); },
|
||||
/Source must be a string: \[any, first\]/);
|
||||
options.source = 'false';
|
||||
assert.throws(function() { osrm.trip(options, function(err, trip) {}); },
|
||||
/'source' param must be one of \[any, first\]/);
|
||||
delete options.source;
|
||||
options.destination = true;
|
||||
assert.throws(function() { osrm.trip(options, function(err, trip) {}); },
|
||||
/Destination must be a string: \[any, last\]/);
|
||||
options.destination = 'true';
|
||||
assert.throws(function() { osrm.trip(options, function(err, trip) {}); },
|
||||
/'destination' param must be one of \[any, last\]/);
|
||||
options.roundtrip = 'any';
|
||||
assert.throws(function() { osrm.trip(options, function(err, trip) {}); },
|
||||
/'roundtrip' param must be a boolean/);
|
||||
});
|
||||
|
||||
test('trip: routes Berlin using shared memory', function(assert) {
|
||||
assert.plan(2);
|
||||
var osrm = new OSRM();
|
||||
osrm.trip({coordinates: [[13.43864,52.51993],[13.415852,52.513191]]}, function(err, trip) {
|
||||
assert.ifError(err);
|
||||
for (t = 0; t < trip.trips.length; t++) {
|
||||
assert.ok(trip.trips[t].geometry);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('trip: routes Berlin with hints', function(assert) {
|
||||
assert.plan(5);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
steps: false
|
||||
};
|
||||
osrm.trip(options, function(err, first) {
|
||||
assert.ifError(err);
|
||||
for (t = 0; t < first.trips.length; t++) {
|
||||
assert.ok(first.trips[t].geometry);
|
||||
}
|
||||
var hints = first.waypoints.map(function(wp) { return wp.hint; });
|
||||
assert.ok(hints.every(function(h) { return typeof h === 'string'; }));
|
||||
options.hints = hints;
|
||||
|
||||
osrm.trip(options, function(err, second) {
|
||||
assert.ifError(err);
|
||||
assert.deepEqual(first, second);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('trip: trip through Berlin with geometry compression', function(assert) {
|
||||
assert.plan(2);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]]
|
||||
};
|
||||
osrm.trip(options, function(err, trip) {
|
||||
assert.ifError(err);
|
||||
for (t = 0; t < trip.trips.length; t++) {
|
||||
assert.equal('string', typeof trip.trips[t].geometry);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('trip: trip through Berlin without geometry compression', function(assert) {
|
||||
assert.plan(2);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
geometries: 'geojson'
|
||||
};
|
||||
osrm.trip(options, function(err, trip) {
|
||||
assert.ifError(err);
|
||||
for (t = 0; t < trip.trips.length; t++) {
|
||||
assert.ok(Array.isArray(trip.trips[t].geometry.coordinates));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('trip: trip through Berlin with speed annotations options', function(assert) {
|
||||
assert.plan(12);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
steps: true,
|
||||
annotations: ['speed'],
|
||||
overview: 'false'
|
||||
};
|
||||
osrm.trip(options, function(err, trip) {
|
||||
assert.ifError(err);
|
||||
assert.equal(trip.trips.length, 1);
|
||||
for (t = 0; t < trip.trips.length; t++) {
|
||||
assert.ok(trip.trips[t]);
|
||||
assert.ok(trip.trips[t].legs.every(function(l) { return l.steps.length > 0; }), 'every leg has steps')
|
||||
assert.ok(trip.trips[t].legs.every(function(l) { return l.annotation; }), 'every leg has annotations')
|
||||
assert.ok(trip.trips[t].legs.every(function(l) { return l.annotation.speed; }), 'every leg has annotations for speed')
|
||||
assert.notOk(trip.trips[t].legs.every(function(l) { return l.annotation.weight; }), 'has no annotations for weight')
|
||||
assert.notOk(trip.trips[t].legs.every(function(l) { return l.annotation.datasources; }), 'has no annotations for datasources')
|
||||
assert.notOk(trip.trips[t].legs.every(function(l) { return l.annotation.duration; }), 'has no annotations for duration')
|
||||
assert.notOk(trip.trips[t].legs.every(function(l) { return l.annotation.distance; }), 'has no annotations for distance')
|
||||
assert.notOk(trip.trips[t].legs.every(function(l) { return l.annotation.nodes; }), 'has no annotations for nodes')
|
||||
assert.notOk(trip.trips[t].geometry);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('trip: trip through Berlin with several (duration, distance, nodes) annotations options', function(assert) {
|
||||
assert.plan(12);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
steps: true,
|
||||
annotations: ['duration', 'distance', 'nodes'],
|
||||
overview: 'false'
|
||||
};
|
||||
osrm.trip(options, function(err, trip) {
|
||||
assert.ifError(err);
|
||||
assert.equal(trip.trips.length, 1);
|
||||
for (t = 0; t < trip.trips.length; t++) {
|
||||
assert.ok(trip.trips[t]);
|
||||
assert.ok(trip.trips[t].legs.every(function(l) { return l.steps.length > 0; }), 'every leg has steps')
|
||||
assert.ok(trip.trips[t].legs.every(function(l) { return l.annotation; }), 'every leg has annotations')
|
||||
assert.ok(trip.trips[t].legs.every(function(l) { return l.annotation.duration; }), 'every leg has annotations for duration')
|
||||
assert.ok(trip.trips[t].legs.every(function(l) { return l.annotation.distance; }), 'every leg has annotations for distance')
|
||||
assert.ok(trip.trips[t].legs.every(function(l) { return l.annotation.nodes; }), 'every leg has annotations for nodes')
|
||||
assert.notOk(trip.trips[t].legs.every(function(l) { return l.annotation.weight; }), 'has no annotations for weight')
|
||||
assert.notOk(trip.trips[t].legs.every(function(l) { return l.annotation.datasources; }), 'has no annotations for datasources')
|
||||
assert.notOk(trip.trips[t].legs.every(function(l) { return l.annotation.speed; }), 'has no annotations for speed')
|
||||
assert.notOk(trip.trips[t].geometry);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('trip: trip through Berlin with options', function(assert) {
|
||||
assert.plan(6);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
steps: true,
|
||||
annotations: true,
|
||||
overview: 'false'
|
||||
};
|
||||
osrm.trip(options, function(err, trip) {
|
||||
assert.ifError(err);
|
||||
assert.equal(trip.trips.length, 1);
|
||||
for (t = 0; t < trip.trips.length; t++) {
|
||||
assert.ok(trip.trips[t]);
|
||||
assert.ok(trip.trips[t].legs.every(function(l) { return l.steps.length > 0; }), 'every leg has steps')
|
||||
assert.ok(trip.trips[t].legs.every(function(l) { return l.annotation; }), 'every leg has annotations')
|
||||
assert.notOk(trip.trips[t].geometry);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('trip: routes Berlin with null hints', function(assert) {
|
||||
assert.plan(1);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
printInstructions: false,
|
||||
hints: [null, null]
|
||||
};
|
||||
osrm.trip(options, function(err, second) {
|
||||
assert.ifError(err);
|
||||
});
|
||||
});
|
||||
|
||||
test('trip: service combinations that are not implemented', function(assert) {
|
||||
assert.plan(3);
|
||||
var osrm = new OSRM(berlin_path);
|
||||
|
||||
// fixed start, non-roundtrip
|
||||
var options = {
|
||||
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
|
||||
source: 'first',
|
||||
roundtrip: false
|
||||
};
|
||||
osrm.trip(options, function(err, second) {
|
||||
assert.equal('NotImplemented', err.message);
|
||||
});
|
||||
|
||||
// fixed start, fixed end, non-roundtrip
|
||||
options.source = 'any';
|
||||
options.destination = 'any';
|
||||
osrm.trip(options, function(err, second) {
|
||||
assert.equal('NotImplemented', err.message);
|
||||
});
|
||||
|
||||
// fixed end, non-roundtrip
|
||||
delete options.source;
|
||||
options.destination = 'last';
|
||||
osrm.trip(options, function(err, second) {
|
||||
assert.equal('NotImplemented', err.message);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
test('trip: fixed start and end combinations', function(assert) {
|
||||
var osrm = new OSRM(berlin_path);
|
||||
|
||||
var options = {
|
||||
coordinates: [[13.36761474609375,52.51663871100423],[13.374481201171875,52.506191342034576]],
|
||||
source: 'first',
|
||||
destination: 'last',
|
||||
roundtrip: false,
|
||||
geometries: 'geojson'
|
||||
};
|
||||
|
||||
// fixed start and end, non-roundtrip
|
||||
osrm.trip(options, function(err, fseTrip) {
|
||||
assert.ifError(err);
|
||||
assert.equal(206.8, fseTrip.trips[0].duration);
|
||||
assert.equal(1, fseTrip.trips.length);
|
||||
var coordinates = fseTrip.trips[0].geometry.coordinates;
|
||||
assert.equal(15, coordinates.length);
|
||||
assert.notEqual(JSON.stringify(coordinates[0]), JSON.stringify(coordinates[coordinates.length - 1]));
|
||||
});
|
||||
|
||||
// variations of roundtrip
|
||||
|
||||
var roundtripChecks = function(options) {
|
||||
osrm.trip(options, function(err, trip) {
|
||||
assert.ifError(err);
|
||||
assert.equal(1, trip.trips.length);
|
||||
assert.equal(422, Math.round(trip.trips[0].duration));
|
||||
var coordinates = trip.trips[0].geometry.coordinates;
|
||||
assert.equal(29, coordinates.length);
|
||||
assert.equal(JSON.stringify(coordinates[0]), JSON.stringify(coordinates[coordinates.length - 1]));
|
||||
});
|
||||
}
|
||||
|
||||
// roundtrip, source and destination not specified
|
||||
roundtripChecks({coordinates: options.coordinates, geometries: options.geometries});
|
||||
|
||||
// roundtrip, fixed destination
|
||||
options.roundtrip = true;
|
||||
delete options.source;
|
||||
roundtripChecks(options);
|
||||
|
||||
//roundtrip, fixed source
|
||||
delete options.destination;
|
||||
options.source = 'first';
|
||||
roundtripChecks(options);
|
||||
|
||||
// roundtrip, non-fixed source, non-fixed destination
|
||||
options.source = 'any';
|
||||
options.destination = 'any';
|
||||
roundtripChecks(options);
|
||||
|
||||
assert.end();
|
||||
});
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
// Somewhere in 2b8dd9343d5e615afc9c67bcc7028a63 Monaco
|
||||
// Somewhere in d41d8cd98f00b204e9800998ecf8427e Berlin
|
||||
|
||||
// Convenience aliases
|
||||
using Longitude = osrm::util::FloatLongitude;
|
||||
@ -15,21 +15,21 @@ using Locations = std::vector<Location>;
|
||||
|
||||
inline Location get_dummy_location()
|
||||
{
|
||||
return {osrm::util::FloatLongitude{7.437069}, osrm::util::FloatLatitude{43.749249}};
|
||||
return {osrm::util::FloatLongitude{13.388860}, osrm::util::FloatLatitude{52.517037}};
|
||||
}
|
||||
|
||||
inline Locations get_locations_in_small_component()
|
||||
{
|
||||
return {{Longitude{7.438023}, Latitude{43.746465}},
|
||||
{Longitude{7.439263}, Latitude{43.746543}},
|
||||
{Longitude{7.438190}, Latitude{43.747560}}};
|
||||
return {{Longitude{13.459765}, Latitude{52.543193}},
|
||||
{Longitude{13.461455}, Latitude{52.542381}},
|
||||
{Longitude{13.462940}, Latitude{52.541774}}};
|
||||
}
|
||||
|
||||
inline Locations get_locations_in_big_component()
|
||||
{
|
||||
return {{Longitude{7.415800}, Latitude{43.734132}},
|
||||
{Longitude{7.417710}, Latitude{43.736721}},
|
||||
{Longitude{7.421315}, Latitude{43.738814}}};
|
||||
return {{Longitude{13.442631}, Latitude{52.551110}},
|
||||
{Longitude{13.441193}, Latitude{52.549506}},
|
||||
{Longitude{13.439648}, Latitude{52.547705}}};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -19,7 +19,7 @@ BOOST_AUTO_TEST_CASE(test_extract_with_invalid_config)
|
||||
BOOST_AUTO_TEST_CASE(test_extract_with_valid_config)
|
||||
{
|
||||
osrm::ExtractorConfig config;
|
||||
config.input_path = {OSRM_TEST_DATA_DIR "/monaco.osm.pbf"};
|
||||
config.input_path = OSRM_TEST_DATA_DIR "/berlin.osm.pbf";
|
||||
config.requested_num_threads = tbb::task_scheduler_init::default_num_threads();
|
||||
BOOST_CHECK_NO_THROW(osrm::extract(config));
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ BOOST_AUTO_TEST_CASE(test_trip_limits)
|
||||
using namespace osrm;
|
||||
|
||||
EngineConfig config;
|
||||
config.storage_config = {OSRM_TEST_DATA_DIR "/monaco_CH.osrm"};
|
||||
config.storage_config = {OSRM_TEST_DATA_DIR "/berlin_CH.osrm"};
|
||||
config.use_shared_memory = false;
|
||||
config.max_locations_trip = 2;
|
||||
|
||||
@ -55,7 +55,7 @@ BOOST_AUTO_TEST_CASE(test_route_limits)
|
||||
using namespace osrm;
|
||||
|
||||
EngineConfig config;
|
||||
config.storage_config = {OSRM_TEST_DATA_DIR "/monaco_CH.osrm"};
|
||||
config.storage_config = {OSRM_TEST_DATA_DIR "/berlin_CH.osrm"};
|
||||
config.use_shared_memory = false;
|
||||
config.max_locations_viaroute = 2;
|
||||
|
||||
@ -82,7 +82,7 @@ BOOST_AUTO_TEST_CASE(test_table_limits)
|
||||
using namespace osrm;
|
||||
|
||||
EngineConfig config;
|
||||
config.storage_config = {OSRM_TEST_DATA_DIR "/monaco_CH.osrm"};
|
||||
config.storage_config = {OSRM_TEST_DATA_DIR "/berlin_CH.osrm"};
|
||||
config.use_shared_memory = false;
|
||||
config.max_locations_distance_table = 2;
|
||||
|
||||
@ -109,7 +109,7 @@ BOOST_AUTO_TEST_CASE(test_match_limits)
|
||||
using namespace osrm;
|
||||
|
||||
EngineConfig config;
|
||||
config.storage_config = {OSRM_TEST_DATA_DIR "/monaco_CH.osrm"};
|
||||
config.storage_config = {OSRM_TEST_DATA_DIR "/berlin_CH.osrm"};
|
||||
config.use_shared_memory = false;
|
||||
config.max_locations_map_matching = 2;
|
||||
|
||||
@ -136,7 +136,7 @@ BOOST_AUTO_TEST_CASE(test_nearest_limits)
|
||||
using namespace osrm;
|
||||
|
||||
EngineConfig config;
|
||||
config.storage_config = {OSRM_TEST_DATA_DIR "/monaco_CH.osrm"};
|
||||
config.storage_config = {OSRM_TEST_DATA_DIR "/berlin_CH.osrm"};
|
||||
config.use_shared_memory = false;
|
||||
config.max_results_nearest = 2;
|
||||
|
||||
|
@ -19,7 +19,7 @@ BOOST_AUTO_TEST_CASE(test_match)
|
||||
{
|
||||
using namespace osrm;
|
||||
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
|
||||
MatchParameters params;
|
||||
params.coordinates.push_back(get_dummy_location());
|
||||
|
@ -16,7 +16,7 @@ BOOST_AUTO_TEST_SUITE(nearest)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_nearest_response)
|
||||
{
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
|
||||
using namespace osrm;
|
||||
|
||||
@ -43,7 +43,7 @@ BOOST_AUTO_TEST_CASE(test_nearest_response)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_nearest_response_no_coordinates)
|
||||
{
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
|
||||
using namespace osrm;
|
||||
|
||||
@ -59,7 +59,7 @@ BOOST_AUTO_TEST_CASE(test_nearest_response_no_coordinates)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_nearest_response_multiple_coordinates)
|
||||
{
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
|
||||
using namespace osrm;
|
||||
|
||||
@ -77,7 +77,7 @@ BOOST_AUTO_TEST_CASE(test_nearest_response_multiple_coordinates)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_nearest_response_for_location_in_small_component)
|
||||
{
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
|
||||
using namespace osrm;
|
||||
|
||||
|
@ -14,7 +14,7 @@ BOOST_AUTO_TEST_CASE(test_ch)
|
||||
using namespace osrm;
|
||||
EngineConfig config;
|
||||
config.use_shared_memory = false;
|
||||
config.storage_config = storage::StorageConfig(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
config.storage_config = storage::StorageConfig(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
config.algorithm = EngineConfig::Algorithm::CH;
|
||||
OSRM osrm{config};
|
||||
}
|
||||
@ -24,7 +24,7 @@ BOOST_AUTO_TEST_CASE(test_corech)
|
||||
using namespace osrm;
|
||||
EngineConfig config;
|
||||
config.use_shared_memory = false;
|
||||
config.storage_config = storage::StorageConfig(OSRM_TEST_DATA_DIR "/monaco_CoreCH.osrm");
|
||||
config.storage_config = storage::StorageConfig(OSRM_TEST_DATA_DIR "/berlin_CoreCH.osrm");
|
||||
config.algorithm = EngineConfig::Algorithm::CoreCH;
|
||||
OSRM osrm{config};
|
||||
}
|
||||
@ -34,7 +34,7 @@ BOOST_AUTO_TEST_CASE(test_mld)
|
||||
using namespace osrm;
|
||||
EngineConfig config;
|
||||
config.use_shared_memory = false;
|
||||
config.storage_config = storage::StorageConfig(OSRM_TEST_DATA_DIR "/monaco_MLD.osrm");
|
||||
config.storage_config = storage::StorageConfig(OSRM_TEST_DATA_DIR "/berlin_MLD.osrm");
|
||||
config.algorithm = EngineConfig::Algorithm::MLD;
|
||||
OSRM osrm{config};
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ BOOST_AUTO_TEST_SUITE(route)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_route_same_coordinates_fixture)
|
||||
{
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
|
||||
using namespace osrm;
|
||||
|
||||
@ -25,44 +25,38 @@ BOOST_AUTO_TEST_CASE(test_route_same_coordinates_fixture)
|
||||
params.steps = true;
|
||||
params.coordinates.push_back(get_dummy_location());
|
||||
params.coordinates.push_back(get_dummy_location());
|
||||
params.generate_hints = false;
|
||||
|
||||
json::Object result;
|
||||
const auto rc = osrm.Route(params, result);
|
||||
BOOST_CHECK(rc == Status::Ok);
|
||||
|
||||
// unset snapping dependent hint
|
||||
for (auto &itr : result.values["waypoints"].get<json::Array>().values)
|
||||
itr.get<json::Object>().values["hint"] = "";
|
||||
|
||||
const auto location = json::Array{{{7.437070}, {43.749248}}};
|
||||
const auto location = json::Array{{{13.3888}, {52.517033}}};
|
||||
|
||||
json::Object reference{
|
||||
{{"code", "Ok"},
|
||||
{"waypoints",
|
||||
json::Array{
|
||||
{json::Object{
|
||||
{{"name", "Boulevard du Larvotto"}, {"location", location}, {"hint", ""}}},
|
||||
json::Object{
|
||||
{{"name", "Boulevard du Larvotto"}, {"location", location}, {"hint", ""}}}}}},
|
||||
json::Array{{json::Object{{{"name", "Friedrichstraße"}, {"location", location}}},
|
||||
json::Object{{{"name", "Friedrichstraße"}, {"location", location}}}}}},
|
||||
{"routes",
|
||||
json::Array{{json::Object{
|
||||
{{"distance", 0.},
|
||||
{"duration", 0.},
|
||||
{"weight", 0.},
|
||||
{"weight_name", "routability"},
|
||||
{"geometry", "yw_jGupkl@??"},
|
||||
{"geometry", "mfp_I__vpA??"},
|
||||
{"legs",
|
||||
json::Array{{json::Object{
|
||||
{{"distance", 0.},
|
||||
{"duration", 0.},
|
||||
{"weight", 0.},
|
||||
{"summary", "Boulevard du Larvotto"},
|
||||
{"summary", "Friedrichstraße"},
|
||||
{"steps",
|
||||
json::Array{{{json::Object{{{"duration", 0.},
|
||||
{"distance", 0.},
|
||||
{"weight", 0.},
|
||||
{"geometry", "yw_jGupkl@??"},
|
||||
{"name", "Boulevard du Larvotto"},
|
||||
{"geometry", "mfp_I__vpA??"},
|
||||
{"name", "Friedrichstraße"},
|
||||
{"mode", "driving"},
|
||||
{"maneuver",
|
||||
json::Object{{
|
||||
@ -81,8 +75,8 @@ BOOST_AUTO_TEST_CASE(test_route_same_coordinates_fixture)
|
||||
json::Object{{{"duration", 0.},
|
||||
{"distance", 0.},
|
||||
{"weight", 0.},
|
||||
{"geometry", "yw_jGupkl@"},
|
||||
{"name", "Boulevard du Larvotto"},
|
||||
{"geometry", "mfp_I__vpA"},
|
||||
{"name", "Friedrichstraße"},
|
||||
{"mode", "driving"},
|
||||
{"maneuver",
|
||||
json::Object{{{"location", location},
|
||||
@ -103,7 +97,7 @@ BOOST_AUTO_TEST_CASE(test_route_same_coordinates_fixture)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_route_same_coordinates)
|
||||
{
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
|
||||
using namespace osrm;
|
||||
|
||||
@ -255,7 +249,7 @@ BOOST_AUTO_TEST_CASE(test_route_same_coordinates)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_route_response_for_locations_in_small_component)
|
||||
{
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
|
||||
using namespace osrm;
|
||||
|
||||
@ -290,7 +284,7 @@ BOOST_AUTO_TEST_CASE(test_route_response_for_locations_in_small_component)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_route_response_for_locations_in_big_component)
|
||||
{
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
|
||||
using namespace osrm;
|
||||
|
||||
@ -325,7 +319,7 @@ BOOST_AUTO_TEST_CASE(test_route_response_for_locations_in_big_component)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_route_response_for_locations_across_components)
|
||||
{
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
|
||||
using namespace osrm;
|
||||
|
||||
@ -362,7 +356,7 @@ BOOST_AUTO_TEST_CASE(test_route_response_for_locations_across_components)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_route_user_disables_generating_hints)
|
||||
{
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
|
||||
using namespace osrm;
|
||||
|
||||
@ -382,7 +376,7 @@ BOOST_AUTO_TEST_CASE(test_route_user_disables_generating_hints)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(speed_annotation_matches_duration_and_distance)
|
||||
{
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
|
||||
using namespace osrm;
|
||||
|
||||
@ -416,7 +410,7 @@ BOOST_AUTO_TEST_CASE(speed_annotation_matches_duration_and_distance)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_manual_setting_of_annotations_property)
|
||||
{
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
|
||||
using namespace osrm;
|
||||
|
||||
|
@ -19,7 +19,7 @@ BOOST_AUTO_TEST_CASE(test_table_three_coords_one_source_one_dest_matrix)
|
||||
{
|
||||
using namespace osrm;
|
||||
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
|
||||
TableParameters params;
|
||||
params.coordinates.push_back(get_dummy_location());
|
||||
@ -66,7 +66,7 @@ BOOST_AUTO_TEST_CASE(test_table_three_coords_one_source_matrix)
|
||||
{
|
||||
using namespace osrm;
|
||||
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
|
||||
TableParameters params;
|
||||
params.coordinates.push_back(get_dummy_location());
|
||||
@ -113,7 +113,7 @@ BOOST_AUTO_TEST_CASE(test_table_three_coordinates_matrix)
|
||||
{
|
||||
using namespace osrm;
|
||||
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
|
||||
TableParameters params;
|
||||
params.coordinates.push_back(get_dummy_location());
|
||||
|
@ -24,16 +24,17 @@ BOOST_AUTO_TEST_CASE(test_tile)
|
||||
{
|
||||
using namespace osrm;
|
||||
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
|
||||
// This tile should contain most of monaco
|
||||
TileParameters params{17059, 11948, 15};
|
||||
// Tile within Berlin dataset at Hackescher Markt (13.40294, 52.52330)
|
||||
TileParameters params{140831, 85967, 18};
|
||||
|
||||
std::string result;
|
||||
const auto rc = osrm.Tile(params, result);
|
||||
BOOST_CHECK(rc == Status::Ok);
|
||||
|
||||
BOOST_CHECK(result.size() > 114000);
|
||||
BOOST_CHECK_GT(result.size(), 1500);
|
||||
BOOST_CHECK_LT(result.size(), 2500);
|
||||
|
||||
protozero::pbf_reader tile_message(result);
|
||||
tile_message.next();
|
||||
@ -208,22 +209,24 @@ BOOST_AUTO_TEST_CASE(test_tile)
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL(number_of_turn_keys, 3);
|
||||
BOOST_CHECK(number_of_turns_found > 700);
|
||||
BOOST_CHECK_GT(number_of_turns_found, 10); // roughly ten turns in the tile
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_tile_turns)
|
||||
{
|
||||
using namespace osrm;
|
||||
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
// Small tile where we can test all the values
|
||||
TileParameters params{272953, 191177, 19};
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
|
||||
// Tile within Berlin dataset at Hackescher Markt (13.40294, 52.52330)
|
||||
TileParameters params{140831, 85967, 18};
|
||||
|
||||
std::string result;
|
||||
const auto rc = osrm.Tile(params, result);
|
||||
BOOST_CHECK(rc == Status::Ok);
|
||||
|
||||
BOOST_CHECK_GT(result.size(), 128);
|
||||
BOOST_CHECK_GT(result.size(), 1500);
|
||||
BOOST_CHECK_LT(result.size(), 2500);
|
||||
|
||||
protozero::pbf_reader tile_message(result);
|
||||
tile_message.next();
|
||||
@ -331,7 +334,7 @@ BOOST_AUTO_TEST_CASE(test_tile_turns)
|
||||
}
|
||||
std::sort(actual_turn_penalties.begin(), actual_turn_penalties.end());
|
||||
const std::vector<float> expected_turn_penalties = {
|
||||
0, 0, 0, 0, 0, 0, .1f, .1f, .3f, .4f, 1.2f, 1.9f, 5.3f, 5.5f, 5.8f, 7.1f, 7.2f, 7.2f};
|
||||
0., 0., 0., 0., 0., 0., 0., 0., 0.1, 0.7, 5.2, 7.1, 7.4};
|
||||
CHECK_EQUAL_RANGE(actual_turn_penalties, expected_turn_penalties);
|
||||
|
||||
// Verify the expected turn angles
|
||||
@ -343,7 +346,7 @@ BOOST_AUTO_TEST_CASE(test_tile_turns)
|
||||
}
|
||||
std::sort(actual_turn_angles.begin(), actual_turn_angles.end());
|
||||
const std::vector<std::int64_t> expected_turn_angles = {
|
||||
-122, -120, -117, -65, -57, -30, -28, -3, -2, 2, 3, 28, 30, 57, 65, 117, 120, 122};
|
||||
-142, -118, -49, -13, -4, -2, -2, 2, 4, 13, 34, 49, 118};
|
||||
CHECK_EQUAL_RANGE(actual_turn_angles, expected_turn_angles);
|
||||
|
||||
// Verify the expected bearings
|
||||
@ -355,7 +358,7 @@ BOOST_AUTO_TEST_CASE(test_tile_turns)
|
||||
}
|
||||
std::sort(actual_turn_bearings.begin(), actual_turn_bearings.end());
|
||||
const std::vector<std::int64_t> expected_turn_bearings = {
|
||||
49, 49, 107, 107, 169, 169, 171, 171, 229, 229, 257, 257, 286, 286, 349, 349, 352, 352};
|
||||
75, 75, 124, 124, 128, 242, 242, 255, 304, 304, 306, 308, 308};
|
||||
CHECK_EQUAL_RANGE(actual_turn_bearings, expected_turn_bearings);
|
||||
}
|
||||
|
||||
@ -363,7 +366,7 @@ BOOST_AUTO_TEST_CASE(test_tile_speeds)
|
||||
{
|
||||
using namespace osrm;
|
||||
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
|
||||
// Small tile so we can test all the values
|
||||
// TileParameters params{272953, 191177, 19};
|
||||
@ -499,26 +502,7 @@ BOOST_AUTO_TEST_CASE(test_tile_speeds)
|
||||
actual_names.push_back(string_vals[i]);
|
||||
}
|
||||
std::sort(actual_names.begin(), actual_names.end());
|
||||
const std::vector<std::string> expected_names = {"Avenue du Carnier",
|
||||
"Avenue du Carnier",
|
||||
"Avenue du Carnier",
|
||||
"Avenue du Carnier",
|
||||
"Avenue du Carnier",
|
||||
"Avenue du Maréchal Foch",
|
||||
"Avenue du Maréchal Foch",
|
||||
"Avenue du Maréchal Foch",
|
||||
"Avenue du Maréchal Foch",
|
||||
"Avenue du Maréchal Foch",
|
||||
"Avenue du Maréchal Foch",
|
||||
"Avenue du Professeur Langevin",
|
||||
"Avenue du Professeur Langevin",
|
||||
"Avenue du Professeur Langevin",
|
||||
"Montée de la Crémaillère",
|
||||
"Montée de la Crémaillère",
|
||||
"Rue Jules Ferry",
|
||||
"Rue Jules Ferry",
|
||||
"Rue Professeur Calmette",
|
||||
"Rue Professeur Calmette"};
|
||||
const std::vector<std::string> expected_names = {};
|
||||
BOOST_CHECK(actual_names == expected_names);
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ BOOST_AUTO_TEST_CASE(test_roundtrip_response_for_locations_in_small_component)
|
||||
{
|
||||
using namespace osrm;
|
||||
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
const auto locations = get_locations_in_small_component();
|
||||
|
||||
TripParameters params;
|
||||
@ -60,7 +60,7 @@ BOOST_AUTO_TEST_CASE(test_roundtrip_response_for_locations_in_big_component)
|
||||
{
|
||||
using namespace osrm;
|
||||
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
const auto locations = get_locations_in_big_component();
|
||||
|
||||
TripParameters params;
|
||||
@ -102,7 +102,7 @@ BOOST_AUTO_TEST_CASE(test_roundtrip_response_for_locations_across_components)
|
||||
{
|
||||
using namespace osrm;
|
||||
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
const auto small = get_locations_in_small_component();
|
||||
const auto big = get_locations_in_big_component();
|
||||
|
||||
@ -148,7 +148,7 @@ BOOST_AUTO_TEST_CASE(test_tfse_1)
|
||||
{
|
||||
using namespace osrm;
|
||||
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
const auto locations = get_locations_in_small_component();
|
||||
|
||||
TripParameters params;
|
||||
@ -194,7 +194,7 @@ BOOST_AUTO_TEST_CASE(test_tfse_2)
|
||||
{
|
||||
using namespace osrm;
|
||||
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
const auto locations = get_locations_in_big_component();
|
||||
|
||||
TripParameters params;
|
||||
@ -265,7 +265,7 @@ BOOST_AUTO_TEST_CASE(test_tfse_illegal_parameters)
|
||||
{
|
||||
using namespace osrm;
|
||||
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
const auto locations = get_locations_in_big_component();
|
||||
auto params = osrm::TripParameters();
|
||||
|
||||
@ -315,7 +315,7 @@ BOOST_AUTO_TEST_CASE(test_tfse_illegal_parameters)
|
||||
BOOST_AUTO_TEST_CASE(test_tfse_legal_parameters)
|
||||
{
|
||||
using namespace osrm;
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/monaco_CH.osrm");
|
||||
auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/berlin_CH.osrm");
|
||||
const auto locations = get_locations_in_big_component();
|
||||
json::Object result;
|
||||
TripParameters params;
|
||||
|
Loading…
Reference in New Issue
Block a user