Compare commits
23 Commits
master
...
v5.20.1-rc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fb343352bc | ||
|
|
4632ec3b67 | ||
|
|
7f9ac81028 | ||
|
|
a123cb6efb | ||
|
|
63e713aa4a | ||
|
|
9daef767fa | ||
|
|
d89a513183 | ||
|
|
c43ea37e05 | ||
|
|
ec6c10661f | ||
|
|
bcdc689ae9 | ||
|
|
b3eb8970f1 | ||
|
|
ab22cc7516 | ||
|
|
18f446735c | ||
|
|
9234b2ae76 | ||
|
|
8b5ade3861 | ||
|
|
baa8214270 | ||
|
|
d41b03b778 | ||
|
|
31d8ff7a74 | ||
|
|
cb2532d0da | ||
|
|
e222fcfb17 | ||
|
|
7a5b6dbede | ||
|
|
c08953c0e6 | ||
|
|
e5a6c73fdf |
@ -13,6 +13,7 @@ notifications:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- "5.20.1"
|
||||
# enable building tags
|
||||
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/
|
||||
|
||||
|
||||
12
CHANGELOG.md
12
CHANGELOG.md
@ -1,4 +1,13 @@
|
||||
# UNRELEASED
|
||||
# 5.20.1 RC 4
|
||||
- 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)
|
||||
- ADDED: if `fallback_speed` is used, a new structure `fallback_speed_cells` will describe which cells contain estimated values [#5259](https://github.com/Project-OSRM/osrm-backend/pull/5259)
|
||||
- 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)
|
||||
@ -8,7 +17,6 @@
|
||||
- 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: 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)
|
||||
- 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)
|
||||
|
||||
10
docs/http.md
10
docs/http.md
@ -235,9 +235,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. |
|
||||
|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.|
|
||||
|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;
|
||||
@ -283,6 +284,7 @@ curl 'http://router.project-osrm.org/table/v1/driving/13.388860,52.517037;13.397
|
||||
the i-th waypoint to the j-th waypoint. Values are given in meters. Can be `null` if no route between `i` and `j` can be found. 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.
|
||||
- `sources` array of `Waypoint` objects describing all sources in order
|
||||
- `destinations` array of `Waypoint` objects describing all destinations in order
|
||||
- `fallback_speed_cells` (optional) array of arrays containing `i,j` pairs indicating which cells contain estimated values based on `fallback_speed`. Will be absent if `fallback_speed` is not used.
|
||||
|
||||
In case of error the following `code`s are supported in addition to the general ones:
|
||||
|
||||
@ -383,6 +385,10 @@ All other properties might be undefined.
|
||||
2361.73,
|
||||
0
|
||||
]
|
||||
],
|
||||
"fallback_speed_cells": [
|
||||
[ 0, 1 ],
|
||||
[ 1, 0 ]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@ -131,6 +131,7 @@ tables. Optionally returns distance table.
|
||||
- `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**
|
||||
@ -156,6 +157,7 @@ Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refer
|
||||
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.
|
||||
**`fallback_speed_cells`**: (optional) if `fallback_speed` is used, will be an array of arrays of `row,column` values, indicating which cells contain estimated values.
|
||||
|
||||
### tile
|
||||
|
||||
|
||||
@ -3,22 +3,25 @@ var util = require('util');
|
||||
module.exports = function () {
|
||||
const durationsRegex = new RegExp(/^I request a travel time matrix I should get$/);
|
||||
const distancesRegex = new RegExp(/^I request a travel distance matrix I should get$/);
|
||||
const estimatesRegex = new RegExp(/^I request a travel time matrix I should get estimates for$/);
|
||||
|
||||
const DURATIONS_NO_ROUTE = 2147483647; // MAX_INT
|
||||
const DISTANCES_NO_ROUTE = 3.40282e+38; // MAX_FLOAT
|
||||
|
||||
this.When(durationsRegex, function(table, callback) {tableParse.call(this, table, DURATIONS_NO_ROUTE, 'durations', callback);}.bind(this));
|
||||
this.When(distancesRegex, function(table, callback) {tableParse.call(this, table, DISTANCES_NO_ROUTE, 'distances', callback);}.bind(this));
|
||||
this.When(estimatesRegex, function(table, callback) {tableParse.call(this, table, DISTANCES_NO_ROUTE, 'fallback_speed_cells', callback);}.bind(this));
|
||||
};
|
||||
|
||||
const durationsParse = function(v) { return isNaN(parseInt(v)); };
|
||||
const distancesParse = function(v) { return isNaN(parseFloat(v)); };
|
||||
const estimatesParse = function(v) { return isNaN(parseFloat(v)); };
|
||||
|
||||
function tableParse(table, noRoute, annotation, callback) {
|
||||
|
||||
const parse = annotation == 'distances' ? distancesParse : durationsParse;
|
||||
const parse = annotation == 'distances' ? distancesParse : (annotation == 'durations' ? durationsParse : estimatesParse);
|
||||
const params = this.queryParams;
|
||||
params.annotations = annotation == 'distances' ? 'distance' : 'duration';
|
||||
params.annotations = ['durations','fallback_speed_cells'].indexOf(annotation) !== -1 ? 'duration' : 'distance';
|
||||
|
||||
var tableRows = table.raw();
|
||||
|
||||
@ -61,11 +64,26 @@ function tableParse(table, noRoute, annotation, callback) {
|
||||
|
||||
var json = JSON.parse(response.body);
|
||||
|
||||
var result = json[annotation].map(row => {
|
||||
var hashes = {};
|
||||
row.forEach((v, i) => { hashes[tableRows[0][i+1]] = parse(v) ? '' : v; });
|
||||
return hashes;
|
||||
});
|
||||
var result = {};
|
||||
if (annotation === 'fallback_speed_cells') {
|
||||
result = table.raw().map(row => row.map(() => ''));
|
||||
json[annotation].forEach(pair => {
|
||||
result[pair[0]+1][pair[1]+1] = 'Y';
|
||||
});
|
||||
result = result.slice(1).map(row => {
|
||||
var hashes = {};
|
||||
row.slice(1).forEach((v,i) => {
|
||||
hashes[tableRows[0][i+1]] = v;
|
||||
});
|
||||
return hashes;
|
||||
});
|
||||
} else {
|
||||
result = json[annotation].map(row => {
|
||||
var hashes = {};
|
||||
row.forEach((v, i) => { hashes[tableRows[0][i+1]] = parse(v) ? '' : v; });
|
||||
return hashes;
|
||||
});
|
||||
}
|
||||
|
||||
var testRow = (row, ri, cb) => {
|
||||
for (var k in result[ri]) {
|
||||
|
||||
@ -596,7 +596,6 @@ Feature: Basic Distance Matrix
|
||||
| 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"
|
||||
@ -620,7 +619,18 @@ Feature: Basic Distance Matrix
|
||||
| f | 900.7 | 600.5 | 0 | 302.2 |
|
||||
| 1 | 1501.1 | 1200.9 | 300.2 | 0 |
|
||||
|
||||
Scenario: Testbot - Filling in noroutes with estimates - use input coordinate
|
||||
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
|
||||
@ -644,6 +654,18 @@ Feature: Basic Distance Matrix
|
||||
| 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"
|
||||
@ -668,22 +690,9 @@ Feature: Basic Distance Matrix
|
||||
| f | 900.7 | 600.5 | 0 | 302.2 |
|
||||
| 1 | 1200.9 | 900.7 | 300.2 | 0 |
|
||||
|
||||
Scenario: Testbot - Asymetric fallback_speed - more sources than destinations
|
||||
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 |
|
||||
|
||||
When I request a travel distance matrix I should get
|
||||
| | a |
|
||||
@ -692,23 +701,3 @@ Feature: Basic Distance Matrix
|
||||
| f | 900.7 |
|
||||
| 1 | 1200.9 |
|
||||
|
||||
Scenario: Testbot - Asymetric fallback_speed - more destinations than sources
|
||||
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 |
|
||||
|
||||
@ -534,6 +534,35 @@ Feature: Basic Duration Matrix
|
||||
| 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 |
|
||||
|
||||
When I request a travel time matrix I should get estimates for
|
||||
| | a | b | f | 1 |
|
||||
| a | | | Y | Y |
|
||||
| b | | | Y | Y |
|
||||
| f | Y | Y | | |
|
||||
| 1 | Y | Y | | |
|
||||
|
||||
When I request a travel time matrix I should get estimates for
|
||||
| | a | b | f | 1 |
|
||||
| a | | | Y | Y |
|
||||
|
||||
When I request a travel time matrix I should get estimates for
|
||||
| | a |
|
||||
| a | |
|
||||
| b | |
|
||||
| f | Y |
|
||||
| 1 | Y |
|
||||
|
||||
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"
|
||||
@ -558,6 +587,36 @@ Feature: Basic Duration Matrix
|
||||
| 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 |
|
||||
|
||||
When I request a travel time matrix I should get estimates for
|
||||
| | a | b | f | 1 |
|
||||
| a | | | Y | Y |
|
||||
| b | | | Y | Y |
|
||||
| f | Y | Y | | |
|
||||
| 1 | Y | Y | | |
|
||||
|
||||
When I request a travel time matrix I should get estimates for
|
||||
| | a | b | f | 1 |
|
||||
| a | | | Y | Y |
|
||||
|
||||
When I request a travel time matrix I should get estimates for
|
||||
| | a |
|
||||
| a | |
|
||||
| b | |
|
||||
| f | Y |
|
||||
| 1 | Y |
|
||||
|
||||
|
||||
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"
|
||||
@ -581,3 +640,138 @@ Feature: Basic Duration Matrix
|
||||
| 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 |
|
||||
|
||||
When I request a travel time matrix I should get estimates for
|
||||
| | a | b | f | 1 |
|
||||
| a | | | Y | Y |
|
||||
| b | | | Y | Y |
|
||||
| f | Y | Y | | |
|
||||
| 1 | Y | Y | | |
|
||||
|
||||
When I request a travel time matrix I should get estimates for
|
||||
| | a | b | f | 1 |
|
||||
| a | | | Y | Y |
|
||||
|
||||
When I request a travel time matrix I should get estimates for
|
||||
| | a |
|
||||
| a | |
|
||||
| b | |
|
||||
| f | Y |
|
||||
| 1 | Y |
|
||||
|
||||
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 |
|
||||
|
||||
When I request a travel time matrix I should get estimates for
|
||||
| | a | b | f | 1 |
|
||||
| a | | | Y | Y |
|
||||
| b | | | Y | Y |
|
||||
| f | Y | Y | | |
|
||||
| 1 | Y | Y | | |
|
||||
|
||||
When I request a travel time matrix I should get estimates for
|
||||
| | a | b | f | 1 |
|
||||
| a | | | Y | Y |
|
||||
|
||||
When I request a travel time matrix I should get estimates for
|
||||
| | a |
|
||||
| a | |
|
||||
| b | |
|
||||
| f | Y |
|
||||
| 1 | Y |
|
||||
|
||||
|
||||
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 |
|
||||
|
||||
@ -31,6 +31,15 @@ namespace api
|
||||
class TableAPI final : public BaseAPI
|
||||
{
|
||||
public:
|
||||
struct TableCellRef
|
||||
{
|
||||
TableCellRef(const std::size_t &row, const std::size_t &column) : row{row}, column{column}
|
||||
{
|
||||
}
|
||||
std::size_t row;
|
||||
std::size_t column;
|
||||
};
|
||||
|
||||
TableAPI(const datafacade::BaseDataFacade &facade_, const TableParameters ¶meters_)
|
||||
: BaseAPI(facade_, parameters_), parameters(parameters_)
|
||||
{
|
||||
@ -39,6 +48,7 @@ class TableAPI final : public BaseAPI
|
||||
virtual void
|
||||
MakeResponse(const std::pair<std::vector<EdgeDuration>, std::vector<EdgeDistance>> &tables,
|
||||
const std::vector<PhantomNode> &phantoms,
|
||||
const std::vector<TableCellRef> &fallback_speed_cells,
|
||||
util::json::Object &response) const
|
||||
{
|
||||
auto number_of_sources = parameters.sources.size();
|
||||
@ -77,6 +87,11 @@ class TableAPI final : public BaseAPI
|
||||
MakeDistanceTable(tables.second, number_of_sources, number_of_destinations);
|
||||
}
|
||||
|
||||
if (parameters.fallback_speed != INVALID_FALLBACK_SPEED && parameters.fallback_speed > 0)
|
||||
{
|
||||
response.values["fallback_speed_cells"] = MakeEstimatesTable(fallback_speed_cells);
|
||||
}
|
||||
|
||||
response.values["code"] = "Ok";
|
||||
}
|
||||
|
||||
@ -163,6 +178,20 @@ class TableAPI final : public BaseAPI
|
||||
return json_table;
|
||||
}
|
||||
|
||||
virtual util::json::Array
|
||||
MakeEstimatesTable(const std::vector<TableCellRef> &fallback_speed_cells) const
|
||||
{
|
||||
util::json::Array json_table;
|
||||
std::for_each(
|
||||
fallback_speed_cells.begin(), fallback_speed_cells.end(), [&](const auto &cell) {
|
||||
util::json::Array row;
|
||||
row.values.push_back(util::json::Number(cell.row));
|
||||
row.values.push_back(util::json::Number(cell.column));
|
||||
json_table.values.push_back(std::move(row));
|
||||
});
|
||||
return json_table;
|
||||
}
|
||||
|
||||
const TableParameters ¶meters;
|
||||
};
|
||||
|
||||
|
||||
@ -59,7 +59,7 @@ struct TableParameters : public BaseParameters
|
||||
{
|
||||
std::vector<std::size_t> sources;
|
||||
std::vector<std::size_t> destinations;
|
||||
double fallback_speed = 0;
|
||||
double fallback_speed = INVALID_FALLBACK_SPEED;
|
||||
|
||||
enum class FallbackCoordinateType
|
||||
{
|
||||
@ -79,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_,
|
||||
@ -105,10 +107,13 @@ struct TableParameters : public BaseParameters
|
||||
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_}
|
||||
fallback_coordinate_type{fallback_coordinate_type_}, annotations{annotations_},
|
||||
scale_factor{scale_factor_}
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
@ -132,7 +137,10 @@ struct TableParameters : public BaseParameters
|
||||
if (std::any_of(begin(destinations), end(destinations), not_in_range))
|
||||
return false;
|
||||
|
||||
if (fallback_speed < 0)
|
||||
if (fallback_speed <= 0)
|
||||
return false;
|
||||
|
||||
if (scale_factor <= 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
@ -1192,7 +1192,7 @@ argumentsToTableParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
|
||||
Nan::ThrowError("fallback_speed must be a number");
|
||||
return table_parameters_ptr();
|
||||
}
|
||||
else if (fallback_speed->NumberValue() < 0)
|
||||
else if (fallback_speed->NumberValue() <= 0)
|
||||
{
|
||||
Nan::ThrowError("fallback_speed must be > 0");
|
||||
return table_parameters_ptr();
|
||||
@ -1229,6 +1229,24 @@ argumentsToTableParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@ -56,16 +56,20 @@ struct TableParametersGrammar : public BaseParametersGrammar<Iterator, Signature
|
||||
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) | fallback_speed_rule(qi::_r1) |
|
||||
(qi::lit("fallback_coordinate=") >
|
||||
fallback_coordinate_type
|
||||
[ph::bind(&engine::api::TableParameters::fallback_coordinate_type,
|
||||
qi::_r1) = qi::_1])) %
|
||||
'&');
|
||||
root_rule = BaseGrammar::query_rule(qi::_r1) > -qi::lit(".json") >
|
||||
-('?' > (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_)
|
||||
@ -94,6 +98,7 @@ struct TableParametersGrammar : public BaseParametersGrammar<Iterator, Signature
|
||||
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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "osrm",
|
||||
"version": "5.20.0-latest.1",
|
||||
"version": "5.20.1-rc.4",
|
||||
"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": {
|
||||
|
||||
@ -95,8 +95,10 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
||||
return Error("NoTable", "No table found", result);
|
||||
}
|
||||
|
||||
std::vector<api::TableAPI::TableCellRef> estimated_pairs;
|
||||
|
||||
// Scan table for null results - if any exist, replace with distance estimates
|
||||
if (params.fallback_speed > 0)
|
||||
if (params.fallback_speed != INVALID_FALLBACK_SPEED || params.scale_factor != 1)
|
||||
{
|
||||
for (std::size_t row = 0; row < num_sources; row++)
|
||||
{
|
||||
@ -104,7 +106,8 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
||||
{
|
||||
const auto &table_index = row * num_destinations + column;
|
||||
BOOST_ASSERT(table_index < result_tables_pair.first.size());
|
||||
if (result_tables_pair.first[table_index] == MAXIMAL_EDGE_DURATION)
|
||||
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]];
|
||||
@ -126,13 +129,32 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
||||
{
|
||||
result_tables_pair.second[table_index] = distance_estimate;
|
||||
}
|
||||
|
||||
estimated_pairs.emplace_back(row, column);
|
||||
}
|
||||
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);
|
||||
table_api.MakeResponse(result_tables_pair, snapped_phantoms, estimated_pairs, result);
|
||||
|
||||
return Status::Ok;
|
||||
}
|
||||
|
||||
@ -56,11 +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)
|
||||
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
|
||||
|
||||
@ -234,7 +234,7 @@ tables.forEach(function(annotation) {
|
||||
});
|
||||
|
||||
test('table: ' + annotation + ' table in Monaco without motorways', function(assert) {
|
||||
assert.plan(1);
|
||||
assert.plan(2);
|
||||
var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
|
||||
var options = {
|
||||
coordinates: two_test_coordinates,
|
||||
@ -243,11 +243,12 @@ tables.forEach(function(annotation) {
|
||||
};
|
||||
osrm.table(options, function(err, response) {
|
||||
assert.equal(response[annotation].length, 2);
|
||||
assert.strictEqual(response.fallback_speed_cells, undefined);
|
||||
});
|
||||
});
|
||||
|
||||
test('table: ' + annotation + ' table in Monaco with fallback speeds', function(assert) {
|
||||
assert.plan(1);
|
||||
assert.plan(2);
|
||||
var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
|
||||
var options = {
|
||||
coordinates: two_test_coordinates,
|
||||
@ -257,8 +258,50 @@ tables.forEach(function(annotation) {
|
||||
};
|
||||
osrm.table(options, function(err, response) {
|
||||
assert.equal(response[annotation].length, 2);
|
||||
assert.equal(response['fallback_speed_cells'].length, 0);
|
||||
});
|
||||
});
|
||||
|
||||
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");
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -91,6 +91,23 @@ BOOST_AUTO_TEST_CASE(invalid_table_urls)
|
||||
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)
|
||||
@ -565,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)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user