Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a123cb6efb | |||
| 63e713aa4a | |||
| 9daef767fa | |||
| d89a513183 | |||
| c43ea37e05 | |||
| ec6c10661f | |||
| bcdc689ae9 | |||
| b3eb8970f1 | |||
| ab22cc7516 | |||
| 18f446735c | |||
| 9234b2ae76 | |||
| 8b5ade3861 | |||
| baa8214270 | |||
| d41b03b778 | |||
| 3d781e6f28 | |||
| 31d8ff7a74 | |||
| cb2532d0da | |||
| e222fcfb17 | |||
| 4976233cff | |||
| 98ea2a0b09 | |||
| f978900ab0 | |||
| 8b6580128b | |||
| 4dde9c7bbe | |||
| 7a5b6dbede | |||
| c08953c0e6 | |||
| 973837207b | |||
| 364e35af06 | |||
| 985ab58f45 | |||
| e5a6c73fdf |
+57
@@ -13,6 +13,7 @@ notifications:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- "5.20.1"
|
||||
# enable building tags
|
||||
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/
|
||||
|
||||
@@ -154,6 +155,14 @@ matrix:
|
||||
packages: ['g++-6', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libboost-all-dev', 'ccache']
|
||||
env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release'
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode9.2
|
||||
compiler: "mason-osx-release-node-10"
|
||||
# we use the xcode provides clang and don't install our own
|
||||
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON ENABLE_LTO=ON NODE="10"
|
||||
after_success:
|
||||
- ./scripts/travis/publish.sh
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode9.2
|
||||
compiler: "mason-osx-release-node-8"
|
||||
@@ -276,6 +285,54 @@ matrix:
|
||||
after_success:
|
||||
- ./scripts/travis/publish.sh
|
||||
|
||||
- os: linux
|
||||
sudo: false
|
||||
compiler: "node-10-mason-linux-release"
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['libstdc++-4.9-dev']
|
||||
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="10"
|
||||
install:
|
||||
- pushd ${OSRM_BUILD_DIR}
|
||||
- |
|
||||
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
|
||||
-DENABLE_MASON=${ENABLE_MASON:-OFF} \
|
||||
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
|
||||
-DENABLE_CCACHE=ON \
|
||||
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
|
||||
-DENABLE_GLIBC_WORKAROUND=ON
|
||||
- make --jobs=${JOBS}
|
||||
- popd
|
||||
script:
|
||||
- npm run nodejs-tests
|
||||
after_success:
|
||||
- ./scripts/travis/publish.sh
|
||||
|
||||
- os: linux
|
||||
sudo: false
|
||||
compiler: "node-10-mason-linux-debug"
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['libstdc++-4.9-dev']
|
||||
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="10"
|
||||
install:
|
||||
- pushd ${OSRM_BUILD_DIR}
|
||||
- |
|
||||
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
|
||||
-DENABLE_MASON=${ENABLE_MASON:-OFF} \
|
||||
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
|
||||
-DENABLE_CCACHE=ON \
|
||||
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
|
||||
-DENABLE_GLIBC_WORKAROUND=ON
|
||||
- make --jobs=${JOBS}
|
||||
- popd
|
||||
script:
|
||||
- npm run nodejs-tests
|
||||
after_success:
|
||||
- ./scripts/travis/publish.sh
|
||||
|
||||
before_install:
|
||||
- source $NVM_DIR/nvm.sh
|
||||
- nvm install $NODE
|
||||
|
||||
+13
-1
@@ -1,10 +1,22 @@
|
||||
# UNRELEASED
|
||||
# 5.20.1 RC 3
|
||||
- Changes from 5.20.0
|
||||
- Features:
|
||||
- ADDED: all waypoints in responses now contain a distance property between the original coordinate and the snapped location. [#5255](https://github.com/Project-OSRM/osrm-backend/pull/5255)
|
||||
- Table:
|
||||
- ADDED: new parameter `scale_factor` which will scale the cell `duration` values by this factor. [#5298](https://github.com/Project-OSRM/osrm-backend/pull/5298)
|
||||
- FIXED: only trigger `scale_factor` code to scan matrix when necessary. [#5303](https://github.com/Project-OSRM/osrm-backend/pull/5303)
|
||||
|
||||
# 5.20.0
|
||||
- Changes from 5.19.0:
|
||||
- Table:
|
||||
- CHANGED: switch to pre-calculated distances for table responses for large speedup and 10% memory increase. [#5251](https://github.com/Project-OSRM/osrm-backend/pull/5251)
|
||||
- ADDED: new parameter `fallback_speed` which will fill `null` cells with estimated value [#5257](https://github.com/Project-OSRM/osrm-backend/pull/5257)
|
||||
- CHANGED: Remove API check for matrix sources/destination length to be less than or equal to coordinates length. [#5298](https://github.com/Project-OSRM/osrm-backend/pull/5289)
|
||||
- FIXED: Fix crashing bug when using fallback_speed parameter with more sources than destinations. [#5291](https://github.com/Project-OSRM/osrm-backend/pull/5291)
|
||||
- Features:
|
||||
- ADDED: direct mmapping of datafiles is now supported via the `--mmap` switch. [#5242](https://github.com/Project-OSRM/osrm-backend/pull/5242)
|
||||
- REMOVED: the previous `--memory_file` switch is now deprecated and will fallback to `--mmap` [#5242](https://github.com/Project-OSRM/osrm-backend/pull/5242)
|
||||
- ADDED: Now publishing Node 10.x LTS binary modules [#5246](https://github.com/Project-OSRM/osrm-backend/pull/5246)
|
||||
- Windows:
|
||||
- FIXED: Windows builds again. [#5249](https://github.com/Project-OSRM/osrm-backend/pull/5249)
|
||||
|
||||
|
||||
+13
-12
@@ -1,15 +1,13 @@
|
||||
FROM alpine:3.6 as buildstage
|
||||
|
||||
FROM debian:buster-slim as builder
|
||||
ARG DOCKER_TAG
|
||||
RUN mkdir -p /src && mkdir -p /opt
|
||||
COPY . /src
|
||||
WORKDIR /src
|
||||
|
||||
RUN NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \
|
||||
echo "@testing http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories && \
|
||||
apk update && \
|
||||
apk upgrade && \
|
||||
apk add git cmake wget make libc-dev gcc g++ bzip2-dev boost-dev zlib-dev expat-dev lua5.2-dev libtbb@testing libtbb-dev@testing && \
|
||||
apt-get update && \
|
||||
apt-get -y --no-install-recommends install cmake make git gcc g++ libbz2-dev libstxxl-dev libstxxl1v5 libxml2-dev \
|
||||
libzip-dev libboost-all-dev lua5.2 liblua5.2-dev libtbb-dev -o APT::Install-Suggests=0 -o APT::Install-Recommends=0 && \
|
||||
NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \
|
||||
echo "Building OSRM ${DOCKER_TAG}" && \
|
||||
git show --format="%H" | head -n1 > /opt/OSRM_GITSHA && \
|
||||
@@ -33,13 +31,16 @@ RUN NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \
|
||||
|
||||
# Multistage build to reduce image size - https://docs.docker.com/engine/userguide/eng-image/multistage-build/#use-multi-stage-builds
|
||||
# Only the content below ends up in the image, this helps remove /src from the image (which is large)
|
||||
FROM alpine:3.6 as runstage
|
||||
FROM debian:buster-slim as runstage
|
||||
RUN mkdir -p /src && mkdir -p /opt
|
||||
RUN echo "@testing http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories && \
|
||||
apk update && \
|
||||
apk add boost-filesystem boost-program_options boost-regex boost-iostreams boost-thread libgomp lua5.2 expat libtbb@testing
|
||||
COPY --from=buildstage /usr/local /usr/local
|
||||
COPY --from=buildstage /opt /opt
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends libboost-program-options1.62.0 libboost-regex1.62.0 \
|
||||
libboost-date-time1.62.0 libboost-chrono1.62.0 libboost-filesystem1.62.0 \
|
||||
libboost-iostreams1.62.0 libboost-thread1.62.0 expat liblua5.2-0 libtbb2 &&\
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
COPY --from=builder /usr/local /usr/local
|
||||
COPY --from=builder /opt /opt
|
||||
RUN chmod 0644 -R /opt
|
||||
WORKDIR /opt
|
||||
|
||||
EXPOSE 5000
|
||||
|
||||
+4
-2
@@ -236,8 +236,10 @@ In addition to the [general options](#general-options) the following options are
|
||||
|------------|--------------------------------------------------|---------------------------------------------|
|
||||
|sources |`{index};{index}[;{index} ...]` or `all` (default)|Use location with given index as source. |
|
||||
|destinations|`{index};{index}[;{index} ...]` or `all` (default)|Use location with given index as destination.|
|
||||
|annotations |`duration` (default), `distance`, or `duration,distance`|Return the requested table or tables in response. Note that computing the `distances` table is currently only implemented for CH. If `annotations=distance` or `annotations=duration,distance` is requested when running a MLD router, a `NotImplemented` error will be returned.
|
||||
|
|
||||
|annotations |`duration` (default), `distance`, or `duration,distance`|Return the requested table or tables in response. |
|
||||
|fallback_speed|`double > 0`| If no route found between a source/destination pair, calculate the as-the-crow-flies distance, then use this speed to estimate duration.|
|
||||
|fallback_coordinate|`input` (default), or `snapped`| When using a `fallback_speed`, use the user-supplied coordinate (`input`), or the snapped location (`snapped`) for calculating distances.|
|
||||
|scale_factor|`double > 0`| Use in conjunction with `annotations=durations`. Scales the table `duration` values by this number.|
|
||||
|
||||
Unlike other array encoded options, the length of `sources` and `destinations` can be **smaller or equal**
|
||||
to number of input locations;
|
||||
|
||||
@@ -129,6 +129,9 @@ tables. Optionally returns distance table.
|
||||
- `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.
|
||||
- `options.approaches` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`.
|
||||
- `options.fallback_speed` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Replace `null` responses in result with as-the-crow-flies estimates based on `fallback_speed`. Value is in metres/second.
|
||||
- `options.fallback_coordinate` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** Either `input` (default) or `snapped`. If using a `fallback_speed`, use either the user-supplied coordinate (`input`), or the snapped coordinate (`snapped`) for calculating the as-the-crow-flies diestance between two points.
|
||||
- `options.scale_factor` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Multiply the table duration values in the table by this number for more controlled input into a route optimization solver.
|
||||
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
|
||||
|
||||
**Examples**
|
||||
|
||||
@@ -80,7 +80,7 @@ module.exports = function () {
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.info(util.format('Node Version', process.version));
|
||||
if (parseInt(process.version.match(/v(\d)/)[1]) < 4) throw new Error('*** Please upgrade to Node 4.+ to run OSRM cucumber tests');
|
||||
if (parseInt(process.version.match(/v(\d+)/)[1]) < 4) throw new Error('*** Please upgrade to Node 4.+ to run OSRM cucumber tests');
|
||||
|
||||
fs.exists(this.TEST_PATH, (exists) => {
|
||||
if (exists)
|
||||
|
||||
@@ -595,3 +595,109 @@ Feature: Basic Distance Matrix
|
||||
| d | 1478.9 | 1579 | 1779.1 | 0 | 1280.1 | 882.5 |
|
||||
| e | 198.8 | 298.9 | 499 | 710.3 | 0 | 1592.8 |
|
||||
| f | 596.4 | 696.5 | 896.6 | 1107.9 | 397.6 | 0 |
|
||||
|
||||
Scenario: Testbot - Filling in noroutes with estimates (defaults to input coordinate location)
|
||||
Given a grid size of 300 meters
|
||||
Given the extract extra arguments "--small-component-size 4"
|
||||
Given the query options
|
||||
| fallback_speed | 5 |
|
||||
Given the node map
|
||||
"""
|
||||
a b f h 1
|
||||
d e g i
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes |
|
||||
| abeda |
|
||||
| fhigf |
|
||||
|
||||
When I request a travel distance matrix I should get
|
||||
| | a | b | f | 1 |
|
||||
| a | 0 | 300.2 | 900.7 | 1501.1 |
|
||||
| b | 300.2 | 0 | 600.5 | 1200.9 |
|
||||
| f | 900.7 | 600.5 | 0 | 302.2 |
|
||||
| 1 | 1501.1 | 1200.9 | 300.2 | 0 |
|
||||
|
||||
When I request a travel distance matrix I should get
|
||||
| | a | b | f | 1 |
|
||||
| a | 0 | 300.2 | 900.7 | 1501.1 |
|
||||
|
||||
When I request a travel distance matrix I should get
|
||||
| | a |
|
||||
| a | 0 |
|
||||
| b | 300.2 |
|
||||
| f | 900.7 |
|
||||
| 1 | 1501.1 |
|
||||
|
||||
Scenario: Testbot - Fise input coordinate
|
||||
Given a grid size of 300 meters
|
||||
Given the extract extra arguments "--small-component-size 4"
|
||||
Given the query options
|
||||
| fallback_speed | 5 |
|
||||
| fallback_coordinate | input |
|
||||
Given the node map
|
||||
"""
|
||||
a b f h 1
|
||||
d e g i
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes |
|
||||
| abeda |
|
||||
| fhigf |
|
||||
|
||||
When I request a travel distance matrix I should get
|
||||
| | a | b | f | 1 |
|
||||
| a | 0 | 300.2 | 900.7 | 1501.1 |
|
||||
| b | 300.2 | 0 | 600.5 | 1200.9 |
|
||||
| f | 900.7 | 600.5 | 0 | 302.2 |
|
||||
| 1 | 1501.1 | 1200.9 | 300.2 | 0 |
|
||||
|
||||
When I request a travel distance matrix I should get
|
||||
| | a | b | f | 1 |
|
||||
| a | 0 | 300.2 | 900.7 | 1501.1 |
|
||||
|
||||
When I request a travel distance matrix I should get
|
||||
| | a |
|
||||
| a | 0 |
|
||||
| b | 300.2 |
|
||||
| f | 900.7 |
|
||||
| 1 | 1501.1 |
|
||||
|
||||
|
||||
Scenario: Testbot - Filling in noroutes with estimates - use snapped coordinate
|
||||
Given a grid size of 300 meters
|
||||
Given the extract extra arguments "--small-component-size 4"
|
||||
Given the query options
|
||||
| fallback_speed | 5 |
|
||||
| fallback_coordinate | snapped |
|
||||
Given the node map
|
||||
"""
|
||||
a b f h 1
|
||||
d e g i
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes |
|
||||
| abeda |
|
||||
| fhigf |
|
||||
|
||||
When I request a travel distance matrix I should get
|
||||
| | a | b | f | 1 |
|
||||
| a | 0 | 300.2 | 900.7 | 1200.9 |
|
||||
| b | 300.2 | 0 | 600.5 | 900.7 |
|
||||
| f | 900.7 | 600.5 | 0 | 302.2 |
|
||||
| 1 | 1200.9 | 900.7 | 300.2 | 0 |
|
||||
|
||||
When I request a travel distance matrix I should get
|
||||
| | a | b | f | 1 |
|
||||
| a | 0 | 300.2 | 900.7 | 1200.9 |
|
||||
|
||||
When I request a travel distance matrix I should get
|
||||
| | a |
|
||||
| a | 0 |
|
||||
| b | 300.2 |
|
||||
| f | 900.7 |
|
||||
| 1 | 1200.9 |
|
||||
|
||||
|
||||
@@ -510,3 +510,195 @@ Feature: Basic Duration Matrix
|
||||
| | a |
|
||||
| a | 0 |
|
||||
| b | 24.1 |
|
||||
|
||||
Scenario: Testbot - Filling in noroutes with estimates (defaults to input coordinate location)
|
||||
Given a grid size of 300 meters
|
||||
Given the extract extra arguments "--small-component-size 4"
|
||||
Given the query options
|
||||
| fallback_speed | 5 |
|
||||
Given the node map
|
||||
"""
|
||||
a b f h 1
|
||||
d e g i
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes |
|
||||
| abeda |
|
||||
| fhigf |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a | b | f | 1 |
|
||||
| a | 0 | 30 | 18 | 30 |
|
||||
| b | 30 | 0 | 12 | 24 |
|
||||
| f | 18 | 12 | 0 | 30 |
|
||||
| 1 | 30 | 24 | 30 | 0 |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a | b | f | 1 |
|
||||
| a | 0 | 30 | 18 | 30 |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a |
|
||||
| a | 0 |
|
||||
| b | 30 |
|
||||
| f | 18 |
|
||||
| 1 | 30 |
|
||||
|
||||
Scenario: Testbot - Filling in noroutes with estimates - use input coordinate
|
||||
Given a grid size of 300 meters
|
||||
Given the extract extra arguments "--small-component-size 4"
|
||||
Given the query options
|
||||
| fallback_speed | 5 |
|
||||
| fallback_coordinate | input |
|
||||
Given the node map
|
||||
"""
|
||||
a b f h 1
|
||||
d e g i
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes |
|
||||
| abeda |
|
||||
| fhigf |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a | b | f | 1 |
|
||||
| a | 0 | 30 | 18 | 30 |
|
||||
| b | 30 | 0 | 12 | 24 |
|
||||
| f | 18 | 12 | 0 | 30 |
|
||||
| 1 | 30 | 24 | 30 | 0 |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a | b | f | 1 |
|
||||
| a | 0 | 30 | 18 | 30 |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a |
|
||||
| a | 0 |
|
||||
| b | 30 |
|
||||
| f | 18 |
|
||||
| 1 | 30 |
|
||||
|
||||
Scenario: Testbot - Filling in noroutes with estimates - use snapped coordinate
|
||||
Given a grid size of 300 meters
|
||||
Given the extract extra arguments "--small-component-size 4"
|
||||
Given the query options
|
||||
| fallback_speed | 5 |
|
||||
| fallback_coordinate | snapped |
|
||||
Given the node map
|
||||
"""
|
||||
a b f h 1
|
||||
d e g i
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes |
|
||||
| abeda |
|
||||
| fhigf |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a | b | f | 1 |
|
||||
| a | 0 | 30 | 18 | 24 |
|
||||
| b | 30 | 0 | 12 | 18 |
|
||||
| f | 18 | 12 | 0 | 30 |
|
||||
| 1 | 24 | 18 | 30 | 0 |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a | b | f | 1 |
|
||||
| a | 0 | 30 | 18 | 24 |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a |
|
||||
| a | 0 |
|
||||
| b | 30 |
|
||||
| f | 18 |
|
||||
| 1 | 24 |
|
||||
|
||||
|
||||
Scenario: Testbot - Travel time matrix of minimal network with scale factor
|
||||
Given the query options
|
||||
| scale_factor | 2 |
|
||||
Given the node map
|
||||
"""
|
||||
a b
|
||||
"""
|
||||
And the ways
|
||||
| nodes |
|
||||
| ab |
|
||||
When I request a travel time matrix I should get
|
||||
| | a | b |
|
||||
| a | 0 | 20 |
|
||||
| b | 20 | 0 |
|
||||
Scenario: Testbot - Test fallback speeds and scale factor
|
||||
Given a grid size of 300 meters
|
||||
Given the extract extra arguments "--small-component-size 4"
|
||||
Given the query options
|
||||
| scale_factor | 2 |
|
||||
| fallback_speed | 5 |
|
||||
| fallback_coordinate | snapped |
|
||||
|
||||
Given the node map
|
||||
"""
|
||||
a b f h 1
|
||||
d e g i
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes |
|
||||
| abeda |
|
||||
| fhigf |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a | b | f | 1 |
|
||||
| a | 0 | 60 | 36 | 48 |
|
||||
| b | 60 | 0 | 24 | 36 |
|
||||
| f | 36 | 24 | 0 | 60 |
|
||||
| 1 | 48 | 36 | 60 | 0 |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a | b | f | 1 |
|
||||
| a | 0 | 60 | 36 | 48 |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a |
|
||||
| a | 0 |
|
||||
| b | 60 |
|
||||
| f | 36 |
|
||||
| 1 | 48 |
|
||||
|
||||
Scenario: Testbot - Travel time matrix of minimal network with overflow scale factor
|
||||
Given the query options
|
||||
| scale_factor | 2147483647 |
|
||||
|
||||
Given the node map
|
||||
"""
|
||||
a b
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes |
|
||||
| ab |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a | b |
|
||||
| a | 0 | 214748364.6 |
|
||||
| b | 214748364.6 | 0 |
|
||||
|
||||
Scenario: Testbot - Travel time matrix of minimal network with fraction scale factor
|
||||
Given the query options
|
||||
| scale_factor | 0.5 |
|
||||
|
||||
Given the node map
|
||||
"""
|
||||
a b
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes |
|
||||
| ab |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a | b |
|
||||
| a | 0 | 5 |
|
||||
| b | 5 | 0 |
|
||||
|
||||
@@ -59,6 +59,15 @@ struct TableParameters : public BaseParameters
|
||||
{
|
||||
std::vector<std::size_t> sources;
|
||||
std::vector<std::size_t> destinations;
|
||||
double fallback_speed = INVALID_FALLBACK_SPEED;
|
||||
|
||||
enum class FallbackCoordinateType
|
||||
{
|
||||
Input = 0,
|
||||
Snapped = 1
|
||||
};
|
||||
|
||||
FallbackCoordinateType fallback_coordinate_type = FallbackCoordinateType::Input;
|
||||
|
||||
enum class AnnotationsType
|
||||
{
|
||||
@@ -70,6 +79,8 @@ struct TableParameters : public BaseParameters
|
||||
|
||||
AnnotationsType annotations = AnnotationsType::Duration;
|
||||
|
||||
double scale_factor = 1;
|
||||
|
||||
TableParameters() = default;
|
||||
template <typename... Args>
|
||||
TableParameters(std::vector<std::size_t> sources_,
|
||||
@@ -90,6 +101,22 @@ struct TableParameters : public BaseParameters
|
||||
{
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
TableParameters(std::vector<std::size_t> sources_,
|
||||
std::vector<std::size_t> destinations_,
|
||||
const AnnotationsType annotations_,
|
||||
double fallback_speed_,
|
||||
FallbackCoordinateType fallback_coordinate_type_,
|
||||
double scale_factor_,
|
||||
Args... args_)
|
||||
: BaseParameters{std::forward<Args>(args_)...}, sources{std::move(sources_)},
|
||||
destinations{std::move(destinations_)}, fallback_speed{fallback_speed_},
|
||||
fallback_coordinate_type{fallback_coordinate_type_}, annotations{annotations_},
|
||||
scale_factor{scale_factor_}
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
bool IsValid() const
|
||||
{
|
||||
if (!BaseParameters::IsValid())
|
||||
@@ -101,14 +128,7 @@ struct TableParameters : public BaseParameters
|
||||
|
||||
// 1/ The user is able to specify duplicates in srcs and dsts, in that case it's their fault
|
||||
|
||||
// 2/ len(srcs) and len(dsts) smaller or equal to len(locations)
|
||||
if (sources.size() > coordinates.size())
|
||||
return false;
|
||||
|
||||
if (destinations.size() > coordinates.size())
|
||||
return false;
|
||||
|
||||
// 3/ 0 <= index < len(locations)
|
||||
// 2/ 0 <= index < len(locations)
|
||||
const auto not_in_range = [this](const std::size_t x) { return x >= coordinates.size(); };
|
||||
|
||||
if (std::any_of(begin(sources), end(sources), not_in_range))
|
||||
@@ -117,6 +137,12 @@ struct TableParameters : public BaseParameters
|
||||
if (std::any_of(begin(destinations), end(destinations), not_in_range))
|
||||
return false;
|
||||
|
||||
if (fallback_speed <= 0)
|
||||
return false;
|
||||
|
||||
if (scale_factor <= 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1183,6 +1183,70 @@ argumentsToTableParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
|
||||
}
|
||||
}
|
||||
|
||||
if (obj->Has(Nan::New("fallback_speed").ToLocalChecked()))
|
||||
{
|
||||
auto fallback_speed = obj->Get(Nan::New("fallback_speed").ToLocalChecked());
|
||||
|
||||
if (!fallback_speed->IsNumber())
|
||||
{
|
||||
Nan::ThrowError("fallback_speed must be a number");
|
||||
return table_parameters_ptr();
|
||||
}
|
||||
else if (fallback_speed->NumberValue() <= 0)
|
||||
{
|
||||
Nan::ThrowError("fallback_speed must be > 0");
|
||||
return table_parameters_ptr();
|
||||
}
|
||||
|
||||
params->fallback_speed = static_cast<double>(fallback_speed->NumberValue());
|
||||
}
|
||||
|
||||
if (obj->Has(Nan::New("fallback_coordinate").ToLocalChecked()))
|
||||
{
|
||||
auto fallback_coordinate = obj->Get(Nan::New("fallback_coordinate").ToLocalChecked());
|
||||
|
||||
if (!fallback_coordinate->IsString())
|
||||
{
|
||||
Nan::ThrowError("fallback_coordinate must be a string: [input, snapped]");
|
||||
return table_parameters_ptr();
|
||||
}
|
||||
|
||||
std::string fallback_coordinate_str = *v8::String::Utf8Value(fallback_coordinate);
|
||||
|
||||
if (fallback_coordinate_str == "snapped")
|
||||
{
|
||||
params->fallback_coordinate_type =
|
||||
osrm::TableParameters::FallbackCoordinateType::Snapped;
|
||||
}
|
||||
else if (fallback_coordinate_str == "input")
|
||||
{
|
||||
params->fallback_coordinate_type = osrm::TableParameters::FallbackCoordinateType::Input;
|
||||
}
|
||||
else
|
||||
{
|
||||
Nan::ThrowError("'fallback_coordinate' param must be one of [input, snapped]");
|
||||
return table_parameters_ptr();
|
||||
}
|
||||
}
|
||||
|
||||
if (obj->Has(Nan::New("scale_factor").ToLocalChecked()))
|
||||
{
|
||||
auto scale_factor = obj->Get(Nan::New("scale_factor").ToLocalChecked());
|
||||
|
||||
if (!scale_factor->IsNumber())
|
||||
{
|
||||
Nan::ThrowError("scale_factor must be a number");
|
||||
return table_parameters_ptr();
|
||||
}
|
||||
else if (scale_factor->NumberValue() <= 0)
|
||||
{
|
||||
Nan::ThrowError("scale_factor must be > 0");
|
||||
return table_parameters_ptr();
|
||||
}
|
||||
|
||||
params->scale_factor = static_cast<double>(scale_factor->NumberValue());
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
|
||||
@@ -178,6 +178,8 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
|
||||
qi::rule<Iterator, Signature> base_rule;
|
||||
qi::rule<Iterator, Signature> query_rule;
|
||||
|
||||
qi::real_parser<double, json_policy> double_;
|
||||
|
||||
private:
|
||||
qi::rule<Iterator, Signature> bearings_rule;
|
||||
qi::rule<Iterator, Signature> radiuses_rule;
|
||||
@@ -195,7 +197,6 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
|
||||
qi::rule<Iterator, unsigned char()> base64_char;
|
||||
qi::rule<Iterator, std::string()> polyline_chars;
|
||||
qi::rule<Iterator, double()> unlimited_rule;
|
||||
qi::real_parser<double, json_policy> double_;
|
||||
|
||||
qi::symbols<char, engine::Approach> approach_type;
|
||||
};
|
||||
|
||||
@@ -48,10 +48,28 @@ struct TableParametersGrammar : public BaseParametersGrammar<Iterator, Signature
|
||||
(qi::lit("all") |
|
||||
(size_t_ % ';')[ph::bind(&engine::api::TableParameters::sources, qi::_r1) = qi::_1]);
|
||||
|
||||
fallback_speed_rule =
|
||||
qi::lit("fallback_speed=") >
|
||||
(double_)[ph::bind(&engine::api::TableParameters::fallback_speed, qi::_r1) = qi::_1];
|
||||
|
||||
fallback_coordinate_type.add("input",
|
||||
engine::api::TableParameters::FallbackCoordinateType::Input)(
|
||||
"snapped", engine::api::TableParameters::FallbackCoordinateType::Snapped);
|
||||
|
||||
scale_factor_rule =
|
||||
qi::lit("scale_factor=") >
|
||||
(double_)[ph::bind(&engine::api::TableParameters::scale_factor, qi::_r1) = qi::_1];
|
||||
|
||||
table_rule = destinations_rule(qi::_r1) | sources_rule(qi::_r1);
|
||||
|
||||
root_rule = BaseGrammar::query_rule(qi::_r1) > -qi::lit(".json") >
|
||||
-('?' > (table_rule(qi::_r1) | base_rule(qi::_r1)) % '&');
|
||||
-('?' > (table_rule(qi::_r1) | base_rule(qi::_r1) | scale_factor_rule(qi::_r1) |
|
||||
fallback_speed_rule(qi::_r1) |
|
||||
(qi::lit("fallback_coordinate=") >
|
||||
fallback_coordinate_type
|
||||
[ph::bind(&engine::api::TableParameters::fallback_coordinate_type,
|
||||
qi::_r1) = qi::_1])) %
|
||||
'&');
|
||||
}
|
||||
|
||||
TableParametersGrammar(qi::rule<Iterator, Signature> &root_rule_) : BaseGrammar(root_rule_)
|
||||
@@ -73,13 +91,20 @@ struct TableParametersGrammar : public BaseParametersGrammar<Iterator, Signature
|
||||
qi::rule<Iterator, Signature> base_rule;
|
||||
|
||||
private:
|
||||
using json_policy = no_trailing_dot_policy<double, 'j', 's', 'o', 'n'>;
|
||||
|
||||
qi::rule<Iterator, Signature> root_rule;
|
||||
qi::rule<Iterator, Signature> table_rule;
|
||||
qi::rule<Iterator, Signature> sources_rule;
|
||||
qi::rule<Iterator, Signature> destinations_rule;
|
||||
qi::rule<Iterator, Signature> fallback_speed_rule;
|
||||
qi::rule<Iterator, Signature> scale_factor_rule;
|
||||
qi::rule<Iterator, std::size_t()> size_t_;
|
||||
qi::symbols<char, engine::api::TableParameters::AnnotationsType> annotations;
|
||||
qi::rule<Iterator, engine::api::TableParameters::AnnotationsType()> annotations_list;
|
||||
qi::symbols<char, engine::api::TableParameters::FallbackCoordinateType>
|
||||
fallback_coordinate_type;
|
||||
qi::real_parser<double, json_policy> double_;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,6 +116,7 @@ static const EdgeDuration MAXIMAL_EDGE_DURATION = std::numeric_limits<EdgeDurati
|
||||
static const EdgeDistance MAXIMAL_EDGE_DISTANCE = std::numeric_limits<EdgeDistance>::max();
|
||||
static const TurnPenalty INVALID_TURN_PENALTY = std::numeric_limits<TurnPenalty>::max();
|
||||
static const EdgeDistance INVALID_EDGE_DISTANCE = std::numeric_limits<EdgeDistance>::max();
|
||||
static const EdgeDistance INVALID_FALLBACK_SPEED = std::numeric_limits<double>::max();
|
||||
|
||||
// FIXME the bitfields we use require a reduced maximal duration, this should be kept consistent
|
||||
// within the code base. For now we have to ensure that we don't case 30 bit to -1 and break any
|
||||
|
||||
Generated
+4483
-636
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "osrm",
|
||||
"version": "5.20.0-latest.1",
|
||||
"version": "5.20.1-rc.3",
|
||||
"private": false,
|
||||
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.",
|
||||
"dependencies": {
|
||||
"mkdirp": "^0.5.1",
|
||||
"nan": "^2.6.2",
|
||||
"nan": "^2.11.1",
|
||||
"node-cmake": "^2.3.2",
|
||||
"node-pre-gyp": "^0.6.36",
|
||||
"rimraf": "^2.5.4"
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "engine/api/table_parameters.hpp"
|
||||
#include "engine/routing_algorithms/many_to_many.hpp"
|
||||
#include "engine/search_engine_data.hpp"
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
#include "util/json_container.hpp"
|
||||
#include "util/string_util.hpp"
|
||||
|
||||
@@ -94,6 +95,60 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
||||
return Error("NoTable", "No table found", result);
|
||||
}
|
||||
|
||||
// Scan table for null results - if any exist, replace with distance estimates
|
||||
if (params.fallback_speed != INVALID_FALLBACK_SPEED || params.scale_factor != 1)
|
||||
{
|
||||
for (std::size_t row = 0; row < num_sources; row++)
|
||||
{
|
||||
for (std::size_t column = 0; column < num_destinations; column++)
|
||||
{
|
||||
const auto &table_index = row * num_destinations + column;
|
||||
BOOST_ASSERT(table_index < result_tables_pair.first.size());
|
||||
if (params.fallback_speed != INVALID_FALLBACK_SPEED && params.fallback_speed > 0 &&
|
||||
result_tables_pair.first[table_index] == MAXIMAL_EDGE_DURATION)
|
||||
{
|
||||
const auto &source =
|
||||
snapped_phantoms[params.sources.empty() ? row : params.sources[row]];
|
||||
const auto &destination =
|
||||
snapped_phantoms[params.destinations.empty() ? column
|
||||
: params.destinations[column]];
|
||||
|
||||
auto distance_estimate =
|
||||
params.fallback_coordinate_type ==
|
||||
api::TableParameters::FallbackCoordinateType::Input
|
||||
? util::coordinate_calculation::fccApproximateDistance(
|
||||
source.input_location, destination.input_location)
|
||||
: util::coordinate_calculation::fccApproximateDistance(
|
||||
source.location, destination.location);
|
||||
|
||||
result_tables_pair.first[table_index] =
|
||||
distance_estimate / (double)params.fallback_speed;
|
||||
if (!result_tables_pair.second.empty())
|
||||
{
|
||||
result_tables_pair.second[table_index] = distance_estimate;
|
||||
}
|
||||
}
|
||||
if (params.scale_factor > 0 && params.scale_factor != 1 &&
|
||||
result_tables_pair.first[table_index] != MAXIMAL_EDGE_DURATION &&
|
||||
result_tables_pair.first[table_index] != 0)
|
||||
{
|
||||
EdgeDuration diff =
|
||||
MAXIMAL_EDGE_DURATION / result_tables_pair.first[table_index];
|
||||
|
||||
if (params.scale_factor >= diff)
|
||||
{
|
||||
result_tables_pair.first[table_index] = MAXIMAL_EDGE_DURATION - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
result_tables_pair.first[table_index] = std::lround(
|
||||
result_tables_pair.first[table_index] * params.scale_factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
api::TableAPI table_api{facade, params};
|
||||
table_api.MakeResponse(result_tables_pair, snapped_phantoms, result);
|
||||
|
||||
|
||||
@@ -56,6 +56,16 @@ std::string getWrongOptionHelp(const engine::api::TableParameters ¶meters)
|
||||
help = "Number of coordinates needs to be at least two.";
|
||||
}
|
||||
|
||||
if (parameters.fallback_speed <= 0)
|
||||
{
|
||||
help = "fallback_speed must be > 0";
|
||||
}
|
||||
|
||||
if (parameters.scale_factor <= 0)
|
||||
{
|
||||
help = "scale_factor must be > 0";
|
||||
}
|
||||
|
||||
return help;
|
||||
}
|
||||
} // anon. ns
|
||||
|
||||
@@ -245,5 +245,61 @@ tables.forEach(function(annotation) {
|
||||
assert.equal(response[annotation].length, 2);
|
||||
});
|
||||
});
|
||||
|
||||
test('table: ' + annotation + ' table in Monaco with fallback speeds', function(assert) {
|
||||
assert.plan(1);
|
||||
var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
|
||||
var options = {
|
||||
coordinates: two_test_coordinates,
|
||||
annotations: [annotation.slice(0,-1)],
|
||||
fallback_speed: 1,
|
||||
fallback_coordinate: 'input'
|
||||
};
|
||||
osrm.table(options, function(err, response) {
|
||||
assert.equal(response[annotation].length, 2);
|
||||
});
|
||||
});
|
||||
|
||||
test('table: ' + annotation + ' table in Monaco with invalid fallback speeds and fallback coordinates', function(assert) {
|
||||
assert.plan(4);
|
||||
var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
|
||||
var options = {
|
||||
coordinates: two_test_coordinates,
|
||||
annotations: [annotation.slice(0,-1)],
|
||||
fallback_speed: -1
|
||||
};
|
||||
|
||||
assert.throws(()=>osrm.table(options, (err, res) => {}), /fallback_speed must be > 0/, "should throw on invalid fallback_speeds");
|
||||
|
||||
options.fallback_speed = '10';
|
||||
assert.throws(()=>osrm.table(options, (err, res) => {}), /fallback_speed must be a number/, "should throw on invalid fallback_speeds");
|
||||
|
||||
options.fallback_speed = 10;
|
||||
options.fallback_coordinate = 'bla';
|
||||
assert.throws(()=>osrm.table(options, (err, res) => {}), /fallback_coordinate' param must be one of \[input, snapped\]/, "should throw on invalid fallback_coordinate");
|
||||
|
||||
options.fallback_coordinate = 10;
|
||||
assert.throws(()=>osrm.table(options, (err, res) => {}), /fallback_coordinate must be a string: \[input, snapped\]/, "should throw on invalid fallback_coordinate");
|
||||
|
||||
});
|
||||
|
||||
test('table: ' + annotation + ' table in Monaco with invalid scale factor', function(assert) {
|
||||
assert.plan(3);
|
||||
var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
|
||||
var options = {
|
||||
coordinates: two_test_coordinates,
|
||||
annotations: [annotation.slice(0,-1)],
|
||||
scale_factor: -1
|
||||
};
|
||||
|
||||
assert.throws(()=>osrm.table(options, (err, res) => {}), /scale_factor must be > 0/, "should throw on invalid scale_factor value");
|
||||
|
||||
options.scale_factor = '-1';
|
||||
assert.throws(()=>osrm.table(options, (err, res) => {}), /scale_factor must be a number/, "should throw on invalid scale_factor value");
|
||||
|
||||
options.scale_factor = 0;
|
||||
assert.throws(()=>osrm.table(options, (err, res) => {}), /scale_factor must be > 0/, "should throw on invalid scale_factor value");
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -89,6 +89,25 @@ BOOST_AUTO_TEST_CASE(invalid_table_urls)
|
||||
BOOST_CHECK_EQUAL(
|
||||
testInvalidOptions<TableParameters>("1,2;3,4?sources=all&destinations=all&annotations=bla"),
|
||||
49UL);
|
||||
BOOST_CHECK_EQUAL(testInvalidOptions<TableParameters>("1,2;3,4?fallback_coordinate=asdf"),
|
||||
28UL);
|
||||
BOOST_CHECK_EQUAL(testInvalidOptions<TableParameters>("1,2;3,4?fallback_coordinate=10"), 28UL);
|
||||
BOOST_CHECK_EQUAL(
|
||||
testInvalidOptions<TableParameters>("1,2;3,4?annotations=durations&scale_factor=-1"), 28UL);
|
||||
BOOST_CHECK_EQUAL(
|
||||
testInvalidOptions<TableParameters>("1,2;3,4?annotations=durations&scale_factor=0"), 28UL);
|
||||
BOOST_CHECK_EQUAL(
|
||||
testInvalidOptions<TableParameters>("1,2;3,4?annotations=durations&fallback_speed=0"),
|
||||
28UL);
|
||||
BOOST_CHECK_EQUAL(
|
||||
testInvalidOptions<TableParameters>("1,2;3,4?annotations=durations&fallback_speed=-1"),
|
||||
28UL);
|
||||
BOOST_CHECK_EQUAL(
|
||||
testInvalidOptions<TableParameters>("1,2;3,4?annotations=durations&fallback_speed=0"),
|
||||
28UL);
|
||||
BOOST_CHECK_EQUAL(
|
||||
testInvalidOptions<TableParameters>("1,2;3,4?annotations=durations&fallback_speed=-1"),
|
||||
28UL);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(valid_route_hint)
|
||||
@@ -563,6 +582,44 @@ BOOST_AUTO_TEST_CASE(valid_table_urls)
|
||||
BOOST_CHECK_EQUAL(result_7->annotations & TableParameters::AnnotationsType::Distance, true);
|
||||
CHECK_EQUAL_RANGE(reference_7.sources, result_7->sources);
|
||||
CHECK_EQUAL_RANGE(reference_7.destinations, result_7->destinations);
|
||||
|
||||
TableParameters reference_8{};
|
||||
reference_8.coordinates = coords_1;
|
||||
auto result_8 =
|
||||
parseParameters<TableParameters>("1,2;3,4?annotations=distance&fallback_speed=2.5");
|
||||
BOOST_CHECK(result_8);
|
||||
BOOST_CHECK_EQUAL(result_8->annotations & TableParameters::AnnotationsType::Distance, true);
|
||||
CHECK_EQUAL_RANGE(reference_8.sources, result_8->sources);
|
||||
CHECK_EQUAL_RANGE(reference_8.destinations, result_8->destinations);
|
||||
|
||||
TableParameters reference_9{};
|
||||
reference_9.coordinates = coords_1;
|
||||
auto result_9 = parseParameters<TableParameters>(
|
||||
"1,2;3,4?annotations=distance&fallback_speed=2.5&fallback_coordinate=input");
|
||||
BOOST_CHECK(result_9);
|
||||
BOOST_CHECK_EQUAL(result_9->annotations & TableParameters::AnnotationsType::Distance, true);
|
||||
CHECK_EQUAL_RANGE(reference_9.sources, result_9->sources);
|
||||
CHECK_EQUAL_RANGE(reference_9.destinations, result_9->destinations);
|
||||
|
||||
TableParameters reference_10{};
|
||||
reference_10.coordinates = coords_1;
|
||||
auto result_10 = parseParameters<TableParameters>(
|
||||
"1,2;3,4?annotations=distance&fallback_speed=20&fallback_coordinate=snapped");
|
||||
BOOST_CHECK(result_10);
|
||||
BOOST_CHECK_EQUAL(result_10->annotations & TableParameters::AnnotationsType::Distance, true);
|
||||
CHECK_EQUAL_RANGE(reference_10.sources, result_10->sources);
|
||||
CHECK_EQUAL_RANGE(reference_10.destinations, result_10->destinations);
|
||||
|
||||
auto result_11 = parseParameters<TableParameters>("1,2;3,4?sources=all&destinations=all&"
|
||||
"annotations=duration&fallback_speed=1&"
|
||||
"fallback_coordinate=snapped&scale_factor=2");
|
||||
BOOST_CHECK(result_11);
|
||||
CHECK_EQUAL_RANGE(reference_1.sources, result_11->sources);
|
||||
CHECK_EQUAL_RANGE(reference_1.destinations, result_11->destinations);
|
||||
CHECK_EQUAL_RANGE(reference_1.bearings, result_11->bearings);
|
||||
CHECK_EQUAL_RANGE(reference_1.radiuses, result_11->radiuses);
|
||||
CHECK_EQUAL_RANGE(reference_1.approaches, result_11->approaches);
|
||||
CHECK_EQUAL_RANGE(reference_1.coordinates, result_11->coordinates);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(valid_match_urls)
|
||||
|
||||
Reference in New Issue
Block a user