Merge branch 'master' into ignore-proposed
This commit is contained in:
commit
dc2c4cf43c
@ -2,14 +2,19 @@
|
||||
- Changes from 5.27.1
|
||||
- Features
|
||||
- ADDED: Add support for a default_radius flag. [#6575](https://github.com/Project-OSRM/osrm-backend/pull/6575)
|
||||
- ADDED: Add support for disabling feature datasets. [#6666](https://github.com/Project-OSRM/osrm-backend/pull/6666)
|
||||
- Build:
|
||||
- ADDED: Add CI job which builds OSRM with gcc 12. [#6455](https://github.com/Project-OSRM/osrm-backend/pull/6455)
|
||||
- CHANGED: Upgrade to clang-tidy 15. [#6439](https://github.com/Project-OSRM/osrm-backend/pull/6439)
|
||||
- CHANGED: Update actions/cache to v3. [#6420](https://github.com/Project-OSRM/osrm-backend/pull/6420)
|
||||
- REMOVED: Drop support of Node 12 & 14. [#6431](https://github.com/Project-OSRM/osrm-backend/pull/6431)
|
||||
- ADDED: Add 'load directly' mode to default Cucumber test suite. [#6663](https://github.com/Project-OSRM/osrm-backend/pull/6663)
|
||||
- NodeJS:
|
||||
- CHANGED: Use node-api instead of NAN. [#6452](https://github.com/Project-OSRM/osrm-backend/pull/6452)
|
||||
- Misc:
|
||||
- FIXED: Fix an error in a RouteParameters AnnotationsType operator overload. [#6646](https://github.com/Project-OSRM/osrm-backend/pull/6646)
|
||||
- ADDED: Add support for "unlimited" to be passed as a value for the default-radius and max-matching-radius flags. [#6599](https://github.com/Project-OSRM/osrm-backend/pull/6599)
|
||||
- CHANGED: Allow -1.0 as unlimited for default_radius value. [#6599](https://github.com/Project-OSRM/osrm-backend/pull/6599)
|
||||
- CHANGED: keep libosrm* in the docker image for downstream linking [#6602](https://github.com/Project-OSRM/osrm-backend/pull/6602)
|
||||
- CHANGED: Move vector in CSVFilesParser instead copying it. [#6470](https://github.com/Project-OSRM/osrm-backend/pull/6470)
|
||||
- REMOVED: Get rid of unused functions in util/json_util.hpp. [#6446](https://github.com/Project-OSRM/osrm-backend/pull/6446)
|
||||
@ -23,6 +28,8 @@
|
||||
- CHANGED: Replace boost::string_ref with std::string_view [#6433](https://github.com/Project-OSRM/osrm-backend/pull/6433)
|
||||
- ADDED: Print tracebacks for Lua runtime errors [#6564](https://github.com/Project-OSRM/osrm-backend/pull/6564)
|
||||
- FIXED: Added a variable to preprocessor guard in file osrm-backend/include/util/range_table.hpp to solve build error. [#6596](https://github.com/Project-OSRM/osrm-backend/pull/6596)
|
||||
- FIXED: Ensure required file check in osrm-routed is correctly enforced. [#6655](https://github.com/Project-OSRM/osrm-backend/pull/6655)
|
||||
- FIXED: Correct HTTP docs to reflect summary output dependency on steps parameter. [#6655](https://github.com/Project-OSRM/osrm-backend/pull/6655)
|
||||
- Profiles:
|
||||
- FIXED: Bicycle and foot profiles now don't route on proposed ways [#6615](https://github.com/Project-OSRM/osrm-backend/pull/6615)
|
||||
- Routing:
|
||||
|
||||
@ -275,8 +275,11 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
find_library(RT_LIB rt)
|
||||
if (RT_LIB)
|
||||
set(MAYBE_RT_LIBRARY -lrt)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
|
||||
@ -58,12 +58,12 @@ Download OpenStreetMap extracts for example from [Geofabrik](http://download.geo
|
||||
|
||||
Pre-process the extract with the car profile and start a routing engine HTTP server on port 5000
|
||||
|
||||
docker run -t -v "${PWD}:/data" ghcr.io/project-osrm/osrm-backend osrm-extract -p /opt/car.lua /data/berlin-latest.osm.pbf || "osrm-extract failed"
|
||||
docker run -t -v "${PWD}:/data" ghcr.io/project-osrm/osrm-backend osrm-extract -p /opt/car.lua /data/berlin-latest.osm.pbf || echo "osrm-extract failed"
|
||||
|
||||
The flag `-v "${PWD}:/data"` creates the directory `/data` inside the docker container and makes the current working directory `"${PWD}"` available there. The file `/data/berlin-latest.osm.pbf` inside the container is referring to `"${PWD}/berlin-latest.osm.pbf"` on the host.
|
||||
|
||||
docker run -t -v "${PWD}:/data" ghcr.io/project-osrm/osrm-backend osrm-partition /data/berlin-latest.osrm || "osrm-partition failed"
|
||||
docker run -t -v "${PWD}:/data" ghcr.io/project-osrm/osrm-backend osrm-customize /data/berlin-latest.osrm || "osrm-customize failed"
|
||||
docker run -t -v "${PWD}:/data" ghcr.io/project-osrm/osrm-backend osrm-partition /data/berlin-latest.osrm || echo "osrm-partition failed"
|
||||
docker run -t -v "${PWD}:/data" ghcr.io/project-osrm/osrm-backend osrm-customize /data/berlin-latest.osrm || echo "osrm-customize failed"
|
||||
|
||||
Note there is no `berlin-latest.osrm` file, but multiple `berlin-latest.osrm.*` files, i.e. `berlin-latest.osrm` is not file path, but "base" path referring to set of files and there is an option to omit this `.osrm` suffix completely(e.g. `osrm-partition /data/berlin-latest`).
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
module.exports = {
|
||||
default: '--strict --tags ~@stress --tags ~@todo --tags ~@mld-only --require features/support --require features/step_definitions',
|
||||
verify: '--strict --tags ~@stress --tags ~@todo --tags ~@mld-only -f progress --require features/support --require features/step_definitions',
|
||||
default: '--strict --tags ~@stress --tags ~@todo --tags ~@mld --require features/support --require features/step_definitions',
|
||||
ch: '--strict --tags ~@stress --tags ~@todo --tags ~@mld -f progress --require features/support --require features/step_definitions',
|
||||
todo: '--strict --tags @todo --require features/support --require features/step_definitions',
|
||||
all: '--strict --require features/support --require features/step_definitions',
|
||||
mld: '--strict --tags ~@stress --tags ~@todo --tags ~@ch --require features/support --require features/step_definitions -f progress'
|
||||
|
||||
@ -92,6 +92,7 @@ Every response object has a `code` property containing one of the strings below
|
||||
| `InvalidValue` | The successfully parsed query parameters are invalid. |
|
||||
| `NoSegment` | One of the supplied input coordinates could not snap to the street segment. |
|
||||
| `TooBig` | The request size violates one of the service-specific request size restrictions. |
|
||||
| `DisabledDataset` | The request tried to access a disabled dataset. |
|
||||
|
||||
- `message` is a **optional** human-readable error message. All other status types are service-dependent.
|
||||
- In case of an error the HTTP status code will be `400`. Otherwise, the HTTP status code will be `200` and `code` will be `Ok`.
|
||||
@ -648,10 +649,10 @@ Represents a route between two waypoints.
|
||||
- `distance`: The distance traveled by this route leg, in `float` meters.
|
||||
- `duration`: The estimated travel time, in `float` number of seconds.
|
||||
- `weight`: The calculated weight of the route leg.
|
||||
- `summary`: Summary of the route taken as `string`. Depends on the `summary` parameter:
|
||||
- `summary`: Summary of the route taken as `string`. Depends on the `steps` parameter:
|
||||
|
||||
| summary | |
|
||||
|--------------|-----------------------------------------------------------------------|
|
||||
| steps | |
|
||||
|-------|-----------------------------------------------------------------------|
|
||||
| true | Names of the two major roads used. Can be empty if the route is too short.|
|
||||
| false | empty `string` |
|
||||
|
||||
|
||||
@ -31,6 +31,7 @@ var osrm = new OSRM('network.osrm');
|
||||
Old behaviour: Path to a file on disk to store the memory using mmap. Current behaviour: setting this value is the same as setting `mmap_memory: true`.
|
||||
- `options.mmap_memory` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Map on-disk files to virtual memory addresses (mmap), rather than loading into RAM.
|
||||
- `options.path` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** The path to the `.osrm` files. This is mutually exclusive with setting {options.shared_memory} to true.
|
||||
- `options.disable_feature_dataset` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Disables a feature dataset from being loaded into memory if not needed. Options: `ROUTE_STEPS`, `ROUTE_GEOMETRY`.
|
||||
- `options.max_locations_trip` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. locations supported in trip query (default: unlimited).
|
||||
- `options.max_locations_viaroute` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. locations supported in viaroute query (default: unlimited).
|
||||
- `options.max_locations_distance_table` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. locations supported in distance table query (default: unlimited).
|
||||
|
||||
@ -68,8 +68,9 @@ class OSRMDirectLoader extends OSRMBaseLoader {
|
||||
super(scope);
|
||||
}
|
||||
|
||||
load (inputFile, callback) {
|
||||
this.inputFile = inputFile;
|
||||
load (ctx, callback) {
|
||||
this.inputFile = ctx.inputFile;
|
||||
this.loaderArgs = ctx.loaderArgs;
|
||||
this.shutdown(() => {
|
||||
this.launch(callback);
|
||||
});
|
||||
@ -78,7 +79,7 @@ class OSRMDirectLoader extends OSRMBaseLoader {
|
||||
osrmUp (callback) {
|
||||
if (this.osrmIsRunning()) return callback(new Error("osrm-routed already running!"));
|
||||
|
||||
const command_arguments = util.format('%s -p %d -i %s -a %s', this.inputFile, this.scope.OSRM_PORT, this.scope.OSRM_IP, this.scope.ROUTING_ALGORITHM);
|
||||
const command_arguments = util.format('%s -p %d -i %s -a %s %s', this.inputFile, this.scope.OSRM_PORT, this.scope.OSRM_IP, this.scope.ROUTING_ALGORITHM, this.loaderArgs);
|
||||
this.child = this.scope.runBin('osrm-routed', command_arguments, this.scope.environment, (err) => {
|
||||
if (err && err.signal !== 'SIGINT') {
|
||||
this.child = null;
|
||||
@ -101,8 +102,9 @@ class OSRMmmapLoader extends OSRMBaseLoader {
|
||||
super(scope);
|
||||
}
|
||||
|
||||
load (inputFile, callback) {
|
||||
this.inputFile = inputFile;
|
||||
load (ctx, callback) {
|
||||
this.inputFile = ctx.inputFile;
|
||||
this.loaderArgs = ctx.loaderArgs;
|
||||
this.shutdown(() => {
|
||||
this.launch(callback);
|
||||
});
|
||||
@ -111,7 +113,7 @@ class OSRMmmapLoader extends OSRMBaseLoader {
|
||||
osrmUp (callback) {
|
||||
if (this.osrmIsRunning()) return callback(new Error("osrm-routed already running!"));
|
||||
|
||||
const command_arguments = util.format('%s -p %d -i %s -a %s --mmap', this.inputFile, this.scope.OSRM_PORT, this.scope.OSRM_IP, this.scope.ROUTING_ALGORITHM);
|
||||
const command_arguments = util.format('%s -p %d -i %s -a %s --mmap %s', this.inputFile, this.scope.OSRM_PORT, this.scope.OSRM_IP, this.scope.ROUTING_ALGORITHM, this.loaderArgs);
|
||||
this.child = this.scope.runBin('osrm-routed', command_arguments, this.scope.environment, (err) => {
|
||||
if (err && err.signal !== 'SIGINT') {
|
||||
this.child = null;
|
||||
@ -134,8 +136,9 @@ class OSRMDatastoreLoader extends OSRMBaseLoader {
|
||||
super(scope);
|
||||
}
|
||||
|
||||
load (inputFile, callback) {
|
||||
this.inputFile = inputFile;
|
||||
load (ctx, callback) {
|
||||
this.inputFile = ctx.inputFile;
|
||||
this.loaderArgs = ctx.loaderArgs;
|
||||
|
||||
this.loadData((err) => {
|
||||
if (err) return callback(err);
|
||||
@ -148,7 +151,7 @@ class OSRMDatastoreLoader extends OSRMBaseLoader {
|
||||
}
|
||||
|
||||
loadData (callback) {
|
||||
const command_arguments = util.format('--dataset-name=%s %s', this.scope.DATASET_NAME, this.inputFile);
|
||||
const command_arguments = util.format('--dataset-name=%s %s %s', this.scope.DATASET_NAME, this.inputFile, this.loaderArgs);
|
||||
this.scope.runBin('osrm-datastore', command_arguments, this.scope.environment, (err) => {
|
||||
if (err) return callback(new Error('*** osrm-datastore exited with ' + err.code + ': ' + err));
|
||||
callback();
|
||||
|
||||
141
features/options/data/disabled_dataset.feature
Normal file
141
features/options/data/disabled_dataset.feature
Normal file
@ -0,0 +1,141 @@
|
||||
@routing @disable-feature-dataset
|
||||
Feature: disable-feature-dataset command line options
|
||||
Background:
|
||||
Given the profile "testbot"
|
||||
And the node map
|
||||
"""
|
||||
0
|
||||
a b c
|
||||
"""
|
||||
And the ways
|
||||
| nodes |
|
||||
| ab |
|
||||
| bc |
|
||||
|
||||
Scenario: disable-feature-dataset - geometry disabled error
|
||||
Given the data load extra arguments "--disable-feature-dataset ROUTE_GEOMETRY"
|
||||
|
||||
# The default values
|
||||
And the query options
|
||||
| overview | simplified |
|
||||
| annotations | false |
|
||||
| steps | false |
|
||||
| skip_waypoints | false |
|
||||
|
||||
When I route I should get
|
||||
| from | to | code |
|
||||
| a | c | DisabledDataset |
|
||||
|
||||
When I plan a trip I should get
|
||||
| waypoints | code |
|
||||
| a,b,c | DisabledDataset |
|
||||
|
||||
When I match I should get
|
||||
| trace | code |
|
||||
| abc | DisabledDataset |
|
||||
|
||||
Scenario: disable-feature-dataset - geometry disabled error table
|
||||
Given the data load extra arguments "--disable-feature-dataset ROUTE_GEOMETRY"
|
||||
|
||||
When I request nearest I should get
|
||||
| in | code |
|
||||
| 0 | DisabledDataset |
|
||||
|
||||
When I request a travel time matrix with these waypoints I should get the response code
|
||||
| waypoints | code |
|
||||
| a,b,c | DisabledDataset |
|
||||
|
||||
|
||||
Scenario: disable-feature-dataset - geometry disabled success
|
||||
Given the data load extra arguments "--disable-feature-dataset ROUTE_GEOMETRY"
|
||||
|
||||
# No geometry values returned
|
||||
And the query options
|
||||
| overview | false |
|
||||
| annotations | false |
|
||||
| steps | false |
|
||||
| skip_waypoints | true |
|
||||
|
||||
When I route I should get
|
||||
| from | to | code |
|
||||
| a | c | Ok |
|
||||
|
||||
When I plan a trip I should get
|
||||
| waypoints | code |
|
||||
| a,b,c | Ok |
|
||||
|
||||
When I match I should get
|
||||
| trace | code |
|
||||
| abc | Ok |
|
||||
|
||||
Scenario: disable-feature-dataset - geometry disabled error table
|
||||
Given the data load extra arguments "--disable-feature-dataset ROUTE_GEOMETRY"
|
||||
|
||||
And the query options
|
||||
| skip_waypoints | true |
|
||||
|
||||
# You would never do this, but just to prove the point.
|
||||
When I request nearest I should get
|
||||
| in | code |
|
||||
| 0 | Ok |
|
||||
|
||||
When I request a travel time matrix with these waypoints I should get the response code
|
||||
| waypoints | code |
|
||||
| a,b,c | Ok |
|
||||
|
||||
|
||||
Scenario: disable-feature-dataset - steps disabled error
|
||||
Given the data load extra arguments "--disable-feature-dataset ROUTE_STEPS"
|
||||
|
||||
# Default + annotations, steps
|
||||
And the query options
|
||||
| overview | simplified |
|
||||
| annotations | true |
|
||||
| steps | true |
|
||||
|
||||
When I route I should get
|
||||
| from | to | code |
|
||||
| a | c | DisabledDataset |
|
||||
|
||||
When I plan a trip I should get
|
||||
| waypoints | code |
|
||||
| a,b,c | DisabledDataset |
|
||||
|
||||
When I match I should get
|
||||
| trace | code |
|
||||
| abc | DisabledDataset |
|
||||
|
||||
|
||||
Scenario: disable-feature-dataset - geometry disabled error table
|
||||
Given the data load extra arguments "--disable-feature-dataset ROUTE_STEPS"
|
||||
|
||||
When I request nearest I should get
|
||||
| in | code |
|
||||
| 0 | Ok |
|
||||
|
||||
When I request a travel time matrix with these waypoints I should get the response code
|
||||
| waypoints | code |
|
||||
| a,b,c | Ok |
|
||||
|
||||
|
||||
Scenario: disable-feature-dataset - steps disabled success
|
||||
Given the data load extra arguments "--disable-feature-dataset ROUTE_STEPS"
|
||||
|
||||
# Default + steps
|
||||
And the query options
|
||||
| overview | simplified |
|
||||
| annotations | true |
|
||||
| steps | false |
|
||||
|
||||
When I route I should get
|
||||
| from | to | code |
|
||||
| a | c | Ok |
|
||||
|
||||
When I plan a trip I should get
|
||||
| waypoints | code |
|
||||
| a,b,c | Ok |
|
||||
|
||||
When I match I should get
|
||||
| trace | code |
|
||||
| abc | Ok |
|
||||
|
||||
@ -33,6 +33,11 @@ module.exports = function () {
|
||||
callback();
|
||||
});
|
||||
|
||||
this.Given(/^the data load extra arguments "(.*?)"$/, (args, callback) => {
|
||||
this.loaderArgs = this.expandOptions(args);
|
||||
callback();
|
||||
});
|
||||
|
||||
this.Given(/^a grid size of ([0-9.]+) meters$/, (meters, callback) => {
|
||||
this.setGridSize(meters);
|
||||
callback();
|
||||
|
||||
@ -5,6 +5,7 @@ var FBResult = require('../support/fbresult_generated').osrm.engine.api.fbresult
|
||||
|
||||
module.exports = function () {
|
||||
const durationsRegex = new RegExp(/^I request a travel time matrix I should get$/);
|
||||
const durationsCodeOnlyRegex = new RegExp(/^I request a travel time matrix with these waypoints I should get the response code$/);
|
||||
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 durationsRegexFb = new RegExp(/^I request a travel time matrix with flatbuffers I should get$/);
|
||||
@ -17,6 +18,7 @@ module.exports = function () {
|
||||
const FORMAT_FB = 'flatbuffers';
|
||||
|
||||
this.When(durationsRegex, function(table, callback) {tableParse.call(this, table, DURATIONS_NO_ROUTE, 'durations', FORMAT_JSON, callback);}.bind(this));
|
||||
this.When(durationsCodeOnlyRegex, function(table, callback) {tableCodeOnlyParse.call(this, table, 'durations', FORMAT_JSON, callback);}.bind(this));
|
||||
this.When(distancesRegex, function(table, callback) {tableParse.call(this, table, DISTANCES_NO_ROUTE, 'distances', FORMAT_JSON, callback);}.bind(this));
|
||||
this.When(estimatesRegex, function(table, callback) {tableParse.call(this, table, DISTANCES_NO_ROUTE, 'fallback_speed_cells', FORMAT_JSON, callback);}.bind(this));
|
||||
this.When(durationsRegexFb, function(table, callback) {tableParse.call(this, table, DURATIONS_NO_ROUTE, 'durations', FORMAT_FB, callback);}.bind(this));
|
||||
@ -27,6 +29,64 @@ 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 tableCodeOnlyParse(table, annotation, format, callback) {
|
||||
|
||||
const params = this.queryParams;
|
||||
params.annotations = ['durations','fallback_speed_cells'].indexOf(annotation) !== -1 ? 'duration' : 'distance';
|
||||
params.output = format;
|
||||
|
||||
var got;
|
||||
|
||||
this.reprocessAndLoadData((e) => {
|
||||
if (e) return callback(e);
|
||||
var testRow = (row, ri, cb) => {
|
||||
var afterRequest = (err, res) => {
|
||||
if (err) return cb(err);
|
||||
|
||||
for (var k in row) {
|
||||
var match = k.match(/param:(.*)/);
|
||||
if (match) {
|
||||
if (row[k] === '(nil)') {
|
||||
params[match[1]] = null;
|
||||
} else if (row[k]) {
|
||||
params[match[1]] = [row[k]];
|
||||
}
|
||||
got[k] = row[k];
|
||||
}
|
||||
}
|
||||
|
||||
var json;
|
||||
got.code = 'unknown';
|
||||
if (res.body.length) {
|
||||
json = JSON.parse(res.body);
|
||||
got.code = json.code;
|
||||
}
|
||||
|
||||
cb(null, got);
|
||||
};
|
||||
|
||||
var params = this.queryParams,
|
||||
waypoints = [];
|
||||
if (row.waypoints) {
|
||||
row.waypoints.split(',').forEach((n) => {
|
||||
var node = this.findNodeByName(n);
|
||||
if (!node) throw new Error(util.format('*** unknown waypoint node "%s"', n.trim()));
|
||||
waypoints.push({ coord: node, type: 'loc' });
|
||||
|
||||
});
|
||||
got = { waypoints: row.waypoints };
|
||||
|
||||
this.requestTable(waypoints, params, afterRequest);
|
||||
} else {
|
||||
throw new Error('*** no waypoints');
|
||||
}
|
||||
};
|
||||
|
||||
this.processRowsAndDiff(table, testRow, callback);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function tableParse(table, noRoute, annotation, format, callback) {
|
||||
|
||||
const parse = annotation == 'distances' ? distancesParse : (annotation == 'durations' ? durationsParse : estimatesParse);
|
||||
@ -62,9 +122,6 @@ function tableParse(table, noRoute, annotation, format, callback) {
|
||||
});
|
||||
}
|
||||
|
||||
var actual = [];
|
||||
actual.push(table.headers);
|
||||
|
||||
this.reprocessAndLoadData((e) => {
|
||||
if (e) return callback(e);
|
||||
// compute matrix
|
||||
|
||||
@ -12,25 +12,31 @@ module.exports = function () {
|
||||
var inNode = this.findNodeByName(row.in);
|
||||
if (!inNode) throw new Error(util.format('*** unknown in-node "%s"', row.in));
|
||||
|
||||
var outNode = this.findNodeByName(row.out);
|
||||
if (!outNode) throw new Error(util.format('*** unknown out-node "%s"', row.out));
|
||||
|
||||
this.requestNearest(inNode, this.queryParams, (err, response) => {
|
||||
if (err) return cb(err);
|
||||
var coord;
|
||||
var headers = new Set(table.raw()[0]);
|
||||
|
||||
if (response.statusCode === 200 && response.body.length) {
|
||||
var got = { in: row.in};
|
||||
|
||||
if (response.body.length) {
|
||||
var json = JSON.parse(response.body);
|
||||
got.code = json.code;
|
||||
|
||||
coord = json.waypoints[0].location;
|
||||
|
||||
var got = { in: row.in, out: row.out };
|
||||
if (response.statusCode === 200) {
|
||||
|
||||
if (headers.has('data_version')) {
|
||||
got.data_version = json.data_version || '';
|
||||
}
|
||||
|
||||
if (json.waypoints && json.waypoints.length && row.out) {
|
||||
coord = json.waypoints[0].location;
|
||||
|
||||
got.out = row.out;
|
||||
|
||||
var outNode = this.findNodeByName(row.out);
|
||||
if (!outNode) throw new Error(util.format('*** unknown out-node "%s"', row.out));
|
||||
|
||||
Object.keys(row).forEach((key) => {
|
||||
if (key === 'out') {
|
||||
if (this.FuzzyMatch.matchLocation(coord, outNode)) {
|
||||
@ -40,7 +46,9 @@ module.exports = function () {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
cb(null, got);
|
||||
}
|
||||
else {
|
||||
|
||||
@ -91,7 +91,7 @@ module.exports = function () {
|
||||
|
||||
var encodedResult = '';
|
||||
|
||||
if (json.trips) row.trips.split(',').forEach((sub, si) => {
|
||||
if (json.trips && row.trips) row.trips.split(',').forEach((sub, si) => {
|
||||
if (si >= subTrips.length) {
|
||||
ok = false;
|
||||
} else {
|
||||
@ -134,7 +134,6 @@ module.exports = function () {
|
||||
} else {
|
||||
var params = this.queryParams,
|
||||
waypoints = [];
|
||||
params['steps'] = 'true';
|
||||
if (row.from && row.to) {
|
||||
var fromNode = this.findNodeByName(row.from);
|
||||
if (!fromNode) throw new Error(util.format('*** unknown from-node "%s"', row.from));
|
||||
|
||||
@ -280,10 +280,11 @@ module.exports = function () {
|
||||
};
|
||||
|
||||
this.reprocessAndLoadData = (callback) => {
|
||||
let p = {loaderArgs: this.loaderArgs, inputFile: this.processedCacheFile};
|
||||
let queue = d3.queue(1);
|
||||
queue.defer(this.writeAndLinkOSM.bind(this));
|
||||
queue.defer(this.extractContractPartitionAndCustomize.bind(this));
|
||||
queue.defer(this.osrmLoader.load.bind(this.osrmLoader), this.processedCacheFile);
|
||||
queue.defer(this.osrmLoader.load.bind(this.osrmLoader), p);
|
||||
queue.awaitAll(callback);
|
||||
};
|
||||
|
||||
|
||||
@ -27,7 +27,8 @@ module.exports = function () {
|
||||
this.DEFAULT_ENVIRONMENT = process.env;
|
||||
this.DEFAULT_PROFILE = 'bicycle';
|
||||
this.DEFAULT_INPUT_FORMAT = 'osm';
|
||||
this.DEFAULT_LOAD_METHOD = process.argv[process.argv.indexOf('-m') +1].match('mmap') ? 'mmap' : 'datastore';
|
||||
let loadMethod = process.argv[process.argv.indexOf('-m') +1];
|
||||
this.DEFAULT_LOAD_METHOD = loadMethod.match('mmap') ? 'mmap' : loadMethod.match('directly') ? 'directly' : 'datastore';
|
||||
this.DEFAULT_ORIGIN = [1,1];
|
||||
this.OSM_USER = 'osrm';
|
||||
this.OSM_UID = 1;
|
||||
|
||||
@ -37,6 +37,7 @@ module.exports = function () {
|
||||
this.contractArgs = '';
|
||||
this.partitionArgs = '';
|
||||
this.customizeArgs = '';
|
||||
this.loaderArgs = '';
|
||||
this.environment = Object.assign(this.DEFAULT_ENVIRONMENT);
|
||||
this.resetOSM();
|
||||
|
||||
|
||||
@ -101,7 +101,8 @@ module.exports = function () {
|
||||
|
||||
this.requestTrip = (waypoints, userParams, callback) => {
|
||||
var defaults = {
|
||||
output: 'json'
|
||||
output: 'json',
|
||||
steps: 'true'
|
||||
},
|
||||
params = this.overwriteParams(defaults, userParams);
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ Feature: Alternative route
|
||||
| 7 | 8 | ca,ab,bd,dc,ca,ca | |
|
||||
|
||||
|
||||
@mld-only
|
||||
@mld
|
||||
Scenario: Alternative loop paths on a single node with an asymmetric circle
|
||||
# The test checks only MLD implementation, alternatives results are unpredictable for CH on windows (#4691, #4693)
|
||||
Given a grid size of 10 meters
|
||||
|
||||
@ -202,7 +202,7 @@ inline RouteParameters::AnnotationsType operator|(RouteParameters::AnnotationsTy
|
||||
static_cast<std::underlying_type_t<RouteParameters::AnnotationsType>>(rhs));
|
||||
}
|
||||
|
||||
inline RouteParameters::AnnotationsType operator|=(RouteParameters::AnnotationsType lhs,
|
||||
inline RouteParameters::AnnotationsType &operator|=(RouteParameters::AnnotationsType &lhs,
|
||||
RouteParameters::AnnotationsType rhs)
|
||||
{
|
||||
return lhs = lhs | rhs;
|
||||
|
||||
@ -31,6 +31,26 @@
|
||||
namespace osrm::engine::datafacade
|
||||
{
|
||||
|
||||
static const std::string DATASET_TURN_DATA = "TurnData";
|
||||
static const std::string DATASET_TURN_LANE_DATA = "NameLaneData";
|
||||
static const std::string DATASET_NAME_DATA = "NameData";
|
||||
static const std::string DATASET_INTERSECTION_BEARINGS = "IntersectionBearings";
|
||||
static const std::string DATASET_ENTRY_CLASS = "EntryClass";
|
||||
|
||||
/**
|
||||
* Macro is not ideal. But without it we either have to:
|
||||
* a) Write this boiler-plate for every usage of an optional dataset.
|
||||
* b) Convert to a function and add lots of polluting NOLINT(bugprone-unchecked-optional-access)
|
||||
* comments. This macro keeps the API code readable.
|
||||
*/
|
||||
#define CHECK_DATASET_DISABLED(val, dataset) \
|
||||
{ \
|
||||
if (!(val)) \
|
||||
{ \
|
||||
throw osrm::util::DisabledDatasetException((dataset)); \
|
||||
} \
|
||||
}
|
||||
|
||||
template <typename AlgorithmT> class ContiguousInternalMemoryAlgorithmDataFacade;
|
||||
|
||||
template <>
|
||||
@ -141,18 +161,15 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
std::string_view m_data_timestamp;
|
||||
util::vector_view<util::Coordinate> m_coordinate_list;
|
||||
extractor::PackedOSMIDsView m_osmnodeid_list;
|
||||
util::vector_view<std::uint32_t> m_lane_description_offsets;
|
||||
util::vector_view<extractor::TurnLaneType::Mask> m_lane_description_masks;
|
||||
std::optional<util::vector_view<std::uint32_t>> m_lane_description_offsets;
|
||||
std::optional<util::vector_view<extractor::TurnLaneType::Mask>> m_lane_description_masks;
|
||||
util::vector_view<TurnPenalty> m_turn_weight_penalties;
|
||||
util::vector_view<TurnPenalty> m_turn_duration_penalties;
|
||||
extractor::SegmentDataView segment_data;
|
||||
extractor::EdgeBasedNodeDataView edge_based_node_data;
|
||||
guidance::TurnDataView turn_data;
|
||||
std::optional<guidance::TurnDataView> turn_data;
|
||||
|
||||
util::vector_view<char> m_datasource_name_data;
|
||||
util::vector_view<std::size_t> m_datasource_name_offsets;
|
||||
util::vector_view<std::size_t> m_datasource_name_lengths;
|
||||
util::vector_view<util::guidance::LaneTupleIdPair> m_lane_tupel_id_pairs;
|
||||
std::optional<util::vector_view<util::guidance::LaneTupleIdPair>> m_lane_tuple_id_pairs;
|
||||
|
||||
util::vector_view<extractor::StorageManeuverOverride> m_maneuver_overrides;
|
||||
util::vector_view<NodeID> m_maneuver_override_node_sequences;
|
||||
@ -161,16 +178,24 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
std::unique_ptr<SharedGeospatialQuery> m_geospatial_query;
|
||||
boost::filesystem::path file_index_path;
|
||||
|
||||
extractor::IntersectionBearingsView intersection_bearings_view;
|
||||
std::optional<extractor::IntersectionBearingsView> intersection_bearings_view;
|
||||
|
||||
extractor::NameTableView m_name_table;
|
||||
std::optional<extractor::NameTableView> m_name_table;
|
||||
// the look-up table for entry classes. An entry class lists the possibility of entry for all
|
||||
// available turns. Such a class id is stored with every edge.
|
||||
util::vector_view<util::guidance::EntryClass> m_entry_class_table;
|
||||
std::optional<util::vector_view<util::guidance::EntryClass>> m_entry_class_table;
|
||||
|
||||
// allocator that keeps the allocation data
|
||||
std::shared_ptr<ContiguousBlockAllocator> allocator;
|
||||
|
||||
bool isIndexed(const storage::SharedDataIndex &index, const std::string &name)
|
||||
{
|
||||
bool result = false;
|
||||
index.List(name,
|
||||
boost::make_function_output_iterator([&](const auto &) { result = true; }));
|
||||
return result;
|
||||
}
|
||||
|
||||
void InitializeInternalPointers(const storage::SharedDataIndex &index,
|
||||
const std::string &metric_name,
|
||||
const std::size_t exclude_index)
|
||||
@ -183,7 +208,17 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
|
||||
exclude_mask = m_profile_properties->excludable_classes[exclude_index];
|
||||
|
||||
m_check_sum = *index.GetBlockPtr<std::uint32_t>("/common/connectivity_checksum");
|
||||
// We no longer use "/common/connectivity_checksum", as osrm.edges is an optional dataset.
|
||||
// Instead, we load the value from the MLD or CH graph, whichever is loaded.
|
||||
if (isIndexed(index, "/mld/connectivity_checksum"))
|
||||
{
|
||||
m_check_sum = *index.GetBlockPtr<std::uint32_t>("/mld/connectivity_checksum");
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(isIndexed(index, "/ch/connectivity_checksum"));
|
||||
m_check_sum = *index.GetBlockPtr<std::uint32_t>("/ch/connectivity_checksum");
|
||||
}
|
||||
|
||||
m_data_timestamp = make_timestamp_view(index, "/common/timestamp");
|
||||
|
||||
@ -196,13 +231,23 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
|
||||
edge_based_node_data = make_ebn_data_view(index, "/common/ebg_node_data");
|
||||
|
||||
if (isIndexed(index, "/common/turn_data"))
|
||||
{
|
||||
turn_data = make_turn_data_view(index, "/common/turn_data");
|
||||
}
|
||||
|
||||
if (isIndexed(index, "/common/names"))
|
||||
{
|
||||
m_name_table = make_name_table_view(index, "/common/names");
|
||||
}
|
||||
|
||||
if (isIndexed(index, "/common/turn_lanes"))
|
||||
{
|
||||
std::tie(m_lane_description_offsets, m_lane_description_masks) =
|
||||
make_turn_lane_description_views(index, "/common/turn_lanes");
|
||||
m_lane_tupel_id_pairs = make_lane_data_view(index, "/common/turn_lanes");
|
||||
|
||||
m_lane_tuple_id_pairs = make_lane_data_view(index, "/common/turn_lanes");
|
||||
}
|
||||
|
||||
m_turn_weight_penalties = make_turn_weight_view(index, "/common/turn_penalty");
|
||||
m_turn_duration_penalties = make_turn_duration_view(index, "/common/turn_penalty");
|
||||
@ -211,10 +256,12 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
|
||||
m_datasources = index.GetBlockPtr<extractor::Datasources>("/common/data_sources_names");
|
||||
|
||||
if (isIndexed(index, "/common/intersection_bearings"))
|
||||
{
|
||||
intersection_bearings_view =
|
||||
make_intersection_bearings_view(index, "/common/intersection_bearings");
|
||||
|
||||
m_entry_class_table = make_entry_classes_view(index, "/common/entry_classes");
|
||||
}
|
||||
|
||||
std::tie(m_maneuver_overrides, m_maneuver_override_node_sequences) =
|
||||
make_maneuver_overrides_views(index, "/common/maneuver_overrides");
|
||||
@ -305,7 +352,8 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
osrm::guidance::TurnInstruction
|
||||
GetTurnInstructionForEdgeID(const EdgeID edge_based_edge_id) const override final
|
||||
{
|
||||
return turn_data.GetTurnInstruction(edge_based_edge_id);
|
||||
CHECK_DATASET_DISABLED(turn_data, DATASET_TURN_DATA);
|
||||
return turn_data->GetTurnInstruction(edge_based_edge_id);
|
||||
}
|
||||
|
||||
std::vector<RTreeLeaf> GetEdgesInBox(const util::Coordinate south_west,
|
||||
@ -406,27 +454,32 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
|
||||
std::string_view GetNameForID(const NameID id) const override final
|
||||
{
|
||||
return m_name_table.GetNameForID(id);
|
||||
CHECK_DATASET_DISABLED(m_name_table, DATASET_NAME_DATA);
|
||||
return m_name_table->GetNameForID(id);
|
||||
}
|
||||
|
||||
std::string_view GetRefForID(const NameID id) const override final
|
||||
{
|
||||
return m_name_table.GetRefForID(id);
|
||||
CHECK_DATASET_DISABLED(m_name_table, DATASET_NAME_DATA);
|
||||
return m_name_table->GetRefForID(id);
|
||||
}
|
||||
|
||||
std::string_view GetPronunciationForID(const NameID id) const override final
|
||||
{
|
||||
return m_name_table.GetPronunciationForID(id);
|
||||
CHECK_DATASET_DISABLED(m_name_table, DATASET_NAME_DATA);
|
||||
return m_name_table->GetPronunciationForID(id);
|
||||
}
|
||||
|
||||
std::string_view GetDestinationsForID(const NameID id) const override final
|
||||
{
|
||||
return m_name_table.GetDestinationsForID(id);
|
||||
CHECK_DATASET_DISABLED(m_name_table, DATASET_NAME_DATA);
|
||||
return m_name_table->GetDestinationsForID(id);
|
||||
}
|
||||
|
||||
std::string_view GetExitsForID(const NameID id) const override final
|
||||
{
|
||||
return m_name_table.GetExitsForID(id);
|
||||
CHECK_DATASET_DISABLED(m_name_table, DATASET_NAME_DATA);
|
||||
return m_name_table->GetExitsForID(id);
|
||||
}
|
||||
|
||||
std::string_view GetDatasourceName(const DatasourceID id) const override final
|
||||
@ -459,46 +512,60 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
util::guidance::BearingClass
|
||||
GetBearingClass(const NodeID node_based_node_id) const override final
|
||||
{
|
||||
return intersection_bearings_view.GetBearingClass(node_based_node_id);
|
||||
CHECK_DATASET_DISABLED(intersection_bearings_view, DATASET_INTERSECTION_BEARINGS);
|
||||
return intersection_bearings_view->GetBearingClass(node_based_node_id);
|
||||
}
|
||||
|
||||
guidance::TurnBearing PreTurnBearing(const EdgeID edge_based_edge_id) const override final
|
||||
{
|
||||
return turn_data.GetPreTurnBearing(edge_based_edge_id);
|
||||
CHECK_DATASET_DISABLED(turn_data, DATASET_TURN_DATA);
|
||||
return turn_data->GetPreTurnBearing(edge_based_edge_id);
|
||||
}
|
||||
guidance::TurnBearing PostTurnBearing(const EdgeID edge_based_edge_id) const override final
|
||||
{
|
||||
return turn_data.GetPostTurnBearing(edge_based_edge_id);
|
||||
CHECK_DATASET_DISABLED(turn_data, DATASET_TURN_DATA);
|
||||
return turn_data->GetPostTurnBearing(edge_based_edge_id);
|
||||
}
|
||||
|
||||
util::guidance::EntryClass GetEntryClass(const EdgeID edge_based_edge_id) const override final
|
||||
{
|
||||
auto entry_class_id = turn_data.GetEntryClassID(edge_based_edge_id);
|
||||
return m_entry_class_table.at(entry_class_id);
|
||||
CHECK_DATASET_DISABLED(m_entry_class_table, DATASET_ENTRY_CLASS);
|
||||
CHECK_DATASET_DISABLED(turn_data, DATASET_TURN_DATA);
|
||||
|
||||
auto entry_class_id = turn_data->GetEntryClassID(edge_based_edge_id);
|
||||
return m_entry_class_table->at(entry_class_id);
|
||||
}
|
||||
|
||||
bool HasLaneData(const EdgeID edge_based_edge_id) const override final
|
||||
{
|
||||
return turn_data.HasLaneData(edge_based_edge_id);
|
||||
CHECK_DATASET_DISABLED(turn_data, DATASET_TURN_DATA);
|
||||
return turn_data->HasLaneData(edge_based_edge_id);
|
||||
}
|
||||
|
||||
util::guidance::LaneTupleIdPair
|
||||
GetLaneData(const EdgeID edge_based_edge_id) const override final
|
||||
{
|
||||
CHECK_DATASET_DISABLED(turn_data, DATASET_TURN_DATA);
|
||||
CHECK_DATASET_DISABLED(m_lane_tuple_id_pairs, DATASET_TURN_LANE_DATA);
|
||||
|
||||
BOOST_ASSERT(HasLaneData(edge_based_edge_id));
|
||||
return m_lane_tupel_id_pairs.at(turn_data.GetLaneDataID(edge_based_edge_id));
|
||||
return m_lane_tuple_id_pairs->at(turn_data->GetLaneDataID(edge_based_edge_id));
|
||||
}
|
||||
|
||||
extractor::TurnLaneDescription
|
||||
GetTurnDescription(const LaneDescriptionID lane_description_id) const override final
|
||||
{
|
||||
CHECK_DATASET_DISABLED(m_lane_description_offsets, DATASET_TURN_LANE_DATA);
|
||||
CHECK_DATASET_DISABLED(m_lane_description_masks, DATASET_TURN_LANE_DATA);
|
||||
|
||||
if (lane_description_id == INVALID_LANE_DESCRIPTIONID)
|
||||
return {};
|
||||
else
|
||||
return extractor::TurnLaneDescription(
|
||||
m_lane_description_masks.begin() + m_lane_description_offsets[lane_description_id],
|
||||
m_lane_description_masks.begin() +
|
||||
m_lane_description_offsets[lane_description_id + 1]);
|
||||
m_lane_description_masks->begin() +
|
||||
m_lane_description_offsets->at(lane_description_id),
|
||||
m_lane_description_masks->begin() +
|
||||
m_lane_description_offsets->at(lane_description_id + 1));
|
||||
}
|
||||
|
||||
bool IsLeftHandDriving(const NodeID edge_based_node_id) const override final
|
||||
|
||||
@ -29,9 +29,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#define ENGINE_CONFIG_HPP
|
||||
|
||||
#include "storage/storage_config.hpp"
|
||||
#include "osrm/datasets.hpp"
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
namespace osrm::engine
|
||||
@ -83,12 +85,13 @@ struct EngineConfig final
|
||||
int max_locations_map_matching = -1;
|
||||
double max_radius_map_matching = -1.0;
|
||||
int max_results_nearest = -1;
|
||||
boost::optional<double> default_radius;
|
||||
boost::optional<double> default_radius = -1.0;
|
||||
int max_alternatives = 3; // set an arbitrary upper bound; can be adjusted by user
|
||||
bool use_shared_memory = true;
|
||||
boost::filesystem::path memory_file;
|
||||
bool use_mmap = true;
|
||||
Algorithm algorithm = Algorithm::CH;
|
||||
std::vector<storage::FeatureDataset> disable_feature_dataset;
|
||||
std::string verbosity;
|
||||
std::string dataset_name;
|
||||
};
|
||||
|
||||
@ -72,7 +72,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
[this, &max_distance, &max_results, input_coordinate](const std::size_t num_results,
|
||||
const CandidateSegment &segment) {
|
||||
return (max_results && num_results >= *max_results) ||
|
||||
(max_distance &&
|
||||
(max_distance && max_distance != -1.0 &&
|
||||
CheckSegmentDistance(input_coordinate, segment, *max_distance));
|
||||
});
|
||||
|
||||
@ -163,7 +163,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
auto distance = GetSegmentDistance(input_coordinate, segment);
|
||||
auto further_than_big_component = distance > big_component_distance;
|
||||
auto no_more_candidates = has_big_component && further_than_big_component;
|
||||
auto too_far_away = max_distance && distance > *max_distance;
|
||||
auto too_far_away =
|
||||
max_distance && max_distance != -1.0 && distance > *max_distance;
|
||||
|
||||
// Time to terminate the search when:
|
||||
// 1. We've found a node from a big component and the next candidate is further away
|
||||
|
||||
@ -205,9 +205,50 @@ inline engine_config_ptr argumentsToEngineConfig(const Napi::CallbackInfo &args)
|
||||
}
|
||||
}
|
||||
|
||||
auto disable_feature_dataset = params.Get("disable_feature_dataset");
|
||||
if (disable_feature_dataset.IsArray())
|
||||
{
|
||||
Napi::Array datasets = disable_feature_dataset.As<Napi::Array>();
|
||||
for (uint32_t i = 0; i < datasets.Length(); ++i)
|
||||
{
|
||||
Napi::Value dataset = datasets.Get(i);
|
||||
if (!dataset.IsString())
|
||||
{
|
||||
ThrowError(args.Env(), "disable_feature_dataset list option must be a string");
|
||||
return engine_config_ptr();
|
||||
}
|
||||
auto dataset_str = dataset.ToString().Utf8Value();
|
||||
if (dataset_str == "ROUTE_GEOMETRY")
|
||||
{
|
||||
engine_config->disable_feature_dataset.push_back(
|
||||
osrm::storage::FeatureDataset::ROUTE_GEOMETRY);
|
||||
}
|
||||
else if (dataset_str == "ROUTE_STEPS")
|
||||
{
|
||||
engine_config->disable_feature_dataset.push_back(
|
||||
osrm::storage::FeatureDataset::ROUTE_STEPS);
|
||||
}
|
||||
else
|
||||
{
|
||||
ThrowError(
|
||||
args.Env(),
|
||||
"disable_feature_dataset array can include 'ROUTE_GEOMETRY', 'ROUTE_STEPS'.");
|
||||
return engine_config_ptr();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!disable_feature_dataset.IsUndefined())
|
||||
{
|
||||
ThrowError(args.Env(),
|
||||
"disable_feature_dataset option must be an array and can include the string "
|
||||
"values 'ROUTE_GEOMETRY', 'ROUTE_STEPS'.");
|
||||
return engine_config_ptr();
|
||||
}
|
||||
|
||||
if (!path.IsUndefined())
|
||||
{
|
||||
engine_config->storage_config = osrm::StorageConfig(path.ToString().Utf8Value());
|
||||
engine_config->storage_config = osrm::StorageConfig(path.ToString().Utf8Value(),
|
||||
engine_config->disable_feature_dataset);
|
||||
|
||||
engine_config->use_shared_memory = false;
|
||||
}
|
||||
@ -317,9 +358,16 @@ inline engine_config_ptr argumentsToEngineConfig(const Napi::CallbackInfo &args)
|
||||
ThrowError(args.Env(), "max_alternatives must be an integral number");
|
||||
return engine_config_ptr();
|
||||
}
|
||||
if (!default_radius.IsUndefined() && !default_radius.IsNumber())
|
||||
if (!max_radius_map_matching.IsUndefined() && max_radius_map_matching.IsString() &&
|
||||
max_radius_map_matching.ToString().Utf8Value() != "unlimited")
|
||||
{
|
||||
ThrowError(args.Env(), "default_radius must be an integral number");
|
||||
ThrowError(args.Env(), "max_radius_map_matching must be unlimited or an integral number");
|
||||
return engine_config_ptr();
|
||||
}
|
||||
if (!default_radius.IsUndefined() && default_radius.IsString() &&
|
||||
default_radius.ToString().Utf8Value() != "unlimited")
|
||||
{
|
||||
ThrowError(args.Env(), "default_radius must be unlimited or an integral number");
|
||||
return engine_config_ptr();
|
||||
}
|
||||
|
||||
@ -337,10 +385,17 @@ inline engine_config_ptr argumentsToEngineConfig(const Napi::CallbackInfo &args)
|
||||
engine_config->max_results_nearest = max_results_nearest.ToNumber().Int32Value();
|
||||
if (max_alternatives.IsNumber())
|
||||
engine_config->max_alternatives = max_alternatives.ToNumber().Int32Value();
|
||||
|
||||
if (max_radius_map_matching.IsNumber())
|
||||
engine_config->max_radius_map_matching = max_radius_map_matching.ToNumber().DoubleValue();
|
||||
else if (max_radius_map_matching.IsString() &&
|
||||
max_radius_map_matching.ToString().Utf8Value() == "unlimited")
|
||||
engine_config->max_radius_map_matching = -1.0;
|
||||
|
||||
if (default_radius.IsNumber())
|
||||
engine_config->default_radius = default_radius.ToNumber().DoubleValue();
|
||||
else if (default_radius.IsString() && default_radius.ToString().Utf8Value() == "unlimited")
|
||||
engine_config->default_radius = -1.0;
|
||||
|
||||
return engine_config;
|
||||
}
|
||||
|
||||
15
include/osrm/datasets.hpp
Normal file
15
include/osrm/datasets.hpp
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef DATASETS_HPP
|
||||
#define DATASETS_HPP
|
||||
|
||||
namespace osrm::storage
|
||||
{
|
||||
|
||||
enum class FeatureDataset
|
||||
{
|
||||
ROUTE_STEPS,
|
||||
ROUTE_GEOMETRY,
|
||||
};
|
||||
|
||||
} // namespace osrm::storage
|
||||
|
||||
#endif
|
||||
@ -23,7 +23,8 @@ enum ErrorCode
|
||||
FileIOError,
|
||||
UnexpectedEndOfFile,
|
||||
IncompatibleDataset,
|
||||
UnknownAlgorithm
|
||||
UnknownAlgorithm,
|
||||
UnknownFeatureDataset
|
||||
#ifndef NDEBUG
|
||||
// Leave this at the end. In debug mode, we assert that the size of
|
||||
// this enum matches the number of messages we have documented, and __ENDMARKER__
|
||||
|
||||
@ -35,6 +35,11 @@ struct IOConfig
|
||||
return {base_path.string() + fileName};
|
||||
}
|
||||
|
||||
bool IsRequiredConfiguredInput(const std::string &fileName) const
|
||||
{
|
||||
return IsConfigured(fileName, required_input_files);
|
||||
}
|
||||
|
||||
boost::filesystem::path base_path;
|
||||
|
||||
protected:
|
||||
|
||||
@ -31,10 +31,61 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
#include "storage/io_config.hpp"
|
||||
#include "osrm/datasets.hpp"
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace osrm::storage
|
||||
{
|
||||
|
||||
std::istream &operator>>(std::istream &in, FeatureDataset &datasets);
|
||||
|
||||
static std::vector<boost::filesystem::path>
|
||||
GetRequiredFiles(const std::vector<storage::FeatureDataset> &disabled_feature_dataset)
|
||||
{
|
||||
std::set<boost::filesystem::path> required{
|
||||
".osrm.datasource_names",
|
||||
".osrm.ebg_nodes",
|
||||
".osrm.edges",
|
||||
".osrm.fileIndex",
|
||||
".osrm.geometry",
|
||||
".osrm.icd",
|
||||
".osrm.maneuver_overrides",
|
||||
".osrm.names",
|
||||
".osrm.nbg_nodes",
|
||||
".osrm.properties",
|
||||
".osrm.ramIndex",
|
||||
".osrm.timestamp",
|
||||
".osrm.tld",
|
||||
".osrm.tls",
|
||||
".osrm.turn_duration_penalties",
|
||||
".osrm.turn_weight_penalties",
|
||||
};
|
||||
|
||||
for (const auto &to_disable : disabled_feature_dataset)
|
||||
{
|
||||
switch (to_disable)
|
||||
{
|
||||
case FeatureDataset::ROUTE_STEPS:
|
||||
for (const auto &dataset : {".osrm.icd", ".osrm.tld", ".osrm.tls"})
|
||||
{
|
||||
required.erase(dataset);
|
||||
}
|
||||
break;
|
||||
case FeatureDataset::ROUTE_GEOMETRY:
|
||||
for (const auto &dataset :
|
||||
{".osrm.edges", ".osrm.icd", ".osrm.names", ".osrm.tld", ".osrm.tls"})
|
||||
{
|
||||
required.erase(dataset);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return std::vector<boost::filesystem::path>(required.begin(), required.end());
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures OSRM's file storage paths.
|
||||
*
|
||||
@ -42,33 +93,18 @@ namespace osrm::storage
|
||||
*/
|
||||
struct StorageConfig final : IOConfig
|
||||
{
|
||||
StorageConfig(const boost::filesystem::path &base) : StorageConfig()
|
||||
|
||||
StorageConfig(const boost::filesystem::path &base,
|
||||
const std::vector<storage::FeatureDataset> &disabled_feature_datasets_ = {})
|
||||
: StorageConfig(disabled_feature_datasets_)
|
||||
{
|
||||
IOConfig::UseDefaultOutputNames(base);
|
||||
}
|
||||
|
||||
StorageConfig()
|
||||
: IOConfig({".osrm.ramIndex",
|
||||
".osrm.fileIndex",
|
||||
".osrm.edges",
|
||||
".osrm.geometry",
|
||||
".osrm.turn_weight_penalties",
|
||||
".osrm.turn_duration_penalties",
|
||||
".osrm.datasource_names",
|
||||
".osrm.names",
|
||||
".osrm.timestamp",
|
||||
".osrm.properties",
|
||||
".osrm.icd",
|
||||
".osrm.maneuver_overrides"},
|
||||
{".osrm.hsgr",
|
||||
".osrm.nbg_nodes",
|
||||
".osrm.ebg_nodes",
|
||||
".osrm.cells",
|
||||
".osrm.cell_metrics",
|
||||
".osrm.mldgr",
|
||||
".osrm.tld",
|
||||
".osrm.tls",
|
||||
".osrm.partition"},
|
||||
StorageConfig(const std::vector<storage::FeatureDataset> &disabled_feature_datasets_ = {})
|
||||
: IOConfig(
|
||||
GetRequiredFiles(disabled_feature_datasets_),
|
||||
{".osrm.hsgr", ".osrm.cells", ".osrm.cell_metrics", ".osrm.mldgr", ".osrm.partition"},
|
||||
{})
|
||||
{
|
||||
}
|
||||
|
||||
@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <iosfwd> //for std::ostream
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
@ -62,7 +62,7 @@ class exception : public std::exception
|
||||
* user supplied bad data, etc).
|
||||
*/
|
||||
|
||||
constexpr const std::array<const char *, 11> ErrorDescriptions = {{
|
||||
constexpr const std::array<const char *, 12> ErrorDescriptions = {{
|
||||
"", // Dummy - ErrorCode values start at 2
|
||||
"", // Dummy - ErrorCode values start at 2
|
||||
"Fingerprint did not match the expected value", // InvalidFingerprint
|
||||
@ -75,7 +75,8 @@ constexpr const std::array<const char *, 11> ErrorDescriptions = {{
|
||||
// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
|
||||
"The dataset you are trying to load is not " // IncompatibleDataset
|
||||
"compatible with the routing algorithm you want to use.", // ...continued...
|
||||
"Incompatible algorithm" // IncompatibleAlgorithm
|
||||
"Incompatible algorithm", // IncompatibleAlgorithm
|
||||
"Unknown feature dataset" // UnknownFeatureDataset
|
||||
}};
|
||||
|
||||
#ifndef NDEBUG
|
||||
@ -84,6 +85,32 @@ static_assert(ErrorDescriptions.size() == ErrorCode::__ENDMARKER__,
|
||||
"ErrorCode list and ErrorDescription lists are different sizes");
|
||||
#endif
|
||||
|
||||
class DisabledDatasetException : public exception
|
||||
{
|
||||
public:
|
||||
explicit DisabledDatasetException(const std::string &dataset_)
|
||||
: exception(BuildMessage(dataset_)), dataset(dataset_)
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &Dataset() const { return dataset; }
|
||||
|
||||
private:
|
||||
// This function exists to 'anchor' the class, and stop the compiler from
|
||||
// copying vtable and RTTI info into every object file that includes
|
||||
// this header. (Caught by -Wweak-vtables under Clang.)
|
||||
virtual void anchor() const override;
|
||||
const std::string dataset;
|
||||
|
||||
static std::string BuildMessage(const std::string &dataset)
|
||||
{
|
||||
return "DisabledDatasetException: Your query tried to access the disabled dataset " +
|
||||
dataset +
|
||||
". Please check your configuration: "
|
||||
"https://github.com/Project-OSRM/osrm-backend/wiki/Disabled-Datasets";
|
||||
}
|
||||
};
|
||||
|
||||
class RuntimeError : public exception
|
||||
{
|
||||
using Base = exception;
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
#include <boost/date_time/gregorian/gregorian.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
2280
package-lock.json
generated
2280
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -14,7 +14,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "node ./node_modules/eslint/bin/eslint.js -c ./.eslintrc features/step_definitions/ features/support/",
|
||||
"test": "npm run lint && node ./node_modules/cucumber/bin/cucumber.js features/ -p verify && node ./node_modules/cucumber/bin/cucumber.js features/ -p verify -m mmap && node ./node_modules/cucumber/bin/cucumber.js features/ -p mld && node ./node_modules/cucumber/bin/cucumber.js features/ -p mld -m mmap",
|
||||
"test": "npm run lint && ./scripts/cucumber_test_matrix.sh",
|
||||
"clean": "rm -rf test/cache",
|
||||
"docs": "./scripts/build_api_docs.sh",
|
||||
"install": "node-pre-gyp install --fallback-to-build=false || ./scripts/node_install.sh",
|
||||
|
||||
18
scripts/cucumber_test_matrix.sh
Executable file
18
scripts/cucumber_test_matrix.sh
Executable file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
set -o nounset
|
||||
|
||||
loadmethods=(datastore mmap directly)
|
||||
profiles=(ch mld)
|
||||
|
||||
for profile in "${profiles[@]}"
|
||||
do
|
||||
for loadmethod in "${loadmethods[@]}"
|
||||
do
|
||||
set -x
|
||||
node ./node_modules/cucumber/bin/cucumber.js features/ -p $profile -m $loadmethod
|
||||
{ set +x; } 2>/dev/null
|
||||
done
|
||||
done
|
||||
@ -13,12 +13,14 @@ bool EngineConfig::IsValid() const
|
||||
return v == -1 || v > limit;
|
||||
};
|
||||
|
||||
const bool limits_valid = unlimited_or_more_than(max_locations_distance_table, 2) &&
|
||||
const bool limits_valid =
|
||||
unlimited_or_more_than(max_locations_distance_table, 2) &&
|
||||
unlimited_or_more_than(max_locations_map_matching, 2) &&
|
||||
unlimited_or_more_than(max_radius_map_matching, 0) &&
|
||||
unlimited_or_more_than(max_locations_trip, 2) &&
|
||||
unlimited_or_more_than(max_locations_viaroute, 2) &&
|
||||
unlimited_or_more_than(max_results_nearest, 0) &&
|
||||
(!default_radius.has_value() || unlimited_or_more_than(*default_radius, 0)) &&
|
||||
max_alternatives >= 0;
|
||||
|
||||
return ((use_shared_memory && all_path_are_empty) || (use_mmap && storage_config.IsValid()) ||
|
||||
|
||||
@ -181,7 +181,7 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
||||
if (tidied.parameters.radiuses.empty())
|
||||
{
|
||||
search_radiuses.resize(tidied.parameters.coordinates.size(),
|
||||
default_radius.has_value()
|
||||
default_radius.has_value() && *default_radius != -1.0
|
||||
? *default_radius
|
||||
: routing_algorithms::DEFAULT_GPS_PRECISION * RADIUS_MULTIPLIER);
|
||||
}
|
||||
@ -199,7 +199,7 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
||||
}
|
||||
else
|
||||
{
|
||||
return default_radius.has_value()
|
||||
return default_radius.has_value() && *default_radius != -1.0
|
||||
? *default_radius
|
||||
: routing_algorithms::DEFAULT_GPS_PRECISION * RADIUS_MULTIPLIER;
|
||||
}
|
||||
|
||||
@ -74,6 +74,7 @@ Napi::Object Engine::Init(Napi::Env env, Napi::Object exports)
|
||||
* Old behaviour: Path to a file on disk to store the memory using mmap. Current behaviour: setting this value is the same as setting `mmap_memory: true`.
|
||||
* @param {Boolean} [options.mmap_memory] Map on-disk files to virtual memory addresses (mmap), rather than loading into RAM.
|
||||
* @param {String} [options.path] The path to the `.osrm` files. This is mutually exclusive with setting {options.shared_memory} to true.
|
||||
* @param {Array} [options.disable_feature_dataset] Disables a feature dataset from being loaded into memory if not needed. Options: `ROUTE_STEPS`, `ROUTE_GEOMETRY`.
|
||||
* @param {Number} [options.max_locations_trip] Max. locations supported in trip query (default: unlimited).
|
||||
* @param {Number} [options.max_locations_viaroute] Max. locations supported in viaroute query (default: unlimited).
|
||||
* @param {Number} [options.max_locations_distance_table] Max. locations supported in distance table query (default: unlimited).
|
||||
|
||||
@ -9,21 +9,16 @@
|
||||
#include "util/log.hpp"
|
||||
#include "util/string_util.hpp"
|
||||
#include "util/timing_util.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include "engine/status.hpp"
|
||||
#include "osrm/osrm.hpp"
|
||||
#include "util/json_container.hpp"
|
||||
|
||||
#include <boost/iostreams/copy.hpp>
|
||||
#include <boost/iostreams/filter/gzip.hpp>
|
||||
#include <boost/iostreams/filtering_streambuf.hpp>
|
||||
|
||||
#include <ctime>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
@ -36,6 +31,48 @@ void RequestHandler::RegisterServiceHandler(
|
||||
service_handler = std::move(service_handler_);
|
||||
}
|
||||
|
||||
void SendResponse(ServiceHandler::ResultT &result, http::reply ¤t_reply)
|
||||
{
|
||||
|
||||
current_reply.headers.emplace_back("Access-Control-Allow-Origin", "*");
|
||||
current_reply.headers.emplace_back("Access-Control-Allow-Methods", "GET");
|
||||
current_reply.headers.emplace_back("Access-Control-Allow-Headers",
|
||||
"X-Requested-With, Content-Type");
|
||||
if (result.is<util::json::Object>())
|
||||
{
|
||||
current_reply.headers.emplace_back("Content-Type", "application/json; charset=UTF-8");
|
||||
current_reply.headers.emplace_back("Content-Disposition",
|
||||
"inline; filename=\"response.json\"");
|
||||
|
||||
util::json::render(current_reply.content, result.get<util::json::Object>());
|
||||
}
|
||||
else if (result.is<flatbuffers::FlatBufferBuilder>())
|
||||
{
|
||||
auto &buffer = result.get<flatbuffers::FlatBufferBuilder>();
|
||||
current_reply.content.resize(buffer.GetSize());
|
||||
std::copy(buffer.GetBufferPointer(),
|
||||
buffer.GetBufferPointer() + buffer.GetSize(),
|
||||
current_reply.content.begin());
|
||||
|
||||
current_reply.headers.emplace_back(
|
||||
"Content-Type", "application/x-flatbuffers;schema=osrm.engine.api.fbresult");
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(result.is<std::string>());
|
||||
current_reply.content.resize(result.get<std::string>().size());
|
||||
std::copy(result.get<std::string>().cbegin(),
|
||||
result.get<std::string>().cend(),
|
||||
current_reply.content.begin());
|
||||
|
||||
current_reply.headers.emplace_back("Content-Type", "application/x-protobuf");
|
||||
}
|
||||
|
||||
// set headers
|
||||
current_reply.headers.emplace_back("Content-Length",
|
||||
std::to_string(current_reply.content.size()));
|
||||
}
|
||||
|
||||
void RequestHandler::HandleRequest(const http::request ¤t_request, http::reply ¤t_reply)
|
||||
{
|
||||
if (!service_handler)
|
||||
@ -96,43 +133,7 @@ void RequestHandler::HandleRequest(const http::request ¤t_request, http::r
|
||||
std::to_string(position) + ": \"" + context + "\"";
|
||||
}
|
||||
|
||||
current_reply.headers.emplace_back("Access-Control-Allow-Origin", "*");
|
||||
current_reply.headers.emplace_back("Access-Control-Allow-Methods", "GET");
|
||||
current_reply.headers.emplace_back("Access-Control-Allow-Headers",
|
||||
"X-Requested-With, Content-Type");
|
||||
if (result.is<util::json::Object>())
|
||||
{
|
||||
current_reply.headers.emplace_back("Content-Type", "application/json; charset=UTF-8");
|
||||
current_reply.headers.emplace_back("Content-Disposition",
|
||||
"inline; filename=\"response.json\"");
|
||||
|
||||
util::json::render(current_reply.content, result.get<util::json::Object>());
|
||||
}
|
||||
else if (result.is<flatbuffers::FlatBufferBuilder>())
|
||||
{
|
||||
auto &buffer = result.get<flatbuffers::FlatBufferBuilder>();
|
||||
current_reply.content.resize(buffer.GetSize());
|
||||
std::copy(buffer.GetBufferPointer(),
|
||||
buffer.GetBufferPointer() + buffer.GetSize(),
|
||||
current_reply.content.begin());
|
||||
|
||||
current_reply.headers.emplace_back(
|
||||
"Content-Type", "application/x-flatbuffers;schema=osrm.engine.api.fbresult");
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(result.is<std::string>());
|
||||
current_reply.content.resize(result.get<std::string>().size());
|
||||
std::copy(result.get<std::string>().cbegin(),
|
||||
result.get<std::string>().cend(),
|
||||
current_reply.content.begin());
|
||||
|
||||
current_reply.headers.emplace_back("Content-Type", "application/x-protobuf");
|
||||
}
|
||||
|
||||
// set headers
|
||||
current_reply.headers.emplace_back("Content-Length",
|
||||
std::to_string(current_reply.content.size()));
|
||||
SendResponse(result, current_reply);
|
||||
|
||||
if (!std::getenv("DISABLE_ACCESS_LOGGING"))
|
||||
{
|
||||
@ -168,6 +169,19 @@ void RequestHandler::HandleRequest(const http::request ¤t_request, http::r
|
||||
<< request_string;
|
||||
}
|
||||
}
|
||||
catch (const util::DisabledDatasetException &e)
|
||||
{
|
||||
current_reply.status = http::reply::bad_request;
|
||||
|
||||
ServiceHandler::ResultT result = util::json::Object();
|
||||
auto &json_result = result.get<util::json::Object>();
|
||||
json_result.values["code"] = "DisabledDataset";
|
||||
json_result.values["message"] = e.what();
|
||||
SendResponse(result, current_reply);
|
||||
|
||||
util::Log(logWARNING) << "[disabled dataset error][" << tid << "] code: DisabledDataset_"
|
||||
<< e.Dataset() << ", uri: " << current_request.uri;
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
current_reply = http::reply::stock_reply(http::reply::internal_server_error);
|
||||
|
||||
@ -294,17 +294,20 @@ std::vector<std::pair<bool, boost::filesystem::path>> Storage::GetStaticFiles()
|
||||
std::vector<std::pair<bool, boost::filesystem::path>> files = {
|
||||
{IS_OPTIONAL, config.GetPath(".osrm.cells")},
|
||||
{IS_OPTIONAL, config.GetPath(".osrm.partition")},
|
||||
{IS_REQUIRED, config.GetPath(".osrm.icd")},
|
||||
{IS_REQUIRED, config.GetPath(".osrm.properties")},
|
||||
{IS_REQUIRED, config.GetPath(".osrm.nbg_nodes")},
|
||||
{IS_REQUIRED, config.GetPath(".osrm.ebg_nodes")},
|
||||
{IS_REQUIRED, config.GetPath(".osrm.tls")},
|
||||
{IS_REQUIRED, config.GetPath(".osrm.tld")},
|
||||
{IS_REQUIRED, config.GetPath(".osrm.timestamp")},
|
||||
{IS_REQUIRED, config.GetPath(".osrm.maneuver_overrides")},
|
||||
{IS_REQUIRED, config.GetPath(".osrm.edges")},
|
||||
{IS_REQUIRED, config.GetPath(".osrm.names")},
|
||||
{IS_REQUIRED, config.GetPath(".osrm.ramIndex")}};
|
||||
{IS_REQUIRED, config.GetPath(".osrm.nbg_nodes")},
|
||||
{IS_REQUIRED, config.GetPath(".osrm.ramIndex")},
|
||||
{IS_REQUIRED, config.GetPath(".osrm.properties")},
|
||||
{IS_REQUIRED, config.GetPath(".osrm.timestamp")}};
|
||||
|
||||
for (const auto &file : {".osrm.edges", ".osrm.names", ".osrm.icd", ".osrm.tls", ".osrm.tld"})
|
||||
{
|
||||
if (config.IsRequiredConfiguredInput(file))
|
||||
{
|
||||
files.push_back({IS_REQUIRED, config.GetPath(file)});
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &file : files)
|
||||
{
|
||||
@ -394,12 +397,6 @@ void Storage::PopulateStaticData(const SharedDataIndex &index)
|
||||
absolute_file_index_path.begin(), absolute_file_index_path.end(), file_index_path_ptr);
|
||||
}
|
||||
|
||||
// Name data
|
||||
{
|
||||
auto name_table = make_name_table_view(index, "/common/names");
|
||||
extractor::files::readNames(config.GetPath(".osrm.names"), name_table);
|
||||
}
|
||||
|
||||
// Timestamp mark
|
||||
{
|
||||
auto timestamp_ref = make_timestamp_view(index, "/common/timestamp");
|
||||
@ -412,25 +409,39 @@ void Storage::PopulateStaticData(const SharedDataIndex &index)
|
||||
}
|
||||
|
||||
// Turn lane data
|
||||
if (config.IsRequiredConfiguredInput(".osrm.tld"))
|
||||
{
|
||||
auto turn_lane_data = make_lane_data_view(index, "/common/turn_lanes");
|
||||
extractor::files::readTurnLaneData(config.GetPath(".osrm.tld"), turn_lane_data);
|
||||
}
|
||||
|
||||
// Turn lane descriptions
|
||||
if (config.IsRequiredConfiguredInput(".osrm.tls"))
|
||||
{
|
||||
auto views = make_turn_lane_description_views(index, "/common/turn_lanes");
|
||||
extractor::files::readTurnLaneDescriptions(
|
||||
config.GetPath(".osrm.tls"), std::get<0>(views), std::get<1>(views));
|
||||
}
|
||||
|
||||
// Load edge-based nodes data
|
||||
// Load intersection data
|
||||
if (config.IsRequiredConfiguredInput(".osrm.icd"))
|
||||
{
|
||||
auto node_data = make_ebn_data_view(index, "/common/ebg_node_data");
|
||||
extractor::files::readNodeData(config.GetPath(".osrm.ebg_nodes"), node_data);
|
||||
auto intersection_bearings_view =
|
||||
make_intersection_bearings_view(index, "/common/intersection_bearings");
|
||||
auto entry_classes = make_entry_classes_view(index, "/common/entry_classes");
|
||||
extractor::files::readIntersections(
|
||||
config.GetPath(".osrm.icd"), intersection_bearings_view, entry_classes);
|
||||
}
|
||||
|
||||
// Name data
|
||||
if (config.IsRequiredConfiguredInput(".osrm.names"))
|
||||
{
|
||||
auto name_table = make_name_table_view(index, "/common/names");
|
||||
extractor::files::readNames(config.GetPath(".osrm.names"), name_table);
|
||||
}
|
||||
|
||||
// Load original edge data
|
||||
if (config.IsRequiredConfiguredInput(".osrm.edges"))
|
||||
{
|
||||
auto turn_data = make_turn_data_view(index, "/common/turn_data");
|
||||
|
||||
@ -441,6 +452,12 @@ void Storage::PopulateStaticData(const SharedDataIndex &index)
|
||||
config.GetPath(".osrm.edges"), turn_data, *connectivity_checksum_ptr);
|
||||
}
|
||||
|
||||
// Load edge-based nodes data
|
||||
{
|
||||
auto node_data = make_ebn_data_view(index, "/common/ebg_node_data");
|
||||
extractor::files::readNodeData(config.GetPath(".osrm.ebg_nodes"), node_data);
|
||||
}
|
||||
|
||||
// Loading list of coordinates
|
||||
{
|
||||
auto views = make_nbn_data_view(index, "/common/nbn_data");
|
||||
@ -466,15 +483,6 @@ void Storage::PopulateStaticData(const SharedDataIndex &index)
|
||||
metric_name = profile_properties_ptr->GetWeightName();
|
||||
}
|
||||
|
||||
// Load intersection data
|
||||
{
|
||||
auto intersection_bearings_view =
|
||||
make_intersection_bearings_view(index, "/common/intersection_bearings");
|
||||
auto entry_classes = make_entry_classes_view(index, "/common/entry_classes");
|
||||
extractor::files::readIntersections(
|
||||
config.GetPath(".osrm.icd"), intersection_bearings_view, entry_classes);
|
||||
}
|
||||
|
||||
if (boost::filesystem::exists(config.GetPath(".osrm.partition")))
|
||||
{
|
||||
auto mlp = make_partition_view(index, "/mld/multilevelpartition");
|
||||
@ -545,15 +553,18 @@ void Storage::PopulateUpdatableData(const SharedDataIndex &index)
|
||||
contractor::files::readGraph(
|
||||
config.GetPath(".osrm.hsgr"), metrics, graph_connectivity_checksum);
|
||||
|
||||
if (config.IsRequiredConfiguredInput("osrm.edges"))
|
||||
{
|
||||
auto turns_connectivity_checksum =
|
||||
*index.GetBlockPtr<std::uint32_t>("/common/connectivity_checksum");
|
||||
if (turns_connectivity_checksum != graph_connectivity_checksum)
|
||||
{
|
||||
throw util::exception(
|
||||
"Connectivity checksum " + std::to_string(graph_connectivity_checksum) + " in " +
|
||||
config.GetPath(".osrm.hsgr").string() + " does not equal to checksum " +
|
||||
std::to_string(turns_connectivity_checksum) + " in " +
|
||||
config.GetPath(".osrm.edges").string());
|
||||
"Connectivity checksum " + std::to_string(graph_connectivity_checksum) +
|
||||
" in " + config.GetPath(".osrm.hsgr").string() +
|
||||
" does not equal to checksum " + std::to_string(turns_connectivity_checksum) +
|
||||
" in " + config.GetPath(".osrm.edges").string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -573,15 +584,18 @@ void Storage::PopulateUpdatableData(const SharedDataIndex &index)
|
||||
customizer::files::readGraph(
|
||||
config.GetPath(".osrm.mldgr"), graph_view, graph_connectivity_checksum);
|
||||
|
||||
if (config.IsRequiredConfiguredInput("osrm.edges"))
|
||||
{
|
||||
auto turns_connectivity_checksum =
|
||||
*index.GetBlockPtr<std::uint32_t>("/common/connectivity_checksum");
|
||||
if (turns_connectivity_checksum != graph_connectivity_checksum)
|
||||
{
|
||||
throw util::exception(
|
||||
"Connectivity checksum " + std::to_string(graph_connectivity_checksum) + " in " +
|
||||
config.GetPath(".osrm.hsgr").string() + " does not equal to checksum " +
|
||||
std::to_string(turns_connectivity_checksum) + " in " +
|
||||
config.GetPath(".osrm.edges").string());
|
||||
"Connectivity checksum " + std::to_string(graph_connectivity_checksum) +
|
||||
" in " + config.GetPath(".osrm.mldgr").string() +
|
||||
" does not equal to checksum " + std::to_string(turns_connectivity_checksum) +
|
||||
" in " + config.GetPath(".osrm.edges").string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
23
src/storage/storage_config.cpp
Normal file
23
src/storage/storage_config.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
#include "osrm/datasets.hpp"
|
||||
#include "osrm/exception.hpp"
|
||||
#include "util/exception_utils.hpp"
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
|
||||
namespace osrm::storage
|
||||
{
|
||||
std::istream &operator>>(std::istream &in, FeatureDataset &datasets)
|
||||
{
|
||||
std::string token;
|
||||
in >> token;
|
||||
boost::to_lower(token);
|
||||
|
||||
if (token == "route_steps")
|
||||
datasets = FeatureDataset::ROUTE_STEPS;
|
||||
else if (token == "route_geometry")
|
||||
datasets = FeatureDataset::ROUTE_GEOMETRY;
|
||||
else
|
||||
throw util::RuntimeError(token, ErrorCode::UnknownFeatureDataset, SOURCE_REF);
|
||||
return in;
|
||||
}
|
||||
|
||||
} // namespace osrm::storage
|
||||
@ -4,6 +4,7 @@
|
||||
#include "util/meminfo.hpp"
|
||||
#include "util/version.hpp"
|
||||
|
||||
#include "osrm/datasets.hpp"
|
||||
#include "osrm/engine_config.hpp"
|
||||
#include "osrm/exception.hpp"
|
||||
#include "osrm/osrm.hpp"
|
||||
@ -12,6 +13,7 @@
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
#include <boost/any.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/optional/optional_io.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
#include <cstdlib>
|
||||
@ -22,7 +24,6 @@
|
||||
#include <exception>
|
||||
#include <future>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <new>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
@ -68,8 +69,36 @@ std::istream &operator>>(std::istream &in, EngineConfig::Algorithm &algorithm)
|
||||
throw util::RuntimeError(token, ErrorCode::UnknownAlgorithm, SOURCE_REF);
|
||||
return in;
|
||||
}
|
||||
|
||||
} // namespace osrm::engine
|
||||
|
||||
// overload validate for the double type to allow "unlimited" as an input
|
||||
namespace boost
|
||||
{
|
||||
void validate(boost::any &v, const std::vector<std::string> &values, double *, double)
|
||||
{
|
||||
boost::program_options::validators::check_first_occurrence(v);
|
||||
const std::string &s = boost::program_options::validators::get_single_string(values);
|
||||
|
||||
if (s == "unlimited")
|
||||
{
|
||||
v = -1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
v = std::stod(s);
|
||||
}
|
||||
catch (const std::invalid_argument &)
|
||||
{
|
||||
throw boost::program_options::validation_error(
|
||||
boost::program_options::validation_error::invalid_option_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace boost
|
||||
|
||||
// generate boost::program_options object for the routing part
|
||||
inline unsigned generateServerProgramOptions(const int argc,
|
||||
const char *argv[],
|
||||
@ -127,6 +156,10 @@ inline unsigned generateServerProgramOptions(const int argc,
|
||||
value<EngineConfig::Algorithm>(&config.algorithm)
|
||||
->default_value(EngineConfig::Algorithm::CH, "CH"),
|
||||
"Algorithm to use for the data. Can be CH, CoreCH, MLD.") //
|
||||
("disable-feature-dataset",
|
||||
value<std::vector<storage::FeatureDataset>>(&config.disable_feature_dataset)->multitoken(),
|
||||
"Disables a feature dataset from being loaded into memory if not needed. Options: "
|
||||
"ROUTE_STEPS, ROUTE_GEOMETRY") //
|
||||
("max-viaroute-size",
|
||||
value<int>(&config.max_locations_viaroute)->default_value(500),
|
||||
"Max. locations supported in viaroute query") //
|
||||
@ -149,7 +182,7 @@ inline unsigned generateServerProgramOptions(const int argc,
|
||||
value<double>(&config.max_radius_map_matching)->default_value(-1.0),
|
||||
"Max. radius size supported in map matching query. Default: unlimited.") //
|
||||
("default-radius",
|
||||
value<boost::optional<double>>(&config.default_radius),
|
||||
value<boost::optional<double>>(&config.default_radius)->default_value(-1.0),
|
||||
"Default radius size for queries. Default: unlimited.");
|
||||
|
||||
// hidden options, will be allowed on command line, but will not be shown to the user
|
||||
@ -248,7 +281,7 @@ try
|
||||
|
||||
if (!base_path.empty())
|
||||
{
|
||||
config.storage_config = storage::StorageConfig(base_path);
|
||||
config.storage_config = storage::StorageConfig(base_path, config.disable_feature_dataset);
|
||||
}
|
||||
if (!config.use_shared_memory && !config.storage_config.IsValid())
|
||||
{
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#include "storage/shared_memory.hpp"
|
||||
#include "storage/shared_monitor.hpp"
|
||||
#include "storage/storage.hpp"
|
||||
#include "osrm/storage_config.hpp"
|
||||
|
||||
#include "osrm/exception.hpp"
|
||||
#include "util/log.hpp"
|
||||
@ -9,6 +10,7 @@
|
||||
#include "util/typedefs.hpp"
|
||||
#include "util/version.hpp"
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
@ -100,7 +102,8 @@ bool generateDataStoreOptions(const int argc,
|
||||
std::string &dataset_name,
|
||||
bool &list_datasets,
|
||||
bool &list_blocks,
|
||||
bool &only_metric)
|
||||
bool &only_metric,
|
||||
std::vector<storage::FeatureDataset> &disable_feature_dataset)
|
||||
{
|
||||
// declare a group of options that will be allowed only on command line
|
||||
boost::program_options::options_description generic_options("Options");
|
||||
@ -125,6 +128,12 @@ bool generateDataStoreOptions(const int argc,
|
||||
boost::program_options::value<std::string>(&dataset_name)->default_value(""),
|
||||
"Name of the dataset to load into memory. This allows having multiple datasets in memory "
|
||||
"at the same time.") //
|
||||
("disable-feature-dataset",
|
||||
boost::program_options::value<std::vector<storage::FeatureDataset>>(
|
||||
&disable_feature_dataset)
|
||||
->multitoken(),
|
||||
"Disables a feature dataset from being loaded into memory if not needed. Options: "
|
||||
"ROUTE_STEPS, ROUTE_GEOMETRY") //
|
||||
("list",
|
||||
boost::program_options::value<bool>(&list_datasets)
|
||||
->default_value(false)
|
||||
@ -239,6 +248,7 @@ try
|
||||
bool list_datasets = false;
|
||||
bool list_blocks = false;
|
||||
bool only_metric = false;
|
||||
std::vector<storage::FeatureDataset> disable_feature_dataset;
|
||||
if (!generateDataStoreOptions(argc,
|
||||
argv,
|
||||
verbosity,
|
||||
@ -247,7 +257,8 @@ try
|
||||
dataset_name,
|
||||
list_datasets,
|
||||
list_blocks,
|
||||
only_metric))
|
||||
only_metric,
|
||||
disable_feature_dataset))
|
||||
{
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@ -260,7 +271,7 @@ try
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
storage::StorageConfig config(base_path);
|
||||
storage::StorageConfig config(base_path, disable_feature_dataset);
|
||||
if (!config.IsValid())
|
||||
{
|
||||
util::Log(logERROR) << "Config contains invalid file paths. Exiting!";
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
#include "util/exception.hpp"
|
||||
|
||||
#include <utility>
|
||||
|
||||
// This function exists to 'anchor' the class, and stop the compiler from
|
||||
// copying vtable and RTTI info into every object file that includes
|
||||
// this header. (Caught by -Wweak-vtables under Clang.)
|
||||
@ -16,4 +18,5 @@ namespace osrm::util
|
||||
|
||||
void exception::anchor() const {}
|
||||
void RuntimeError::anchor() const {}
|
||||
void DisabledDatasetException::anchor() const {}
|
||||
} // namespace osrm::util
|
||||
|
||||
@ -118,10 +118,17 @@ test('constructor: takes a default_radius argument', function(assert) {
|
||||
assert.ok(osrm);
|
||||
});
|
||||
|
||||
test('constructor: takes a default_radius unlimited argument', function(assert) {
|
||||
assert.plan(1);
|
||||
var osrm = new OSRM({algorithm: 'MLD', path: monaco_mld_path, default_radius: 'unlimited'});
|
||||
assert.ok(osrm);
|
||||
});
|
||||
|
||||
test('constructor: throws if default_radius is not a number', function(assert) {
|
||||
assert.plan(2);
|
||||
assert.throws(function() { new OSRM({algorithm: 'MLD', path: monaco_mld_path, default_radius: 'abc'}); }, /default_radius must be an integral number/, 'Does not accept string');
|
||||
assert.plan(3);
|
||||
assert.throws(function() { new OSRM({algorithm: 'MLD', path: monaco_mld_path, default_radius: 'abc'}); }, /default_radius must be unlimited or an integral number/, 'Does not accept invalid string');
|
||||
assert.ok(new OSRM({algorithm: 'MLD', path: monaco_mld_path, default_radius: 1}), 'Does accept number');
|
||||
assert.ok(new OSRM({algorithm: 'MLD', path: monaco_mld_path, default_radius: 'unlimited'}), 'Does accept unlimited');
|
||||
});
|
||||
|
||||
test('constructor: parses custom limits', function(assert) {
|
||||
@ -135,6 +142,7 @@ test('constructor: parses custom limits', function(assert) {
|
||||
max_locations_map_matching: 1,
|
||||
max_results_nearest: 1,
|
||||
max_alternatives: 1,
|
||||
default_radius: 1
|
||||
});
|
||||
assert.ok(osrm);
|
||||
});
|
||||
@ -150,10 +158,48 @@ test('constructor: throws on invalid custom limits', function(assert) {
|
||||
max_locations_distance_table: false,
|
||||
max_locations_map_matching: 'a lot',
|
||||
max_results_nearest: null,
|
||||
max_alternatives: '10'
|
||||
max_alternatives: '10',
|
||||
default_radius: '10'
|
||||
})
|
||||
});
|
||||
});
|
||||
test('constructor: throws on invalid disable_feature_dataset option', function(assert) {
|
||||
assert.plan(1);
|
||||
assert.throws(function() {
|
||||
var osrm = new OSRM({
|
||||
path: monaco_path,
|
||||
disable_feature_dataset: ['NOT_EXIST'],
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
test('constructor: throws on non-array disable_feature_dataset', function(assert) {
|
||||
assert.plan(1);
|
||||
assert.throws(function() {
|
||||
var osrm = new OSRM({
|
||||
path: monaco_path,
|
||||
disable_feature_dataset: 'ROUTE_GEOMETRY',
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
test('constructor: ok on valid disable_feature_dataset option', function(assert) {
|
||||
assert.plan(1);
|
||||
var osrm = new OSRM({
|
||||
path: monaco_path,
|
||||
disable_feature_dataset: ['ROUTE_GEOMETRY'],
|
||||
});
|
||||
assert.ok(osrm);
|
||||
});
|
||||
|
||||
test('constructor: ok on multiple overlapping disable_feature_dataset options', function(assert) {
|
||||
assert.plan(1);
|
||||
var osrm = new OSRM({
|
||||
path: monaco_path,
|
||||
disable_feature_dataset: ['ROUTE_GEOMETRY', 'ROUTE_STEPS'],
|
||||
});
|
||||
assert.ok(osrm);
|
||||
});
|
||||
|
||||
require('./route.js');
|
||||
require('./trip.js');
|
||||
|
||||
@ -398,3 +398,65 @@ test('match: match in Monaco with waypoints', function(assert) {
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
test('match: throws on disabled geometry', function (assert) {
|
||||
assert.plan(1);
|
||||
var osrm = new OSRM({'path': data_path, 'disable_feature_dataset': ['ROUTE_GEOMETRY']});
|
||||
var options = {
|
||||
coordinates: three_test_coordinates.concat(three_test_coordinates),
|
||||
};
|
||||
osrm.match(options, function(err, route) {
|
||||
console.log(err)
|
||||
assert.match(err.message, /DisabledDatasetException/);
|
||||
});
|
||||
});
|
||||
|
||||
test('match: ok on disabled geometry', function (assert) {
|
||||
assert.plan(2);
|
||||
var osrm = new OSRM({'path': data_path, 'disable_feature_dataset': ['ROUTE_GEOMETRY']});
|
||||
var options = {
|
||||
steps: false,
|
||||
overview: 'false',
|
||||
annotations: false,
|
||||
skip_waypoints: true,
|
||||
coordinates: three_test_coordinates.concat(three_test_coordinates),
|
||||
};
|
||||
osrm.match(options, function(err, response) {
|
||||
assert.ifError(err);
|
||||
assert.equal(response.matchings.length, 1);
|
||||
});
|
||||
});
|
||||
|
||||
test('match: throws on disabled steps', function (assert) {
|
||||
assert.plan(1);
|
||||
var osrm = new OSRM({'path': data_path, 'disable_feature_dataset': ['ROUTE_STEPS']});
|
||||
var options = {
|
||||
steps: true,
|
||||
coordinates: three_test_coordinates.concat(three_test_coordinates),
|
||||
};
|
||||
osrm.match(options, function(err, route) {
|
||||
console.log(err)
|
||||
assert.match(err.message, /DisabledDatasetException/);
|
||||
});
|
||||
});
|
||||
|
||||
test('match: ok on disabled steps', function (assert) {
|
||||
assert.plan(8);
|
||||
var osrm = new OSRM({'path': data_path, 'disable_feature_dataset': ['ROUTE_STEPS']});
|
||||
var options = {
|
||||
steps: false,
|
||||
overview: 'simplified',
|
||||
annotations: true,
|
||||
coordinates: three_test_coordinates.concat(three_test_coordinates),
|
||||
};
|
||||
osrm.match(options, function(err, response) {
|
||||
assert.ifError(err);
|
||||
assert.ok(response.tracepoints);
|
||||
assert.ok(response.matchings);
|
||||
assert.equal(response.matchings.length, 1);
|
||||
assert.ok(response.matchings[0].geometry, "the match has geometry");
|
||||
assert.ok(response.matchings[0].legs, "the match has legs");
|
||||
assert.notok(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');
|
||||
});
|
||||
});
|
||||
|
||||
@ -103,3 +103,40 @@ test('nearest: nearest in Monaco without motorways', function(assert) {
|
||||
assert.equal(response.waypoints.length, 1);
|
||||
});
|
||||
});
|
||||
|
||||
test('nearest: throws on disabled geometry', function(assert) {
|
||||
assert.plan(1);
|
||||
var osrm = new OSRM({path: data_path, 'disable_feature_dataset': ['ROUTE_GEOMETRY']});
|
||||
var options = {
|
||||
coordinates: [two_test_coordinates[0]],
|
||||
};
|
||||
osrm.nearest(options, function(err, response) {
|
||||
console.log(err)
|
||||
assert.match(err.message, /DisabledDatasetException/);
|
||||
});
|
||||
});
|
||||
test('nearest: ok on disabled geometry', function(assert) {
|
||||
assert.plan(2);
|
||||
var osrm = new OSRM({path: data_path, 'disable_feature_dataset': ['ROUTE_GEOMETRY']});
|
||||
var options = {
|
||||
coordinates: [two_test_coordinates[0]],
|
||||
skip_waypoints: true,
|
||||
};
|
||||
osrm.nearest(options, function(err, response) {
|
||||
assert.ifError(err);
|
||||
assert.notok(response.waypoints);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
test('nearest: ok on disabled steps', function(assert) {
|
||||
assert.plan(2);
|
||||
var osrm = new OSRM({path: data_path, 'disable_feature_dataset': ['ROUTE_STEPS']});
|
||||
var options = {
|
||||
coordinates: [two_test_coordinates[0]],
|
||||
};
|
||||
osrm.nearest(options, function(err, response) {
|
||||
assert.ifError(err);
|
||||
assert.equal(response.waypoints.length, 1);
|
||||
});
|
||||
});
|
||||
|
||||
@ -762,3 +762,65 @@ test('route: snapping parameter passed through OK', function(assert) {
|
||||
assert.equal(Math.round(route.routes[0].distance * 10), 1315); // Round it to nearest 0.1m to eliminate floating point comparison error
|
||||
});
|
||||
});
|
||||
|
||||
test('route: throws on disabled geometry', function (assert) {
|
||||
assert.plan(1);
|
||||
var osrm = new OSRM({'path': monaco_path, 'disable_feature_dataset': ['ROUTE_GEOMETRY']});
|
||||
var options = {
|
||||
coordinates: three_test_coordinates,
|
||||
};
|
||||
osrm.route(options, function(err, route) {
|
||||
console.log(err)
|
||||
assert.match(err.message, /DisabledDatasetException/);
|
||||
});
|
||||
});
|
||||
|
||||
test('route: ok on disabled geometry', function (assert) {
|
||||
assert.plan(2);
|
||||
var osrm = new OSRM({'path': monaco_path, 'disable_feature_dataset': ['ROUTE_GEOMETRY']});
|
||||
var options = {
|
||||
steps: false,
|
||||
overview: 'false',
|
||||
annotations: false,
|
||||
skip_waypoints: true,
|
||||
coordinates: three_test_coordinates,
|
||||
};
|
||||
osrm.route(options, function(err, response) {
|
||||
assert.ifError(err);
|
||||
assert.equal(response.routes.length, 1);
|
||||
});
|
||||
});
|
||||
|
||||
test('route: throws on disabled steps', function (assert) {
|
||||
assert.plan(1);
|
||||
var osrm = new OSRM({'path': monaco_path, 'disable_feature_dataset': ['ROUTE_STEPS']});
|
||||
var options = {
|
||||
steps: true,
|
||||
coordinates: three_test_coordinates,
|
||||
};
|
||||
osrm.route(options, function(err, route) {
|
||||
console.log(err)
|
||||
assert.match(err.message, /DisabledDatasetException/);
|
||||
});
|
||||
});
|
||||
|
||||
test('route: ok on disabled steps', function (assert) {
|
||||
assert.plan(8);
|
||||
var osrm = new OSRM({'path': monaco_path, 'disable_feature_dataset': ['ROUTE_STEPS']});
|
||||
var options = {
|
||||
steps: false,
|
||||
overview: 'simplified',
|
||||
annotations: true,
|
||||
coordinates: three_test_coordinates,
|
||||
};
|
||||
osrm.route(options, function(err, response) {
|
||||
assert.ifError(err);
|
||||
assert.ok(response.waypoints);
|
||||
assert.ok(response.routes);
|
||||
assert.equal(response.routes.length, 1);
|
||||
assert.ok(response.routes[0].geometry, "the route has geometry");
|
||||
assert.ok(response.routes[0].legs, "the route has legs");
|
||||
assert.notok(response.routes[0].legs.every(l => { return l.steps.length > 0; }), 'every leg has steps');
|
||||
assert.ok(response.routes[0].legs.every(l => { return l.annotation;}), 'every leg has annotations');
|
||||
});
|
||||
});
|
||||
|
||||
@ -369,3 +369,43 @@ tables.forEach(function(annotation) {
|
||||
});
|
||||
});
|
||||
|
||||
test('table: throws on disabled geometry', function (assert) {
|
||||
assert.plan(1);
|
||||
var osrm = new OSRM({'path': data_path, 'disable_feature_dataset': ['ROUTE_GEOMETRY']});
|
||||
var options = {
|
||||
coordinates: [three_test_coordinates[0], three_test_coordinates[1]],
|
||||
};
|
||||
osrm.table(options, function(err, table) {
|
||||
console.log(err)
|
||||
assert.match(err.message, /DisabledDatasetException/);
|
||||
});
|
||||
});
|
||||
|
||||
test('table: ok on disabled geometry', function (assert) {
|
||||
assert.plan(4);
|
||||
var osrm = new OSRM({'path': data_path, 'disable_feature_dataset': ['ROUTE_GEOMETRY']});
|
||||
var options = {
|
||||
coordinates: [three_test_coordinates[0], three_test_coordinates[1]],
|
||||
skip_waypoints: true
|
||||
};
|
||||
osrm.table(options, function(err, table) {
|
||||
assert.ifError(err);
|
||||
assert.ok(table.durations, 'distances table result should exist');
|
||||
assert.notok(table.sources)
|
||||
assert.notok(table.destinations)
|
||||
});
|
||||
});
|
||||
|
||||
test('table: ok on disabled steps', function (assert) {
|
||||
assert.plan(4);
|
||||
var osrm = new OSRM({'path': data_path, 'disable_feature_dataset': ['ROUTE_STEPS']});
|
||||
var options = {
|
||||
coordinates: [three_test_coordinates[0], three_test_coordinates[1]],
|
||||
};
|
||||
osrm.table(options, function(err, table) {
|
||||
assert.ifError(err);
|
||||
assert.ok(table.durations, 'distances table result should exist');
|
||||
assert.ok(table.sources.length, 2)
|
||||
assert.ok(table.destinations.length, 2)
|
||||
});
|
||||
});
|
||||
|
||||
@ -23,3 +23,20 @@ test.test('tile interface pre-conditions', function(assert) {
|
||||
assert.throws(function() { osrm.tile(17059, 11948, 15, function(err, result) {}) }, /must be an array \[x, y, z\]/);
|
||||
assert.throws(function() { osrm.tile([17059, 11948, -15], function(err, result) {}) }, /must be unsigned/);
|
||||
});
|
||||
|
||||
test.test('tile fails to load with geometry disabled', function(assert) {
|
||||
assert.plan(1);
|
||||
var osrm = new OSRM({'path': data_path, 'disable_feature_dataset': ['ROUTE_GEOMETRY']});
|
||||
osrm.tile(tile.at, function(err, result) {
|
||||
console.log(err)
|
||||
assert.match(err.message, /DisabledDatasetException/);
|
||||
});
|
||||
});
|
||||
test.test('tile ok with steps disabled', function(assert) {
|
||||
assert.plan(2);
|
||||
var osrm = new OSRM({'path': data_path, 'disable_feature_dataset': ['ROUTE_STEPS']});
|
||||
osrm.tile(tile.at, function(err, result) {
|
||||
assert.ifError(err);
|
||||
assert.equal(result.length, tile.size);
|
||||
});
|
||||
});
|
||||
|
||||
@ -368,3 +368,65 @@ test('trip: trip in Monaco without motorways', function(assert) {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('trip: throws on disabled geometry', function (assert) {
|
||||
assert.plan(1);
|
||||
var osrm = new OSRM({'path': data_path, 'disable_feature_dataset': ['ROUTE_GEOMETRY']});
|
||||
var options = {
|
||||
coordinates: three_test_coordinates.concat(three_test_coordinates),
|
||||
};
|
||||
osrm.trip(options, function(err, route) {
|
||||
console.log(err)
|
||||
assert.match(err.message, /DisabledDatasetException/);
|
||||
});
|
||||
});
|
||||
|
||||
test('trip: ok on disabled geometry', function (assert) {
|
||||
assert.plan(2);
|
||||
var osrm = new OSRM({'path': data_path, 'disable_feature_dataset': ['ROUTE_GEOMETRY']});
|
||||
var options = {
|
||||
steps: false,
|
||||
overview: 'false',
|
||||
annotations: false,
|
||||
skip_waypoints: true,
|
||||
coordinates: three_test_coordinates.concat(three_test_coordinates),
|
||||
};
|
||||
osrm.trip(options, function(err, response) {
|
||||
assert.ifError(err);
|
||||
assert.equal(response.trips.length, 1);
|
||||
});
|
||||
});
|
||||
|
||||
test('trip: throws on disabled steps', function (assert) {
|
||||
assert.plan(1);
|
||||
var osrm = new OSRM({'path': data_path, 'disable_feature_dataset': ['ROUTE_STEPS']});
|
||||
var options = {
|
||||
steps: true,
|
||||
coordinates: three_test_coordinates.concat(three_test_coordinates),
|
||||
};
|
||||
osrm.trip(options, function(err, route) {
|
||||
console.log(err)
|
||||
assert.match(err.message, /DisabledDatasetException/);
|
||||
});
|
||||
});
|
||||
|
||||
test('trip: ok on disabled steps', function (assert) {
|
||||
assert.plan(8);
|
||||
var osrm = new OSRM({'path': data_path, 'disable_feature_dataset': ['ROUTE_STEPS']});
|
||||
var options = {
|
||||
steps: false,
|
||||
overview: 'simplified',
|
||||
annotations: true,
|
||||
coordinates: three_test_coordinates.concat(three_test_coordinates),
|
||||
};
|
||||
osrm.trip(options, function(err, response) {
|
||||
assert.ifError(err);
|
||||
assert.ok(response.waypoints);
|
||||
assert.ok(response.trips);
|
||||
assert.equal(response.trips.length, 1);
|
||||
assert.ok(response.trips[0].geometry, "trip has geometry");
|
||||
assert.ok(response.trips[0].legs, "trip has legs");
|
||||
assert.notok(response.trips[0].legs.every(l => { return l.steps.length > 0; }), 'every leg has steps');
|
||||
assert.ok(response.trips[0].legs.every(l => { return l.annotation;}), 'every leg has annotations');
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user