Compare commits
73 Commits
v5.8.1
...
v5.9.0-rc.1
| Author | SHA1 | Date | |
|---|---|---|---|
| c9017090a2 | |||
| e7061591e3 | |||
| 5ede5577d1 | |||
| 0bfbe5ad16 | |||
| 54ceb05420 | |||
| fef0344be0 | |||
| b12fee5c0a | |||
| 1ef75c7a61 | |||
| 8c5ac84f0c | |||
| 44739f2dc3 | |||
| d52d530cbe | |||
| 5fb00ff7bf | |||
| 4c7aa8f1c0 | |||
| 2522f70f86 | |||
| e47e8ed335 | |||
| 2927b491c3 | |||
| ba2a0b3566 | |||
| 98caa0bcd9 | |||
| 4a2a100569 | |||
| 3073f4c0d1 | |||
| 7d900e3b5a | |||
| 6d78c11fd2 | |||
| 1bee82e288 | |||
| a41caf0efb | |||
| a3e0eb03db | |||
| 34f62b4894 | |||
| b28077a437 | |||
| 359ab2b56e | |||
| e42c23686b | |||
| d98f1a2632 | |||
| aa736dbe3a | |||
| 3534203083 | |||
| 517cb5f094 | |||
| b910ab9bcb | |||
| 5a29e29535 | |||
| 0fd71260d3 | |||
| 54367bfa98 | |||
| 1e9806f872 | |||
| 1e704aa7f2 | |||
| 8a404ea850 | |||
| e2e279bc85 | |||
| c914afdbf1 | |||
| 49a057ebc0 | |||
| d660c1609c | |||
| 74bc8966a8 | |||
| 9d8a3e3c97 | |||
| a308b86056 | |||
| 1b540fe0ba | |||
| 929e5a4de6 | |||
| df4f0d043a | |||
| 09df8d47a5 | |||
| c8b75c9046 | |||
| dd8f5ac01d | |||
| 22479ff5d8 | |||
| 688b1f8bef | |||
| e5464526c8 | |||
| 37b8d3acd4 | |||
| 4f13208ce8 | |||
| 383640caaf | |||
| 42f3401dd7 | |||
| 7fb57c924f | |||
| 97592e5bc3 | |||
| 9922c0f4f7 | |||
| f27434f2fb | |||
| 32d39b7b49 | |||
| 5c20c7b295 | |||
| df000debe9 | |||
| 31511416ed | |||
| 99b02cedfb | |||
| 4136bf2808 | |||
| 93d6fd05a9 | |||
| 73c4bc1411 | |||
| dc9b4bcfec |
@@ -0,0 +1,15 @@
|
||||
# Set the default behavior, in case people don't have core.autocrlf set.
|
||||
* text=auto
|
||||
|
||||
# Explicitly declare text files you want to always be normalized and converted
|
||||
# to native line endings on checkout.
|
||||
*.cpp text
|
||||
*.hpp text
|
||||
|
||||
# Declare files that will always have CRLF line endings on checkout.
|
||||
*.bat text eol=crlf
|
||||
*.cmd text eol=crlf
|
||||
*.ps1 text eol=crlf
|
||||
|
||||
# Declare files that will always have LF line endings on checkout.
|
||||
*.sh text eol=lf
|
||||
@@ -61,6 +61,11 @@ Thumbs.db
|
||||
.cproject
|
||||
.project
|
||||
|
||||
# Visual Studio (Code) related files #
|
||||
######################################
|
||||
/.vs*
|
||||
/*.local.bat
|
||||
|
||||
# stxxl related files #
|
||||
#######################
|
||||
.stxxl
|
||||
|
||||
@@ -19,6 +19,7 @@ branches:
|
||||
- master
|
||||
# enable building tags
|
||||
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/
|
||||
- "5.9"
|
||||
|
||||
cache:
|
||||
yarn: true
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
# 5.9.0 RC1
|
||||
- Changes from 5.8:
|
||||
- Algorithm:
|
||||
- Multi-Level Dijkstra:
|
||||
- Plugins supported: `table`
|
||||
- Adds alternative routes support (see [#4047](https://github.com/Project-OSRM/osrm-backend/pull/4047) and [3905](https://github.com/Project-OSRM/osrm-backend/issues/3905)): provides reasonably looking alternative routes (many, if possible) with reasonable query times.
|
||||
- API:
|
||||
- Exposes `alternatives=Number` parameter overload in addition to the boolean flag.
|
||||
- Support for exits numbers and names. New member `exits` in `RouteStep`, based on `junction:ref` on ways
|
||||
- `RouteStep` now has new parameter `classes` that can be set in the profile on each way.
|
||||
- Profiles:
|
||||
- `result.exits` allows you to set a way's exit numbers and names, see [`junction:ref`](http://wiki.openstreetmap.org/wiki/Proposed_features/junction_details)
|
||||
- `ExtractionWay` now as new property `forward_classes` and `backward_classes` that can set in the `way_function`.
|
||||
The maximum number of classes is 8.
|
||||
- Node.js Bindings:
|
||||
- Exposes `alternatives=Number` parameter overload in addition to the boolean flag
|
||||
- Tools:
|
||||
- Exposes engine limit on number of alternatives to generate `--max-alternatives` in `osrm-routed` (3 by default)
|
||||
|
||||
# 5.8.0
|
||||
- Changes from 5.7
|
||||
- API:
|
||||
@@ -26,6 +45,7 @@
|
||||
- Fixed a copy/paste issue assigning wrong directions in similar turns (left over right)
|
||||
- #4074: fixed a bug that would announce entering highway ramps as u-turns
|
||||
- #4122: osrm-routed/libosrm should throw exception when a dataset incompatible with the requested algorithm is loaded
|
||||
- Avoid collapsing u-turns into combined turn instructions
|
||||
|
||||
# 5.7.1
|
||||
- Bugfixes
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ if (POLICY CMP0048)
|
||||
endif()
|
||||
project(OSRM C CXX)
|
||||
set(OSRM_VERSION_MAJOR 5)
|
||||
set(OSRM_VERSION_MINOR 8)
|
||||
set(OSRM_VERSION_MINOR 9)
|
||||
set(OSRM_VERSION_PATCH 0)
|
||||
set(OSRM_VERSION "${OSRM_VERSION_MAJOR}.${OSRM_VERSION_MINOR}.${OSRM_VERSION_PATCH}")
|
||||
|
||||
|
||||
@@ -16,8 +16,10 @@ The following services are available via HTTP API, C++ library interface and Nod
|
||||
|
||||
To quickly try OSRM use our [demo server](http://map.project-osrm.org) which comes with both the backend and a frontend on top.
|
||||
|
||||
For a quick introduction about how the road network is represented in OpenStreetMap and how to map specific road network features have a look at [this guide about mapping for navigation](https://www.mapbox.com/mapping/mapping-for-navigation/).
|
||||
|
||||
Related [Project-OSRM](https://github.com/Project-OSRM) repositories:
|
||||
- [node-osrm](https://github.com/Project-OSRM/node-osrm) - Production-ready NodeJs bindings for the routing engine
|
||||
- [node-osrm](https://www.npmjs.com/package/osrm) - Production-ready NodeJs bindings for the routing engine
|
||||
- [osrm-frontend](https://github.com/Project-OSRM/osrm-frontend) - User-facing frontend with map. The demo server runs this on top of the backend
|
||||
- [osrm-text-instructions](https://github.com/Project-OSRM/osrm-text-instructions) - Text instructions from OSRM route response
|
||||
- [osrm-backend-docker](https://hub.docker.com/r/osrm/osrm-backend/) - Ready to use Docker images
|
||||
@@ -119,7 +121,7 @@ osrm-routed berlin-latest.osrm
|
||||
Running Queries
|
||||
|
||||
```
|
||||
curl http://127.0.0.1:5000/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true
|
||||
curl "http://127.0.0.1:5000/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true"
|
||||
```
|
||||
|
||||
### Request Against the Demo Server
|
||||
@@ -128,9 +130,36 @@ Read the [API usage policy](https://github.com/Project-OSRM/osrm-backend/wiki/Ap
|
||||
Simple query with instructions and alternatives on Berlin:
|
||||
|
||||
```
|
||||
curl https://router.project-osrm.org/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true&alternatives=true
|
||||
curl "https://router.project-osrm.org/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true&alternatives=true"
|
||||
```
|
||||
|
||||
### Using the Node.js Bindings
|
||||
|
||||
The Node.js bindings provide read-only access to the routing engine.
|
||||
We provide API documentation and examples [here](docs/nodejs/api.md).
|
||||
|
||||
You will need a modern `libstdc++` toolchain (`>= GLIBCXX_3.4.20`) for binary compatibility if you want to use the pre-built binaries.
|
||||
For older Ubuntu systems you can upgrade your standard library for example with:
|
||||
|
||||
```
|
||||
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y libstdc++-5-dev
|
||||
```
|
||||
|
||||
You can install the Node.js bindings via `npm install osrm` or from this repository either via
|
||||
|
||||
npm install
|
||||
|
||||
which will check and use pre-built binaries if they're available for this release and your Node version, or via
|
||||
|
||||
npm install --build-from-source
|
||||
|
||||
to always force building the Node.js bindings from source.
|
||||
|
||||
For usage details have a look [these API docs](docs/nodejs/api.md).
|
||||
|
||||
|
||||
## References in publications
|
||||
|
||||
When using the code in a (scientific) publication, please cite
|
||||
|
||||
+1
-1
@@ -3,5 +3,5 @@ module.exports = {
|
||||
verify: '--strict --tags ~@stress --tags ~@todo -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 ~@alternative --tags ~@matrix --tags ~@trip --require features/support --require features/step_definitions -f progress'
|
||||
mld: '--strict --tags ~@stress --tags ~@todo --tags ~@alternative --require features/support --require features/step_definitions -f progress'
|
||||
}
|
||||
|
||||
+13
-10
@@ -165,21 +165,21 @@ curl 'http://router.project-osrm.org/nearest/v1/driving/13.388860,52.517037?numb
|
||||
Finds the fastest route between coordinates in the supplied order.
|
||||
|
||||
```endpoint
|
||||
GET /route/v1/{profile}/{coordinates}?alternatives={true|false}&steps={true|false}&geometries={polyline|polyline6|geojson}&overview={full|simplified|false}&annotations={true|false}
|
||||
GET /route/v1/{profile}/{coordinates}?alternatives={true|false|number}&steps={true|false}&geometries={polyline|polyline6|geojson}&overview={full|simplified|false}&annotations={true|false}
|
||||
```
|
||||
|
||||
In addition to the [general options](#general-options) the following options are supported for this service:
|
||||
|
||||
|Option |Values |Description |
|
||||
|------------|---------------------------------------------|-------------------------------------------------------------------------------|
|
||||
|alternatives|`true`, `false` (default) |Search for alternative routes and return as well.\* |
|
||||
|steps |`true`, `false` (default) |Return route steps for each route leg |
|
||||
|alternatives|`true`, `false` (default), or Number |Search for alternative routes. Passing a number `alternatives=n` searches for up to `n` alternative routes.\* |
|
||||
|steps |`true`, `false` (default) |Returned route steps for each route leg |
|
||||
|annotations |`true`, `false` (default), `nodes`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. |
|
||||
|geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) |
|
||||
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
|
||||
|continue\_straight |`default` (default), `true`, `false` |Forces the route to keep going straight at waypoints constraining uturns there even if it would be faster. Default value depends on the profile. |
|
||||
|
||||
\* Please note that even if an alternative route is requested, a result cannot be guaranteed.
|
||||
\* Please note that even if alternative routes are requested, a result cannot be guaranteed.
|
||||
|
||||
**Response**
|
||||
|
||||
@@ -275,7 +275,7 @@ In addition to the [general options](#general-options) the following options are
|
||||
|
||||
|Option |Values |Description |
|
||||
|------------|------------------------------------------------|------------------------------------------------------------------------------------------|
|
||||
|steps |`true`, `false` (default) |Return route steps for each route |
|
||||
|steps |`true`, `false` (default) |Returned route steps for each route |
|
||||
|geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) |
|
||||
|annotations |`true`, `false` (default), `nodes`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. |
|
||||
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
|
||||
@@ -328,10 +328,10 @@ In addition to the [general options](#general-options) the following options are
|
||||
|
||||
|Option |Values |Description |
|
||||
|------------|------------------------------------------------|---------------------------------------------------------------------------|
|
||||
|roundtrip |`true` (default), `false` |Return route is a roundtrip (route returns to first location) |
|
||||
|source |`any` (default), `first` |Return route starts at `any` or `first` coordinate |
|
||||
|destination |`any` (default), `last` |Return route ends at `any` or `last` coordinate |
|
||||
|steps |`true`, `false` (default) |Return route instructions for each trip |
|
||||
|roundtrip |`true` (default), `false` |Returned route is a roundtrip (route returns to first location) |
|
||||
|source |`any` (default), `first` |Returned route starts at `any` or `first` coordinate |
|
||||
|destination |`any` (default), `last` |Returned route ends at `any` or `last` coordinate |
|
||||
|steps |`true`, `false` (default) |Returned route instructions for each trip |
|
||||
|annotations |`true`, `false` (default), `nodes`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. |
|
||||
|geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) |
|
||||
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
|
||||
@@ -581,7 +581,9 @@ step.
|
||||
- `ref`: A reference number or code for the way. Optionally included, if ref data is available for the given way.
|
||||
- `pronunciation`: The pronunciation hint of the way name. Will be `undefined` if there is no pronunciation hit.
|
||||
- `destinations`: The destinations of the way. Will be `undefined` if there are no destinations.
|
||||
- `exits`: The exit numbers or names of the way. Will be `undefined` if there are no exit numbers or names.
|
||||
- `mode`: A string signifying the mode of transportation.
|
||||
- `classes`: An array of strings signifying the classes of the road as specified in the profile.
|
||||
- `maneuver`: A `StepManeuver` object representing the maneuver.
|
||||
- `intersections`: A list of `Intersection` objects that are passed along the segment, the very first belonging to the StepManeuver
|
||||
- `rotary_name`: The name for the rotary. Optionally included, if the step is a rotary and a rotary name is available.
|
||||
@@ -595,6 +597,7 @@ step.
|
||||
"mode" : "driving",
|
||||
"duration" : 15.6,
|
||||
"weight" : 15.6,
|
||||
"classes": ["toll", "restricted"],
|
||||
"intersections" : [
|
||||
{ "bearings" : [ 10, 92, 184, 270 ],
|
||||
"lanes" : [
|
||||
@@ -659,7 +662,7 @@ step.
|
||||
| `roundabout` | traverse roundabout, has additional property `exit` with NR if the roundabout is left. The modifier specifies the direction of entering the roundabout. |
|
||||
| `rotary` | a traffic circle. While very similar to a larger version of a roundabout, it does not necessarily follow roundabout rules for right of way. It can offer `rotary_name` and/or `rotary_pronunciation` parameters (located in the RouteStep object) in addition to the `exit` parameter (located on the StepManeuver object). |
|
||||
| `roundabout turn`| Describes a turn at a small roundabout that should be treated as normal turn. The `modifier` indicates the turn direciton. Example instruction: `At the roundabout turn left`. |
|
||||
| `notification` | not an actual turn but a change in the driving conditions. For example the travel mode. If the road takes a turn itself, the `modifier` describes the direction |
|
||||
| `notification` | not an actual turn but a change in the driving conditions. For example the travel mode or classes. If the road takes a turn itself, the `modifier` describes the direction |
|
||||
|
||||
Please note that even though there are `new name` and `notification` instructions, the `mode` and `name` can change
|
||||
between all instructions. They only offer a fallback in case nothing else is to report.
|
||||
|
||||
+21
-21
@@ -41,7 +41,7 @@ Returns the fastest route between two or more coordinates while visiting the way
|
||||
- `options.hints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Hints for the coordinate snapping. Array of base64 encoded strings.
|
||||
- `options.alternatives` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Search for alternative routes and return as well.
|
||||
_Please note that even if an alternative route is requested, a result cannot be guaranteed._ (optional, default `false`)
|
||||
- `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route steps for each route leg. (optional, default `false`)
|
||||
- `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Returned route steps for each route leg. (optional, default `false`)
|
||||
- `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`)
|
||||
- `options.geometries` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route geometry format (influences overview and per step). Can also be `geojson`. (optional, default `polyline`)
|
||||
- `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`). (optional, default `simplified`)
|
||||
@@ -188,7 +188,7 @@ if they can not be matched successfully.
|
||||
- `options.bearings` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the search to segments with given bearing in degrees towards true north in clockwise direction.
|
||||
Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`.
|
||||
- `options.hints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Hints for the coordinate snapping. Array of base64 encoded strings.
|
||||
- `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route steps for each route. (optional, default `false`)
|
||||
- `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Returned route steps for each route. (optional, default `false`)
|
||||
- `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`)
|
||||
- `options.geometries` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route geometry format (influences overview and per step). Can also be `geojson`. (optional, default `polyline`)
|
||||
- `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`). (optional, default `simplified`)
|
||||
@@ -229,7 +229,25 @@ The trip plugin solves the Traveling Salesman Problem using a greedy heuristic
|
||||
waypoints. The returned path does not have to be the shortest path, _ as TSP is NP-hard it is
|
||||
only an approximation.
|
||||
|
||||
Note that all input coordinates have to be connected for the trip service to work.
|
||||
**Parameters**
|
||||
|
||||
- `options` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Object literal containing parameters for the trip query.
|
||||
- `options.coordinates` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** The coordinates this request will use, coordinates as `[{lon},{lat}]` values, in decimal degrees.
|
||||
- `options.bearings` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the search to segments with given bearing in degrees towards true north in clockwise direction.
|
||||
Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`.
|
||||
- `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the coordinate snapping to streets in the given radius in meters. Can be `double >= 0` or `null` (unlimited, default).
|
||||
- `options.hints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Hints for the coordinate snapping. Array of base64 encoded strings.
|
||||
- `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Returned route steps for each route. (optional, default `false`)
|
||||
- `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`)
|
||||
- `options.geometries` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route geometry format (influences overview and per step). Can also be `geojson`. (optional, default `polyline`)
|
||||
- `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` (optional, default `simplified`)
|
||||
- `options.roundtrip` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Returned route is a roundtrip (route returns to first location). (optional, default `true`)
|
||||
- `options.source` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route starts at `any` or `first` coordinate. (optional, default `any`)
|
||||
- `options.destination` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route ends at `any` or `last` coordinate. (optional, default `any`)
|
||||
- `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`.
|
||||
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
|
||||
|
||||
A requirement for computing trips is that all input coordinates are connected.
|
||||
Currently, not all combinations of `roundtrip`, `source` and `destination` are supported.
|
||||
Right now, the following combinations are possible:
|
||||
|
||||
@@ -244,24 +262,6 @@ Right now, the following combinations are possible:
|
||||
| false | any | last | no |
|
||||
| false | any | any | no |
|
||||
|
||||
**Parameters**
|
||||
|
||||
- `options` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Object literal containing parameters for the trip query.
|
||||
- `options.coordinates` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** The coordinates this request will use, coordinates as `[{lon},{lat}]` values, in decimal degrees.
|
||||
- `options.bearings` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the search to segments with given bearing in degrees towards true north in clockwise direction.
|
||||
Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`.
|
||||
- `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the coordinate snapping to streets in the given radius in meters. Can be `double >= 0` or `null` (unlimited, default).
|
||||
- `options.hints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Hints for the coordinate snapping. Array of base64 encoded strings.
|
||||
- `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route steps for each route. (optional, default `false`)
|
||||
- `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`)
|
||||
- `options.geometries` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route geometry format (influences overview and per step). Can also be `geojson`. (optional, default `polyline`)
|
||||
- `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` (optional, default `simplified`)
|
||||
- `options.roundtrip` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route is a roundtrip. (optional, default `true`)
|
||||
- `options.source` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Return route starts at `any` or `first` coordinate. (optional, default `any`)
|
||||
- `options.destination` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Return route ends at `any` or `last` coordinate. (optional, default `any`)
|
||||
- `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`.
|
||||
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
|
||||
|
||||
**Examples**
|
||||
|
||||
```javascript
|
||||
|
||||
+14
-10
@@ -27,16 +27,16 @@ As you scroll down the file you'll see local variables, and then local functions
|
||||
|
||||
The following global properties can be set in your profile:
|
||||
|
||||
Attribute | Type | Notes
|
||||
------------------------------|----------|----------------------------------------------------------------------------
|
||||
weight_name | String | Name used in output for the routing weight property (default `'duration'`)
|
||||
weight_precision | Unsigned | Decimal precision of edge weights (default `1`)
|
||||
left_hand_driving | Boolean | Are vehicles assumed to drive on the left? (used in guidance, default `false`)
|
||||
use_turn_restrictions | Boolean | Are turn instructions followed? (default `false`)
|
||||
continue_straight_at_waypoint | Boolean | Must the route continue straight on at a via point, or are U-turns allowed? (default `true`)
|
||||
max_speed_for_map_matching | Float | Maximum vehicle speed to be assumed in matching (in m/s)
|
||||
max_turn_weight | Float | Maximum turn penalty weight
|
||||
force_split_edges | Boolean | True value forces a split of forward and backward edges of extracted ways and guarantees that `segment_function` will be called for all segments (default `false`)
|
||||
Attribute | Type | Notes
|
||||
-------------------------------------|----------|----------------------------------------------------------------------------
|
||||
weight_name | String | Name used in output for the routing weight property (default `'duration'`)
|
||||
weight_precision | Unsigned | Decimal precision of edge weights (default `1`)
|
||||
left_hand_driving | Boolean | Are vehicles assumed to drive on the left? (used in guidance, default `false`)
|
||||
use_turn_restrictions | Boolean | Are turn instructions followed? (default `false`)
|
||||
continue_straight_at_waypoint | Boolean | Must the route continue straight on at a via point, or are U-turns allowed? (default `true`)
|
||||
max_speed_for_map_matching | Float | Maximum vehicle speed to be assumed in matching (in m/s)
|
||||
max_turn_weight | Float | Maximum turn penalty weight
|
||||
force_split_edges | Boolean | True value forces a split of forward and backward edges of extracted ways and guarantees that `segment_function` will be called for all segments (default `false`)
|
||||
|
||||
## way_function
|
||||
|
||||
@@ -56,6 +56,8 @@ forward_rate | Float | Routing weight, expressed a
|
||||
backward_rate | Float | " "
|
||||
forward_mode | Enum | Mode of travel (e.g. `car`, `ferry`). Mandatory. Defined in `include/extractor/travel_mode.hpp`.
|
||||
backward_mode | Enum | " "
|
||||
forward_classes | Table | Mark this way as being of a specific class, e.g. `result.classes["toll"] = true`. This will be exposed in the API as `classes` on each `RouteStep`.
|
||||
backward_classes | Table | " "
|
||||
duration | Float | Alternative setter for duration of the whole way in both directions
|
||||
weight | Float | Alternative setter for weight of the whole way in both directions
|
||||
turn_lanes_forward | String | Directions for individual lanes (normalised OSM `turn:lanes` value)
|
||||
@@ -67,6 +69,8 @@ roundabout | Boolean | Is this part of a roundabou
|
||||
circular | Boolean | Is this part of a non-roundabout circular junction?
|
||||
name | String | Name of the way
|
||||
ref | String | Road number
|
||||
destinations | String | The road's destinations
|
||||
exits | String | The ramp's exit numbers or names
|
||||
pronunciation | String | Name pronunciation
|
||||
road_classification.motorway_class | Boolean | Guidance: way is a motorway
|
||||
road_classification.link_class | Boolean | Guidance: way is a slip/link road
|
||||
|
||||
@@ -82,16 +82,16 @@ Feature: Bike - Cycle tracks/lanes
|
||||
|
||||
Scenario: Bike - Cycleway on oneways, modes
|
||||
Then routability should be
|
||||
| highway | cycleway | oneway | forw | backw |
|
||||
| motorway | track | yes | cycling | |
|
||||
| residential | track | yes | cycling | pushing bike |
|
||||
| cycleway | track | yes | cycling | pushing bike |
|
||||
| footway | track | yes | pushing bike | pushing bike |
|
||||
| highway | cycleway | oneway | forw | backw |
|
||||
| motorway | track | yes | cycling | |
|
||||
| residential | track | yes | cycling | pushing bike |
|
||||
| cycleway | track | yes | cycling | pushing bike |
|
||||
| footway | track | yes | cycling | pushing bike |
|
||||
|
||||
Scenario: Bike - Cycleway on oneways, speeds
|
||||
Then routability should be
|
||||
| highway | cycleway | oneway | forw | backw |
|
||||
| motorway | track | yes | 15 km/h | |
|
||||
| residential | track | yes | 15 km/h | 6 km/h |
|
||||
| cycleway | track | yes | 15 km/h | 6 km/h |
|
||||
| footway | track | yes | 6 km/h +-1 | 6 km/h +-1 |
|
||||
| highway | cycleway | oneway | forw | backw |
|
||||
| motorway | track | yes | 15 km/h | |
|
||||
| residential | track | yes | 15 km/h | 6 km/h +-1 |
|
||||
| cycleway | track | yes | 15 km/h | 6 km/h +-1 |
|
||||
| footway | track | yes | 15 km/h | 6 km/h +-1 |
|
||||
|
||||
@@ -53,8 +53,7 @@ Feature: Bike - Handle ferry routes
|
||||
Scenario: Bike - Ferry duration, multiple nodes
|
||||
Given the node map
|
||||
"""
|
||||
x y
|
||||
a b c d
|
||||
x a b c d y
|
||||
"""
|
||||
|
||||
And the ways
|
||||
|
||||
@@ -134,3 +134,12 @@ Feature: Bike - Oneway streets
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
| a | c | ab,bc,bc |
|
||||
|
||||
|
||||
Scenario: Bike - Left/right cycleways on oneways
|
||||
Then routability should be
|
||||
| highway | oneway | cycleway:left | cycleway:right | forw | backw |
|
||||
| primary | yes | | | cycling | pushing bike |
|
||||
| primary | yes | | track | cycling | pushing bike |
|
||||
| primary | yes | track | | cycling | cycling |
|
||||
| primary | yes | track | track | cycling | cycling |
|
||||
@@ -0,0 +1,105 @@
|
||||
@routing @bicycle @safety
|
||||
Feature: Bicycle - Adds penalties to unsafe roads
|
||||
|
||||
Background:
|
||||
Given the profile file
|
||||
"""
|
||||
require 'bicycle'
|
||||
properties.weight_name = 'cyclability'
|
||||
"""
|
||||
|
||||
Scenario: Bike - Apply penalties to ways without cycleways
|
||||
Then routability should be
|
||||
| highway | cycleway | forw | backw | forw_rate | backw_rate |
|
||||
| motorway | | | | | |
|
||||
| primary | | 15 km/h | 15 km/h | 2.9 | 2.9 |
|
||||
| secondary | | 15 km/h | 15 km/h | 3.1 | 3.1 |
|
||||
| tertiary | | 15 km/h | 15 km/h | 3.3 | 3.3 |
|
||||
| primary_link | | 15 km/h | 15 km/h | 2.9 | 2.9 |
|
||||
| secondary_link | | 15 km/h | 15 km/h | 3.1 | 3.1 |
|
||||
| tertiary_link | | 15 km/h | 15 km/h | 3.3 | 3.3 |
|
||||
| residential | | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| cycleway | | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| footway | | 6 km/h +-1 | 6 km/h +-1 | 1.7 | 1.7 |
|
||||
|
||||
Scenario: Bike - Apply no penalties to ways with cycleways
|
||||
Then routability should be
|
||||
| highway | cycleway | forw | backw | forw_rate | backw_rate |
|
||||
| motorway | track | 15 km/h | | 4.2 | |
|
||||
| primary | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| secondary | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| tertiary | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| primary_link | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| secondary_link | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| tertiary_link | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| residential | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| cycleway | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| footway | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| motorway | lane | 15 km/h | | 4.2 | |
|
||||
| primary | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| secondary | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| tertiary | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| primary_link | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| secondary_link | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| tertiary_link | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| residential | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| cycleway | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| footway | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| motorway | shared_lane | 15 km/h | | 4.2 | |
|
||||
| primary | shared_lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
|
||||
Scenario: Bike - Apply no penalties to ways in direction of cycleways
|
||||
Then routability should be
|
||||
| highway | cycleway:right | cycleway:left | forw | backw | forw_rate | backw_rate |
|
||||
| motorway | track | | 15 km/h | | 4.2 | |
|
||||
| primary | track | | 15 km/h | 15 km/h | 4.2 | 2.9 |
|
||||
| secondary | track | | 15 km/h | 15 km/h | 4.2 | 3.1 |
|
||||
| tertiary | track | | 15 km/h | 15 km/h | 4.2 | 3.3 |
|
||||
| primary_link | track | | 15 km/h | 15 km/h | 4.2 | 2.9 |
|
||||
| secondary_link | track | | 15 km/h | 15 km/h | 4.2 | 3.1 |
|
||||
| tertiary_link | track | | 15 km/h | 15 km/h | 4.2 | 3.3 |
|
||||
| residential | track | | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| cycleway | track | | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| footway | track | | 15 km/h | 6 km/h +-1 | 4.2 | 1.7 |
|
||||
| motorway | | track | | 15 km/h | | 4.2 |
|
||||
| primary | | track | 15 km/h | 15 km/h | 2.9 | 4.2 |
|
||||
| secondary | | track | 15 km/h | 15 km/h | 3.1 | 4.2 |
|
||||
| tertiary | | track | 15 km/h | 15 km/h | 3.3 | 4.2 |
|
||||
| primary_link | | track | 15 km/h | 15 km/h | 2.9 | 4.2 |
|
||||
| secondary_link | | track | 15 km/h | 15 km/h | 3.1 | 4.2 |
|
||||
| tertiary_link | | track | 15 km/h | 15 km/h | 3.3 | 4.2 |
|
||||
| residential | | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| cycleway | | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| footway | | track | 6 km/h +-1 | 15 km/h | 1.7 | 4.2 |
|
||||
| motorway | lane | | 15 km/h | | 4.2 | |
|
||||
| primary | lane | | 15 km/h | 15 km/h | 4.2 | 2.9 |
|
||||
| secondary | lane | | 15 km/h | 15 km/h | 4.2 | 3.1 |
|
||||
| tertiary | lane | | 15 km/h | 15 km/h | 4.2 | 3.3 |
|
||||
| primary_link | lane | | 15 km/h | 15 km/h | 4.2 | 2.9 |
|
||||
| secondary_link | lane | | 15 km/h | 15 km/h | 4.2 | 3.1 |
|
||||
| tertiary_link | lane | | 15 km/h | 15 km/h | 4.2 | 3.3 |
|
||||
| residential | lane | | 15 km/h +-1 | 15 km/h +-1 | 4.2 | 4.2 |
|
||||
| cycleway | lane | | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| footway | lane | | 15 km/h | 6 km/h +-1 | 4.2 | 1.7 |
|
||||
| motorway | | lane | | 15 km/h | | 4.2 |
|
||||
| primary | | lane | 15 km/h | 15 km/h | 2.9 | 4.2 |
|
||||
| secondary | | lane | 15 km/h +-1 | 15 km/h +-1 | 3.1 | 4.2 |
|
||||
| tertiary | | lane | 15 km/h | 15 km/h | 3.3 | 4.2 |
|
||||
| primary_link | | lane | 15 km/h | 15 km/h | 2.9 | 4.2 |
|
||||
| secondary_link | | lane | 15 km/h | 15 km/h | 3.1 | 4.2 |
|
||||
| tertiary_link | | lane | 15 km/h | 15 km/h | 3.3 | 4.2 |
|
||||
| residential | | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| cycleway | | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| footway | | lane | 6 km/h +-1 | 15 km/h | 1.7 | 4.2 |
|
||||
| motorway | shared_lane | | 15 km/h | | 4.2 | |
|
||||
| primary | shared_lane | | 15 km/h | 15 km/h | 4.2 | 2.9 |
|
||||
| motorway | | shared_lane | | 15 km/h | | 4.2 |
|
||||
| primary | | shared_lane | 15 km/h | 15 km/h | 2.9 | 4.2 |
|
||||
|
||||
|
||||
Scenario: Bike - Don't apply penalties for all kind of cycleways
|
||||
Then routability should be
|
||||
| highway | cycleway | forw | backw | forw_rate | backw_rate |
|
||||
| tertiary | shared_lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| tertiary | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
|
||||
| tertiary | opposite | 15 km/h | 15 km/h | 3.3 | 4.2 |
|
||||
@@ -0,0 +1,53 @@
|
||||
@routing @bicycle @startpoint
|
||||
Feature: Bike - Allowed start/end modes
|
||||
|
||||
Background:
|
||||
Given the profile "bicycle"
|
||||
|
||||
Scenario: Bike - Don't start/stop on ferries
|
||||
Given the node map
|
||||
"""
|
||||
a 1 b 2 c
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | route | bicycle |
|
||||
| ab | primary | | |
|
||||
| bc | | ferry | yes |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | modes |
|
||||
| 1 | 2 | ab,ab | cycling,cycling |
|
||||
| 2 | 1 | ab,ab | cycling,cycling |
|
||||
|
||||
Scenario: Bike - Don't start/stop on trains
|
||||
Given the node map
|
||||
"""
|
||||
a 1 b 2 c
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | railway | bicycle |
|
||||
| ab | primary | | |
|
||||
| bc | | train | yes |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | modes |
|
||||
| 1 | 2 | ab,ab | cycling,cycling |
|
||||
| 2 | 1 | ab,ab | cycling,cycling |
|
||||
|
||||
Scenario: Bike - OK to start pushing bike
|
||||
Given the node map
|
||||
"""
|
||||
a 1 b 2 c
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| ab | primary |
|
||||
| bc | steps |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | modes |
|
||||
| 1 | 2 | ab,bc,bc | cycling,pushing bike,pushing bike |
|
||||
| 2 | 1 | bc,ab,ab | pushing bike,cycling,cycling |
|
||||
@@ -1,39 +1,71 @@
|
||||
@routing @bicycle @train
|
||||
Feature: Bike - Handle ferry routes
|
||||
# Bringing bikes on trains and subways
|
||||
# We cannot currently use a 'routability' type test, since the bike
|
||||
# profile does not allow starting/stopping on trains, and
|
||||
# it's not possible to modify the bicycle profile table because it's
|
||||
# defined as local.
|
||||
|
||||
Background:
|
||||
Given the profile "bicycle"
|
||||
|
||||
Scenario: Bike - Bringing bikes on trains
|
||||
Then routability should be
|
||||
| highway | railway | bicycle | bothw |
|
||||
| primary | | | cycling |
|
||||
| (nil) | train | | |
|
||||
| (nil) | train | no | |
|
||||
| (nil) | train | yes | train |
|
||||
| (nil) | railway | | |
|
||||
| (nil) | railway | no | |
|
||||
| (nil) | railway | yes | train |
|
||||
| (nil) | subway | | |
|
||||
| (nil) | subway | no | |
|
||||
| (nil) | subway | yes | train |
|
||||
| (nil) | tram | | |
|
||||
| (nil) | tram | no | |
|
||||
| (nil) | tram | yes | train |
|
||||
| (nil) | light_rail | | |
|
||||
| (nil) | light_rail | no | |
|
||||
| (nil) | light_rail | yes | train |
|
||||
| (nil) | monorail | | |
|
||||
| (nil) | monorail | no | |
|
||||
| (nil) | monorail | yes | train |
|
||||
| (nil) | some_tag | | |
|
||||
| (nil) | some_tag | no | |
|
||||
| (nil) | some_tag | yes | cycling |
|
||||
Given the node map
|
||||
"""
|
||||
a 1 b c 2 d e 3 f g 4 h
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | railway | bicycle |
|
||||
| ab | primary | | |
|
||||
| cd | primary | | |
|
||||
| ef | primary | | |
|
||||
| gh | primary | | |
|
||||
| bc | | train | |
|
||||
| de | | train | yes |
|
||||
| fg | | train | no |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
| 1 | 2 | |
|
||||
| 2 | 3 | cd,de,ef,ef |
|
||||
| 3 | 4 | |
|
||||
|
||||
Scenario: Bike - Bringing bikes on trains, invalid railway tag is accepted if access specified
|
||||
Given the node map
|
||||
"""
|
||||
a 1 b c 2 d e 3 f g 4 h
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | railway | bicycle |
|
||||
| ab | primary | | |
|
||||
| cd | primary | | |
|
||||
| ef | primary | | |
|
||||
| gh | primary | | |
|
||||
| bc | | invalid_tag | |
|
||||
| de | | invalid_tag | yes |
|
||||
| fg | | invalid_tag | no |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
| 1 | 2 | |
|
||||
| 2 | 3 | cd,de,ef|
|
||||
| 3 | 4 | |
|
||||
|
||||
@construction
|
||||
Scenario: Bike - Don't route on railways under construction
|
||||
Then routability should be
|
||||
| highway | railway | bicycle | bothw |
|
||||
| primary | | | cycling |
|
||||
| (nil) | construction | yes | |
|
||||
Given the node map
|
||||
"""
|
||||
a 1 b c 2 d
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | railway | bicycle |
|
||||
| ab | primary | | |
|
||||
| cd | primary | | |
|
||||
| bc | | construction | yes |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
| 1 | 2 | |
|
||||
|
||||
+20
-20
@@ -183,9 +183,9 @@ Feature: Car - Restricted access
|
||||
Scenario: Car - designated HOV ways are rated low
|
||||
Then routability should be
|
||||
| highway | hov | bothw | forw_rate | backw_rate |
|
||||
| primary | designated | x | 18 | 18 |
|
||||
| primary | yes | x | 18 | 18 |
|
||||
| primary | no | x | 18 | 18 |
|
||||
| primary | designated | x | 18.2 | 18.2 |
|
||||
| primary | yes | x | 18.2 | 18.2 |
|
||||
| primary | no | x | 18.2 | 18.2 |
|
||||
|
||||
# Models:
|
||||
# https://www.openstreetmap.org/way/124891268
|
||||
@@ -201,24 +201,24 @@ Feature: Car - Restricted access
|
||||
Scenario: Car - a way with all lanes HOV-designated is highly penalized by default (similar to hov=designated)
|
||||
Then routability should be
|
||||
| highway | hov:lanes:forward | hov:lanes:backward | hov:lanes | oneway | forw | backw | forw_rate | backw_rate |
|
||||
| primary | designated | designated | | | x | x | 18 | 18 |
|
||||
| primary | designated | designated | | | x | x | 18.2 | 18.2 |
|
||||
# This test is flaky because non-deterministic turn generation sometimes emits a NoTurn here that is marked as restricted. #3769
|
||||
#| primary | | designated | | | x | x | 18 | 18 |
|
||||
#| primary | designated | | | | x | x | 18 | 18 |
|
||||
| primary | designated\|designated | designated\|designated | | | x | x | 18 | 18 |
|
||||
| primary | designated\|no | designated\|no | | | x | x | 18 | 18 |
|
||||
| primary | yes\|no | yes\|no | | | x | x | 18 | 18 |
|
||||
| primary | | | | | x | x | 18 | 18 |
|
||||
| primary | designated | | | -1 | | x | | 18 |
|
||||
| primary | | designated | | -1 | | x | | 18 |
|
||||
| primary | | | designated | yes | x | | 18 | |
|
||||
| primary | | | designated | -1 | | x | | 18 |
|
||||
| primary | | | designated\| | yes | x | | 18 | |
|
||||
| primary | | | designated\| | -1 | | x | | 18 |
|
||||
| primary | | | designated\|designated | yes | x | | 18 | |
|
||||
| primary | | | designated\|designated | -1 | | x | | 18 |
|
||||
| primary | | | designated\|yes | yes | x | | 18 | |
|
||||
| primary | | | designated\|no | -1 | | x | | 18 |
|
||||
#| primary | | designated | | | x | x | 18.2 | 18.2 |
|
||||
#| primary | designated | | | | x | x | 18.2 | 18.2 |
|
||||
| primary | designated\|designated | designated\|designated | | | x | x | 18.2 | 18.2 |
|
||||
| primary | designated\|no | designated\|no | | | x | x | 18.2 | 18.2 |
|
||||
| primary | yes\|no | yes\|no | | | x | x | 18.2 | 18.2 |
|
||||
| primary | | | | | x | x | 18.2 | 18.2 |
|
||||
| primary | designated | | | -1 | | x | | 18.2 |
|
||||
| primary | | designated | | -1 | | x | | 18.2 |
|
||||
| primary | | | designated | yes | x | | 18.2 | |
|
||||
| primary | | | designated | -1 | | x | | 18.2 |
|
||||
| primary | | | designated\| | yes | x | | 18.2 | |
|
||||
| primary | | | designated\| | -1 | | x | | 18.2 |
|
||||
| primary | | | designated\|designated | yes | x | | 18.2 | |
|
||||
| primary | | | designated\|designated | -1 | | x | | 18.2 |
|
||||
| primary | | | designated\|yes | yes | x | | 18.2 | |
|
||||
| primary | | | designated\|no | -1 | | x | | 18.2 |
|
||||
|
||||
Scenario: Car - these toll roads always work
|
||||
Then routability should be
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
@routing @car @mode
|
||||
Feature: Car - Mode flag
|
||||
Background:
|
||||
Given the profile "car"
|
||||
|
||||
Scenario: Car - We tag ferries with a class
|
||||
Given the node map
|
||||
"""
|
||||
a b
|
||||
c d
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | route |
|
||||
| ab | primary | |
|
||||
| bc | | ferry |
|
||||
| cd | primary | |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | turns | classes |
|
||||
| a | d | ab,bc,cd,cd | depart,notification right,notification left,arrive | ,ferry,, |
|
||||
| d | a | cd,bc,ab,ab | depart,notification right,notification left,arrive | ,ferry,, |
|
||||
| c | a | bc,ab,ab | depart,notification left,arrive | ferry,, |
|
||||
| d | b | cd,bc,bc | depart,notification right,arrive | ,ferry,ferry |
|
||||
| a | c | ab,bc,bc | depart,notification right,arrive | ,ferry,ferry |
|
||||
| b | d | bc,cd,cd | depart,notification left,arrive | ferry,, |
|
||||
|
||||
|
||||
Scenario: Car - We tag motorways with a class
|
||||
Given the node map
|
||||
"""
|
||||
a b
|
||||
c d
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| ab | primary |
|
||||
| bc | motorway|
|
||||
| cd | primary |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | turns | classes | # |
|
||||
| a | d | ab,bc,cd | depart,notification right,arrive | ,motorway, | |
|
||||
| a | c | ab,bc,bc | depart,notification right,arrive | ,motorway,motorway | |
|
||||
| b | d | bc,cd | depart,arrive | motorway, | we don't announce when we leave the highway |
|
||||
|
||||
Scenario: Car - We tag motorway_link with a class
|
||||
Given the node map
|
||||
"""
|
||||
a b
|
||||
c d
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| ab | primary |
|
||||
| bc | motorway_link |
|
||||
| cd | primary |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | turns | classes | # |
|
||||
| a | d | ab,bc,cd | depart,on ramp right,arrive | ,motorway, | notification replaced by on-ramp |
|
||||
| a | c | ab,bc,bc | depart,on ramp right,arrive | ,motorway,motorway | " " |
|
||||
| b | d | bc,cd | depart,arrive | motorway, | no announcement |
|
||||
|
||||
|
||||
Scenario: Car - We tag restricted with a class
|
||||
Given the node map
|
||||
"""
|
||||
a b
|
||||
c d
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | access |
|
||||
| ab | primary | private |
|
||||
| bc | motorway| private |
|
||||
| cd | primary | |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | turns | classes |
|
||||
| a | d | ab,bc,cd | depart,notification right,arrive| restricted,motorway;restricted, |
|
||||
|
||||
Scenario: Car - We toll restricted with a class
|
||||
Given the node map
|
||||
"""
|
||||
a b
|
||||
c d
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | toll |
|
||||
| ab | primary | yes |
|
||||
| bc | motorway| yes |
|
||||
| cd | primary | |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | turns | classes |
|
||||
| a | d | ab,bc,cd | depart,notification right,arrive | toll,motorway;toll, |
|
||||
|
||||
@@ -23,11 +23,11 @@ Feature: Car - Destination only, no passing through
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
| a | b | ab,ab |
|
||||
| a | c | ab,bcd |
|
||||
| a | c | ab,bcd,bcd |
|
||||
| a | d | ab,bcd,bcd |
|
||||
| a | e | axye,axye |
|
||||
| e | d | de,de |
|
||||
| e | c | de,bcd |
|
||||
| e | c | de,bcd,bcd |
|
||||
| e | b | de,bcd,bcd |
|
||||
| e | a | axye,axye |
|
||||
|
||||
@@ -51,12 +51,12 @@ Feature: Car - Destination only, no passing through
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
| a | b | ab,ab |
|
||||
| a | c | ab,bc |
|
||||
| a | d | ab,cd |
|
||||
| a | c | ab,bc,bc |
|
||||
| a | d | ab,bc,cd |
|
||||
| a | e | axye,axye |
|
||||
| e | d | de,de |
|
||||
| e | c | de,cd |
|
||||
| e | b | de,bc |
|
||||
| e | c | de,cd,cd |
|
||||
| e | b | de,cd,bc |
|
||||
| e | a | axye,axye |
|
||||
|
||||
Scenario: Car - Routing inside a destination only area
|
||||
|
||||
@@ -88,18 +88,18 @@ OSRM will use 4/5 of the projected free-flow speed.
|
||||
| highway | maxspeed | width | maxspeed:forward | maxspeed:backward | forw | backw | forw_rate | backw_rate |
|
||||
| primary | | | | | 64 km/h | 64 km/h | 18 | 18 |
|
||||
| primary | | 3 | | | 64 km/h | 64 km/h | 9 | 9 |
|
||||
| primary | 60 | | | | 47 km/h | 47 km/h | 13 | 13 |
|
||||
| primary | 60 | 3 | | | 47 km/h | 47 km/h | 7 | 7 |
|
||||
| primary | | | 60 | | 47 km/h | 64 km/h | 13 | 18 |
|
||||
| primary | | 3 | 60 | | 47 km/h | 64 km/h | 7 | 9 |
|
||||
| primary | | | | 60 | 64 km/h | 47 km/h | 18 | 13 |
|
||||
| primary | | 3 | | 60 | 64 km/h | 47 km/h | 9 | 7 |
|
||||
| primary | 15 | | 60 | | 47 km/h | 11 km/h | 13 | 3 |
|
||||
| primary | 15 | 3 | 60 | | 48 km/h | 12 km/h | 7 | 2 |
|
||||
| primary | 15 | | | 60 | 12 km/h | 47 km/h | 3 | 13 |
|
||||
| primary | 15 | 3 | | 60 | 12 km/h | 47 km/h | 2 | 7 |
|
||||
| primary | 15 | | 30 | 60 | 23 km/h | 47 km/h | 7 | 13 |
|
||||
| primary | 15 | 3 | 30 | 60 | 23 km/h | 47 km/h | 3 | 7 |
|
||||
| primary | 60 | | | | 47 km/h | 47 km/h | 13.3 | 13.3 |
|
||||
| primary | 60 | 3 | | | 47 km/h | 47 km/h | 6.7 | 6.7 |
|
||||
| primary | | | 60 | | 47 km/h | 64 km/h | 13.3 | 18 |
|
||||
| primary | | 3 | 60 | | 47 km/h | 64 km/h | 6.7 | 9 |
|
||||
| primary | | | | 60 | 64 km/h | 47 km/h | 18 | 13.3 |
|
||||
| primary | | 3 | | 60 | 64 km/h | 47 km/h | 9 | 6.7 |
|
||||
| primary | 15 | | 60 | | 47 km/h | 11 km/h | 13.3 | 3.3 |
|
||||
| primary | 15 | 3 | 60 | | 48 km/h | 12 km/h | 6.7 | 1.7 |
|
||||
| primary | 15 | | | 60 | 12 km/h | 47 km/h | 3.3 | 13.3 |
|
||||
| primary | 15 | 3 | | 60 | 12 km/h | 47 km/h | 1.7 | 6.7 |
|
||||
| primary | 15 | | 30 | 60 | 23 km/h | 47 km/h | 6.7 | 13.3 |
|
||||
| primary | 15 | 3 | 30 | 60 | 23 km/h | 47 km/h | 3.3 | 6.7 |
|
||||
|
||||
Scenario: Car - Single lane streets be ignored or incur a penalty
|
||||
Then routability should be
|
||||
@@ -107,33 +107,33 @@ OSRM will use 4/5 of the projected free-flow speed.
|
||||
| highway | maxspeed | lanes | maxspeed:forward | maxspeed:backward | forw | backw | forw_rate | backw_rate |
|
||||
| primary | | | | | 64 km/h | 64 km/h | 18 | 18 |
|
||||
| primary | | 1 | | | 64 km/h | 64 km/h | 9 | 9 |
|
||||
| primary | 60 | | | | 47 km/h | 47 km/h | 13 | 13 |
|
||||
| primary | 60 | 1 | | | 47 km/h | 47 km/h | 7 | 7 |
|
||||
| primary | | | 60 | | 47 km/h | 64 km/h | 13 | 18 |
|
||||
| primary | | 1 | 60 | | 47 km/h | 64 km/h | 7 | 9 |
|
||||
| primary | | | | 60 | 64 km/h | 47 km/h | 18 | 13 |
|
||||
| primary | | 1 | | 60 | 64 km/h | 47 km/h | 9 | 7 |
|
||||
| primary | 15 | | 60 | | 47 km/h | 11 km/h | 13 | 3 |
|
||||
| primary | 15 | 1 | 60 | | 48 km/h | 12 km/h | 7 | 2 |
|
||||
| primary | 15 | | | 60 | 12 km/h | 47 km/h | 3 | 13 |
|
||||
| primary | 15 | 1 | | 60 | 12 km/h | 47 km/h | 2 | 7 |
|
||||
| primary | 15 | | 30 | 60 | 23 km/h | 47 km/h | 7 | 13 |
|
||||
| primary | 15 | 1 | 30 | 60 | 23 km/h | 47 km/h | 3 | 7 |
|
||||
| primary | 60 | | | | 47 km/h | 47 km/h | 13.3 | 13.3 |
|
||||
| primary | 60 | 1 | | | 47 km/h | 47 km/h | 6.7 | 6.7 |
|
||||
| primary | | | 60 | | 47 km/h | 64 km/h | 13.3 | 18 |
|
||||
| primary | | 1 | 60 | | 47 km/h | 64 km/h | 6.7 | 9 |
|
||||
| primary | | | | 60 | 64 km/h | 47 km/h | 18 | 13.3 |
|
||||
| primary | | 1 | | 60 | 64 km/h | 47 km/h | 9 | 6.7 |
|
||||
| primary | 15 | | 60 | | 47 km/h | 11 km/h | 13.3 | 3.3 |
|
||||
| primary | 15 | 1 | 60 | | 48 km/h | 12 km/h | 6.7 | 1.7 |
|
||||
| primary | 15 | | | 60 | 12 km/h | 47 km/h | 3.3 | 13.3 |
|
||||
| primary | 15 | 1 | | 60 | 12 km/h | 47 km/h | 1.7 | 6.7 |
|
||||
| primary | 15 | | 30 | 60 | 23 km/h | 47 km/h | 6.7 | 13.3 |
|
||||
| primary | 15 | 1 | 30 | 60 | 23 km/h | 47 km/h | 3.3 | 6.7 |
|
||||
|
||||
Scenario: Car - Single lane streets only incur a penalty for two-way streets
|
||||
Then routability should be
|
||||
| highway | maxspeed | lanes | oneway | forw | backw | forw_rate | backw_rate |
|
||||
| primary | 30 | 1 | yes | 23 km/h | | 7 | |
|
||||
| primary | 30 | 1 | -1 | | 23 km/h | | 7 |
|
||||
| primary | 30 | 1 | | 23 km/h | 23 km/h | 3 | 3 |
|
||||
| primary | 30 | 2 | | 23 km/h | 23 km/h | 7 | 7 |
|
||||
| primary | 30 | 1 | yes | 23 km/h | | 6.7 | |
|
||||
| primary | 30 | 1 | -1 | | 23 km/h | | 6.7 |
|
||||
| primary | 30 | 1 | | 23 km/h | 23 km/h | 3.3 | 3.3 |
|
||||
| primary | 30 | 2 | | 23 km/h | 23 km/h | 6.7 | 6.7 |
|
||||
|
||||
Scenario: Car - Forward/backward maxspeed on reverse oneways
|
||||
Then routability should be
|
||||
| highway | maxspeed | maxspeed:forward | maxspeed:backward | oneway | forw | backw | forw_rate | backw_rate |
|
||||
| primary | | | | -1 | | 64 km/h | | 18 |
|
||||
| primary | 30 | | | -1 | | 23 km/h | | 7 |
|
||||
| primary | 30 | | | -1 | | 23 km/h | | 6.7 |
|
||||
| primary | | 30 | | -1 | | 64 km/h | | 18 |
|
||||
| primary | | | 30 | -1 | | 23 km/h | | 7 |
|
||||
| primary | 20 | 30 | | -1 | | 15 km/h | | 4 |
|
||||
| primary | 20 | | 30 | -1 | | 23 km/h | | 7 |
|
||||
| primary | | | 30 | -1 | | 23 km/h | | 6.7 |
|
||||
| primary | 20 | 30 | | -1 | | 15 km/h | | 4.4 |
|
||||
| primary | 20 | | 30 | -1 | | 23 km/h | | 6.7 |
|
||||
|
||||
@@ -7,8 +7,8 @@ Feature: Car - Surfaces
|
||||
Scenario: Car - Ways tagged service should reduce speed
|
||||
Then routability should be
|
||||
| highway | service | forw | backw | forw_rate |
|
||||
| service | alley | 15 km/h +-1 | 15 km/h +-1 | 2 |
|
||||
| service | alley | 15 km/h +-1 | 15 km/h +-1 | 2.1 |
|
||||
| service | emergency_access | | | |
|
||||
| service | driveway | 15 km/h +-1 | 15 km/h +-1 | 2 |
|
||||
| service | drive-through | 15 km/h +-1 | 15 km/h +-1 | 2 |
|
||||
| service | parking | 15 km/h +-1 | 15 km/h +-1 | 2 |
|
||||
| service | driveway | 15 km/h +-1 | 15 km/h +-1 | 2.1 |
|
||||
| service | drive-through | 15 km/h +-1 | 15 km/h +-1 | 2.1 |
|
||||
| service | parking | 15 km/h +-1 | 15 km/h +-1 | 2.1 |
|
||||
|
||||
@@ -50,4 +50,4 @@ Feature: Car - speeds
|
||||
Then routability should be
|
||||
|
||||
| highway | side_road | forw | backw | forw_rate | backw_rate |
|
||||
| primary | yes | 64 km/h | 64 km/h | 14 | 14 |
|
||||
| primary | yes | 64 km/h | 64 km/h | 14.4 | 14.4 |
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
@routing @car @startpoint
|
||||
Feature: Car - Allowed start/end modes
|
||||
|
||||
Background:
|
||||
Given the profile "car"
|
||||
|
||||
Scenario: Car - Don't start/stop on ferries
|
||||
Given the node map
|
||||
"""
|
||||
a 1 b 2 c
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | route | bicycle |
|
||||
| ab | primary | | |
|
||||
| bc | | ferry | yes |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | modes |
|
||||
| 1 | 2 | ab,ab | driving,driving |
|
||||
| 2 | 1 | ab,ab | driving,driving |
|
||||
|
||||
Scenario: Car - Don't start/stop on trains
|
||||
Given the node map
|
||||
"""
|
||||
a 1 b 2 c
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | railway | bicycle |
|
||||
| ab | primary | | |
|
||||
| bc | | train | yes |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | modes |
|
||||
| 1 | 2 | ab,ab | driving,driving |
|
||||
| 2 | 1 | ab,ab | driving,driving |
|
||||
@@ -0,0 +1,37 @@
|
||||
@routing @foot @startpoint
|
||||
Feature: Foot - Allowed start/end modes
|
||||
|
||||
Background:
|
||||
Given the profile "foot"
|
||||
|
||||
Scenario: Foot - Don't start/stop on ferries
|
||||
Given the node map
|
||||
"""
|
||||
a 1 b 2 c
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | route | bicycle |
|
||||
| ab | primary | | |
|
||||
| bc | | ferry | yes |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | modes |
|
||||
| 1 | 2 | ab,ab | walking,walking |
|
||||
| 2 | 1 | ab,ab | walking,walking |
|
||||
|
||||
Scenario: Foot - Don't start/stop on trains
|
||||
Given the node map
|
||||
"""
|
||||
a 1 b 2 c
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | railway | bicycle |
|
||||
| ab | primary | | |
|
||||
| bc | | train | yes |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | modes |
|
||||
| 1 | 2 | ab,ab | walking,walking |
|
||||
| 2 | 1 | ab,ab | walking,walking |
|
||||
@@ -35,10 +35,10 @@ Feature: Turn Lane Guidance
|
||||
| restriction | bc | cd | c | no_right_turn |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | in,cross,cross | depart,turn left,arrive | ,left:true straight:false right:false, |
|
||||
| a,g | in,straight,straight | depart,new name straight,arrive | ,left:false straight:true right:false, |
|
||||
| a,f | in,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true, |
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | in,cross,cross | depart,turn left,arrive | ,left:true straight:false, |
|
||||
| a,g | in,straight,straight | depart,new name straight,arrive | ,left:false straight:true, |
|
||||
| a,f | in,cross,cross | depart,continue right,arrive | ,, |
|
||||
|
||||
@sliproads
|
||||
Scenario: Separate Turn Lanes
|
||||
|
||||
@@ -359,7 +359,7 @@ Feature: Collapse
|
||||
| a,g | first,second,second | depart,turn left,arrive | a,b,g |
|
||||
| d,g | first,second,second | depart,turn right,arrive | d,e,g |
|
||||
| g,f | second,first,first | depart,turn right,arrive | g,e,f |
|
||||
| g,c | second,first,first | depart,end of road left,arrive | g,b,c |
|
||||
| g,c | second,first,first | depart,turn left,arrive | g,e,c |
|
||||
|
||||
Scenario: Do not collapse turning roads
|
||||
Given the node map
|
||||
@@ -399,7 +399,7 @@ Feature: Collapse
|
||||
| waypoints | route | turns |
|
||||
| a,d | , | depart,arrive |
|
||||
|
||||
# This scenario could be considered to require a `turn left`. The danger to create random/unwanted instructions
|
||||
# This scenario could be considered to require a `turn left`. The danger to create random/unwanted instructions
|
||||
# from a setting like this are just to big, though. Therefore I opted to use `depart,arrive` only
|
||||
Scenario: Crossing Bridge into Segregated Turn
|
||||
Given the node map
|
||||
@@ -690,9 +690,9 @@ Feature: Collapse
|
||||
| restriction | bc | dc | c | no_right_turn |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | locations |
|
||||
| a,g | road,cross,cross | depart,turn left,arrive | a,b,g |
|
||||
| a,e | road,road | depart,arrive | a,e |
|
||||
| waypoints | route | turns | locations |
|
||||
| a,g | road,road,cross,cross | depart,continue slight left,turn left,arrive | a,b,c,g |
|
||||
| a,e | road,road | depart,arrive | a,e |
|
||||
|
||||
Scenario: On-Off on Highway
|
||||
Given the node map
|
||||
@@ -996,8 +996,8 @@ Feature: Collapse
|
||||
a . . b .'
|
||||
` d.
|
||||
f e
|
||||
"""
|
||||
#Check collapse.detail for a similar case (shorter) that does not classify these turns as a sliproad anymore
|
||||
"""
|
||||
#Check collapse.detail for a similar case (shorter) that does not classify these turns as a sliproad anymore
|
||||
|
||||
And the ways
|
||||
| nodes | name | oneway | highway |
|
||||
@@ -1016,9 +1016,9 @@ Feature: Collapse
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | locations |
|
||||
| a,g | road,cross,cross | depart,fork left,arrive | a,b,g |
|
||||
| a,e | road,road,road | depart,fork slight right,arrive | a,b,e |
|
||||
| a,f | road,road,cross,cross | depart,fork slight right,turn right,arrive | a,b,d,f |
|
||||
| a,g | road,road,cross,cross | depart,fork slight left,turn left,arrive | a,b,c,g |
|
||||
| a,e | road,road,road | depart,fork slight right,arrive | a,b,e |
|
||||
| a,f | road,road,cross,cross | depart,fork slight right,turn right,arrive | a,b,d,f |
|
||||
|
||||
|
||||
# http://www.openstreetmap.org/way/92415447 #3933
|
||||
@@ -1055,3 +1055,22 @@ Feature: Collapse
|
||||
When I route I should get
|
||||
| waypoints | route | turns | locations |
|
||||
| a,i | President Avenue,Princes Highway,Princes Highway | depart,turn left,arrive | a,b,i |
|
||||
|
||||
|
||||
Scenario: Don't combine uturns
|
||||
Given the node map
|
||||
"""
|
||||
2 d
|
||||
a - - b - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c
|
||||
1
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| ab | tertiary |
|
||||
| bc | tertiary |
|
||||
| bd | service |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | bearings | route | turns | locations |
|
||||
| 1,2 | 90 270 | ab,bd,bd,ab,ab | depart,turn left,continue uturn,turn right,arrive | _,b,d,b,_ |
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
@driveway @guidance
|
||||
Feature: Driveways intersections
|
||||
|
||||
Background:
|
||||
Given the profile "car"
|
||||
Given a grid size of 5 meters
|
||||
|
||||
Scenario: Road with a turn to service road
|
||||
Given the node map
|
||||
"""
|
||||
a
|
||||
~.
|
||||
b----c----d
|
||||
|
|
||||
e
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | oneway |
|
||||
| abc | trunk | first | yes |
|
||||
| cd | trunk | second | yes |
|
||||
| be | service | parking | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | locations |
|
||||
| a,d | first,second | depart,arrive | a,d |
|
||||
|
||||
|
||||
Scenario: Turn Instead of Ramp
|
||||
Given the node map
|
||||
"""
|
||||
a
|
||||
~.
|
||||
b----c----d
|
||||
|
|
||||
e
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | oneway |
|
||||
| ab | trunk | | yes |
|
||||
| bc | trunk | | yes |
|
||||
| cd | trunk | second | yes |
|
||||
| be | service | parking | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | locations |
|
||||
| a,d | ,second | depart,arrive | a,d |
|
||||
@@ -0,0 +1,98 @@
|
||||
@routing @guidance
|
||||
Feature: Exit Numbers and Names
|
||||
|
||||
Background:
|
||||
Given the profile "car"
|
||||
Given a grid size of 10 meters
|
||||
|
||||
Scenario: Exit number on the way after the motorway junction
|
||||
Given the node map
|
||||
"""
|
||||
a . . b . c . . d
|
||||
` e . . f
|
||||
"""
|
||||
|
||||
And the nodes
|
||||
| node | highway |
|
||||
| b | motorway_junction |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | junction:ref |
|
||||
| abcd | motorway | MainRoad | |
|
||||
| be | motorway_link | ExitRamp | 3 |
|
||||
| ef | motorway_link | ExitRamp | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | exits |
|
||||
| a,f | MainRoad,ExitRamp,ExitRamp | depart,off ramp slight right,arrive | ,3, |
|
||||
|
||||
|
||||
Scenario: Exit number on the way, motorway junction node tag missing, multiple numbers
|
||||
Given the node map
|
||||
"""
|
||||
a . . b . c . . d
|
||||
` e . . f
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | junction:ref |
|
||||
| abcd | motorway | MainRoad | |
|
||||
| be | motorway_link | ExitRamp | 10;12 |
|
||||
| ef | motorway_link | ExitRamp | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | exits |
|
||||
| a,f | MainRoad,ExitRamp,ExitRamp | depart,off ramp slight right,arrive | ,10;12, |
|
||||
|
||||
|
||||
Scenario: Exit number on the ways after the motorway junction, multiple exits
|
||||
Given the node map
|
||||
"""
|
||||
a . . b . c . . d
|
||||
` e . . f
|
||||
` g . . h
|
||||
"""
|
||||
|
||||
And the nodes
|
||||
| node | highway |
|
||||
| b | motorway_junction |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | junction:ref |
|
||||
| abcd | motorway | MainRoad | |
|
||||
| be | motorway_link | ExitRamp | 3 |
|
||||
| ef | motorway_link | ExitRamp | |
|
||||
| bg | motorway_link | ExitRamp | 3 |
|
||||
| gh | motorway_link | ExitRamp | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | exits |
|
||||
| a,f | MainRoad,ExitRamp,ExitRamp | depart,off ramp slight right,arrive | ,3, |
|
||||
| a,h | MainRoad,ExitRamp,ExitRamp | depart,off ramp right,arrive | ,3, |
|
||||
|
||||
|
||||
|
||||
# http://www.openstreetmap.org/way/417524818#map=17/37.38663/-121.97972
|
||||
Scenario: Exit 393 on Bayshore Freeway
|
||||
Given the node map
|
||||
"""
|
||||
a
|
||||
` b
|
||||
` c
|
||||
. ` d
|
||||
f ` e
|
||||
"""
|
||||
|
||||
And the nodes
|
||||
| node | highway |
|
||||
| c | motorway_junction |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | junction:ref | oneway | destination |
|
||||
| abcde | motorway | Bayshore Freeway | | yes | |
|
||||
| cf | motorway_link | | 393 | yes | Great America Parkway;Bowers Avenue |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | exits | destinations |
|
||||
| a,e | Bayshore Freeway,Bayshore Freeway | depart,arrive | , | , |
|
||||
| a,f | Bayshore Freeway,, | depart,off ramp slight right,arrive | ,393,393 | ,Great America Parkway, Bowers Avenue,Great America Parkway, Bowers Avenue |
|
||||
@@ -201,14 +201,14 @@ Feature: Simple Turns
|
||||
| ef | residential | road | 2 | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | locations |
|
||||
| a,c | road,road | depart,arrive | a,c |
|
||||
| c,a | road,road | depart,arrive | c,a |
|
||||
| g,a | turn,road,road | depart,turn left,arrive | g,b,a |
|
||||
| g,c | turn,road,road | depart,turn right,arrive | g,b,c |
|
||||
| g,f | turn,road,road | depart,turn left,arrive | g,e,f |
|
||||
| c,f | road,road,road | depart,continue right,arrive | c,b,f |
|
||||
| a,f | road,road,road | depart,continue uturn,arrive | a,b,f |
|
||||
| waypoints | route | turns | locations |
|
||||
| a,c | road,road | depart,arrive | a,c |
|
||||
| c,a | road,road | depart,arrive | c,a |
|
||||
| g,a | turn,road,road | depart,turn left,arrive | g,b,a |
|
||||
| g,c | turn,road,road | depart,turn right,arrive | g,b,c |
|
||||
| g,f | turn,road,road | depart,end of road left,arrive | g,e,f |
|
||||
| c,f | road,road,road | depart,turn right,arrive | c,b,f |
|
||||
| a,f | road,road,road | depart,continue uturn,arrive | a,b,f |
|
||||
|
||||
# http://www.openstreetmap.org/#map=19/52.48753/13.52838
|
||||
Scenario: Traffic Circle
|
||||
@@ -1312,8 +1312,8 @@ Feature: Simple Turns
|
||||
|
||||
# we don't care for turn instructions, this is a coordinate extraction bug check
|
||||
When I route I should get
|
||||
| waypoints | route | intersections |
|
||||
| a,g | ab,bcdefgh | true:90,true:45 false:180 false:270;true:180 |
|
||||
| waypoints | route | intersections |
|
||||
| a,g | ab,bcdefgh,bcdefgh | true:90;true:45 false:180 false:270;true:180 |
|
||||
|
||||
#https://github.com/Project-OSRM/osrm-backend/pull/3469#issuecomment-270806580
|
||||
Scenario: Oszillating Lower Priority Road
|
||||
@@ -1371,3 +1371,76 @@ Feature: Simple Turns
|
||||
When I route I should get
|
||||
| waypoints | route |
|
||||
| g,e | abcde,abcde |
|
||||
|
||||
# 4205
|
||||
# https://www.openstreetmap.org/node/36153635#map=19/51.97548/7.61795
|
||||
Scenario: merging onto a through street
|
||||
Given the node map
|
||||
"""
|
||||
e
|
||||
`
|
||||
`
|
||||
`
|
||||
`
|
||||
d
|
||||
c
|
||||
a - - - - - - - b``
|
||||
`
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
`
|
||||
|
||||
`
|
||||
|
||||
|
||||
`
|
||||
|
||||
|
||||
`
|
||||
|
||||
|
||||
f
|
||||
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | oneway | name |
|
||||
| abc | yes | fww |
|
||||
| fcde | no | jahn |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,f | fww,jahn,jahn | depart,turn right,arrive |
|
||||
| a,e | fww,jahn,jahn | depart,turn left,arrive |
|
||||
|
||||
@@ -1215,3 +1215,32 @@ Feature: Turn Lane Guidance
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | road,cross,cross | depart,turn left,arrive | ,none:true none:false right:false, |
|
||||
| a,c | road,road | depart,arrive | , |
|
||||
|
||||
@4189
|
||||
Scenario: U-turn after a traffic light
|
||||
Given the node map
|
||||
"""
|
||||
j k
|
||||
: :
|
||||
f---g-h-i
|
||||
: :
|
||||
a-b-c-d-e
|
||||
: :
|
||||
l m
|
||||
"""
|
||||
|
||||
And the nodes
|
||||
| node | highway |
|
||||
| b | traffic_signals |
|
||||
|
||||
And the ways
|
||||
| nodes | name | lanes | turn:lanes | oneway |
|
||||
| ab | road1 | 3 | left\|through\|through;right | yes |
|
||||
| bcde | road1 | 2 | | yes |
|
||||
| ihgf | road1 | 2 | | yes |
|
||||
| jgcl | road2 | 2 | | yes |
|
||||
| mdhk | road2 | 2 | | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes | locations |
|
||||
| a,f | road1,road1,road1 | depart,continue uturn,arrive | ,left:true straight:false straight;right:false, | a,d,f |
|
||||
|
||||
@@ -1319,3 +1319,33 @@ Feature: Simple Turns
|
||||
When I route I should get
|
||||
| waypoints | route | ref | turns |
|
||||
| a,h | Road,,, | C 42,,C 42,C 42 | depart,on ramp right,merge slight left,arrive |
|
||||
|
||||
Scenario: End of road, T-intersection, no obvious turn, only one road allowed
|
||||
Given the node map
|
||||
"""
|
||||
d
|
||||
.
|
||||
a . b . . c
|
||||
' .
|
||||
'e
|
||||
.
|
||||
f
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | oneway | ref |
|
||||
| ab | primary | | B 191 |
|
||||
| bc | primary | | B 191 |
|
||||
| be | primary_link | yes | |
|
||||
| dc | primary | | B 4;B 191 |
|
||||
| ce | primary | | B 4 |
|
||||
| ef | primary | | B 4 |
|
||||
|
||||
And the relations
|
||||
| type | way:from | way:to | node:via | restriction |
|
||||
| restriction | bc | ce | c | no_right_turn |
|
||||
| restriction | be | ef | e | only_right_turn |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,d | ab,dc,dc | depart,turn left,arrive |
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# Broken see issue #4065
|
||||
@contract @options @edge-weight-updates-over-factor @todo
|
||||
@contract @options @edge-weight-updates-over-factor
|
||||
Feature: osrm-contract command line option: edge-weight-updates-over-factor
|
||||
|
||||
Background: Log edge weight updates over given factor
|
||||
@@ -22,6 +21,7 @@ Feature: osrm-contract command line option: edge-weight-updates-over-factor
|
||||
|
||||
Scenario: Logging weight with updates over factor of 2, long segment
|
||||
When I run "osrm-extract --profile {profile_file} {osm_file}"
|
||||
And the data has been partitioned
|
||||
When I run "osrm-contract --edge-weight-updates-over-factor 2 --segment-speed-file {speeds_file} {processed_file}"
|
||||
Then stderr should not contain "Speed values were used to update 2 segment(s)"
|
||||
And stderr should contain "Segment: 1,2"
|
||||
|
||||
@@ -34,7 +34,7 @@ module.exports = function () {
|
||||
outputRow[rate] = result[direction].status ?
|
||||
result[direction].status.toString() : '';
|
||||
break;
|
||||
case /^\d+$/.test(want):
|
||||
case /^\d+(\.\d+){0,1}$/.test(want):
|
||||
if (result[direction].rate !== undefined && !isNaN(result[direction].rate)) {
|
||||
outputRow[rate] = result[direction].rate.toString();
|
||||
} else {
|
||||
@@ -135,7 +135,7 @@ module.exports = function () {
|
||||
if (r.route.split(',')[0] === util.format('w%d', i)) {
|
||||
r.time = r.json.routes[0].duration;
|
||||
r.distance = r.json.routes[0].distance;
|
||||
r.rate = Math.round(r.distance / r.json.routes[0].weight);
|
||||
r.rate = Math.round(r.distance / r.json.routes[0].weight * 10) / 10.;
|
||||
r.speed = r.time > 0 ? parseInt(3.6 * r.distance / r.time) : null;
|
||||
|
||||
// use the mode of the first step of the route
|
||||
|
||||
@@ -85,8 +85,7 @@ module.exports = function () {
|
||||
}
|
||||
|
||||
var ok = true,
|
||||
encodedResult = '',
|
||||
extendedTarget = '';
|
||||
encodedResult = '';
|
||||
|
||||
if (json.trips) row.trips.split(',').forEach((sub, si) => {
|
||||
if (si >= subTrips.length) {
|
||||
@@ -98,11 +97,9 @@ module.exports = function () {
|
||||
outNode = subTrips[si][ni];
|
||||
if (this.FuzzyMatch.matchLocation(outNode, node)) {
|
||||
encodedResult += sub[ni];
|
||||
extendedTarget += sub[ni];
|
||||
} else {
|
||||
ok = false;
|
||||
encodedResult += util.format('? [%s,%s]', outNode[0], outNode[1]);
|
||||
extendedTarget += util.format('%s [%d,%d]', sub[ni], node.lat, node.lon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,9 +238,9 @@ module.exports = function () {
|
||||
// a shallow copy of scenario parameters to avoid data inconsistency
|
||||
// if a cucumber timeout occurs during deferred jobs
|
||||
let p = {extractArgs: this.extractArgs, contractArgs: this.contractArgs,
|
||||
partitionArgs: this.partitionArgs, customizeArgs: this.customizeArgs,
|
||||
profileFile: this.profileFile, inputCacheFile: this.inputCacheFile,
|
||||
processedCacheFile: this.processedCacheFile, environment: this.environment};
|
||||
partitionArgs: this.partitionArgs, customizeArgs: this.customizeArgs,
|
||||
profileFile: this.profileFile, inputCacheFile: this.inputCacheFile,
|
||||
processedCacheFile: this.processedCacheFile, environment: this.environment};
|
||||
let queue = d3.queue(1);
|
||||
queue.defer(this.extractData.bind(this), p);
|
||||
queue.defer(this.partitionData.bind(this), p);
|
||||
|
||||
@@ -155,6 +155,10 @@ module.exports = function () {
|
||||
return this.extractInstructionList(instructions, s => s.destinations || '');
|
||||
};
|
||||
|
||||
this.exitsList = (instructions) => {
|
||||
return this.extractInstructionList(instructions, s => s.exits || '');
|
||||
};
|
||||
|
||||
this.reverseBearing = (bearing) => {
|
||||
if (bearing >= 180)
|
||||
return bearing - 180.;
|
||||
@@ -256,6 +260,10 @@ module.exports = function () {
|
||||
return this.extractInstructionList(instructions, s => s.mode);
|
||||
};
|
||||
|
||||
this.classesList = (instructions) => {
|
||||
return this.extractInstructionList(instructions, s => s.classes ? s.classes.join(';') : '');
|
||||
};
|
||||
|
||||
this.timeList = (instructions) => {
|
||||
return this.extractInstructionList(instructions, s => s.duration + 's');
|
||||
};
|
||||
|
||||
@@ -34,7 +34,7 @@ module.exports = function () {
|
||||
var afterRequest = (err, res, body) => {
|
||||
if (err) return cb(err);
|
||||
if (body && body.length) {
|
||||
let destinations, pronunciations, instructions, refs, bearings, turns, modes, times,
|
||||
let destinations, exits, pronunciations, instructions, refs, bearings, turns, modes, times, classes,
|
||||
distances, summary, intersections, lanes, locations, annotation, weight_name, weights, approaches;
|
||||
|
||||
let json = JSON.parse(body);
|
||||
@@ -48,10 +48,12 @@ module.exports = function () {
|
||||
pronunciations = this.pronunciationList(json.routes[0]);
|
||||
refs = this.refList(json.routes[0]);
|
||||
destinations = this.destinationsList(json.routes[0]);
|
||||
exits = this.exitsList(json.routes[0]);
|
||||
bearings = this.bearingList(json.routes[0]);
|
||||
turns = this.turnList(json.routes[0]);
|
||||
intersections = this.intersectionList(json.routes[0]);
|
||||
modes = this.modeList(json.routes[0]);
|
||||
classes = this.classesList(json.routes[0]);
|
||||
times = this.timeList(json.routes[0]);
|
||||
distances = this.distanceList(json.routes[0]);
|
||||
lanes = this.lanesList(json.routes[0]);
|
||||
@@ -173,10 +175,12 @@ module.exports = function () {
|
||||
putValue('bearing', bearings);
|
||||
putValue('turns', turns);
|
||||
putValue('modes', modes);
|
||||
putValue('classes', classes);
|
||||
putValue('times', times);
|
||||
putValue('distances', distances);
|
||||
putValue('pronunciations', pronunciations);
|
||||
putValue('destinations', destinations);
|
||||
putValue('exits', exits);
|
||||
putValue('weight_name', weight_name);
|
||||
putValue('weights', weights);
|
||||
putValue('weight', weight);
|
||||
@@ -243,7 +247,7 @@ module.exports = function () {
|
||||
} else if (row.waypoints) {
|
||||
row.waypoints.split(',').forEach((n) => {
|
||||
var node = this.findNodeByName(n.trim());
|
||||
if (!node) return cb(new Error('*** unknown waypoint node "%s"', n.trim()));
|
||||
if (!node) return cb(new Error(util.format('*** unknown waypoint node "%s"', n.trim())));
|
||||
waypoints.push(node);
|
||||
});
|
||||
got.waypoints = row.waypoints;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
@routing @approach
|
||||
@routing @approach @testbot
|
||||
Feature: Approach parameter
|
||||
|
||||
Background:
|
||||
Given the profile "car"
|
||||
Given the profile "testbot"
|
||||
And a grid size of 10 meters
|
||||
|
||||
Scenario: Start End same approach, option unrestricted for Start and End
|
||||
@@ -358,8 +358,8 @@ Feature: Basic Map Matching
|
||||
| trace | matchings | alternatives |
|
||||
| abcdef | abcde | 0,0,0,0,1,1 |
|
||||
|
||||
Scenario: Testbot - Speed greater than speed threshhold
|
||||
Given a grid size of 10 meters
|
||||
Scenario: Testbot - Speed greater than speed threshold
|
||||
Given a grid size of 100 meters
|
||||
Given the query options
|
||||
| geometries | geojson |
|
||||
|
||||
@@ -379,8 +379,8 @@ Feature: Basic Map Matching
|
||||
| trace | timestamps | matchings |
|
||||
| abcd | 0 1 2 3 | ab,cd |
|
||||
|
||||
Scenario: Testbot - Speed less than speed threshhold
|
||||
Given a grid size of 10 meters
|
||||
Scenario: Testbot - Speed less than speed threshold
|
||||
Given a grid size of 100 meters
|
||||
Given the query options
|
||||
| geometries | geojson |
|
||||
|
||||
@@ -397,6 +397,28 @@ Feature: Basic Map Matching
|
||||
| trace | timestamps | matchings |
|
||||
| abcd | 0 1 2 3 | abcd |
|
||||
|
||||
Scenario: Testbot - Huge gap in the coordinates
|
||||
Given a grid size of 100 meters
|
||||
Given the query options
|
||||
| geometries | geojson |
|
||||
| gaps | ignore |
|
||||
|
||||
Given the node map
|
||||
"""
|
||||
a b c d ---- x
|
||||
|
|
||||
|
|
||||
y ---- z ---- efjk
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
| abcdxyzefjk | no |
|
||||
|
||||
When I match I should get
|
||||
| trace | timestamps | matchings |
|
||||
| abcdefjk | 0 1 2 3 50 51 52 53 | abcdefjk |
|
||||
|
||||
# Regression test 1 for issue 3176
|
||||
Scenario: Testbot - multiple segments: properly expose OSM IDs
|
||||
Given the query options
|
||||
|
||||
@@ -48,21 +48,40 @@ Feature: Multi level routing
|
||||
│ │ │ │
|
||||
l───k───p───o
|
||||
"""
|
||||
|
||||
And the nodes
|
||||
| node | highway |
|
||||
| i | traffic_signals |
|
||||
| n | traffic_signals |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abcda | primary |
|
||||
| efghe | primary |
|
||||
| ijkli | primary |
|
||||
| nmop | primary |
|
||||
| mnopm | primary |
|
||||
| cm | primary |
|
||||
| hj | primary |
|
||||
| kp | primary |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | time |
|
||||
| a | b | abcda,abcda | 20s |
|
||||
| a | f | abcda,cm,nmop,kp,ijkli,hj,efghe,efghe | 257.7s |
|
||||
| c | m | cm,cm | 44.7s |
|
||||
| from | to | route | time |
|
||||
| a | b | abcda,abcda | 20s |
|
||||
| a | f | abcda,cm,mnopm,kp,ijkli,hj,efghe,efghe | 229.4s |
|
||||
| a | l | abcda,cm,mnopm,kp,ijkli,ijkli | 144.7s |
|
||||
| a | o | abcda,cm,mnopm,mnopm,mnopm | 124.7s |
|
||||
| f | l | efghe,hj,ijkli,ijkli,ijkli | 124.7s |
|
||||
| f | o | efghe,hj,ijkli,kp,mnopm,mnopm | 144.7s |
|
||||
| l | o | ijkli,kp,mnopm,mnopm | 60s |
|
||||
| c | m | cm,cm | 44.7s |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a | f | l | o |
|
||||
| a | 0 | 229.4 | 144.7 | 124.7 |
|
||||
| f | 229.4 | 0 | 124.7 | 144.7 |
|
||||
| l | 144.7 | 124.7 | 0 | 60 |
|
||||
| o | 124.7 | 144.7 | 60 | 0 |
|
||||
|
||||
|
||||
Scenario: Testbot - Multi level routing: horizontal road
|
||||
Given the node map
|
||||
@@ -127,3 +146,44 @@ Feature: Multi level routing
|
||||
When I route I should get
|
||||
| from | to | route | time |
|
||||
| a | k | abcda,ch,hf,fi,ijkli,ijkli | 724.3s |
|
||||
|
||||
|
||||
Scenario: Testbot - Edge case for matrix plugin with
|
||||
Given the node map
|
||||
"""
|
||||
a───b
|
||||
│ ╳ │
|
||||
d───c
|
||||
│ │
|
||||
e f
|
||||
│ ╱ │
|
||||
h g───i
|
||||
"""
|
||||
And the partition extra arguments "--small-component-size 1 --max-cell-sizes 5,16,64"
|
||||
|
||||
And the nodes
|
||||
| node | highway |
|
||||
| e | traffic_signals |
|
||||
| g | traffic_signals |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | maxspeed |
|
||||
| abcda | primary | |
|
||||
| ac | primary | |
|
||||
| db | primary | |
|
||||
| deh | primary | |
|
||||
| cfg | primary | |
|
||||
| ef | primary | 1 |
|
||||
| eg | primary | 1 |
|
||||
| hf | primary | 1 |
|
||||
| hg | primary | 1 |
|
||||
| gi | primary | |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | time |
|
||||
| h | i | deh,abcda,cfg,gi,gi | 134s |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | h | i |
|
||||
| h | 0 | 134 |
|
||||
| i | 134 | 0 |
|
||||
|
||||
@@ -14,6 +14,7 @@ Feature: Testbot - Check assigning nil values
|
||||
result.name = nil
|
||||
result.ref = nil
|
||||
result.destinations = nil
|
||||
result.exits = nil
|
||||
result.pronunciation = nil
|
||||
result.turn_lanes_forward = nil
|
||||
result.turn_lanes_backward = nil
|
||||
|
||||
@@ -65,16 +65,9 @@ class Contractor
|
||||
std::vector<EdgeWeight> &&node_weights,
|
||||
std::vector<bool> &is_core_node,
|
||||
std::vector<float> &inout_node_levels) const;
|
||||
void WriteCoreNodeMarker(std::vector<bool> &&is_core_node) const;
|
||||
void WriteContractedGraph(unsigned number_of_edge_based_nodes,
|
||||
util::DeallocatingVector<QueryEdge> contracted_edge_list);
|
||||
|
||||
private:
|
||||
ContractorConfig config;
|
||||
|
||||
EdgeID LoadEdgeExpandedGraph(const ContractorConfig &config,
|
||||
std::vector<extractor::EdgeBasedEdge> &edge_based_edge_list,
|
||||
std::vector<EdgeWeight> &node_weights);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,27 @@ namespace contractor
|
||||
{
|
||||
namespace files
|
||||
{
|
||||
// reads .osrm.core
|
||||
template <typename CoreVectorT>
|
||||
void readCoreMarker(const boost::filesystem::path &path, CoreVectorT &is_core_node)
|
||||
{
|
||||
static_assert(util::is_view_or_vector<bool, CoreVectorT>::value,
|
||||
"is_core_node must be a vector");
|
||||
storage::io::FileReader reader(path, storage::io::FileReader::VerifyFingerprint);
|
||||
|
||||
storage::serialization::read(reader, is_core_node);
|
||||
}
|
||||
|
||||
// writes .osrm.core
|
||||
template <typename CoreVectorT>
|
||||
void writeCoreMarker(const boost::filesystem::path &path, const CoreVectorT &is_core_node)
|
||||
{
|
||||
static_assert(util::is_view_or_vector<bool, CoreVectorT>::value,
|
||||
"is_core_node must be a vector");
|
||||
storage::io::FileWriter writer(path, storage::io::FileWriter::GenerateFingerprint);
|
||||
|
||||
storage::serialization::write(writer, is_core_node);
|
||||
}
|
||||
|
||||
// reads .osrm.hsgr file
|
||||
template <typename QueryGraphT>
|
||||
|
||||
@@ -91,8 +91,8 @@ class GraphContractor
|
||||
|
||||
GraphContractor(int nodes,
|
||||
std::vector<ContractorEdge> edges,
|
||||
std::vector<float> &&node_levels_,
|
||||
std::vector<EdgeWeight> &&node_weights_);
|
||||
std::vector<float> node_levels_,
|
||||
std::vector<EdgeWeight> node_weights_);
|
||||
|
||||
/* Flush all data from the contraction to disc and reorder stuff for better locality */
|
||||
void FlushDataAndRebuildContractorGraph(ThreadDataContainer &thread_data_list,
|
||||
@@ -101,12 +101,14 @@ class GraphContractor
|
||||
|
||||
void Run(double core_factor = 1.0);
|
||||
|
||||
void GetCoreMarker(std::vector<bool> &out_is_core_node);
|
||||
std::vector<bool> GetCoreMarker();
|
||||
|
||||
void GetNodeLevels(std::vector<float> &out_node_levels);
|
||||
std::vector<float> GetNodeLevels();
|
||||
|
||||
template <class Edge> inline void GetEdges(util::DeallocatingVector<Edge> &edges)
|
||||
template <class Edge> inline util::DeallocatingVector<Edge> GetEdges()
|
||||
{
|
||||
util::DeallocatingVector<Edge> edges;
|
||||
|
||||
util::UnbufferedLog log;
|
||||
log << "Getting edges of minimized graph ";
|
||||
util::Percent p(log, contractor_graph->GetNumberOfNodes());
|
||||
@@ -161,6 +163,13 @@ class GraphContractor
|
||||
|
||||
edges.append(external_edge_list.begin(), external_edge_list.end());
|
||||
external_edge_list.clear();
|
||||
|
||||
// sort and remove duplicates
|
||||
tbb::parallel_sort(edges.begin(), edges.end());
|
||||
auto new_end = std::unique(edges.begin(), edges.end());
|
||||
edges.resize(new_end - edges.begin());
|
||||
|
||||
return edges;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -20,6 +20,7 @@ class CellCustomizer
|
||||
struct HeapData
|
||||
{
|
||||
bool from_clique;
|
||||
EdgeDuration duration;
|
||||
};
|
||||
|
||||
public:
|
||||
@@ -41,31 +42,41 @@ class CellCustomizer
|
||||
{
|
||||
std::unordered_set<NodeID> destinations_set(destinations.begin(), destinations.end());
|
||||
heap.Clear();
|
||||
heap.Insert(source, 0, {false});
|
||||
heap.Insert(source, 0, {false, 0});
|
||||
|
||||
// explore search space
|
||||
while (!heap.Empty() && !destinations_set.empty())
|
||||
{
|
||||
const NodeID node = heap.DeleteMin();
|
||||
const EdgeWeight weight = heap.GetKey(node);
|
||||
const EdgeDuration duration = heap.GetData(node).duration;
|
||||
|
||||
if (level == 1)
|
||||
RelaxNode<true>(graph, cells, heap, level, node, weight);
|
||||
RelaxNode<true>(graph, cells, heap, level, node, weight, duration);
|
||||
else
|
||||
RelaxNode<false>(graph, cells, heap, level, node, weight);
|
||||
RelaxNode<false>(graph, cells, heap, level, node, weight, duration);
|
||||
|
||||
destinations_set.erase(node);
|
||||
}
|
||||
|
||||
// fill a map of destination nodes to placeholder pointers
|
||||
auto destination_iter = destinations.begin();
|
||||
for (auto &weight : cell.GetOutWeight(source))
|
||||
auto weights = cell.GetOutWeight(source);
|
||||
auto durations = cell.GetOutDuration(source);
|
||||
for (auto &destination : destinations)
|
||||
{
|
||||
BOOST_ASSERT(destination_iter != destinations.end());
|
||||
const auto destination = *destination_iter++;
|
||||
weight =
|
||||
heap.WasInserted(destination) ? heap.GetKey(destination) : INVALID_EDGE_WEIGHT;
|
||||
BOOST_ASSERT(!weights.empty());
|
||||
BOOST_ASSERT(!durations.empty());
|
||||
|
||||
const bool inserted = heap.WasInserted(destination);
|
||||
weights.front() = inserted ? heap.GetKey(destination) : INVALID_EDGE_WEIGHT;
|
||||
durations.front() =
|
||||
inserted ? heap.GetData(destination).duration : MAXIMAL_EDGE_DURATION;
|
||||
|
||||
weights.advance_begin(1);
|
||||
durations.advance_begin(1);
|
||||
}
|
||||
BOOST_ASSERT(weights.empty());
|
||||
BOOST_ASSERT(durations.empty());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +105,8 @@ class CellCustomizer
|
||||
Heap &heap,
|
||||
LevelID level,
|
||||
NodeID node,
|
||||
EdgeWeight weight) const
|
||||
EdgeWeight weight,
|
||||
EdgeDuration duration) const
|
||||
{
|
||||
BOOST_ASSERT(heap.WasInserted(node));
|
||||
|
||||
@@ -113,24 +125,26 @@ class CellCustomizer
|
||||
auto subcell_id = partition.GetCell(level - 1, node);
|
||||
auto subcell = cells.GetCell(level - 1, subcell_id);
|
||||
auto subcell_destination = subcell.GetDestinationNodes().begin();
|
||||
auto subcell_duration = subcell.GetOutDuration(node).begin();
|
||||
for (auto subcell_weight : subcell.GetOutWeight(node))
|
||||
{
|
||||
if (subcell_weight != INVALID_EDGE_WEIGHT)
|
||||
{
|
||||
const NodeID to = *subcell_destination;
|
||||
const EdgeWeight to_weight = subcell_weight + weight;
|
||||
const EdgeWeight to_weight = weight + subcell_weight;
|
||||
if (!heap.WasInserted(to))
|
||||
{
|
||||
heap.Insert(to, to_weight, {true});
|
||||
heap.Insert(to, to_weight, {true, duration + *subcell_duration});
|
||||
}
|
||||
else if (to_weight < heap.GetKey(to))
|
||||
{
|
||||
heap.DecreaseKey(to, to_weight);
|
||||
heap.GetData(to).from_clique = true;
|
||||
heap.GetData(to) = {true, duration + *subcell_duration};
|
||||
}
|
||||
}
|
||||
|
||||
++subcell_destination;
|
||||
++subcell_duration;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -144,15 +158,15 @@ class CellCustomizer
|
||||
(first_level ||
|
||||
partition.GetCell(level - 1, node) != partition.GetCell(level - 1, to)))
|
||||
{
|
||||
const EdgeWeight to_weight = data.weight + weight;
|
||||
const EdgeWeight to_weight = weight + data.weight;
|
||||
if (!heap.WasInserted(to))
|
||||
{
|
||||
heap.Insert(to, to_weight, {false});
|
||||
heap.Insert(to, to_weight, {false, duration + data.duration});
|
||||
}
|
||||
else if (to_weight < heap.GetKey(to))
|
||||
{
|
||||
heap.DecreaseKey(to, to_weight);
|
||||
heap.GetData(to).from_clique = false;
|
||||
heap.GetData(to) = {false, duration + data.duration};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +93,9 @@ template <> struct HasGetTileTurns<corech::Algorithm> final : std::true_type
|
||||
};
|
||||
|
||||
// Algorithms supported by Multi-Level Dijkstra
|
||||
template <> struct HasAlternativePathSearch<mld::Algorithm> final : std::true_type
|
||||
{
|
||||
};
|
||||
template <> struct HasDirectShortestPathSearch<mld::Algorithm> final : std::true_type
|
||||
{
|
||||
};
|
||||
@@ -102,6 +105,9 @@ template <> struct HasShortestPathSearch<mld::Algorithm> final : std::true_type
|
||||
template <> struct HasMapMatching<mld::Algorithm> final : std::true_type
|
||||
{
|
||||
};
|
||||
template <> struct HasManyToManySearch<mld::Algorithm> final : std::true_type
|
||||
{
|
||||
};
|
||||
template <> struct HasGetTileTurns<mld::Algorithm> final : std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
@@ -89,8 +89,9 @@ struct RouteParameters : public BaseParameters
|
||||
const boost::optional<bool> continue_straight_,
|
||||
Args... args_)
|
||||
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
||||
annotations{false}, annotations_type{AnnotationsType::None}, geometries{geometries_},
|
||||
overview{overview_}, continue_straight{continue_straight_}
|
||||
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{false},
|
||||
annotations_type{AnnotationsType::None}, geometries{geometries_}, overview{overview_},
|
||||
continue_straight{continue_straight_}
|
||||
// Once we perfectly-forward `args` (see #2990) this constructor can delegate to the one below.
|
||||
{
|
||||
}
|
||||
@@ -105,7 +106,7 @@ struct RouteParameters : public BaseParameters
|
||||
const boost::optional<bool> continue_straight_,
|
||||
Args... args_)
|
||||
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
||||
annotations{annotations_},
|
||||
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{annotations_},
|
||||
annotations_type{annotations_ ? AnnotationsType::All : AnnotationsType::None},
|
||||
geometries{geometries_}, overview{overview_}, continue_straight{continue_straight_}
|
||||
{
|
||||
@@ -121,6 +122,7 @@ struct RouteParameters : public BaseParameters
|
||||
const boost::optional<bool> continue_straight_,
|
||||
Args... args_)
|
||||
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
||||
number_of_alternatives{alternatives_ ? 1u : 0u},
|
||||
annotations{annotations_ == AnnotationsType::None ? false : true},
|
||||
annotations_type{annotations_}, geometries{geometries_}, overview{overview_},
|
||||
continue_straight{continue_straight_}
|
||||
@@ -128,14 +130,21 @@ struct RouteParameters : public BaseParameters
|
||||
}
|
||||
|
||||
bool steps = false;
|
||||
// TODO: in v6 we should remove the boolean and only keep the number parameter; for compat.
|
||||
bool alternatives = false;
|
||||
unsigned number_of_alternatives = 0;
|
||||
bool annotations = false;
|
||||
AnnotationsType annotations_type = AnnotationsType::None;
|
||||
GeometriesType geometries = GeometriesType::Polyline;
|
||||
OverviewType overview = OverviewType::Simplified;
|
||||
boost::optional<bool> continue_straight;
|
||||
|
||||
bool IsValid() const { return coordinates.size() >= 2 && BaseParameters::IsValid(); }
|
||||
bool IsValid() const
|
||||
{
|
||||
const auto coordinates_ok = coordinates.size() >= 2;
|
||||
const auto base_params_ok = BaseParameters::IsValid();
|
||||
return coordinates_ok && base_params_ok;
|
||||
}
|
||||
};
|
||||
|
||||
inline bool operator&(RouteParameters::AnnotationsType lhs, RouteParameters::AnnotationsType rhs)
|
||||
|
||||
@@ -42,7 +42,6 @@ class TableAPI final : public BaseAPI
|
||||
{
|
||||
auto number_of_sources = parameters.sources.size();
|
||||
auto number_of_destinations = parameters.destinations.size();
|
||||
;
|
||||
|
||||
// symmetric case
|
||||
if (parameters.sources.empty())
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "extractor/datasources.hpp"
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "extractor/intersection_bearings_container.hpp"
|
||||
#include "extractor/node_data_container.hpp"
|
||||
#include "extractor/packed_osm_ids.hpp"
|
||||
#include "extractor/profile_properties.hpp"
|
||||
@@ -218,7 +219,6 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
unsigned m_check_sum;
|
||||
util::vector_view<util::Coordinate> m_coordinate_list;
|
||||
extractor::PackedOSMIDsView m_osmnodeid_list;
|
||||
util::NameTable m_names_table;
|
||||
util::vector_view<std::uint32_t> m_lane_description_offsets;
|
||||
util::vector_view<extractor::guidance::TurnLaneType::Mask> m_lane_description_masks;
|
||||
util::vector_view<TurnPenalty> m_turn_weight_penalties;
|
||||
@@ -236,19 +236,12 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
std::unique_ptr<SharedGeospatialQuery> m_geospatial_query;
|
||||
boost::filesystem::path file_index_path;
|
||||
|
||||
util::NameTable m_name_table;
|
||||
// bearing classes by node based node
|
||||
util::vector_view<BearingClassID> m_bearing_class_id_table;
|
||||
// entry class IDs
|
||||
util::vector_view<EntryClassID> m_entry_class_id_list;
|
||||
extractor::IntersectionBearingsView intersection_bearings_view;
|
||||
|
||||
util::NameTable 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;
|
||||
// the look-up table for distinct bearing classes. A bearing class lists the available bearings
|
||||
// at an intersection
|
||||
std::shared_ptr<util::RangeTable<16, storage::Ownership::View>> m_bearing_ranges_table;
|
||||
util::vector_view<DiscreteBearing> m_bearing_values_table;
|
||||
|
||||
// allocator that keeps the allocation data
|
||||
std::shared_ptr<ContiguousBlockAllocator> allocator;
|
||||
@@ -325,7 +318,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
void InitializeEdgeBasedNodeDataInformationPointers(storage::DataLayout &layout,
|
||||
char *memory_ptr)
|
||||
{
|
||||
auto via_geometry_list_ptr =
|
||||
const auto via_geometry_list_ptr =
|
||||
layout.GetBlockPtr<GeometryID>(memory_ptr, storage::DataLayout::GEOMETRY_ID_LIST);
|
||||
util::vector_view<GeometryID> geometry_ids(
|
||||
via_geometry_list_ptr, layout.num_entries[storage::DataLayout::GEOMETRY_ID_LIST]);
|
||||
@@ -345,10 +338,16 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
util::vector_view<extractor::TravelMode> travel_modes(
|
||||
travel_mode_list_ptr, layout.num_entries[storage::DataLayout::TRAVEL_MODE_LIST]);
|
||||
|
||||
const auto classes_list_ptr =
|
||||
layout.GetBlockPtr<extractor::ClassData>(memory_ptr, storage::DataLayout::CLASSES_LIST);
|
||||
util::vector_view<extractor::ClassData> classes(
|
||||
classes_list_ptr, layout.num_entries[storage::DataLayout::CLASSES_LIST]);
|
||||
|
||||
edge_based_node_data = extractor::EdgeBasedNodeDataView(std::move(geometry_ids),
|
||||
std::move(name_ids),
|
||||
std::move(component_ids),
|
||||
std::move(travel_modes));
|
||||
std::move(travel_modes),
|
||||
std::move(classes));
|
||||
}
|
||||
|
||||
void InitializeEdgeInformationPointers(storage::DataLayout &layout, char *memory_ptr)
|
||||
@@ -502,15 +501,13 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
{
|
||||
auto bearing_class_id_ptr = data_layout.GetBlockPtr<BearingClassID>(
|
||||
memory_block, storage::DataLayout::BEARING_CLASSID);
|
||||
typename util::vector_view<BearingClassID> bearing_class_id_table(
|
||||
util::vector_view<BearingClassID> bearing_class_id(
|
||||
bearing_class_id_ptr, data_layout.num_entries[storage::DataLayout::BEARING_CLASSID]);
|
||||
m_bearing_class_id_table = std::move(bearing_class_id_table);
|
||||
|
||||
auto bearing_class_ptr = data_layout.GetBlockPtr<DiscreteBearing>(
|
||||
auto bearing_values_ptr = data_layout.GetBlockPtr<DiscreteBearing>(
|
||||
memory_block, storage::DataLayout::BEARING_VALUES);
|
||||
typename util::vector_view<DiscreteBearing> bearing_class_table(
|
||||
bearing_class_ptr, data_layout.num_entries[storage::DataLayout::BEARING_VALUES]);
|
||||
m_bearing_values_table = std::move(bearing_class_table);
|
||||
util::vector_view<DiscreteBearing> bearing_values(
|
||||
bearing_values_ptr, data_layout.num_entries[storage::DataLayout::BEARING_VALUES]);
|
||||
|
||||
auto offsets_ptr =
|
||||
data_layout.GetBlockPtr<unsigned>(memory_block, storage::DataLayout::BEARING_OFFSETS);
|
||||
@@ -521,12 +518,15 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
util::vector_view<IndexBlock> bearing_blocks(
|
||||
blocks_ptr, data_layout.num_entries[storage::DataLayout::BEARING_BLOCKS]);
|
||||
|
||||
m_bearing_ranges_table = std::make_unique<util::RangeTable<16, storage::Ownership::View>>(
|
||||
bearing_offsets, bearing_blocks, static_cast<unsigned>(m_bearing_values_table.size()));
|
||||
util::RangeTable<16, storage::Ownership::View> bearing_range_table(
|
||||
bearing_offsets, bearing_blocks, static_cast<unsigned>(bearing_values.size()));
|
||||
|
||||
intersection_bearings_view = extractor::IntersectionBearingsView{
|
||||
std::move(bearing_values), std::move(bearing_class_id), std::move(bearing_range_table)};
|
||||
|
||||
auto entry_class_ptr = data_layout.GetBlockPtr<util::guidance::EntryClass>(
|
||||
memory_block, storage::DataLayout::ENTRY_CLASS);
|
||||
typename util::vector_view<util::guidance::EntryClass> entry_class_table(
|
||||
util::vector_view<util::guidance::EntryClass> entry_class_table(
|
||||
entry_class_ptr, data_layout.num_entries[storage::DataLayout::ENTRY_CLASS]);
|
||||
m_entry_class_table = std::move(entry_class_table);
|
||||
}
|
||||
@@ -789,6 +789,22 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
return edge_based_node_data.GetTravelMode(id);
|
||||
}
|
||||
|
||||
extractor::ClassData GetClassData(const NodeID id) const override final
|
||||
{
|
||||
return edge_based_node_data.GetClassData(id);
|
||||
}
|
||||
|
||||
std::vector<std::string> GetClasses(const extractor::ClassData class_data) const override final
|
||||
{
|
||||
auto indexes = extractor::getClassIndexes(class_data);
|
||||
std::vector<std::string> classes(indexes.size());
|
||||
std::transform(indexes.begin(), indexes.end(), classes.begin(), [this](const auto index) {
|
||||
return m_profile_properties->GetClassName(index);
|
||||
});
|
||||
|
||||
return classes;
|
||||
}
|
||||
|
||||
NameID GetNameIndex(const NodeID id) const override final
|
||||
{
|
||||
return edge_based_node_data.GetNameID(id);
|
||||
@@ -814,6 +830,11 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
return m_name_table.GetDestinationsForID(id);
|
||||
}
|
||||
|
||||
StringView GetExitsForID(const NameID id) const override final
|
||||
{
|
||||
return m_name_table.GetExitsForID(id);
|
||||
}
|
||||
|
||||
StringView GetDatasourceName(const DatasourceID id) const override final
|
||||
{
|
||||
return m_datasources->GetSourceName(id);
|
||||
@@ -843,27 +864,9 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
return m_profile_properties->GetWeightMultiplier();
|
||||
}
|
||||
|
||||
BearingClassID GetBearingClassID(const NodeID id) const override final
|
||||
util::guidance::BearingClass GetBearingClass(const NodeID node) const override final
|
||||
{
|
||||
return m_bearing_class_id_table.at(id);
|
||||
}
|
||||
|
||||
util::guidance::BearingClass
|
||||
GetBearingClass(const BearingClassID bearing_class_id) const override final
|
||||
{
|
||||
BOOST_ASSERT(bearing_class_id != INVALID_BEARING_CLASSID);
|
||||
auto range = m_bearing_ranges_table->GetRange(bearing_class_id);
|
||||
util::guidance::BearingClass result;
|
||||
for (auto itr = m_bearing_values_table.begin() + range.front();
|
||||
itr != m_bearing_values_table.begin() + range.back() + 1;
|
||||
++itr)
|
||||
result.add(*itr);
|
||||
return result;
|
||||
}
|
||||
|
||||
EntryClassID GetEntryClassID(const EdgeID eid) const override final
|
||||
{
|
||||
return turn_data.GetEntryClassID(eid);
|
||||
return intersection_bearings_view.GetBearingClass(node);
|
||||
}
|
||||
|
||||
util::guidance::TurnBearing PreTurnBearing(const EdgeID eid) const override final
|
||||
@@ -875,8 +878,9 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
return turn_data.GetPostTurnBearing(eid);
|
||||
}
|
||||
|
||||
util::guidance::EntryClass GetEntryClass(const EntryClassID entry_class_id) const override final
|
||||
util::guidance::EntryClass GetEntryClass(const EdgeID turn_id) const override final
|
||||
{
|
||||
auto entry_class_id = turn_data.GetEntryClassID(turn_id);
|
||||
return m_entry_class_table.at(entry_class_id);
|
||||
}
|
||||
|
||||
@@ -987,6 +991,8 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
|
||||
|
||||
auto mld_cell_weights_ptr = data_layout.GetBlockPtr<EdgeWeight>(
|
||||
memory_block, storage::DataLayout::MLD_CELL_WEIGHTS);
|
||||
auto mld_cell_durations_ptr = data_layout.GetBlockPtr<EdgeDuration>(
|
||||
memory_block, storage::DataLayout::MLD_CELL_DURATIONS);
|
||||
auto mld_source_boundary_ptr = data_layout.GetBlockPtr<NodeID>(
|
||||
memory_block, storage::DataLayout::MLD_CELL_SOURCE_BOUNDARY);
|
||||
auto mld_destination_boundary_ptr = data_layout.GetBlockPtr<NodeID>(
|
||||
@@ -998,6 +1004,8 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
|
||||
|
||||
auto weight_entries_count =
|
||||
data_layout.GetBlockEntries(storage::DataLayout::MLD_CELL_WEIGHTS);
|
||||
auto duration_entries_count =
|
||||
data_layout.GetBlockEntries(storage::DataLayout::MLD_CELL_DURATIONS);
|
||||
auto source_boundary_entries_count =
|
||||
data_layout.GetBlockEntries(storage::DataLayout::MLD_CELL_SOURCE_BOUNDARY);
|
||||
auto destination_boundary_entries_count =
|
||||
@@ -1006,7 +1014,11 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
|
||||
auto cell_level_offsets_entries_count =
|
||||
data_layout.GetBlockEntries(storage::DataLayout::MLD_CELL_LEVEL_OFFSETS);
|
||||
|
||||
BOOST_ASSERT(weight_entries_count == duration_entries_count);
|
||||
|
||||
util::vector_view<EdgeWeight> weights(mld_cell_weights_ptr, weight_entries_count);
|
||||
util::vector_view<EdgeDuration> durations(mld_cell_durations_ptr,
|
||||
duration_entries_count);
|
||||
util::vector_view<NodeID> source_boundary(mld_source_boundary_ptr,
|
||||
source_boundary_entries_count);
|
||||
util::vector_view<NodeID> destination_boundary(mld_destination_boundary_ptr,
|
||||
@@ -1017,6 +1029,7 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
|
||||
cell_level_offsets_entries_count);
|
||||
|
||||
mld_cell_storage = partition::CellStorageView{std::move(weights),
|
||||
std::move(durations),
|
||||
std::move(source_boundary),
|
||||
std::move(destination_boundary),
|
||||
std::move(cells),
|
||||
|
||||
@@ -3,14 +3,19 @@
|
||||
|
||||
// Exposes all data access interfaces to the algorithms via base class ptr
|
||||
|
||||
#include "engine/approach.hpp"
|
||||
#include "engine/phantom_node.hpp"
|
||||
|
||||
#include "contractor/query_edge.hpp"
|
||||
|
||||
#include "extractor/class_data.hpp"
|
||||
#include "extractor/edge_based_node_segment.hpp"
|
||||
#include "extractor/external_memory_node.hpp"
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "extractor/original_edge_data.hpp"
|
||||
#include "engine/approach.hpp"
|
||||
#include "engine/phantom_node.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
|
||||
#include "util/exception.hpp"
|
||||
#include "util/guidance/bearing_class.hpp"
|
||||
#include "util/guidance/entry_class.hpp"
|
||||
@@ -87,6 +92,10 @@ class BaseDataFacade
|
||||
|
||||
virtual extractor::TravelMode GetTravelMode(const NodeID id) const = 0;
|
||||
|
||||
virtual extractor::ClassData GetClassData(const NodeID id) const = 0;
|
||||
|
||||
virtual std::vector<std::string> GetClasses(const extractor::ClassData class_data) const = 0;
|
||||
|
||||
virtual std::vector<RTreeLeaf> GetEdgesInBox(const util::Coordinate south_west,
|
||||
const util::Coordinate north_east) const = 0;
|
||||
|
||||
@@ -158,6 +167,8 @@ class BaseDataFacade
|
||||
|
||||
virtual StringView GetDestinationsForID(const NameID id) const = 0;
|
||||
|
||||
virtual StringView GetExitsForID(const NameID id) const = 0;
|
||||
|
||||
virtual std::string GetTimestamp() const = 0;
|
||||
|
||||
virtual bool GetContinueStraightDefault() const = 0;
|
||||
@@ -170,17 +181,12 @@ class BaseDataFacade
|
||||
|
||||
virtual double GetWeightMultiplier() const = 0;
|
||||
|
||||
virtual BearingClassID GetBearingClassID(const NodeID id) const = 0;
|
||||
|
||||
virtual util::guidance::TurnBearing PreTurnBearing(const EdgeID eid) const = 0;
|
||||
virtual util::guidance::TurnBearing PostTurnBearing(const EdgeID eid) const = 0;
|
||||
|
||||
virtual util::guidance::BearingClass
|
||||
GetBearingClass(const BearingClassID bearing_class_id) const = 0;
|
||||
virtual util::guidance::BearingClass GetBearingClass(const NodeID node) const = 0;
|
||||
|
||||
virtual EntryClassID GetEntryClassID(const EdgeID eid) const = 0;
|
||||
|
||||
virtual util::guidance::EntryClass GetEntryClass(const EntryClassID entry_class_id) const = 0;
|
||||
virtual util::guidance::EntryClass GetEntryClass(const EdgeID turn_id) const = 0;
|
||||
|
||||
virtual bool IsLeftHandDriving() const = 0;
|
||||
};
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "engine/datafacade/contiguous_block_allocator.hpp"
|
||||
#include "engine/datafacade_provider.hpp"
|
||||
#include "engine/engine_config.hpp"
|
||||
#include "engine/engine_config.hpp"
|
||||
#include "engine/plugins/match.hpp"
|
||||
#include "engine/plugins/nearest.hpp"
|
||||
#include "engine/plugins/table.hpp"
|
||||
@@ -54,12 +53,12 @@ template <typename Algorithm> class Engine final : public EngineInterface
|
||||
{
|
||||
public:
|
||||
explicit Engine(const EngineConfig &config)
|
||||
: route_plugin(config.max_locations_viaroute), //
|
||||
table_plugin(config.max_locations_distance_table), //
|
||||
nearest_plugin(config.max_results_nearest), //
|
||||
trip_plugin(config.max_locations_trip), //
|
||||
match_plugin(config.max_locations_map_matching), //
|
||||
tile_plugin() //
|
||||
: route_plugin(config.max_locations_viaroute, config.max_alternatives), //
|
||||
table_plugin(config.max_locations_distance_table), //
|
||||
nearest_plugin(config.max_results_nearest), //
|
||||
trip_plugin(config.max_locations_trip), //
|
||||
match_plugin(config.max_locations_map_matching), //
|
||||
tile_plugin() //
|
||||
|
||||
{
|
||||
if (config.use_shared_memory)
|
||||
|
||||
@@ -87,6 +87,7 @@ struct EngineConfig final
|
||||
int max_locations_distance_table = -1;
|
||||
int max_locations_map_matching = -1;
|
||||
int max_results_nearest = -1;
|
||||
int max_alternatives = 3; // set an arbitrary upper bound; can be adjusted by user
|
||||
bool use_shared_memory = true;
|
||||
Algorithm algorithm = Algorithm::CH;
|
||||
};
|
||||
|
||||
@@ -53,6 +53,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
: source_node.forward_segment_id.id;
|
||||
const auto source_name_id = facade.GetNameIndex(source_node_id);
|
||||
const auto source_mode = facade.GetTravelMode(source_node_id);
|
||||
auto source_classes = facade.GetClasses(facade.GetClassData(source_node_id));
|
||||
|
||||
const EdgeWeight target_duration =
|
||||
target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration;
|
||||
@@ -62,6 +63,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
: target_node.forward_segment_id.id;
|
||||
const auto target_name_id = facade.GetNameIndex(target_node_id);
|
||||
const auto target_mode = facade.GetTravelMode(target_node_id);
|
||||
auto target_classes = facade.GetClasses(facade.GetClassData(target_node_id));
|
||||
|
||||
const auto number_of_segments = leg_geometry.GetNumberOfSegments();
|
||||
|
||||
@@ -114,13 +116,16 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
const auto ref = facade.GetRefForID(step_name_id);
|
||||
const auto pronunciation = facade.GetPronunciationForID(step_name_id);
|
||||
const auto destinations = facade.GetDestinationsForID(step_name_id);
|
||||
const auto exits = facade.GetExitsForID(step_name_id);
|
||||
const auto distance = leg_geometry.segment_distances[segment_index];
|
||||
auto classes = facade.GetClasses(path_point.classes);
|
||||
|
||||
steps.push_back(RouteStep{step_name_id,
|
||||
name.to_string(),
|
||||
ref.to_string(),
|
||||
pronunciation.to_string(),
|
||||
destinations.to_string(),
|
||||
exits.to_string(),
|
||||
NO_ROTARY_NAME,
|
||||
NO_ROTARY_NAME,
|
||||
segment_duration / 10.,
|
||||
@@ -130,7 +135,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
maneuver,
|
||||
leg_geometry.FrontIndex(segment_index),
|
||||
leg_geometry.BackIndex(segment_index) + 1,
|
||||
{intersection}});
|
||||
{intersection},
|
||||
std::move(classes)});
|
||||
|
||||
if (leg_data_index + 1 < leg_data.size())
|
||||
{
|
||||
@@ -144,9 +150,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
// extract bearings
|
||||
bearings = std::make_pair<std::uint16_t, std::uint16_t>(
|
||||
path_point.pre_turn_bearing.Get(), path_point.post_turn_bearing.Get());
|
||||
const auto entry_class = facade.GetEntryClass(path_point.entry_classid);
|
||||
const auto bearing_class =
|
||||
facade.GetBearingClass(facade.GetBearingClassID(path_point.turn_via_node));
|
||||
const auto bearing_class = facade.GetBearingClass(path_point.turn_via_node);
|
||||
auto bearing_data = bearing_class.getAvailableBearings();
|
||||
intersection.in = bearing_class.findMatchingBearing(bearings.first);
|
||||
intersection.out = bearing_class.findMatchingBearing(bearings.second);
|
||||
@@ -174,7 +178,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
intersection.entry.clear();
|
||||
for (auto idx : util::irange<std::size_t>(0, intersection.bearings.size()))
|
||||
{
|
||||
intersection.entry.push_back(entry_class.allowsEntry(idx));
|
||||
intersection.entry.push_back(path_point.entry_class.allowsEntry(idx));
|
||||
}
|
||||
std::int16_t bearing_in_driving_direction =
|
||||
util::bearing::reverse(std::round(bearings.first));
|
||||
@@ -198,6 +202,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
facade.GetRefForID(step_name_id).to_string(),
|
||||
facade.GetPronunciationForID(step_name_id).to_string(),
|
||||
facade.GetDestinationsForID(step_name_id).to_string(),
|
||||
facade.GetExitsForID(step_name_id).to_string(),
|
||||
NO_ROTARY_NAME,
|
||||
NO_ROTARY_NAME,
|
||||
duration / 10.,
|
||||
@@ -207,7 +212,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
maneuver,
|
||||
leg_geometry.FrontIndex(segment_index),
|
||||
leg_geometry.BackIndex(segment_index) + 1,
|
||||
{intersection}});
|
||||
{intersection},
|
||||
std::move(target_classes)});
|
||||
}
|
||||
// In this case the source + target are on the same edge segment
|
||||
else
|
||||
@@ -239,6 +245,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
facade.GetRefForID(source_name_id).to_string(),
|
||||
facade.GetPronunciationForID(source_name_id).to_string(),
|
||||
facade.GetDestinationsForID(source_name_id).to_string(),
|
||||
facade.GetExitsForID(source_name_id).to_string(),
|
||||
NO_ROTARY_NAME,
|
||||
NO_ROTARY_NAME,
|
||||
duration / 10.,
|
||||
@@ -248,7 +255,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
std::move(maneuver),
|
||||
leg_geometry.FrontIndex(segment_index),
|
||||
leg_geometry.BackIndex(segment_index) + 1,
|
||||
{intersection}});
|
||||
{intersection},
|
||||
std::move(source_classes)});
|
||||
}
|
||||
|
||||
BOOST_ASSERT(segment_index == number_of_segments - 1);
|
||||
@@ -277,6 +285,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
facade.GetRefForID(target_name_id).to_string(),
|
||||
facade.GetPronunciationForID(target_name_id).to_string(),
|
||||
facade.GetDestinationsForID(target_name_id).to_string(),
|
||||
facade.GetExitsForID(target_name_id).to_string(),
|
||||
NO_ROTARY_NAME,
|
||||
NO_ROTARY_NAME,
|
||||
ZERO_DURATION,
|
||||
@@ -286,7 +295,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
std::move(maneuver),
|
||||
leg_geometry.locations.size() - 1,
|
||||
leg_geometry.locations.size(),
|
||||
{intersection}});
|
||||
{intersection},
|
||||
std::move(target_classes)});
|
||||
|
||||
BOOST_ASSERT(steps.front().intersections.size() == 1);
|
||||
BOOST_ASSERT(steps.front().intersections.front().bearings.size() == 1);
|
||||
|
||||
@@ -130,8 +130,14 @@ inline bool haveSameName(const RouteStep &lhs, const RouteStep &rhs)
|
||||
|
||||
// ok, bite the sour grape and check the strings already
|
||||
else
|
||||
return !util::guidance::requiresNameAnnounced(
|
||||
lhs.name, lhs.ref, lhs.pronunciation, rhs.name, rhs.ref, rhs.pronunciation);
|
||||
return !util::guidance::requiresNameAnnounced(lhs.name,
|
||||
lhs.ref,
|
||||
lhs.pronunciation,
|
||||
lhs.exits,
|
||||
rhs.name,
|
||||
rhs.ref,
|
||||
rhs.pronunciation,
|
||||
rhs.exits);
|
||||
}
|
||||
|
||||
// alias for readability, both turn right | left
|
||||
|
||||
@@ -62,6 +62,7 @@ struct RouteStep
|
||||
std::string ref;
|
||||
std::string pronunciation;
|
||||
std::string destinations;
|
||||
std::string exits;
|
||||
std::string rotary_name;
|
||||
std::string rotary_pronunciation;
|
||||
double duration; // duration in seconds
|
||||
@@ -73,6 +74,7 @@ struct RouteStep
|
||||
std::size_t geometry_begin;
|
||||
std::size_t geometry_end;
|
||||
std::vector<IntermediateIntersection> intersections;
|
||||
std::vector<std::string> classes;
|
||||
|
||||
// remove all information from the route step, marking it as invalid (used to indicate empty
|
||||
// steps to be removed).
|
||||
@@ -114,6 +116,7 @@ inline void RouteStep::Invalidate()
|
||||
ref.clear();
|
||||
pronunciation.clear();
|
||||
destinations.clear();
|
||||
exits.clear();
|
||||
rotary_name.clear();
|
||||
rotary_pronunciation.clear();
|
||||
duration = 0;
|
||||
@@ -125,6 +128,7 @@ inline void RouteStep::Invalidate()
|
||||
geometry_end = 0;
|
||||
intersections.clear();
|
||||
intersections.push_back(getInvalidIntersection());
|
||||
classes.clear();
|
||||
}
|
||||
|
||||
// Elongate by another step in front
|
||||
@@ -178,6 +182,7 @@ inline RouteStep &RouteStep::AdaptStepSignage(const RouteStep &origin)
|
||||
name = origin.name;
|
||||
pronunciation = origin.pronunciation;
|
||||
destinations = origin.destinations;
|
||||
exits = origin.exits;
|
||||
ref = origin.ref;
|
||||
|
||||
return *this;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "engine/phantom_node.hpp"
|
||||
#include "osrm/coordinate.hpp"
|
||||
#include "util/guidance/entry_class.hpp"
|
||||
#include "util/guidance/turn_bearing.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
@@ -32,8 +33,10 @@ struct PathData
|
||||
util::guidance::LaneTupleIdPair lane_data;
|
||||
// travel mode of the street that leads to the turn
|
||||
extractor::TravelMode travel_mode : 4;
|
||||
// user defined classed of the street that leads to the turn
|
||||
extractor::ClassData classes;
|
||||
// entry class of the turn, indicating possibility of turns
|
||||
EntryClassID entry_classid;
|
||||
util::guidance::EntryClass entry_class;
|
||||
|
||||
// Source of the speed value on this road segment
|
||||
DatasourceID datasource_id;
|
||||
@@ -58,6 +61,18 @@ struct InternalRouteResult
|
||||
{
|
||||
return (leg != unpacked_path_segments.size() - 1);
|
||||
}
|
||||
|
||||
// Note: includes duration for turns, except for at start and end node.
|
||||
EdgeWeight duration() const
|
||||
{
|
||||
EdgeWeight ret{0};
|
||||
|
||||
for (const auto &leg : unpacked_path_segments)
|
||||
for (const auto &segment : leg)
|
||||
ret += segment.duration_until_turn;
|
||||
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
struct InternalManyRoutesResult
|
||||
|
||||
@@ -27,9 +27,10 @@ class ViaRoutePlugin final : public BasePlugin
|
||||
{
|
||||
private:
|
||||
const int max_locations_viaroute;
|
||||
const int max_alternatives;
|
||||
|
||||
public:
|
||||
explicit ViaRoutePlugin(int max_locations_viaroute);
|
||||
explicit ViaRoutePlugin(int max_locations_viaroute, int max_alternatives);
|
||||
|
||||
Status HandleRequest(const datafacade::ContiguousInternalMemoryDataFacadeBase &facade,
|
||||
const RoutingAlgorithmsInterface &algorithms,
|
||||
|
||||
@@ -20,7 +20,8 @@ class RoutingAlgorithmsInterface
|
||||
{
|
||||
public:
|
||||
virtual InternalManyRoutesResult
|
||||
AlternativePathSearch(const PhantomNodes &phantom_node_pair) const = 0;
|
||||
AlternativePathSearch(const PhantomNodes &phantom_node_pair,
|
||||
unsigned number_of_alternatives) const = 0;
|
||||
|
||||
virtual InternalRouteResult
|
||||
ShortestPathSearch(const std::vector<PhantomNodes> &phantom_node_pair,
|
||||
@@ -66,7 +67,8 @@ template <typename Algorithm> class RoutingAlgorithms final : public RoutingAlgo
|
||||
virtual ~RoutingAlgorithms() = default;
|
||||
|
||||
InternalManyRoutesResult
|
||||
AlternativePathSearch(const PhantomNodes &phantom_node_pair) const final override;
|
||||
AlternativePathSearch(const PhantomNodes &phantom_node_pair,
|
||||
unsigned number_of_alternatives) const final override;
|
||||
|
||||
InternalRouteResult ShortestPathSearch(
|
||||
const std::vector<PhantomNodes> &phantom_node_pair,
|
||||
@@ -130,9 +132,11 @@ template <typename Algorithm> class RoutingAlgorithms final : public RoutingAlgo
|
||||
|
||||
template <typename Algorithm>
|
||||
InternalManyRoutesResult
|
||||
RoutingAlgorithms<Algorithm>::AlternativePathSearch(const PhantomNodes &phantom_node_pair) const
|
||||
RoutingAlgorithms<Algorithm>::AlternativePathSearch(const PhantomNodes &phantom_node_pair,
|
||||
unsigned number_of_alternatives) const
|
||||
{
|
||||
return routing_algorithms::ch::alternativePathSearch(heaps, facade, phantom_node_pair);
|
||||
return routing_algorithms::alternativePathSearch(
|
||||
heaps, facade, phantom_node_pair, number_of_alternatives);
|
||||
}
|
||||
|
||||
template <typename Algorithm>
|
||||
@@ -157,7 +161,7 @@ RoutingAlgorithms<Algorithm>::ManyToManySearch(const std::vector<PhantomNode> &p
|
||||
const std::vector<std::size_t> &source_indices,
|
||||
const std::vector<std::size_t> &target_indices) const
|
||||
{
|
||||
return routing_algorithms::ch::manyToManySearch(
|
||||
return routing_algorithms::manyToManySearch(
|
||||
heaps, facade, phantom_nodes, source_indices, target_indices);
|
||||
}
|
||||
|
||||
@@ -189,7 +193,8 @@ inline std::vector<routing_algorithms::TurnData> RoutingAlgorithms<Algorithm>::G
|
||||
// CoreCH overrides
|
||||
template <>
|
||||
InternalManyRoutesResult inline RoutingAlgorithms<
|
||||
routing_algorithms::corech::Algorithm>::AlternativePathSearch(const PhantomNodes &) const
|
||||
routing_algorithms::corech::Algorithm>::AlternativePathSearch(const PhantomNodes &,
|
||||
unsigned) const
|
||||
{
|
||||
throw util::exception("AlternativePathSearch is disabled due to performance reasons");
|
||||
}
|
||||
@@ -203,25 +208,7 @@ RoutingAlgorithms<routing_algorithms::corech::Algorithm>::ManyToManySearch(
|
||||
{
|
||||
throw util::exception("ManyToManySearch is disabled due to performance reasons");
|
||||
}
|
||||
|
||||
// MLD overrides for not implemented
|
||||
template <>
|
||||
InternalManyRoutesResult inline RoutingAlgorithms<
|
||||
routing_algorithms::mld::Algorithm>::AlternativePathSearch(const PhantomNodes &) const
|
||||
{
|
||||
throw util::exception("AlternativePathSearch is not implemented");
|
||||
}
|
||||
|
||||
template <>
|
||||
inline std::vector<EdgeWeight>
|
||||
RoutingAlgorithms<routing_algorithms::mld::Algorithm>::ManyToManySearch(
|
||||
const std::vector<PhantomNode> &,
|
||||
const std::vector<std::size_t> &,
|
||||
const std::vector<std::size_t> &) const
|
||||
{
|
||||
throw util::exception("ManyToManySearch is not implemented");
|
||||
}
|
||||
}
|
||||
}
|
||||
} // ns engine
|
||||
} // ns osrm
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,13 +15,19 @@ namespace engine
|
||||
{
|
||||
namespace routing_algorithms
|
||||
{
|
||||
namespace ch
|
||||
{
|
||||
|
||||
InternalManyRoutesResult
|
||||
alternativePathSearch(SearchEngineData<Algorithm> &search_engine_data,
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
|
||||
const PhantomNodes &phantom_node_pair);
|
||||
} // namespace ch
|
||||
alternativePathSearch(SearchEngineData<ch::Algorithm> &search_engine_data,
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<ch::Algorithm> &facade,
|
||||
const PhantomNodes &phantom_node_pair,
|
||||
unsigned number_of_alternatives);
|
||||
|
||||
InternalManyRoutesResult
|
||||
alternativePathSearch(SearchEngineData<mld::Algorithm> &search_engine_data,
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<mld::Algorithm> &facade,
|
||||
const PhantomNodes &phantom_node_pair,
|
||||
unsigned number_of_alternatives);
|
||||
|
||||
} // namespace routing_algorithms
|
||||
} // namespace engine
|
||||
} // namespace osrm
|
||||
|
||||
@@ -21,20 +21,11 @@ namespace routing_algorithms
|
||||
/// by the previous route.
|
||||
/// This variation is only an optimazation for graphs with slow queries, for example
|
||||
/// not fully contracted graphs.
|
||||
InternalRouteResult directShortestPathSearch(
|
||||
SearchEngineData<ch::Algorithm> &engine_working_data,
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<ch::Algorithm> &facade,
|
||||
const PhantomNodes &phantom_nodes);
|
||||
|
||||
InternalRouteResult directShortestPathSearch(
|
||||
SearchEngineData<corech::Algorithm> &engine_working_data,
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<corech::Algorithm> &facade,
|
||||
const PhantomNodes &phantom_nodes);
|
||||
|
||||
InternalRouteResult directShortestPathSearch(
|
||||
SearchEngineData<mld::Algorithm> &engine_working_data,
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<mld::Algorithm> &facade,
|
||||
const PhantomNodes &phantom_nodes);
|
||||
template <typename Algorithm>
|
||||
InternalRouteResult
|
||||
directShortestPathSearch(SearchEngineData<Algorithm> &engine_working_data,
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
|
||||
const PhantomNodes &phantom_nodes);
|
||||
|
||||
} // namespace routing_algorithms
|
||||
} // namespace engine
|
||||
|
||||
@@ -16,15 +16,13 @@ namespace engine
|
||||
namespace routing_algorithms
|
||||
{
|
||||
|
||||
namespace ch
|
||||
{
|
||||
template <typename Algorithm>
|
||||
std::vector<EdgeWeight>
|
||||
manyToManySearch(SearchEngineData<Algorithm> &engine_working_data,
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
|
||||
const std::vector<PhantomNode> &phantom_nodes,
|
||||
const std::vector<std::size_t> &source_indices,
|
||||
const std::vector<std::size_t> &target_indices);
|
||||
} // namespace ch
|
||||
|
||||
} // namespace routing_algorithms
|
||||
} // namespace engine
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "engine/algorithm.hpp"
|
||||
#include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
|
||||
#include "engine/internal_route_result.hpp"
|
||||
#include "engine/phantom_node.hpp"
|
||||
#include "engine/search_engine_data.hpp"
|
||||
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
@@ -38,14 +39,10 @@ static constexpr bool REVERSE_DIRECTION = false;
|
||||
static constexpr bool DO_NOT_FORCE_LOOPS = false;
|
||||
|
||||
bool needsLoopForward(const PhantomNode &source_phantom, const PhantomNode &target_phantom);
|
||||
|
||||
bool needsLoopBackwards(const PhantomNode &source_phantom, const PhantomNode &target_phantom);
|
||||
|
||||
void insertSourceInHeap(SearchEngineData<ch::Algorithm>::ManyToManyQueryHeap &heap,
|
||||
const PhantomNode &phantom_node);
|
||||
|
||||
void insertTargetInHeap(SearchEngineData<ch::Algorithm>::ManyToManyQueryHeap &heap,
|
||||
const PhantomNode &phantom_node);
|
||||
bool needsLoopForward(const PhantomNodes &phantoms);
|
||||
bool needsLoopBackwards(const PhantomNodes &phantoms);
|
||||
|
||||
template <typename Heap>
|
||||
void insertNodesInHeaps(Heap &forward_heap, Heap &reverse_heap, const PhantomNodes &nodes)
|
||||
@@ -81,6 +78,40 @@ void insertNodesInHeaps(Heap &forward_heap, Heap &reverse_heap, const PhantomNod
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ManyToManyQueryHeap>
|
||||
void insertSourceInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_node)
|
||||
{
|
||||
if (phantom_node.IsValidForwardSource())
|
||||
{
|
||||
heap.Insert(phantom_node.forward_segment_id.id,
|
||||
-phantom_node.GetForwardWeightPlusOffset(),
|
||||
{phantom_node.forward_segment_id.id, -phantom_node.GetForwardDuration()});
|
||||
}
|
||||
if (phantom_node.IsValidReverseSource())
|
||||
{
|
||||
heap.Insert(phantom_node.reverse_segment_id.id,
|
||||
-phantom_node.GetReverseWeightPlusOffset(),
|
||||
{phantom_node.reverse_segment_id.id, -phantom_node.GetReverseDuration()});
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ManyToManyQueryHeap>
|
||||
void insertTargetInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_node)
|
||||
{
|
||||
if (phantom_node.IsValidForwardTarget())
|
||||
{
|
||||
heap.Insert(phantom_node.forward_segment_id.id,
|
||||
phantom_node.GetForwardWeightPlusOffset(),
|
||||
{phantom_node.forward_segment_id.id, phantom_node.GetForwardDuration()});
|
||||
}
|
||||
if (phantom_node.IsValidReverseTarget())
|
||||
{
|
||||
heap.Insert(phantom_node.reverse_segment_id.id,
|
||||
phantom_node.GetReverseWeightPlusOffset(),
|
||||
{phantom_node.reverse_segment_id.id, phantom_node.GetReverseDuration()});
|
||||
}
|
||||
}
|
||||
|
||||
template <typename FacadeT>
|
||||
void annotatePath(const FacadeT &facade,
|
||||
const PhantomNodes &phantom_node_pair,
|
||||
@@ -112,6 +143,7 @@ void annotatePath(const FacadeT &facade,
|
||||
const auto name_index = facade.GetNameIndex(node_id);
|
||||
const auto turn_instruction = facade.GetTurnInstructionForEdgeID(turn_id);
|
||||
const extractor::TravelMode travel_mode = facade.GetTravelMode(node_id);
|
||||
const auto classes = facade.GetClassData(node_id);
|
||||
|
||||
const auto geometry_index = facade.GetGeometryIndex(node_id);
|
||||
std::vector<NodeID> id_vector;
|
||||
@@ -158,7 +190,8 @@ void annotatePath(const FacadeT &facade,
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
{{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID},
|
||||
travel_mode,
|
||||
INVALID_ENTRY_CLASSID,
|
||||
classes,
|
||||
EMPTY_ENTRY_CLASS,
|
||||
datasource_vector[segment_idx],
|
||||
util::guidance::TurnBearing(0),
|
||||
util::guidance::TurnBearing(0)});
|
||||
@@ -167,7 +200,7 @@ void annotatePath(const FacadeT &facade,
|
||||
if (facade.HasLaneData(turn_id))
|
||||
unpacked_path.back().lane_data = facade.GetLaneData(turn_id);
|
||||
|
||||
unpacked_path.back().entry_classid = facade.GetEntryClassID(turn_id);
|
||||
unpacked_path.back().entry_class = facade.GetEntryClass(turn_id);
|
||||
unpacked_path.back().turn_instruction = turn_instruction;
|
||||
unpacked_path.back().duration_until_turn += facade.GetDurationPenaltyForEdgeID(turn_id);
|
||||
unpacked_path.back().weight_until_turn += facade.GetWeightPenaltyForEdgeID(turn_id);
|
||||
@@ -233,7 +266,8 @@ void annotatePath(const FacadeT &facade,
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
{{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID},
|
||||
facade.GetTravelMode(target_node_id),
|
||||
INVALID_ENTRY_CLASSID,
|
||||
facade.GetClassData(target_node_id),
|
||||
EMPTY_ENTRY_CLASS,
|
||||
datasource_vector[segment_idx],
|
||||
util::guidance::TurnBearing(0),
|
||||
util::guidance::TurnBearing(0)});
|
||||
@@ -338,6 +372,39 @@ double getPathDistance(const datafacade::ContiguousInternalMemoryDataFacade<Algo
|
||||
return distance;
|
||||
}
|
||||
|
||||
template <typename AlgorithmT>
|
||||
InternalRouteResult
|
||||
extractRoute(const datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT> &facade,
|
||||
const EdgeWeight weight,
|
||||
const PhantomNodes &phantom_nodes,
|
||||
const std::vector<NodeID> &unpacked_nodes,
|
||||
const std::vector<EdgeID> &unpacked_edges)
|
||||
{
|
||||
InternalRouteResult raw_route_data;
|
||||
raw_route_data.segment_end_coordinates = {phantom_nodes};
|
||||
|
||||
// No path found for both target nodes?
|
||||
if (INVALID_EDGE_WEIGHT == weight)
|
||||
{
|
||||
return raw_route_data;
|
||||
}
|
||||
|
||||
raw_route_data.shortest_path_weight = weight;
|
||||
raw_route_data.unpacked_path_segments.resize(1);
|
||||
raw_route_data.source_traversed_in_reverse.push_back(
|
||||
(unpacked_nodes.front() != phantom_nodes.source_phantom.forward_segment_id.id));
|
||||
raw_route_data.target_traversed_in_reverse.push_back(
|
||||
(unpacked_nodes.back() != phantom_nodes.target_phantom.forward_segment_id.id));
|
||||
|
||||
annotatePath(facade,
|
||||
phantom_nodes,
|
||||
unpacked_nodes,
|
||||
unpacked_edges,
|
||||
raw_route_data.unpacked_path_segments.front());
|
||||
|
||||
return raw_route_data;
|
||||
}
|
||||
|
||||
} // namespace routing_algorithms
|
||||
} // namespace engine
|
||||
} // namespace osrm
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace engine
|
||||
@@ -24,7 +30,7 @@ namespace
|
||||
// Unrestricted search (Args is const PhantomNodes &):
|
||||
// * use partition.GetQueryLevel to find the node query level based on source and target phantoms
|
||||
// * allow to traverse all cells
|
||||
inline LevelID getNodeQureyLevel(const partition::MultiLevelPartitionView &partition,
|
||||
inline LevelID getNodeQueryLevel(const partition::MultiLevelPartitionView &partition,
|
||||
NodeID node,
|
||||
const PhantomNodes &phantom_nodes)
|
||||
{
|
||||
@@ -49,7 +55,7 @@ inline bool checkParentCellRestriction(CellID, const PhantomNodes &) { return tr
|
||||
// * use the fixed level for queries
|
||||
// * check if the node cell is the same as the specified parent onr
|
||||
inline LevelID
|
||||
getNodeQureyLevel(const partition::MultiLevelPartitionView &, NodeID, LevelID level, CellID)
|
||||
getNodeQueryLevel(const partition::MultiLevelPartitionView &, NodeID, LevelID level, CellID)
|
||||
{
|
||||
return level;
|
||||
}
|
||||
@@ -60,6 +66,70 @@ inline bool checkParentCellRestriction(CellID cell, LevelID, CellID parent)
|
||||
}
|
||||
}
|
||||
|
||||
// Heaps only record for each node its predecessor ("parent") on the shortest path.
|
||||
// For re-constructing the actual path we need to trace back all parent "pointers".
|
||||
// In contrast to the CH code MLD needs to know the edges (with clique arc property).
|
||||
|
||||
using PackedEdge = std::tuple</*from*/ NodeID, /*to*/ NodeID, /*from_clique_arc*/ bool>;
|
||||
using PackedPath = std::vector<PackedEdge>;
|
||||
|
||||
template <bool DIRECTION, typename OutIter>
|
||||
inline void retrievePackedPathFromSingleHeap(const SearchEngineData<Algorithm>::QueryHeap &heap,
|
||||
const NodeID middle,
|
||||
OutIter out)
|
||||
{
|
||||
NodeID current = middle;
|
||||
NodeID parent = heap.GetData(current).parent;
|
||||
|
||||
while (current != parent)
|
||||
{
|
||||
const auto &data = heap.GetData(current);
|
||||
|
||||
if (DIRECTION == FORWARD_DIRECTION)
|
||||
{
|
||||
*out = std::make_tuple(parent, current, data.from_clique_arc);
|
||||
++out;
|
||||
}
|
||||
else if (DIRECTION == REVERSE_DIRECTION)
|
||||
{
|
||||
*out = std::make_tuple(current, parent, data.from_clique_arc);
|
||||
++out;
|
||||
}
|
||||
|
||||
current = parent;
|
||||
parent = heap.GetData(parent).parent;
|
||||
}
|
||||
}
|
||||
|
||||
template <bool DIRECTION>
|
||||
inline PackedPath
|
||||
retrievePackedPathFromSingleHeap(const SearchEngineData<Algorithm>::QueryHeap &heap,
|
||||
const NodeID middle)
|
||||
{
|
||||
PackedPath packed_path;
|
||||
retrievePackedPathFromSingleHeap<DIRECTION>(heap, middle, std::back_inserter(packed_path));
|
||||
return packed_path;
|
||||
}
|
||||
|
||||
// Trace path from middle to start in the forward search space (in reverse)
|
||||
// and from middle to end in the reverse search space. Middle connects paths.
|
||||
|
||||
inline PackedPath
|
||||
retrievePackedPathFromHeap(const SearchEngineData<Algorithm>::QueryHeap &forward_heap,
|
||||
const SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
|
||||
const NodeID middle)
|
||||
{
|
||||
// Retrieve start -> middle. Is in reverse order since tracing back starts from middle.
|
||||
auto packed_path = retrievePackedPathFromSingleHeap<FORWARD_DIRECTION>(forward_heap, middle);
|
||||
std::reverse(begin(packed_path), end(packed_path));
|
||||
|
||||
// Retrieve middle -> end. Is already in correct order, tracing starts from middle.
|
||||
auto into = std::back_inserter(packed_path);
|
||||
retrievePackedPathFromSingleHeap<REVERSE_DIRECTION>(reverse_heap, middle, into);
|
||||
|
||||
return packed_path;
|
||||
}
|
||||
|
||||
template <bool DIRECTION, typename... Args>
|
||||
void routingStep(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
|
||||
SearchEngineData<Algorithm>::QueryHeap &forward_heap,
|
||||
@@ -96,7 +166,7 @@ void routingStep(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm>
|
||||
}
|
||||
}
|
||||
|
||||
const auto level = getNodeQureyLevel(partition, node, args...);
|
||||
const auto level = getNodeQueryLevel(partition, node, args...);
|
||||
|
||||
if (level >= 1 && !forward_heap.GetData(node).from_clique_arc)
|
||||
{
|
||||
@@ -112,6 +182,7 @@ void routingStep(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm>
|
||||
if (shortcut_weight != INVALID_EDGE_WEIGHT && node != to)
|
||||
{
|
||||
const EdgeWeight to_weight = weight + shortcut_weight;
|
||||
BOOST_ASSERT(to_weight >= weight);
|
||||
if (!forward_heap.WasInserted(to))
|
||||
{
|
||||
forward_heap.Insert(to, to_weight, {node, true});
|
||||
@@ -137,6 +208,7 @@ void routingStep(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm>
|
||||
if (shortcut_weight != INVALID_EDGE_WEIGHT && node != to)
|
||||
{
|
||||
const EdgeWeight to_weight = weight + shortcut_weight;
|
||||
BOOST_ASSERT(to_weight >= weight);
|
||||
if (!forward_heap.WasInserted(to))
|
||||
{
|
||||
forward_heap.Insert(to, to_weight, {node, true});
|
||||
@@ -179,16 +251,24 @@ void routingStep(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm>
|
||||
}
|
||||
}
|
||||
|
||||
// With (s, middle, t) we trace back the paths middle -> s and middle -> t.
|
||||
// This gives us a packed path (node ids) from the base graph around s and t,
|
||||
// and overlay node ids otherwise. We then have to unpack the overlay clique
|
||||
// edges by recursively descending unpacking the path down to the base graph.
|
||||
|
||||
using UnpackedNodes = std::vector<NodeID>;
|
||||
using UnpackedEdges = std::vector<EdgeID>;
|
||||
using UnpackedPath = std::tuple<EdgeWeight, UnpackedNodes, UnpackedEdges>;
|
||||
|
||||
template <typename... Args>
|
||||
std::tuple<EdgeWeight, std::vector<NodeID>, std::vector<EdgeID>>
|
||||
search(SearchEngineData<Algorithm> &engine_working_data,
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
|
||||
SearchEngineData<Algorithm>::QueryHeap &forward_heap,
|
||||
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
|
||||
const bool force_loop_forward,
|
||||
const bool force_loop_reverse,
|
||||
EdgeWeight weight_upper_bound,
|
||||
Args... args)
|
||||
UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
|
||||
SearchEngineData<Algorithm>::QueryHeap &forward_heap,
|
||||
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
|
||||
const bool force_loop_forward,
|
||||
const bool force_loop_reverse,
|
||||
EdgeWeight weight_upper_bound,
|
||||
Args... args)
|
||||
{
|
||||
if (forward_heap.Empty() || reverse_heap.Empty())
|
||||
{
|
||||
@@ -242,27 +322,12 @@ search(SearchEngineData<Algorithm> &engine_working_data,
|
||||
return std::make_tuple(INVALID_EDGE_WEIGHT, std::vector<NodeID>(), std::vector<EdgeID>());
|
||||
}
|
||||
|
||||
// Get packed path as edges {from node ID, to node ID, edge ID}
|
||||
std::vector<std::tuple<NodeID, NodeID, bool>> packed_path;
|
||||
NodeID current_node = middle, parent_node = forward_heap.GetData(middle).parent;
|
||||
while (parent_node != current_node)
|
||||
{
|
||||
const auto &data = forward_heap.GetData(current_node);
|
||||
packed_path.push_back(std::make_tuple(parent_node, current_node, data.from_clique_arc));
|
||||
current_node = parent_node;
|
||||
parent_node = forward_heap.GetData(parent_node).parent;
|
||||
}
|
||||
std::reverse(std::begin(packed_path), std::end(packed_path));
|
||||
const NodeID source_node = current_node;
|
||||
// Get packed path as edges {from node ID, to node ID, from_clique_arc}
|
||||
auto packed_path = retrievePackedPathFromHeap(forward_heap, reverse_heap, middle);
|
||||
|
||||
current_node = middle, parent_node = reverse_heap.GetData(middle).parent;
|
||||
while (parent_node != current_node)
|
||||
{
|
||||
const auto &data = reverse_heap.GetData(current_node);
|
||||
packed_path.push_back(std::make_tuple(current_node, parent_node, data.from_clique_arc));
|
||||
current_node = parent_node;
|
||||
parent_node = reverse_heap.GetData(parent_node).parent;
|
||||
}
|
||||
// Beware the edge case when start, middle, end are all the same.
|
||||
// In this case we return a single node, no edges. We also don't unpack.
|
||||
const NodeID source_node = !packed_path.empty() ? std::get<0>(packed_path.front()) : middle;
|
||||
|
||||
// Unpack path
|
||||
std::vector<NodeID> unpacked_nodes;
|
||||
@@ -271,6 +336,7 @@ search(SearchEngineData<Algorithm> &engine_working_data,
|
||||
unpacked_edges.reserve(packed_path.size());
|
||||
|
||||
unpacked_nodes.push_back(source_node);
|
||||
|
||||
for (auto const &packed_edge : packed_path)
|
||||
{
|
||||
NodeID source, target;
|
||||
@@ -283,7 +349,7 @@ search(SearchEngineData<Algorithm> &engine_working_data,
|
||||
}
|
||||
else
|
||||
{ // an overlay graph edge
|
||||
LevelID level = getNodeQureyLevel(partition, source, args...);
|
||||
LevelID level = getNodeQueryLevel(partition, source, args...);
|
||||
CellID parent_cell_id = partition.GetCell(level, source);
|
||||
BOOST_ASSERT(parent_cell_id == partition.GetCell(level, target));
|
||||
|
||||
|
||||
@@ -78,6 +78,19 @@ struct MultiLayerDijkstraHeapData
|
||||
MultiLayerDijkstraHeapData(NodeID p, bool from) : parent(p), from_clique_arc(from) {}
|
||||
};
|
||||
|
||||
struct ManyToManyMultiLayerDijkstraHeapData : MultiLayerDijkstraHeapData
|
||||
{
|
||||
EdgeWeight duration;
|
||||
ManyToManyMultiLayerDijkstraHeapData(NodeID p, EdgeWeight duration)
|
||||
: MultiLayerDijkstraHeapData(p), duration(duration)
|
||||
{
|
||||
}
|
||||
ManyToManyMultiLayerDijkstraHeapData(NodeID p, bool from, EdgeWeight duration)
|
||||
: MultiLayerDijkstraHeapData(p, from), duration(duration)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct SearchEngineData<routing_algorithms::mld::Algorithm>
|
||||
{
|
||||
using QueryHeap = util::QueryHeap<NodeID,
|
||||
@@ -86,12 +99,23 @@ template <> struct SearchEngineData<routing_algorithms::mld::Algorithm>
|
||||
MultiLayerDijkstraHeapData,
|
||||
util::UnorderedMapStorage<NodeID, int>>;
|
||||
|
||||
using ManyToManyQueryHeap = util::QueryHeap<NodeID,
|
||||
NodeID,
|
||||
EdgeWeight,
|
||||
ManyToManyMultiLayerDijkstraHeapData,
|
||||
util::UnorderedMapStorage<NodeID, int>>;
|
||||
|
||||
using SearchEngineHeapPtr = boost::thread_specific_ptr<QueryHeap>;
|
||||
|
||||
using ManyToManyHeapPtr = boost::thread_specific_ptr<ManyToManyQueryHeap>;
|
||||
|
||||
static SearchEngineHeapPtr forward_heap_1;
|
||||
static SearchEngineHeapPtr reverse_heap_1;
|
||||
static ManyToManyHeapPtr many_to_many_heap;
|
||||
|
||||
void InitializeOrClearFirstThreadLocalStorage(unsigned number_of_nodes);
|
||||
|
||||
void InitializeOrClearManyToManyThreadLocalStorage(unsigned number_of_nodes);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef OSRM_EXTRACTOR_CLASSES_DATA_HPP
|
||||
#define OSRM_EXTRACTOR_CLASSES_DATA_HPP
|
||||
|
||||
#include "util/bit_range.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
using ClassData = std::uint8_t;
|
||||
static const std::uint8_t MAX_CLASS_INDEX = 8 - 1;
|
||||
|
||||
inline bool isSubset(const ClassData lhs, const ClassData rhs) { return (lhs & rhs) == lhs; }
|
||||
|
||||
inline auto getClassIndexes(const ClassData data) { return util::makeBitRange<ClassData>(data); }
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -83,8 +83,6 @@ class EdgeBasedGraphFactory
|
||||
const extractor::PackedOSMIDs &osm_node_ids,
|
||||
ProfileProperties profile_properties,
|
||||
const util::NameTable &name_table,
|
||||
std::vector<std::uint32_t> &turn_lane_offsets,
|
||||
std::vector<guidance::TurnLaneType::Mask> &turn_lane_masks,
|
||||
guidance::LaneDescriptionMap &lane_description_map);
|
||||
|
||||
void Run(ScriptingEnvironment &scripting_environment,
|
||||
@@ -150,8 +148,6 @@ class EdgeBasedGraphFactory
|
||||
ProfileProperties profile_properties;
|
||||
|
||||
const util::NameTable &name_table;
|
||||
std::vector<std::uint32_t> &turn_lane_offsets;
|
||||
std::vector<guidance::TurnLaneType::Mask> &turn_lane_masks;
|
||||
guidance::LaneDescriptionMap &lane_description_map;
|
||||
|
||||
unsigned RenumberEdges();
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
#ifndef EXTERNAL_MEMORY_NODE_HPP_
|
||||
#define EXTERNAL_MEMORY_NODE_HPP_
|
||||
|
||||
#include "extractor/query_node.hpp"
|
||||
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
struct ExternalMemoryNode : QueryNode
|
||||
{
|
||||
ExternalMemoryNode(const util::FixedLongitude lon_,
|
||||
const util::FixedLatitude lat_,
|
||||
OSMNodeID node_id_,
|
||||
bool barrier_,
|
||||
bool traffic_lights_)
|
||||
: QueryNode(lon_, lat_, node_id_), barrier(barrier_), traffic_lights(traffic_lights_)
|
||||
{
|
||||
}
|
||||
|
||||
ExternalMemoryNode() : barrier(false), traffic_lights(false) {}
|
||||
|
||||
static ExternalMemoryNode min_value()
|
||||
{
|
||||
return ExternalMemoryNode(
|
||||
util::FixedLongitude{0}, util::FixedLatitude{0}, MIN_OSM_NODEID, false, false);
|
||||
}
|
||||
|
||||
static ExternalMemoryNode max_value()
|
||||
{
|
||||
return ExternalMemoryNode(util::FixedLongitude{std::numeric_limits<std::int32_t>::max()},
|
||||
util::FixedLatitude{std::numeric_limits<std::int32_t>::max()},
|
||||
MAX_OSM_NODEID,
|
||||
false,
|
||||
false);
|
||||
}
|
||||
|
||||
bool barrier;
|
||||
bool traffic_lights;
|
||||
};
|
||||
|
||||
struct ExternalMemoryNodeSTXXLCompare
|
||||
{
|
||||
using value_type = ExternalMemoryNode;
|
||||
value_type max_value() { return value_type::max_value(); }
|
||||
value_type min_value() { return value_type::min_value(); }
|
||||
bool operator()(const value_type &left, const value_type &right) const
|
||||
{
|
||||
return left.node_id < right.node_id;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* EXTERNAL_MEMORY_NODE_HPP_ */
|
||||
@@ -1,10 +1,10 @@
|
||||
#ifndef EXTRACTION_CONTAINERS_HPP
|
||||
#define EXTRACTION_CONTAINERS_HPP
|
||||
|
||||
#include "extractor/external_memory_node.hpp"
|
||||
#include "extractor/first_and_last_segment_of_way.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "extractor/internal_extractor_edge.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
#include "extractor/restriction.hpp"
|
||||
#include "extractor/scripting_environment.hpp"
|
||||
|
||||
@@ -46,13 +46,15 @@ class ExtractionContainers
|
||||
|
||||
public:
|
||||
using STXXLNodeIDVector = stxxl::vector<OSMNodeID>;
|
||||
using STXXLNodeVector = stxxl::vector<ExternalMemoryNode>;
|
||||
using STXXLNodeVector = stxxl::vector<QueryNode>;
|
||||
using STXXLEdgeVector = stxxl::vector<InternalExtractorEdge>;
|
||||
using RestrictionsVector = std::vector<InputRestrictionContainer>;
|
||||
using STXXLWayIDStartEndVector = stxxl::vector<FirstAndLastSegmentOfWay>;
|
||||
using STXXLNameCharData = stxxl::vector<unsigned char>;
|
||||
using STXXLNameOffsets = stxxl::vector<unsigned>;
|
||||
|
||||
std::vector<OSMNodeID> barrier_nodes;
|
||||
std::vector<OSMNodeID> traffic_lights;
|
||||
STXXLNodeIDVector used_node_id_list;
|
||||
STXXLNodeVector all_nodes_list;
|
||||
STXXLEdgeVector all_edges_list;
|
||||
|
||||
@@ -53,6 +53,7 @@ struct ExtractionWay
|
||||
ref.clear();
|
||||
pronunciation.clear();
|
||||
destinations.clear();
|
||||
exits.clear();
|
||||
forward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
|
||||
backward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
|
||||
turn_lanes_forward.clear();
|
||||
@@ -69,6 +70,8 @@ struct ExtractionWay
|
||||
const char *GetRef() const { return ref.c_str(); }
|
||||
void SetDestinations(const char *value) { detail::maybeSetString(destinations, value); }
|
||||
const char *GetDestinations() const { return destinations.c_str(); }
|
||||
void SetExits(const char *value) { detail::maybeSetString(exits, value); }
|
||||
const char *GetExits() const { return exits.c_str(); }
|
||||
void SetPronunciation(const char *value) { detail::maybeSetString(pronunciation, value); }
|
||||
const char *GetPronunciation() const { return pronunciation.c_str(); }
|
||||
void SetTurnLanesForward(const char *value)
|
||||
@@ -82,6 +85,10 @@ struct ExtractionWay
|
||||
}
|
||||
const char *GetTurnLanesBackward() const { return turn_lanes_backward.c_str(); }
|
||||
|
||||
// markers for determining user-defined classes for each way
|
||||
std::unordered_map<std::string, bool> forward_classes;
|
||||
std::unordered_map<std::string, bool> backward_classes;
|
||||
|
||||
// speed in km/h
|
||||
double forward_speed;
|
||||
double backward_speed;
|
||||
@@ -96,6 +103,7 @@ struct ExtractionWay
|
||||
std::string ref;
|
||||
std::string pronunciation;
|
||||
std::string destinations;
|
||||
std::string exits;
|
||||
std::string turn_lanes_forward;
|
||||
std::string turn_lanes_backward;
|
||||
guidance::RoadClassification road_classification;
|
||||
|
||||
@@ -56,8 +56,8 @@ class Extractor
|
||||
private:
|
||||
ExtractorConfig config;
|
||||
|
||||
std::vector<TurnRestriction> ParseOSMData(ScriptingEnvironment &scripting_environment,
|
||||
const unsigned number_of_threads);
|
||||
std::tuple<guidance::LaneDescriptionMap, std::vector<TurnRestriction>>
|
||||
ParseOSMData(ScriptingEnvironment &scripting_environment, const unsigned number_of_threads);
|
||||
|
||||
std::pair<std::size_t, EdgeID>
|
||||
BuildEdgeExpandedGraph(ScriptingEnvironment &scripting_environment,
|
||||
@@ -69,9 +69,8 @@ class Extractor
|
||||
std::vector<EdgeWeight> &edge_based_node_weights,
|
||||
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
|
||||
const std::string &intersection_class_output_file,
|
||||
std::vector<TurnRestriction> &turn_restrictions);
|
||||
void WriteProfileProperties(const std::string &output_path,
|
||||
const ProfileProperties &properties) const;
|
||||
std::vector<TurnRestriction> &turn_restrictions,
|
||||
guidance::LaneDescriptionMap &turn_lane_map);
|
||||
void FindComponents(unsigned max_edge_id,
|
||||
const util::DeallocatingVector<EdgeBasedEdge> &input_edge_list,
|
||||
const std::vector<EdgeBasedNodeSegment> &input_node_segments,
|
||||
@@ -92,20 +91,10 @@ class Extractor
|
||||
const std::vector<util::guidance::BearingClass> &bearing_classes,
|
||||
const std::vector<util::guidance::EntryClass> &entry_classes) const;
|
||||
|
||||
void WriteTurnLaneData(const std::string &turn_lane_file) const;
|
||||
|
||||
// Writes compressed node based graph and its embedding into a file for osrm-partition to use.
|
||||
static void WriteCompressedNodeBasedGraph(const std::string &path,
|
||||
const util::NodeBasedDynamicGraph &graph,
|
||||
const std::vector<util::Coordinate> &coordiantes);
|
||||
|
||||
// globals persisting during the extraction process and the graph generation process
|
||||
|
||||
// during turn lane analysis, we might have to combine lanes for roads that are modelled as two
|
||||
// but are more or less experienced as one. This can be due to solid lines in between lanes, for
|
||||
// example, that genereate a small separation between them. As a result, we might have to
|
||||
// augment the turn lane map during processing, further adding more types.
|
||||
guidance::LaneDescriptionMap turn_lane_map;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef EXTRACTOR_CALLBACKS_HPP
|
||||
#define EXTRACTOR_CALLBACKS_HPP
|
||||
|
||||
#include "extractor/class_data.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
@@ -18,10 +19,10 @@ class Way;
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <> struct hash<std::tuple<std::string, std::string, std::string, std::string>>
|
||||
template <> struct hash<std::tuple<std::string, std::string, std::string, std::string, std::string>>
|
||||
{
|
||||
std::size_t
|
||||
operator()(const std::tuple<std::string, std::string, std::string, std::string> &mk) const
|
||||
std::size_t operator()(
|
||||
const std::tuple<std::string, std::string, std::string, std::string, std::string> &mk) const
|
||||
noexcept
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
@@ -29,6 +30,7 @@ template <> struct hash<std::tuple<std::string, std::string, std::string, std::s
|
||||
boost::hash_combine(seed, std::get<1>(mk));
|
||||
boost::hash_combine(seed, std::get<2>(mk));
|
||||
boost::hash_combine(seed, std::get<3>(mk));
|
||||
boost::hash_combine(seed, std::get<4>(mk));
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
@@ -55,18 +57,23 @@ struct ProfileProperties;
|
||||
class ExtractorCallbacks
|
||||
{
|
||||
private:
|
||||
// used to deduplicate street names, refs, destinations, pronunciation: actually maps to name
|
||||
// ids
|
||||
using MapKey = std::tuple<std::string, std::string, std::string, std::string>;
|
||||
// used to deduplicate street names, refs, destinations, pronunciation, exits:
|
||||
// actually maps to name ids
|
||||
using MapKey = std::tuple<std::string, std::string, std::string, std::string, std::string>;
|
||||
using MapVal = unsigned;
|
||||
std::unordered_map<MapKey, MapVal> string_map;
|
||||
guidance::LaneDescriptionMap lane_description_map;
|
||||
ExtractionContainers &external_memory;
|
||||
std::unordered_map<std::string, ClassData> &classes_map;
|
||||
guidance::LaneDescriptionMap &lane_description_map;
|
||||
bool fallback_to_duration;
|
||||
bool force_split_edges;
|
||||
|
||||
public:
|
||||
using ClassesMap = std::unordered_map<std::string, ClassData>;
|
||||
|
||||
explicit ExtractorCallbacks(ExtractionContainers &extraction_containers,
|
||||
std::unordered_map<std::string, ClassData> &classes_map,
|
||||
guidance::LaneDescriptionMap &lane_description_map,
|
||||
const ProfileProperties &properties);
|
||||
|
||||
ExtractorCallbacks(const ExtractorCallbacks &) = delete;
|
||||
@@ -80,9 +87,6 @@ class ExtractorCallbacks
|
||||
|
||||
// warning: caller needs to take care of synchronization!
|
||||
void ProcessWay(const osmium::Way ¤t_way, const ExtractionWay &result_way);
|
||||
|
||||
// destroys the internal laneDescriptionMap
|
||||
guidance::LaneDescriptionMap &&moveOutLaneDescriptionMap();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,15 @@
|
||||
#include "extractor/edge_based_edge.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "extractor/node_data_container.hpp"
|
||||
#include "extractor/profile_properties.hpp"
|
||||
#include "extractor/serialization.hpp"
|
||||
#include "extractor/turn_data_container.hpp"
|
||||
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/guidance/bearing_class.hpp"
|
||||
#include "util/guidance/entry_class.hpp"
|
||||
#include "util/packed_vector.hpp"
|
||||
#include "util/range_table.hpp"
|
||||
#include "util/serialization.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
@@ -20,6 +24,58 @@ namespace extractor
|
||||
namespace files
|
||||
{
|
||||
|
||||
// writes the .osrm.icd file
|
||||
template <typename IntersectionBearingsT, typename EntryClassVectorT>
|
||||
inline void writeIntersections(const boost::filesystem::path &path,
|
||||
const IntersectionBearingsT &intersection_bearings,
|
||||
const EntryClassVectorT &entry_classes)
|
||||
{
|
||||
static_assert(std::is_same<IntersectionBearingsContainer, IntersectionBearingsT>::value ||
|
||||
std::is_same<IntersectionBearingsView, IntersectionBearingsT>::value,
|
||||
"");
|
||||
|
||||
storage::io::FileWriter writer(path, storage::io::FileWriter::GenerateFingerprint);
|
||||
|
||||
serialization::write(writer, intersection_bearings);
|
||||
storage::serialization::write(writer, entry_classes);
|
||||
}
|
||||
|
||||
// read the .osrm.icd file
|
||||
template <typename IntersectionBearingsT, typename EntryClassVectorT>
|
||||
inline void readIntersections(const boost::filesystem::path &path,
|
||||
IntersectionBearingsT &intersection_bearings,
|
||||
EntryClassVectorT &entry_classes)
|
||||
{
|
||||
static_assert(std::is_same<IntersectionBearingsContainer, IntersectionBearingsT>::value ||
|
||||
std::is_same<IntersectionBearingsView, IntersectionBearingsT>::value,
|
||||
"");
|
||||
|
||||
storage::io::FileReader reader(path, storage::io::FileReader::VerifyFingerprint);
|
||||
|
||||
serialization::read(reader, intersection_bearings);
|
||||
storage::serialization::read(reader, entry_classes);
|
||||
}
|
||||
|
||||
// reads .osrm.properties
|
||||
inline void readProfileProperties(const boost::filesystem::path &path,
|
||||
ProfileProperties &properties)
|
||||
{
|
||||
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
|
||||
storage::io::FileReader reader{path, fingerprint};
|
||||
|
||||
serialization::read(reader, properties);
|
||||
}
|
||||
|
||||
// writes .osrm.properties
|
||||
inline void writeProfileProperties(const boost::filesystem::path &path,
|
||||
const ProfileProperties &properties)
|
||||
{
|
||||
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint;
|
||||
storage::io::FileWriter writer{path, fingerprint};
|
||||
|
||||
serialization::write(writer, properties);
|
||||
}
|
||||
|
||||
template <typename EdgeBasedEdgeVector>
|
||||
void writeEdgeBasedGraph(const boost::filesystem::path &path,
|
||||
EdgeID const max_edge_id,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#ifndef FIRST_AND_LAST_SEGMENT_OF_WAY_HPP
|
||||
#define FIRST_AND_LAST_SEGMENT_OF_WAY_HPP
|
||||
|
||||
#include "extractor/external_memory_node.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <limits>
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef OSRM_EXTRACTOR_GUIDANCE_DRIVEWAY_HANDLER_HPP
|
||||
#define OSRM_EXTRACTOR_GUIDANCE_DRIVEWAY_HANDLER_HPP
|
||||
|
||||
#include "extractor/guidance/intersection_handler.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
|
||||
// Intersection handlers deal with all issues related to intersections.
|
||||
class DrivewayHandler final : public IntersectionHandler
|
||||
{
|
||||
public:
|
||||
DrivewayHandler(const IntersectionGenerator &intersection_generator,
|
||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
||||
const std::vector<util::Coordinate> &coordinates,
|
||||
const util::NameTable &name_table,
|
||||
const SuffixTable &street_name_suffix_table);
|
||||
|
||||
~DrivewayHandler() override final = default;
|
||||
|
||||
// check whether the handler can actually handle the intersection
|
||||
bool canProcess(const NodeID nid,
|
||||
const EdgeID via_eid,
|
||||
const Intersection &intersection) const override final;
|
||||
|
||||
// process the intersection
|
||||
Intersection operator()(const NodeID nid,
|
||||
const EdgeID via_eid,
|
||||
Intersection intersection) const override final;
|
||||
};
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif /* OSRM_EXTRACTOR_GUIDANCE_DRIVEWAY_HANDLER_HPP */
|
||||
@@ -27,7 +27,6 @@ namespace guidance
|
||||
{
|
||||
|
||||
// Intersection handlers deal with all issues related to intersections.
|
||||
// They assign appropriate turn operations to the TurnOperations.
|
||||
// This base class provides both the interface and implementations for
|
||||
// common functions.
|
||||
class IntersectionHandler
|
||||
@@ -114,6 +113,8 @@ class IntersectionHandler
|
||||
// For this scenario returns intersection at `b` and `b`.
|
||||
boost::optional<IntersectionHandler::IntersectionViewAndNode>
|
||||
getNextIntersection(const NodeID at, const EdgeID via) const;
|
||||
|
||||
bool isSameName(const EdgeID source_edge_id, const EdgeID target_edge_id) const;
|
||||
};
|
||||
|
||||
// Impl.
|
||||
@@ -410,14 +411,11 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
|
||||
const auto &best_option_data =
|
||||
node_based_graph.GetEdgeData(intersection[best_option].eid);
|
||||
const auto adjusted_distinction_ratio = [&]() {
|
||||
// not allowed competitors are easily distinct
|
||||
if (!intersection[index].entry_allowed)
|
||||
return 0.7 * DISTINCTION_RATIO;
|
||||
// a bit less obvious are road classes
|
||||
else if (in_way_data.road_classification == best_option_data.road_classification &&
|
||||
best_option_data.road_classification.GetPriority() <
|
||||
node_based_graph.GetEdgeData(intersection[index].eid)
|
||||
.road_classification.GetPriority())
|
||||
// obviousness by road classes
|
||||
if (in_way_data.road_classification == best_option_data.road_classification &&
|
||||
best_option_data.road_classification.GetPriority() <
|
||||
node_based_graph.GetEdgeData(intersection[index].eid)
|
||||
.road_classification.GetPriority())
|
||||
return 0.8 * DISTINCTION_RATIO;
|
||||
// if road classes are the same, we use the full ratio
|
||||
else
|
||||
|
||||
@@ -20,7 +20,6 @@ namespace guidance
|
||||
{
|
||||
|
||||
// Intersection handlers deal with all issues related to intersections.
|
||||
// They assign appropriate turn operations to the TurnOperations.
|
||||
class MotorwayHandler : public IntersectionHandler
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -21,7 +21,6 @@ namespace guidance
|
||||
{
|
||||
|
||||
// Intersection handlers deal with all issues related to intersections.
|
||||
// They assign appropriate turn operations to the TurnOperations.
|
||||
class SliproadHandler final : public IntersectionHandler
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define OSRM_EXTRACTOR_TURN_ANALYSIS
|
||||
|
||||
#include "extractor/compressed_edge_container.hpp"
|
||||
#include "extractor/guidance/driveway_handler.hpp"
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/guidance/intersection_generator.hpp"
|
||||
#include "extractor/guidance/intersection_normalization_operation.hpp"
|
||||
@@ -87,6 +88,7 @@ class TurnAnalysis
|
||||
const TurnHandler turn_handler;
|
||||
const SliproadHandler sliproad_handler;
|
||||
const SuppressModeHandler suppress_mode_handler;
|
||||
const DrivewayHandler driveway_handler;
|
||||
|
||||
// Utility function, setting basic turn types. Prepares for normal turn handling.
|
||||
Intersection
|
||||
|
||||
@@ -24,7 +24,6 @@ namespace guidance
|
||||
{
|
||||
|
||||
// Intersection handlers deal with all issues related to intersections.
|
||||
// They assign appropriate turn operations to the TurnOperations.
|
||||
class TurnHandler : public IntersectionHandler
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -73,8 +73,6 @@ class TurnLaneHandler
|
||||
typedef std::vector<TurnLaneData> LaneDataVector;
|
||||
|
||||
TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||
const std::vector<std::uint32_t> &turn_lane_offsets,
|
||||
const std::vector<TurnLaneType::Mask> &turn_lane_masks,
|
||||
LaneDescriptionMap &lane_description_map,
|
||||
const TurnAnalysis &turn_analysis,
|
||||
util::guidance::LaneDataIdMap &id_map);
|
||||
@@ -90,8 +88,8 @@ class TurnLaneHandler
|
||||
// we need to be able to look at previous intersections to, in some cases, find the correct turn
|
||||
// lanes for a turn
|
||||
const util::NodeBasedDynamicGraph &node_based_graph;
|
||||
const std::vector<std::uint32_t> &turn_lane_offsets;
|
||||
const std::vector<TurnLaneType::Mask> &turn_lane_masks;
|
||||
std::vector<std::uint32_t> turn_lane_offsets;
|
||||
std::vector<TurnLaneType::Mask> turn_lane_masks;
|
||||
LaneDescriptionMap &lane_description_map;
|
||||
const TurnAnalysis &turn_analysis;
|
||||
util::guidance::LaneDataIdMap &id_map;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <bitset>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <numeric> //partial_sum
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
@@ -99,6 +100,34 @@ typedef util::ConcurrentIDMap<guidance::TurnLaneDescription,
|
||||
guidance::TurnLaneDescription_hash>
|
||||
LaneDescriptionMap;
|
||||
|
||||
inline std::tuple<std::vector<std::uint32_t>, std::vector<TurnLaneType::Mask>>
|
||||
transformTurnLaneMapIntoArrays(const LaneDescriptionMap &turn_lane_map)
|
||||
{
|
||||
// could use some additional capacity? To avoid a copy during processing, though small data so
|
||||
// probably not that important.
|
||||
//
|
||||
// From the map, we construct an adjacency array that allows access from all IDs to the list of
|
||||
// associated Turn Lane Masks.
|
||||
//
|
||||
// turn lane offsets points into the locations of the turn_lane_masks array. We use a standard
|
||||
// adjacency array like structure to store the turn lane masks.
|
||||
std::vector<std::uint32_t> turn_lane_offsets(turn_lane_map.data.size() +
|
||||
2); // empty ID + sentinel
|
||||
for (auto entry = turn_lane_map.data.begin(); entry != turn_lane_map.data.end(); ++entry)
|
||||
turn_lane_offsets[entry->second + 1] = entry->first.size();
|
||||
|
||||
// inplace prefix sum
|
||||
std::partial_sum(turn_lane_offsets.begin(), turn_lane_offsets.end(), turn_lane_offsets.begin());
|
||||
|
||||
// allocate the current masks
|
||||
std::vector<guidance::TurnLaneType::Mask> turn_lane_masks(turn_lane_offsets.back());
|
||||
for (auto entry = turn_lane_map.data.begin(); entry != turn_lane_map.data.end(); ++entry)
|
||||
std::copy(entry->first.begin(),
|
||||
entry->first.end(),
|
||||
turn_lane_masks.begin() + turn_lane_offsets[entry->second]);
|
||||
return std::make_tuple(std::move(turn_lane_offsets), std::move(turn_lane_masks));
|
||||
}
|
||||
|
||||
} // guidance
|
||||
} // extractor
|
||||
} // osrm
|
||||
|
||||
@@ -72,6 +72,7 @@ struct InternalExtractorEdge
|
||||
false, // local access only
|
||||
false, // split edge
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
0,
|
||||
guidance::TurnLaneType::empty,
|
||||
guidance::RoadClassification()),
|
||||
weight_data(), duration_data()
|
||||
@@ -91,6 +92,7 @@ struct InternalExtractorEdge
|
||||
bool restricted,
|
||||
bool is_split,
|
||||
TravelMode travel_mode,
|
||||
ClassData classes,
|
||||
LaneDescriptionID lane_description,
|
||||
guidance::RoadClassification road_classification,
|
||||
util::Coordinate source_coordinate)
|
||||
@@ -107,6 +109,7 @@ struct InternalExtractorEdge
|
||||
restricted,
|
||||
is_split,
|
||||
travel_mode,
|
||||
classes,
|
||||
lane_description,
|
||||
std::move(road_classification)),
|
||||
weight_data(std::move(weight_data)), duration_data(std::move(duration_data)),
|
||||
@@ -139,6 +142,7 @@ struct InternalExtractorEdge
|
||||
false, // local access only
|
||||
false, // split edge
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
0,
|
||||
INVALID_LANE_DESCRIPTIONID,
|
||||
guidance::RoadClassification(),
|
||||
util::Coordinate());
|
||||
@@ -158,6 +162,7 @@ struct InternalExtractorEdge
|
||||
false, // local access only
|
||||
false, // split edge
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
0,
|
||||
INVALID_LANE_DESCRIPTIONID,
|
||||
guidance::RoadClassification(),
|
||||
util::Coordinate());
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
#ifndef OSRM_EXTRACTOR_BEARING_CONTAINER_HPP
|
||||
#define OSRM_EXTRACTOR_BEARING_CONTAINER_HPP
|
||||
|
||||
#include "storage/shared_memory_ownership.hpp"
|
||||
|
||||
#include "util/guidance/bearing_class.hpp"
|
||||
#include "util/range_table.hpp"
|
||||
#include "util/vector_view.hpp"
|
||||
|
||||
#include <numeric>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template <storage::Ownership Ownership> class IntersectionBearingsContainer;
|
||||
}
|
||||
|
||||
namespace serialization
|
||||
{
|
||||
template <storage::Ownership Ownership>
|
||||
void read(storage::io::FileReader &reader,
|
||||
detail::IntersectionBearingsContainer<Ownership> &turn_data);
|
||||
|
||||
template <storage::Ownership Ownership>
|
||||
void write(storage::io::FileWriter &writer,
|
||||
const detail::IntersectionBearingsContainer<Ownership> &turn_data);
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <storage::Ownership Ownership> class IntersectionBearingsContainer
|
||||
{
|
||||
template <typename T> using Vector = util::ViewOrVector<T, Ownership>;
|
||||
template <unsigned size> using RangeTable = util::RangeTable<size, Ownership>;
|
||||
|
||||
public:
|
||||
IntersectionBearingsContainer() = default;
|
||||
IntersectionBearingsContainer(IntersectionBearingsContainer &&) = default;
|
||||
IntersectionBearingsContainer(const IntersectionBearingsContainer &) = default;
|
||||
IntersectionBearingsContainer &operator=(IntersectionBearingsContainer &&) = default;
|
||||
IntersectionBearingsContainer &operator=(const IntersectionBearingsContainer &) = default;
|
||||
|
||||
IntersectionBearingsContainer(std::vector<BearingClassID> node_to_class_id_,
|
||||
const std::vector<util::guidance::BearingClass> &bearing_classes)
|
||||
: node_to_class_id(std::move(node_to_class_id_))
|
||||
{
|
||||
std::vector<unsigned> bearing_counts(bearing_classes.size());
|
||||
std::transform(bearing_classes.begin(),
|
||||
bearing_classes.end(),
|
||||
bearing_counts.begin(),
|
||||
[](const auto &bearings) { return bearings.getAvailableBearings().size(); });
|
||||
auto total_bearings = std::accumulate(bearing_counts.begin(), bearing_counts.end(), 0);
|
||||
class_id_to_ranges_table = RangeTable<16>{bearing_counts};
|
||||
|
||||
values.reserve(total_bearings);
|
||||
for (const auto &bearing_class : bearing_classes)
|
||||
{
|
||||
const auto &bearings = bearing_class.getAvailableBearings();
|
||||
values.insert(values.end(), bearings.begin(), bearings.end());
|
||||
}
|
||||
}
|
||||
|
||||
IntersectionBearingsContainer(Vector<DiscreteBearing> values_,
|
||||
Vector<BearingClassID> node_to_class_id_,
|
||||
RangeTable<16> class_id_to_ranges_table_)
|
||||
: values(std::move(values_)), node_to_class_id(std::move(node_to_class_id_)),
|
||||
class_id_to_ranges_table(std::move(class_id_to_ranges_table_))
|
||||
{
|
||||
}
|
||||
|
||||
// Returns the bearing class for an intersection node
|
||||
util::guidance::BearingClass GetBearingClass(const NodeID node) const
|
||||
{
|
||||
auto class_id = node_to_class_id[node];
|
||||
auto range = class_id_to_ranges_table.GetRange(class_id);
|
||||
util::guidance::BearingClass result;
|
||||
std::for_each(values.begin() + range.front(),
|
||||
values.begin() + range.back() + 1,
|
||||
[&](const DiscreteBearing &bearing) { result.add(bearing); });
|
||||
return result;
|
||||
}
|
||||
|
||||
friend void serialization::read<Ownership>(storage::io::FileReader &reader,
|
||||
IntersectionBearingsContainer &turn_data_container);
|
||||
friend void
|
||||
serialization::write<Ownership>(storage::io::FileWriter &writer,
|
||||
const IntersectionBearingsContainer &turn_data_container);
|
||||
|
||||
private:
|
||||
Vector<DiscreteBearing> values;
|
||||
Vector<BearingClassID> node_to_class_id;
|
||||
RangeTable<16> class_id_to_ranges_table;
|
||||
};
|
||||
}
|
||||
|
||||
using IntersectionBearingsContainer =
|
||||
detail::IntersectionBearingsContainer<storage::Ownership::Container>;
|
||||
using IntersectionBearingsView = detail::IntersectionBearingsContainer<storage::Ownership::View>;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef NODE_BASED_EDGE_HPP
|
||||
#define NODE_BASED_EDGE_HPP
|
||||
|
||||
#include "extractor/class_data.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
@@ -28,6 +29,7 @@ struct NodeBasedEdge
|
||||
bool restricted,
|
||||
bool is_split,
|
||||
TravelMode travel_mode,
|
||||
ClassData classes,
|
||||
const LaneDescriptionID lane_description_id,
|
||||
guidance::RoadClassification road_classification);
|
||||
|
||||
@@ -46,6 +48,7 @@ struct NodeBasedEdge
|
||||
std::uint8_t restricted : 1; // 1
|
||||
std::uint8_t is_split : 1; // 1
|
||||
TravelMode travel_mode : 4; // 4
|
||||
ClassData classes; // 8 1
|
||||
LaneDescriptionID lane_description_id; // 16 2
|
||||
guidance::RoadClassification road_classification; // 16 2
|
||||
};
|
||||
@@ -65,6 +68,7 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge
|
||||
bool restricted,
|
||||
bool is_split,
|
||||
TravelMode travel_mode,
|
||||
ClassData classes,
|
||||
const LaneDescriptionID lane_description_id,
|
||||
guidance::RoadClassification road_classification);
|
||||
|
||||
@@ -95,12 +99,14 @@ inline NodeBasedEdge::NodeBasedEdge(NodeID source,
|
||||
bool restricted,
|
||||
bool is_split,
|
||||
TravelMode travel_mode,
|
||||
ClassData classes,
|
||||
const LaneDescriptionID lane_description_id,
|
||||
guidance::RoadClassification road_classification)
|
||||
: source(source), target(target), name_id(name_id), weight(weight), duration(duration),
|
||||
forward(forward), backward(backward), roundabout(roundabout), circular(circular),
|
||||
startpoint(startpoint), restricted(restricted), is_split(is_split), travel_mode(travel_mode),
|
||||
lane_description_id(lane_description_id), road_classification(std::move(road_classification))
|
||||
classes(classes), lane_description_id(lane_description_id),
|
||||
road_classification(std::move(road_classification))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -134,6 +140,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(OSMNodeID source,
|
||||
bool restricted,
|
||||
bool is_split,
|
||||
TravelMode travel_mode,
|
||||
ClassData classes,
|
||||
const LaneDescriptionID lane_description_id,
|
||||
guidance::RoadClassification road_classification)
|
||||
: NodeBasedEdge(SPECIAL_NODEID,
|
||||
@@ -149,6 +156,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(OSMNodeID source,
|
||||
restricted,
|
||||
is_split,
|
||||
travel_mode,
|
||||
classes,
|
||||
lane_description_id,
|
||||
std::move(road_classification)),
|
||||
osm_source_id(std::move(source)), osm_target_id(std::move(target))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef OSRM_EXTRACTOR_NODE_DATA_CONTAINER_HPP
|
||||
#define OSRM_EXTRACTOR_NODE_DATA_CONTAINER_HPP
|
||||
|
||||
#include "extractor/class_data.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
|
||||
#include "storage/io_fwd.hpp"
|
||||
@@ -41,16 +42,18 @@ template <storage::Ownership Ownership> class EdgeBasedNodeDataContainerImpl
|
||||
EdgeBasedNodeDataContainerImpl() = default;
|
||||
|
||||
EdgeBasedNodeDataContainerImpl(std::size_t size)
|
||||
: geometry_ids(size), name_ids(size), component_ids(size), travel_modes(size)
|
||||
: geometry_ids(size), name_ids(size), component_ids(size), travel_modes(size), classes(size)
|
||||
{
|
||||
}
|
||||
|
||||
EdgeBasedNodeDataContainerImpl(Vector<GeometryID> geometry_ids,
|
||||
Vector<NameID> name_ids,
|
||||
Vector<ComponentID> component_ids,
|
||||
Vector<TravelMode> travel_modes)
|
||||
Vector<TravelMode> travel_modes,
|
||||
Vector<ClassData> classes)
|
||||
: geometry_ids(std::move(geometry_ids)), name_ids(std::move(name_ids)),
|
||||
component_ids(std::move(component_ids)), travel_modes(std::move(travel_modes))
|
||||
component_ids(std::move(component_ids)), travel_modes(std::move(travel_modes)),
|
||||
classes(std::move(classes))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -62,13 +65,20 @@ template <storage::Ownership Ownership> class EdgeBasedNodeDataContainerImpl
|
||||
|
||||
ComponentID GetComponentID(const NodeID node_id) const { return component_ids[node_id]; }
|
||||
|
||||
ClassData GetClassData(const NodeID node_id) const { return classes[node_id]; }
|
||||
|
||||
// Used by EdgeBasedGraphFactory to fill data structure
|
||||
template <typename = std::enable_if<Ownership == storage::Ownership::Container>>
|
||||
void SetData(NodeID node_id, GeometryID geometry_id, NameID name_id, TravelMode travel_mode)
|
||||
void SetData(NodeID node_id,
|
||||
GeometryID geometry_id,
|
||||
NameID name_id,
|
||||
TravelMode travel_mode,
|
||||
ClassData class_data)
|
||||
{
|
||||
geometry_ids[node_id] = geometry_id;
|
||||
name_ids[node_id] = name_id;
|
||||
travel_modes[node_id] = travel_mode;
|
||||
classes[node_id] = class_data;
|
||||
}
|
||||
|
||||
// Used by EdgeBasedGraphFactory to fill data structure
|
||||
@@ -91,6 +101,7 @@ template <storage::Ownership Ownership> class EdgeBasedNodeDataContainerImpl
|
||||
util::inplacePermutation(name_ids.begin(), name_ids.end(), permutation);
|
||||
util::inplacePermutation(component_ids.begin(), component_ids.end(), permutation);
|
||||
util::inplacePermutation(travel_modes.begin(), travel_modes.end(), permutation);
|
||||
util::inplacePermutation(classes.begin(), classes.end(), permutation);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -98,6 +109,7 @@ template <storage::Ownership Ownership> class EdgeBasedNodeDataContainerImpl
|
||||
Vector<NameID> name_ids;
|
||||
Vector<ComponentID> component_ids;
|
||||
Vector<TravelMode> travel_modes;
|
||||
Vector<ClassData> classes;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
#ifndef PROFILE_PROPERTIES_HPP
|
||||
#define PROFILE_PROPERTIES_HPP
|
||||
|
||||
#include "extractor/class_data.hpp"
|
||||
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@@ -17,6 +20,7 @@ const constexpr auto DEFAULT_MAX_SPEED = 180 / 3.6; // 180kmph -> m/s
|
||||
struct ProfileProperties
|
||||
{
|
||||
static constexpr int MAX_WEIGHT_NAME_LENGTH = 255;
|
||||
static constexpr int MAX_CLASS_NAME_LENGTH = 255;
|
||||
|
||||
ProfileProperties()
|
||||
: traffic_signal_penalty(0), u_turn_penalty(0),
|
||||
@@ -66,6 +70,22 @@ struct ProfileProperties
|
||||
return std::string(weight_name);
|
||||
}
|
||||
|
||||
void SetClassName(std::size_t index, const std::string &name)
|
||||
{
|
||||
char *name_ptr = class_names[index];
|
||||
auto count = std::min<std::size_t>(name.length(), MAX_CLASS_NAME_LENGTH) + 1;
|
||||
std::copy_n(name.c_str(), count, name_ptr);
|
||||
// Make sure this is always zero terminated
|
||||
BOOST_ASSERT(class_names[index][count - 1] == '\0');
|
||||
BOOST_ASSERT(class_names[index][MAX_CLASS_NAME_LENGTH] == '\0');
|
||||
}
|
||||
|
||||
std::string GetClassName(std::size_t index) const
|
||||
{
|
||||
BOOST_ASSERT(index <= MAX_CLASS_INDEX);
|
||||
return std::string(class_names[index]);
|
||||
}
|
||||
|
||||
double GetWeightMultiplier() const { return std::pow(10., weight_precision); }
|
||||
|
||||
double GetMaxTurnWeight() const
|
||||
@@ -86,9 +106,10 @@ struct ProfileProperties
|
||||
bool fallback_to_duration;
|
||||
//! stores the name of the weight (e.g. 'duration', 'distance', 'safety')
|
||||
char weight_name[MAX_WEIGHT_NAME_LENGTH + 1];
|
||||
//! stores the names of each class
|
||||
std::array<char[MAX_CLASS_NAME_LENGTH + 1], MAX_CLASS_INDEX + 1> class_names;
|
||||
unsigned weight_precision = 1;
|
||||
bool force_split_edges = false;
|
||||
|
||||
bool call_tagless_node_function = true;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
#define OSRM_EXTRACTOR_IO_HPP
|
||||
|
||||
#include "extractor/datasources.hpp"
|
||||
#include "extractor/intersection_bearings_container.hpp"
|
||||
#include "extractor/nbg_to_ebg.hpp"
|
||||
#include "extractor/node_data_container.hpp"
|
||||
#include "extractor/profile_properties.hpp"
|
||||
#include "extractor/restriction.hpp"
|
||||
#include "extractor/segment_data_container.hpp"
|
||||
#include "extractor/turn_data_container.hpp"
|
||||
@@ -20,6 +22,36 @@ namespace extractor
|
||||
namespace serialization
|
||||
{
|
||||
|
||||
// read/write for bearing data
|
||||
template <storage::Ownership Ownership>
|
||||
inline void read(storage::io::FileReader &reader,
|
||||
detail::IntersectionBearingsContainer<Ownership> &intersection_bearings)
|
||||
{
|
||||
storage::serialization::read(reader, intersection_bearings.values);
|
||||
storage::serialization::read(reader, intersection_bearings.node_to_class_id);
|
||||
util::serialization::read(reader, intersection_bearings.class_id_to_ranges_table);
|
||||
}
|
||||
|
||||
template <storage::Ownership Ownership>
|
||||
inline void write(storage::io::FileWriter &writer,
|
||||
const detail::IntersectionBearingsContainer<Ownership> &intersection_bearings)
|
||||
{
|
||||
storage::serialization::write(writer, intersection_bearings.values);
|
||||
storage::serialization::write(writer, intersection_bearings.node_to_class_id);
|
||||
util::serialization::write(writer, intersection_bearings.class_id_to_ranges_table);
|
||||
}
|
||||
|
||||
// read/write for properties file
|
||||
inline void read(storage::io::FileReader &reader, ProfileProperties &properties)
|
||||
{
|
||||
reader.ReadInto(properties);
|
||||
}
|
||||
|
||||
inline void write(storage::io::FileWriter &writer, const ProfileProperties &properties)
|
||||
{
|
||||
writer.WriteFrom(properties);
|
||||
}
|
||||
|
||||
// read/write for datasources file
|
||||
inline void read(storage::io::FileReader &reader, Datasources &sources)
|
||||
{
|
||||
@@ -89,6 +121,7 @@ inline void read(storage::io::FileReader &reader,
|
||||
storage::serialization::read(reader, node_data_container.name_ids);
|
||||
storage::serialization::read(reader, node_data_container.component_ids);
|
||||
storage::serialization::read(reader, node_data_container.travel_modes);
|
||||
storage::serialization::read(reader, node_data_container.classes);
|
||||
}
|
||||
|
||||
template <storage::Ownership Ownership>
|
||||
@@ -99,6 +132,7 @@ inline void write(storage::io::FileWriter &writer,
|
||||
storage::serialization::write(writer, node_data_container.name_ids);
|
||||
storage::serialization::write(writer, node_data_container.component_ids);
|
||||
storage::serialization::write(writer, node_data_container.travel_modes);
|
||||
storage::serialization::write(writer, node_data_container.classes);
|
||||
}
|
||||
|
||||
// read/write for conditional turn restrictions file
|
||||
|
||||
@@ -703,7 +703,7 @@ argumentsToRouteParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
|
||||
|
||||
if (!value->IsBoolean() && !value->IsNull())
|
||||
{
|
||||
Nan::ThrowError("'continue_straight' parama must be boolean or null");
|
||||
Nan::ThrowError("'continue_straight' param must be boolean or null");
|
||||
return route_parameters_ptr();
|
||||
}
|
||||
if (value->IsBoolean())
|
||||
@@ -718,12 +718,21 @@ argumentsToRouteParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
|
||||
if (value.IsEmpty())
|
||||
return route_parameters_ptr();
|
||||
|
||||
if (!value->IsBoolean())
|
||||
if (value->IsBoolean())
|
||||
{
|
||||
Nan::ThrowError("'alternatives' parama must be boolean");
|
||||
params->alternatives = value->BooleanValue();
|
||||
params->number_of_alternatives = 1u;
|
||||
}
|
||||
else if (value->IsNumber())
|
||||
{
|
||||
params->alternatives = value->BooleanValue();
|
||||
params->number_of_alternatives = static_cast<unsigned>(value->NumberValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
Nan::ThrowError("'alternatives' param must be boolean or number");
|
||||
return route_parameters_ptr();
|
||||
}
|
||||
params->alternatives = value->BooleanValue();
|
||||
}
|
||||
|
||||
bool parsedSuccessfully = parseCommonParameters(obj, params);
|
||||
|
||||
@@ -46,18 +46,18 @@ namespace detail
|
||||
template <storage::Ownership Ownership> class CellStorageImpl
|
||||
{
|
||||
public:
|
||||
using WeightOffset = std::uint32_t;
|
||||
using ValueOffset = std::uint32_t;
|
||||
using BoundaryOffset = std::uint32_t;
|
||||
using BoundarySize = std::uint32_t;
|
||||
using SourceIndex = std::uint32_t;
|
||||
using DestinationIndex = std::uint32_t;
|
||||
|
||||
static constexpr auto INVALID_WEIGHT_OFFSET = std::numeric_limits<WeightOffset>::max();
|
||||
static constexpr auto INVALID_VALUE_OFFSET = std::numeric_limits<ValueOffset>::max();
|
||||
static constexpr auto INVALID_BOUNDARY_OFFSET = std::numeric_limits<BoundaryOffset>::max();
|
||||
|
||||
struct CellData
|
||||
{
|
||||
WeightOffset weight_offset = INVALID_WEIGHT_OFFSET;
|
||||
ValueOffset value_offset = INVALID_VALUE_OFFSET;
|
||||
BoundaryOffset source_boundary_offset = INVALID_BOUNDARY_OFFSET;
|
||||
BoundaryOffset destination_boundary_offset = INVALID_BOUNDARY_OFFSET;
|
||||
BoundarySize num_source_nodes = 0;
|
||||
@@ -69,15 +69,16 @@ template <storage::Ownership Ownership> class CellStorageImpl
|
||||
|
||||
// Implementation of the cell view. We need a template parameter here
|
||||
// because we need to derive a read-only and read-write view from this.
|
||||
template <typename WeightValueT> class CellImpl
|
||||
template <typename WeightValueT, typename DurationValueT> class CellImpl
|
||||
{
|
||||
private:
|
||||
using WeightPtrT = WeightValueT *;
|
||||
using WeightRefT = WeightValueT &;
|
||||
using DurationPtrT = DurationValueT *;
|
||||
BoundarySize num_source_nodes;
|
||||
BoundarySize num_destination_nodes;
|
||||
|
||||
WeightPtrT const weights;
|
||||
DurationPtrT const durations;
|
||||
const NodeID *const source_boundary;
|
||||
const NodeID *const destination_boundary;
|
||||
|
||||
@@ -123,20 +124,19 @@ template <storage::Ownership Ownership> class CellStorageImpl
|
||||
const std::size_t stride;
|
||||
};
|
||||
|
||||
public:
|
||||
auto GetOutWeight(NodeID node) const
|
||||
template <typename ValuePtr> auto GetOutRange(const ValuePtr ptr, const NodeID node) const
|
||||
{
|
||||
auto iter = std::find(source_boundary, source_boundary + num_source_nodes, node);
|
||||
if (iter == source_boundary + num_source_nodes)
|
||||
return boost::make_iterator_range(weights, weights);
|
||||
return boost::make_iterator_range(ptr, ptr);
|
||||
|
||||
auto row = std::distance(source_boundary, iter);
|
||||
auto begin = weights + num_destination_nodes * row;
|
||||
auto begin = ptr + num_destination_nodes * row;
|
||||
auto end = begin + num_destination_nodes;
|
||||
return boost::make_iterator_range(begin, end);
|
||||
}
|
||||
|
||||
auto GetInWeight(NodeID node) const
|
||||
template <typename ValuePtr> auto GetInRange(const ValuePtr ptr, const NodeID node) const
|
||||
{
|
||||
auto iter =
|
||||
std::find(destination_boundary, destination_boundary + num_destination_nodes, node);
|
||||
@@ -144,12 +144,21 @@ template <storage::Ownership Ownership> class CellStorageImpl
|
||||
return boost::make_iterator_range(ColumnIterator{}, ColumnIterator{});
|
||||
|
||||
auto column = std::distance(destination_boundary, iter);
|
||||
auto begin = ColumnIterator{weights + column, num_destination_nodes};
|
||||
auto end = ColumnIterator{weights + column + num_source_nodes * num_destination_nodes,
|
||||
auto begin = ColumnIterator{ptr + column, num_destination_nodes};
|
||||
auto end = ColumnIterator{ptr + column + num_source_nodes * num_destination_nodes,
|
||||
num_destination_nodes};
|
||||
return boost::make_iterator_range(begin, end);
|
||||
}
|
||||
|
||||
public:
|
||||
auto GetOutWeight(NodeID node) const { return GetOutRange(weights, node); }
|
||||
|
||||
auto GetInWeight(NodeID node) const { return GetInRange(weights, node); }
|
||||
|
||||
auto GetOutDuration(NodeID node) const { return GetOutRange(durations, node); }
|
||||
|
||||
auto GetInDuration(NodeID node) const { return GetInRange(durations, node); }
|
||||
|
||||
auto GetSourceNodes() const
|
||||
{
|
||||
return boost::make_iterator_range(source_boundary, source_boundary + num_source_nodes);
|
||||
@@ -162,16 +171,19 @@ template <storage::Ownership Ownership> class CellStorageImpl
|
||||
}
|
||||
|
||||
CellImpl(const CellData &data,
|
||||
WeightPtrT const all_weight,
|
||||
WeightPtrT const all_weights,
|
||||
DurationPtrT const all_durations,
|
||||
const NodeID *const all_sources,
|
||||
const NodeID *const all_destinations)
|
||||
: num_source_nodes{data.num_source_nodes},
|
||||
num_destination_nodes{data.num_destination_nodes},
|
||||
weights{all_weight + data.weight_offset},
|
||||
weights{all_weights + data.value_offset},
|
||||
durations{all_durations + data.value_offset},
|
||||
source_boundary{all_sources + data.source_boundary_offset},
|
||||
destination_boundary{all_destinations + data.destination_boundary_offset}
|
||||
{
|
||||
BOOST_ASSERT(all_weight != nullptr);
|
||||
BOOST_ASSERT(all_weights != nullptr);
|
||||
BOOST_ASSERT(all_durations != nullptr);
|
||||
BOOST_ASSERT(num_source_nodes == 0 || all_sources != nullptr);
|
||||
BOOST_ASSERT(num_destination_nodes == 0 || all_destinations != nullptr);
|
||||
}
|
||||
@@ -180,8 +192,8 @@ template <storage::Ownership Ownership> class CellStorageImpl
|
||||
std::size_t LevelIDToIndex(LevelID level) const { return level - 1; }
|
||||
|
||||
public:
|
||||
using Cell = CellImpl<EdgeWeight>;
|
||||
using ConstCell = CellImpl<const EdgeWeight>;
|
||||
using Cell = CellImpl<EdgeWeight, EdgeDuration>;
|
||||
using ConstCell = CellImpl<const EdgeWeight, const EdgeDuration>;
|
||||
|
||||
CellStorageImpl() {}
|
||||
|
||||
@@ -304,24 +316,27 @@ template <storage::Ownership Ownership> class CellStorageImpl
|
||||
<< " Number of unconnected nodes is " << number_of_unconneced;
|
||||
}
|
||||
|
||||
// Set weight offsets and calculate total storage size
|
||||
WeightOffset weight_offset = 0;
|
||||
// Set cell values offsets and calculate total storage size
|
||||
ValueOffset value_offset = 0;
|
||||
for (auto &cell : cells)
|
||||
{
|
||||
cell.weight_offset = weight_offset;
|
||||
weight_offset += cell.num_source_nodes * cell.num_destination_nodes;
|
||||
cell.value_offset = value_offset;
|
||||
value_offset += cell.num_source_nodes * cell.num_destination_nodes;
|
||||
}
|
||||
|
||||
weights.resize(weight_offset + 1, INVALID_EDGE_WEIGHT);
|
||||
weights.resize(value_offset + 1, INVALID_EDGE_WEIGHT);
|
||||
durations.resize(value_offset + 1, MAXIMAL_EDGE_DURATION);
|
||||
}
|
||||
|
||||
template <typename = std::enable_if<Ownership == storage::Ownership::View>>
|
||||
CellStorageImpl(Vector<EdgeWeight> weights_,
|
||||
Vector<EdgeDuration> durations_,
|
||||
Vector<NodeID> source_boundary_,
|
||||
Vector<NodeID> destination_boundary_,
|
||||
Vector<CellData> cells_,
|
||||
Vector<std::uint64_t> level_to_cell_offset_)
|
||||
: weights(std::move(weights_)), source_boundary(std::move(source_boundary_)),
|
||||
: weights(std::move(weights_)), durations(std::move(durations_)),
|
||||
source_boundary(std::move(source_boundary_)),
|
||||
destination_boundary(std::move(destination_boundary_)), cells(std::move(cells_)),
|
||||
level_to_cell_offset(std::move(level_to_cell_offset_))
|
||||
{
|
||||
@@ -336,6 +351,7 @@ template <storage::Ownership Ownership> class CellStorageImpl
|
||||
BOOST_ASSERT(cell_index < cells.size());
|
||||
return ConstCell{cells[cell_index],
|
||||
weights.data(),
|
||||
durations.data(),
|
||||
source_boundary.empty() ? nullptr : source_boundary.data(),
|
||||
destination_boundary.empty() ? nullptr : destination_boundary.data()};
|
||||
}
|
||||
@@ -348,8 +364,11 @@ template <storage::Ownership Ownership> class CellStorageImpl
|
||||
const auto offset = level_to_cell_offset[level_index];
|
||||
const auto cell_index = offset + id;
|
||||
BOOST_ASSERT(cell_index < cells.size());
|
||||
return Cell{
|
||||
cells[cell_index], weights.data(), source_boundary.data(), destination_boundary.data()};
|
||||
return Cell{cells[cell_index],
|
||||
weights.data(),
|
||||
durations.data(),
|
||||
source_boundary.data(),
|
||||
destination_boundary.data()};
|
||||
}
|
||||
|
||||
friend void serialization::read<Ownership>(storage::io::FileReader &reader,
|
||||
@@ -359,6 +378,7 @@ template <storage::Ownership Ownership> class CellStorageImpl
|
||||
|
||||
private:
|
||||
Vector<EdgeWeight> weights;
|
||||
Vector<EdgeDuration> durations;
|
||||
Vector<NodeID> source_boundary;
|
||||
Vector<NodeID> destination_boundary;
|
||||
Vector<CellData> cells;
|
||||
|
||||
@@ -55,6 +55,7 @@ template <storage::Ownership Ownership>
|
||||
inline void read(storage::io::FileReader &reader, detail::CellStorageImpl<Ownership> &storage)
|
||||
{
|
||||
storage::serialization::read(reader, storage.weights);
|
||||
storage::serialization::read(reader, storage.durations);
|
||||
storage::serialization::read(reader, storage.source_boundary);
|
||||
storage::serialization::read(reader, storage.destination_boundary);
|
||||
storage::serialization::read(reader, storage.cells);
|
||||
@@ -66,6 +67,7 @@ inline void write(storage::io::FileWriter &writer,
|
||||
const detail::CellStorageImpl<Ownership> &storage)
|
||||
{
|
||||
storage::serialization::write(writer, storage.weights);
|
||||
storage::serialization::write(writer, storage.durations);
|
||||
storage::serialization::write(writer, storage.source_boundary);
|
||||
storage::serialization::write(writer, storage.destination_boundary);
|
||||
storage::serialization::write(writer, storage.cells);
|
||||
|
||||
@@ -30,7 +30,13 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
|
||||
{
|
||||
route_rule =
|
||||
(qi::lit("alternatives=") >
|
||||
qi::bool_[ph::bind(&engine::api::RouteParameters::alternatives, qi::_r1) = qi::_1]) |
|
||||
(qi::uint_[ph::bind(&engine::api::RouteParameters::number_of_alternatives, qi::_r1) =
|
||||
qi::_1,
|
||||
ph::bind(&engine::api::RouteParameters::alternatives, qi::_r1) =
|
||||
qi::_1 > 0] |
|
||||
qi::bool_[ph::bind(&engine::api::RouteParameters::number_of_alternatives, qi::_r1) =
|
||||
qi::_1,
|
||||
ph::bind(&engine::api::RouteParameters::alternatives, qi::_r1) = qi::_1])) |
|
||||
(qi::lit("continue_straight=") >
|
||||
(qi::lit("default") |
|
||||
qi::bool_[ph::bind(&engine::api::RouteParameters::continue_straight, qi::_r1) =
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
#include <cstring>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
@@ -104,7 +104,47 @@ template <typename T> void write(io::FileWriter &writer, const util::vector_view
|
||||
{
|
||||
const auto count = data.size();
|
||||
writer.WriteElementCount64(count);
|
||||
return writer.WriteFrom(data.data(), count);
|
||||
writer.WriteFrom(data.data(), count);
|
||||
}
|
||||
|
||||
template <> inline void read<bool>(io::FileReader &reader, util::vector_view<bool> &data)
|
||||
{
|
||||
const auto count = reader.ReadElementCount64();
|
||||
BOOST_ASSERT(data.size() == count);
|
||||
for (const auto index : util::irange<std::uint64_t>(0, count))
|
||||
{
|
||||
data[index] = reader.ReadOne<bool>();
|
||||
}
|
||||
}
|
||||
|
||||
template <> inline void write<bool>(io::FileWriter &writer, const util::vector_view<bool> &data)
|
||||
{
|
||||
const auto count = data.size();
|
||||
writer.WriteElementCount64(count);
|
||||
for (const auto index : util::irange<std::uint64_t>(0, count))
|
||||
{
|
||||
writer.WriteOne<bool>(data[index]);
|
||||
}
|
||||
}
|
||||
|
||||
template <> inline void read<bool>(io::FileReader &reader, std::vector<bool> &data)
|
||||
{
|
||||
const auto count = reader.ReadElementCount64();
|
||||
BOOST_ASSERT(data.size() == count);
|
||||
for (const auto index : util::irange<std::uint64_t>(0, count))
|
||||
{
|
||||
data[index] = reader.ReadOne<bool>();
|
||||
}
|
||||
}
|
||||
|
||||
template <> inline void write<bool>(io::FileWriter &writer, const std::vector<bool> &data)
|
||||
{
|
||||
const auto count = data.size();
|
||||
writer.WriteElementCount64(count);
|
||||
for (const auto index : util::irange<std::uint64_t>(0, count))
|
||||
{
|
||||
writer.WriteOne<bool>(data[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ const constexpr char *block_id_to_name[] = {"NAME_CHAR_DATA",
|
||||
"NAME_ID_LIST",
|
||||
"COMPONENT_ID_LIST",
|
||||
"TRAVEL_MODE_LIST",
|
||||
"CLASSES_LIST",
|
||||
"CH_GRAPH_NODE_LIST",
|
||||
"CH_GRAPH_EDGE_LIST",
|
||||
"COORDINATE_LIST",
|
||||
@@ -61,6 +62,7 @@ const constexpr char *block_id_to_name[] = {"NAME_CHAR_DATA",
|
||||
"MLD_PARTITION",
|
||||
"MLD_CELL_TO_CHILDREN",
|
||||
"MLD_CELL_WEIGHTS",
|
||||
"MLD_CELL_DURATIONS",
|
||||
"MLD_CELL_SOURCE_BOUNDARY",
|
||||
"MLD_CELL_DESTINATION_BOUNDARY",
|
||||
"MLD_CELLS",
|
||||
@@ -78,6 +80,7 @@ struct DataLayout
|
||||
NAME_ID_LIST,
|
||||
COMPONENT_ID_LIST,
|
||||
TRAVEL_MODE_LIST,
|
||||
CLASSES_LIST,
|
||||
CH_GRAPH_NODE_LIST,
|
||||
CH_GRAPH_EDGE_LIST,
|
||||
COORDINATE_LIST,
|
||||
@@ -116,6 +119,7 @@ struct DataLayout
|
||||
MLD_PARTITION,
|
||||
MLD_CELL_TO_CHILDREN,
|
||||
MLD_CELL_WEIGHTS,
|
||||
MLD_CELL_DURATIONS,
|
||||
MLD_CELL_SOURCE_BOUNDARY,
|
||||
MLD_CELL_DESTINATION_BOUNDARY,
|
||||
MLD_CELLS,
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
#ifndef OSRM_UTIL_BIT_RANGE_HPP
|
||||
#define OSRM_UTIL_BIT_RANGE_HPP
|
||||
|
||||
#include "util/msb.hpp"
|
||||
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename T> std::size_t countOnes(T value)
|
||||
{
|
||||
static_assert(std::is_unsigned<T>::value, "Only unsigned types allowed");
|
||||
std::size_t number_of_ones = 0;
|
||||
while (value > 0)
|
||||
{
|
||||
auto index = msb(value);
|
||||
value = value & ~(T{1} << index);
|
||||
number_of_ones++;
|
||||
}
|
||||
return number_of_ones;
|
||||
}
|
||||
|
||||
#if (defined(__clang__) || defined(__GNUC__) || defined(__GNUG__))
|
||||
inline std::size_t countOnes(std::uint8_t value)
|
||||
{
|
||||
return __builtin_popcount(std::uint32_t{value});
|
||||
}
|
||||
inline std::size_t countOnes(std::uint16_t value)
|
||||
{
|
||||
return __builtin_popcount(std::uint32_t{value});
|
||||
}
|
||||
inline std::size_t countOnes(unsigned int value) { return __builtin_popcount(value); }
|
||||
inline std::size_t countOnes(unsigned long value) { return __builtin_popcountl(value); }
|
||||
inline std::size_t countOnes(unsigned long long value) { return __builtin_popcountll(value); }
|
||||
#endif
|
||||
}
|
||||
|
||||
// Investigate if we can replace this with
|
||||
// http://www.boost.org/doc/libs/1_64_0/libs/dynamic_bitset/dynamic_bitset.html
|
||||
template <typename DataT>
|
||||
class BitIterator : public boost::iterator_facade<BitIterator<DataT>,
|
||||
const std::size_t,
|
||||
boost::forward_traversal_tag,
|
||||
const std::size_t>
|
||||
{
|
||||
typedef boost::iterator_facade<BitIterator<DataT>,
|
||||
const std::size_t,
|
||||
boost::forward_traversal_tag,
|
||||
const std::size_t>
|
||||
base_t;
|
||||
|
||||
public:
|
||||
typedef typename base_t::value_type value_type;
|
||||
typedef typename base_t::difference_type difference_type;
|
||||
typedef typename base_t::reference reference;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
|
||||
explicit BitIterator() : m_value(0) {}
|
||||
explicit BitIterator(const DataT x) : m_value(std::move(x)) {}
|
||||
|
||||
private:
|
||||
void increment()
|
||||
{
|
||||
auto index = msb(m_value);
|
||||
m_value = m_value & ~(DataT{1} << index);
|
||||
}
|
||||
|
||||
difference_type distance_to(const BitIterator &other) const
|
||||
{
|
||||
return detail::countOnes(m_value) - detail::countOnes(other.m_value);
|
||||
}
|
||||
|
||||
bool equal(const BitIterator &other) const { return m_value == other.m_value; }
|
||||
|
||||
reference dereference() const
|
||||
{
|
||||
BOOST_ASSERT(m_value > 0);
|
||||
return msb(m_value);
|
||||
}
|
||||
|
||||
friend class ::boost::iterator_core_access;
|
||||
DataT m_value;
|
||||
};
|
||||
|
||||
// Returns range over all 1 bits of value
|
||||
template <typename T> auto makeBitRange(const T value)
|
||||
{
|
||||
return boost::make_iterator_range(BitIterator<T>{value}, BitIterator<T>{});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -27,6 +27,29 @@ struct ConcurrentIDMap
|
||||
std::unordered_map<KeyType, ValueType, HashType> data;
|
||||
mutable UpgradableMutex mutex;
|
||||
|
||||
ConcurrentIDMap() = default;
|
||||
ConcurrentIDMap(ConcurrentIDMap &&other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
ScopedWriterLock other_lock{other.mutex};
|
||||
ScopedWriterLock lock{mutex};
|
||||
|
||||
data = std::move(other.data);
|
||||
}
|
||||
}
|
||||
ConcurrentIDMap &operator=(ConcurrentIDMap &&other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
ScopedWriterLock other_lock{other.mutex};
|
||||
ScopedWriterLock lock{mutex};
|
||||
|
||||
data = std::move(other.data);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const ValueType ConcurrentFindOrAdd(const KeyType &key)
|
||||
{
|
||||
{
|
||||
@@ -54,4 +77,4 @@ struct ConcurrentIDMap
|
||||
} // util
|
||||
} // osrm
|
||||
|
||||
#endif // CONCURRENT_ID_MAP_HPP
|
||||
#endif // CONCURRENT_ID_MAP_HPP
|
||||
|
||||
@@ -258,8 +258,12 @@ template <typename ElementT> class DeallocatingVector
|
||||
DeallocatingVector(DeallocatingVector &other) = delete;
|
||||
DeallocatingVector &operator=(DeallocatingVector &other) = delete;
|
||||
// moving is fine
|
||||
DeallocatingVector(DeallocatingVector &&other) = default;
|
||||
DeallocatingVector &operator=(DeallocatingVector &&other) = default;
|
||||
DeallocatingVector(DeallocatingVector &&other) { swap(other); }
|
||||
DeallocatingVector &operator=(DeallocatingVector &&other)
|
||||
{
|
||||
swap(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
~DeallocatingVector() { clear(); }
|
||||
|
||||
|
||||
@@ -46,7 +46,8 @@ inline void print(const engine::guidance::RouteStep &step)
|
||||
std::cout << ")";
|
||||
}
|
||||
std::cout << "] name[" << step.name_id << "]: " << step.name << " Ref: " << step.ref
|
||||
<< " Pronunciation: " << step.pronunciation << "Destination: " << step.destinations;
|
||||
<< " Pronunciation: " << step.pronunciation << "Destination: " << step.destinations
|
||||
<< "Exits: " << step.exits;
|
||||
}
|
||||
|
||||
inline void print(const std::vector<engine::guidance::RouteStep> &steps)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef OSRM_GEOJSON_DEBUG_POLICY_TOOLKIT_HPP
|
||||
#define OSRM_GEOJSON_DEBUG_POLICY_TOOLKIT_HPP
|
||||
|
||||
#include "extractor/external_memory_node.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/json_container.hpp"
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#ifndef GRAPH_LOADER_HPP
|
||||
#define GRAPH_LOADER_HPP
|
||||
|
||||
#include "extractor/external_memory_node.hpp"
|
||||
#include "extractor/node_based_edge.hpp"
|
||||
#include "extractor/packed_osm_ids.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
@@ -50,7 +49,7 @@ NodeID loadNodesFromFile(storage::io::FileReader &file_reader,
|
||||
coordinates.resize(number_of_nodes);
|
||||
osm_node_ids.reserve(number_of_nodes);
|
||||
|
||||
extractor::ExternalMemoryNode current_node;
|
||||
extractor::QueryNode current_node;
|
||||
for (NodeID i = 0; i < number_of_nodes; ++i)
|
||||
{
|
||||
file_reader.ReadInto(¤t_node, 1);
|
||||
@@ -58,18 +57,18 @@ NodeID loadNodesFromFile(storage::io::FileReader &file_reader,
|
||||
coordinates[i].lon = current_node.lon;
|
||||
coordinates[i].lat = current_node.lat;
|
||||
osm_node_ids.push_back(current_node.node_id);
|
||||
}
|
||||
|
||||
if (current_node.barrier)
|
||||
{
|
||||
*barriers = i;
|
||||
++barriers;
|
||||
}
|
||||
auto num_barriers = file_reader.ReadElementCount64();
|
||||
for (auto index = 0UL; index < num_barriers; ++index)
|
||||
{
|
||||
*barriers++ = file_reader.ReadOne<NodeID>();
|
||||
}
|
||||
|
||||
if (current_node.traffic_lights)
|
||||
{
|
||||
*traffic_signals = i;
|
||||
++traffic_signals;
|
||||
}
|
||||
auto num_lights = file_reader.ReadElementCount64();
|
||||
for (auto index = 0UL; index < num_lights; ++index)
|
||||
{
|
||||
*traffic_signals++ = file_reader.ReadOne<NodeID>();
|
||||
}
|
||||
|
||||
return number_of_nodes;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user