Compare commits

..

61 Commits

Author SHA1 Message Date
Patrick Niklaus a3621f3655 [skip ci] Bump package version to latest.3 2017-04-04 23:03:04 +00:00
Pepijn Schoen 789311abd6 Remove osrm namespace indication where possible, wrap out shared_memory_ownership 2017-04-04 17:00:36 +00:00
Pepijn Schoen 091a495632 clang-format 2017-04-04 17:00:36 +00:00
Pepijn Schoen 16665aeb00 Renaming of MemorySetting > Ownership 2017-04-04 17:00:36 +00:00
Pepijn Schoen d6e56c38d5 Rename SharedMemoryWrapper to vector_view 2017-04-04 17:00:36 +00:00
Pepijn Schoen 87874006c7 rename to vector_view, replace some missing ShM occurences 2017-04-04 17:00:36 +00:00
Pepijn Schoen 703588b684 clang-format 2017-04-04 17:00:36 +00:00
Pepijn Schoen b21ee1b63b Fixed regression 2017-04-04 17:00:36 +00:00
Pepijn Schoen 427437d49b Use a one-time defined generic signature for SharedMemoryVectors 2017-04-04 17:00:36 +00:00
Pepijn Schoen 01deefc3bc First pass at adjustment for comments 2017-04-04 17:00:36 +00:00
Pepijn Schoen 157ca9161f clang-format 2017-04-04 17:00:36 +00:00
Pepijn Schoen 266e65e6d2 Replace bool for using shared memory with MemorySetting enum 2017-04-04 17:00:36 +00:00
Daniel J. Hofmann 70b3962c35 NodeJS Binding Tests
Does not run the nodejs tests in sanitized builds. We'd have to

    export LD_PRELOAD='/usr/lib/x86_64-linux-gnu/libasan.so.2'

the asan lib. But it seems like our Clang from mason does not like the
system's libasan. Also we'd need a suppression file for v8 and node.
2017-04-04 16:57:44 +00:00
Patrick Niklaus e568b600f0 Tag a new latest version for publishing 2017-04-03 12:50:45 +00:00
Patrick Niklaus 273fd689ce Always check local variables 2017-03-30 20:12:07 +00:00
Patrick Niklaus 0363d64722 Update releasing docs 2017-03-30 20:12:07 +00:00
Patrick Niklaus d200507424 Fix travis.yml 2017-03-30 20:12:07 +00:00
Patrick Niklaus fc84f605af Switch from commit message publishing to tag-based publishing 2017-03-30 20:12:07 +00:00
Patrick Niklaus 927dea37bb Fix publishing node binaries 2017-03-30 20:12:07 +00:00
Patrick Niklaus de98ae57b7 Switch to yarn 2017-03-30 20:12:07 +00:00
Patrick Niklaus 614398ed6c Integrate MLD in node bindings 2017-03-30 20:12:07 +00:00
Michael Krasnyk 2cd4ba9a0a move split_edges to global properties 2017-03-30 11:20:13 +02:00
Michael Krasnyk 57d3f71bf9 added change log entry and documentation 2017-03-30 11:20:13 +02:00
Michael Krasnyk 8f8df969a2 use signed slope to distinguish uphills and downhills 2017-03-30 11:20:13 +02:00
Michael Krasnyk e39dc3c464 adjust rasterbot test to check split_edges flag 2017-03-30 11:20:13 +02:00
Michael Krasnyk dbc6535221 add split_edge flag in extracted ways 2017-03-30 11:20:13 +02:00
Michael Krasnyk e262cac3e8 Flip source and target coordinates for segments in only backward direction 2017-03-29 22:05:37 +00:00
Michael Krasnyk 4ab3165ae3 Fix unnecessary duplication of backward segments for non-split edges
for edges with the split flag false and in_backward_direction true
if in_forward_direction is also true backward segments can be incorrectly duplicated
2017-03-29 22:05:37 +00:00
Michael Krasnyk 7a1a209168 use std::regex_token_iterator instead of boost tokenized 2017-03-29 10:23:42 +00:00
Michael Krasnyk ac6f07a744 make adaptors::tokenized compatible with boost 1.54 2017-03-29 10:23:42 +00:00
Michael Krasnyk dac929f8df Make max-cell-sizes parameter a comma-separated list 2017-03-29 10:23:42 +00:00
MichalPP ebd938a8fc add kerb to foot.profile barrier whitelist 2017-03-29 10:25:28 +02:00
Michael Krasnyk 5ba54a62d6 Fix clang format for 3dcc713 2017-03-28 13:39:22 +00:00
Michael Krasnyk 827a595b6c Enable coverage reports for unit_tests 2017-03-28 10:40:13 +00:00
Michael Krasnyk c03f74d8b0 Remove unused id parameter 2017-03-28 10:40:13 +00:00
Michael Krasnyk f5393f44f7 Add minimal representative example for #3866 2017-03-28 10:40:13 +00:00
Patrick Niklaus ad6e834992 Add regression test 2017-03-28 10:40:13 +00:00
Patrick Niklaus 3439b21177 Fix internal edges for nodes not in the boundary 2017-03-28 10:40:13 +00:00
Pepijn Schoen 730c809395 Fix Win tests by copying data explicitly to test/data 2017-03-28 12:08:49 +02:00
Emil Tin 5a2da798c8 fixes speed on cycleway+oneway #3853 2017-03-28 12:07:38 +02:00
Daniel J. Hofmann c0e7f6e9f4 Documents the user having to be in the docker group for running our images 2017-03-28 12:05:09 +02:00
Richard Fairhurst ed83d3ed13 More turn parameters as per @daniel-j-h's comment 2017-03-28 11:58:42 +02:00
Richard Fairhurst aa1dff3fc4 Update _rate as per @TheMarex's comment 2017-03-28 11:58:42 +02:00
Richard Fairhurst c1901e9689 Add new property from #3840 2017-03-28 11:58:42 +02:00
Richard Fairhurst c6e6d9fa94 Explain parameters as per @daniel-j-h's suggestion 2017-03-28 11:58:42 +02:00
Richard Fairhurst 88eabb98b9 Document all options available to Lua profiles
Recent improvements to OSRM have led to a lot of changes to the Lua scripting interface, and refactoring of the default profiles makes them slightly more abstract and difficult to grok for those writing profiles from scratch.

This is therefore an attempt to fully document the attributes that can be read and set from Lua profiles. I've done it from my own understanding and from reading the source, but I may well have missed things or mistaken them!
2017-03-28 11:58:42 +02:00
Michael Krasnyk 3dcc7132b6 Add max-cell-sizes option to partitioner 2017-03-28 11:53:14 +02:00
Daniel Patterson 379380abd8 These don't need to be warning messages, debug is sufficient. 2017-03-22 10:41:10 +00:00
Lev Dragunov 497709da13 Review fixes 2017-03-22 10:39:36 +00:00
Lev Dragunov b95a58591d Tidying matching without ts case 2017-03-22 10:39:36 +00:00
Lev Dragunov 5727b1387e Test fixes 2017-03-22 10:39:36 +00:00
Lev Dragunov 221cd00b1a Remove redundant bitsetting 2017-03-22 10:39:36 +00:00
Lev Dragunov cce4f6344c TODO fixes 2017-03-22 10:39:36 +00:00
Lev Dragunov a49c6f433b Cucumber tests 2017-03-22 10:39:36 +00:00
Lev Dragunov ef308ac53a Compilation fix. 2017-03-22 10:39:36 +00:00
Lev Dragunov 2fab696bb3 New tidying and gaps parameters. 2017-03-22 10:39:36 +00:00
Lev Dragunov 836a5066c2 CHANGELOG entry 2017-03-22 10:39:36 +00:00
Lev Dragunov 69422cc4e7 Clang formatting. 2017-03-22 10:39:36 +00:00
Lev Dragunov e9c0987e8a Integration #3149 and #3815 2017-03-22 10:39:36 +00:00
Daniel J. Hofmann bd9eb76a2d Transparently Tidy Traces in Map Matching, resolves #2840.
The Map Matching plugin currently has issues with:
- high frequency traces and (performance)
- blobs, think noise at traffic signals (correctness)

This changeset implements trace-tidying transparently for the user.

We hopefully will see both performance gains as well as better matches!
2017-03-22 10:39:36 +00:00
Lev Dragunov 441eae9df2 Tidying prarameter for the map matching plugin. 2017-03-22 10:39:36 +00:00
79 changed files with 1667 additions and 796 deletions
+10 -1
View File
@@ -16,6 +16,8 @@ notifications:
branches:
only:
- master
# enable building tags
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/
cache:
yarn: true
@@ -26,6 +28,8 @@ cache:
env:
global:
- secure: "hk+32aXXF5t1ApaM2Wjqooz3dx1si907L87WRMkO47WlpJmUUU/Ye+MJk9sViH8MdhOcceocVAmdYl5/WFWOIbDWNlBya9QvXDZyIu2KIre/0QyOCTZbrsif8paBXKIO5O/R4OTvIZ8rvWZsadBdmAT9GSbDhih6FzqXAEgeIYQ="
- secure: "VE+cFkseFwW4jK6XwkP0yW3h4DixPJ8+Eb3yKcchGZ5iIJxlZ/8i1vKHYxadgPRwSYwPSB14tF70xj2OmiT2keGzZUfphmPXinBaLEhYk+Bde+GZZkoSl5ND109I/LcyNr0nG9dDgtV6pkvFchgchpyP9JnVOOS0+crEZlAz0RE="
- CCACHE_TEMPDIR=/tmp/.ccache-temp
- CCACHE_COMPRESS=1
- CASHER_TIME_OUT=599 # one second less than 10m to avoid 10m timeout error: https://github.com/Project-OSRM/osrm-backend/issues/2742
@@ -144,6 +148,8 @@ before_install:
sudo mdutil -i off /
npm install -g yarn
fi
- export PACKAGE_JSON_VERSION=$(node -e "console.log(require('./package.json').version)")
- export PUBLISH=$([[ "${TRAVIS_TAG:-}" == "v${PACKAGE_JSON_VERSION}" ]] && echo "On" || echo "Off")
- echo "Using ${JOBS} jobs"
- yarn install --ignore-scripts
# Bootstrap cmake to be able to run mason
@@ -217,6 +223,10 @@ script:
- ./unit_tests/util-tests
- ./unit_tests/server-tests
- ./unit_tests/partition-tests
- |
if [ -n "${ENABLE_NODE_BINDINGS}" ] && [ -z "${ENABLE_SANITIZER}" ]; then
npm run nodejs-tests
fi
- popd
- yarn test
@@ -228,6 +238,5 @@ after_success:
- |
if [ -n "${ENABLE_NODE_BINDINGS}" ]; then
source ./scripts/travis/build.sh
./scripts/travis/publish.sh
fi
+4
View File
@@ -1,3 +1,5 @@
- Track preprocessing flag in the map matching plugin.
# 5.7.0
- Changes from 5.6
- NodeJs Bindings
@@ -8,6 +10,8 @@
- .osrm.datasource_index file was removed. Data is now part of .osrm.geometries.
- .osrm.edge_lookup was removed. The option `--generate-edge-lookup` does nothing now.
- `osrm-contract` does not depend on the `.osrm.fileIndex` file anymore
- Profiles
- Added `force_split_edges` flag to global properties. True value guarantees that segment_function will be called for all segments, but also could double memory consumption
# 5.6.3
- Changes from 5.6.0
+2
View File
@@ -303,6 +303,8 @@ endif()
if (ENABLE_SANITIZER)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
set(OSRM_CXXFLAGS "${OSRM_CXXFLAGS} -fsanitize=address")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address")
endif()
# Configuring compilers
+14 -6
View File
@@ -41,19 +41,27 @@ The easiest and quickest way to setup your own routing engine backend is to use
### Using Docker
We base the Docker images on Alpine Linux and make sure they are as lightweight as possible (around 10-15 MB).
In the following, replace `X.Y.Z` with the current stable release version.
We base [our Docker images](https://hub.docker.com/r/osrm/osrm-backend/) on Alpine Linux and make sure they are as lightweight as possible.
```
wget http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf
docker run -t -v $(pwd):/data osrm/osrm-backend:vX.Y.Z osrm-extract -p /opt/car.lua /data/berlin-latest.osm.pbf
docker run -t -v $(pwd):/data osrm/osrm-backend:vX.Y.Z osrm-contract /data/berlin-latest.osrm
docker run -t -i -p 5000:5000 -v $(pwd):/data osrm/osrm-backend:vX.Y.Z osrm-routed /data/berlin-latest.osrm
docker run -t -v $(pwd):/data osrm/osrm-backend osrm-extract -p /opt/car.lua /data/berlin-latest.osm.pbf
docker run -t -v $(pwd):/data osrm/osrm-backend osrm-contract /data/berlin-latest.osrm
docker run -t -i -p 5000:5000 -v $(pwd):/data osrm/osrm-backend osrm-routed /data/berlin-latest.osrm
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"
```
In case Docker complains about not being able to connect to the Docker daemon make sure you are in the `docker` group.
```
sudo usermod -aG docker $USER
```
After adding yourself to the `docker` group make sure to log out and back in again with your terminal.
### Building from Source
The following targets Ubuntu 16.04.
+9 -3
View File
@@ -141,15 +141,21 @@ SET test_osm=%test_region%.osm.pbf
IF NOT EXIST %test_osm% powershell Invoke-WebRequest https://s3.amazonaws.com/mapbox/osrm/testing/monaco.osm.pbf -OutFile %test_osm%
%Configuration%\osrm-extract.exe -p ../profiles/car.lua %test_osm%
MKDIR ch
XCOPY %test_region%.osrm %test_region%.osrm.* ch\
XCOPY %test_region%.osrm.* ch\
XCOPY %test_region%.osrm ch\
MKDIR corech
XCOPY %test_region%.osrm %test_region%.osrm.* corech\
XCOPY %test_region%.osrm.* corech\
XCOPY %test_region%.osrm corech\
MKDIR mld
XCOPY %test_region%.osrm %test_region%.osrm.* mld\
XCOPY %test_region%.osrm.* mld\
XCOPY %test_region%.osrm mld\
%Configuration%\osrm-contract.exe %test_region_ch%.osrm
%Configuration%\osrm-contract.exe --core 0.8 %test_region_corech%.osrm
%Configuration%\osrm-partition.exe %test_region_mld%.osrm
%Configuration%\osrm-customize.exe %test_region_mld%.osrm
XCOPY /Y ch\*.* ..\test\data\ch\
XCOPY /Y corech\*.* ..\test\data\corech\
XCOPY /Y mld\*.* ..\test\data\mld\
unit_tests\%Configuration%\library-tests.exe
IF NOT "%APPVEYOR_REPO_BRANCH%"=="master" GOTO DONE
+75
View File
@@ -0,0 +1,75 @@
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "user for publishing to s3://mapbox-node-binary/osrm",
"Resources": {
"User": {
"Type": "AWS::IAM::User",
"Properties": {
"Policies": [
{
"PolicyName": "list",
"PolicyDocument": {
"Statement": [
{
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::mapbox-node-binary",
"Condition": {
"StringLike": {
"s3:prefix": [
"osrm/*"
]
}
}
}
]
}
},
{
"PolicyName": "publish",
"PolicyDocument": {
"Statement": [
{
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:GetObjectAcl",
"s3:PutObject",
"s3:PutObjectAcl"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::mapbox-node-binary/osrm/*"
}
]
}
}
]
}
},
"AccessKey": {
"Type": "AWS::IAM::AccessKey",
"Properties": {
"UserName": {
"Ref": "User"
}
}
}
},
"Outputs": {
"AccessKeyId": {
"Value": {
"Ref": "AccessKey"
}
},
"SecretAccessKey": {
"Value": {
"Fn::GetAtt": [
"AccessKey",
"SecretAccessKey"
]
}
}
}
}
+59
View File
@@ -0,0 +1,59 @@
var cf = require('@mapbox/cloudfriend');
var package_json = require('../package.json')
module.exports = {
AWSTemplateFormatVersion: '2010-09-09',
Description: 'user for publishing to s3://mapbox-node-binary/' + package_json.name,
Resources: {
User: {
Type: 'AWS::IAM::User',
Properties: {
Policies: [
{
PolicyName: 'list',
PolicyDocument: {
Statement: [
{
Action: ['s3:ListBucket'],
Effect: 'Allow',
Resource: 'arn:aws:s3:::mapbox-node-binary',
Condition : {
StringLike : {
"s3:prefix": [ package_json.name + "/*"]
}
}
}
]
}
},
{
PolicyName: 'publish',
PolicyDocument: {
Statement: [
{
Action: ['s3:DeleteObject', 's3:GetObject', 's3:GetObjectAcl', 's3:PutObject', 's3:PutObjectAcl'],
Effect: 'Allow',
Resource: 'arn:aws:s3:::mapbox-node-binary/' + package_json.name + '/*'
}
]
}
}
]
}
},
AccessKey: {
Type: 'AWS::IAM::AccessKey',
Properties: {
UserName: cf.ref('User')
}
}
},
Outputs: {
AccessKeyId: {
Value: cf.ref('AccessKey')
},
SecretAccessKey: {
Value: cf.getAtt('AccessKey', 'SecretAccessKey')
}
}
};
-1
View File
@@ -1,7 +1,6 @@
coverage:
ignore:
- unit_tests/.*
- third_party/.*
comment: off
+5 -3
View File
@@ -279,6 +279,8 @@ In addition to the [general options](#general-options) the following options are
|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.|
|timestamps |`{timestamp};{timestamp}[;{timestamp} ...]` |Timestamps for the input locations in seconds since UNIX epoch. Timestamps need to be monotonically increasing. |
|radiuses |`{radius};{radius}[;{radius} ...]` |Standard deviation of GPS precision used for map matching. If applicable use GPS accuracy.|
|gaps |`split` (default), `ignore` |Allows the input track splitting based on huge timestamp gaps between points. |
|tidy |`true`, `false` (default) |Allows the input track modification to obtain better matching quality for noisy tracks. |
|Parameter |Values |
|------------|-----------------------------------|
@@ -314,7 +316,7 @@ All other properties might be undefined.
The trip plugin solves the Traveling Salesman Problem using a greedy heuristic (farthest-insertion algorithm) for 10 or more waypoints and uses brute force for less than 10 waypoints.
The returned path does not have to be the fastest path. As TSP is NP-hard it only returns an approximation.
Note that all input coordinates have to be connected for the trip service to work.
Note that all input coordinates have to be connected for the trip service to work.
```endpoint
GET /trip/v1/{profile}/{coordinates}?roundtrip={true|false}&source{any|first}&destination{any|last}&steps={true|false}&geometries={polyline|polyline6|geojson}&overview={simplified|full|false}&annotations={true|false}'
@@ -334,7 +336,7 @@ In addition to the [general options](#general-options) the following options are
**Fixing Start and End Points**
It is possible to explicitely set the start or end coordinate of the trip.
It is possible to explicitely set the start or end coordinate of the trip.
When source is set to `first`, the first coordinate is used as start coordinate of the trip in the output. When destination is set to `last`, the last coordinate will be used as destination of the trip in the returned output. If you specify `any`, any of the coordinates can be used as the first or last coordinate in the output.
However, if `source=any&destination=any` the returned round-trip will still start at the first input coordinate by default.
@@ -344,7 +346,7 @@ Right now, the following combinations are possible:
| roundtrip | source | destination | supported |
| :-- | :-- | :-- | :-- |
| true | first | last | **yes** |
| true | first | last | **yes** |
| true | first | any | **yes** |
| true | any | last | **yes** |
| true | any | any | **yes** |
+80 -3
View File
@@ -25,6 +25,19 @@ As you scroll down the file you'll see local variables, and then local functions
`way_function` and `node_function` are the important functions which are called when extracting OpenStreetMap data with `osrm-extract`.
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)
use_turn_restrictions | Boolean | Are turn instructions followed?
continue_straight_at_waypoint | Boolean | Must the route continue straight on at a via point, or are U-turns allowed?
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
## way_function
Given an OpenStreetMap way, the way_function will either return nothing (meaning we are not going to route over this way at all), or it will set up a result hash to be returned. The most important thing it will do is set the value of `result.forward_speed` and `result.backward_speed` as a suitable integer value representing the speed for traversing the way.
@@ -33,15 +46,79 @@ All other calculations stem from that, including the returned timings in driving
Using the power of the scripting language you wouldn't typically see something as simple as a `result.forward_speed = 20` line within the way_function. Instead a way_function will examine the tagging (e.g. `way:get_value_by_key("highway")` and many others), process this information in various ways, calling other local functions, referencing the global variables and look-up hashes, before arriving at the result.
## Guidance
The following attributes can be set on the result in way_function:
Attribute | Type | Notes
----------------------------------------|----------|--------------------------------------------------------------------------
forward_speed | Float | Speed on this way in km/h
backward_speed | Float | " "
forward_rate | Float | Routing weight, expressed as meters/*weight* (e.g. for a fastest-route weighting, you would want this to be meters/second, so set it to forward_speed/3.6)
backward_rate | Float | " "
forward_mode | Enum | Mode of travel (e.g. car, ferry). Defined in include/extractor/travel_mode.hpp
backward_mode | Enum | " "
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)
turn_lanes_backward | String | " "
forward_restricted | Boolean | Is this a restricted access road? (e.g. private, or deliveries only; used to enable high turn penalty, so that way is only chosen for start/end of route)
backward_restricted | Boolean | " "
is_startpoint | Boolean | Can a journey start on this way? (e.g. ferry; if false, prevents snapping the start point to this way)
roundabout | Boolean | Is this part of a roundabout?
circular | Boolean | Is this part of a non-roundabout circular junction?
name | String | Name of the way
ref | String | Road number
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
road_classification.road_priority_class | Enum | Guidance: order in priority list. Defined in include/extractor/guidance/road_classification.hpp
road_classification.may_be_ignored | Boolean | Guidance: way is non-highway
road_classification.num_lanes | Unsigned | Guidance: total number of lanes in way
### Guidance
The guidance parameters in profiles are currently a work in progress. They can and will change.
Please be aware of this when using guidance configuration possibilities.
### Road Classification
Guidance uses road classes to decide on when/if to emit specific instructions and to discover which road is obvious when following a route.
Classification uses three flags and a priority-category.
The flags indicate whether a road is a motorway (required for on/off ramps), a link type (the ramps itself, if also a motorway) and whether a road may be omittted in considerations (is considered purely for connectivity).
The priority-category influences the decision which road is considered the obvious choice and which roads can be seen as fork.
Forks can be emitted between roads of similar priority category only. Obvious choices follow a major priority road, if the priority difference is large.
## node_function
The following attributes can be set on the result in node_function:
Attribute | Type | Notes
----------------|---------|-------------------------------------------------------
barrier | Boolean | Is it an impassable barrier?
traffic_lights | Boolean | Is it a traffic light (incurs delay in turn_function)?
## segment_function
The following attributes can be read and set on the result in segment_function:
Attribute | Read/write? | Type | Notes
-------------------|-------------|---------|------------------------------------------------------
source.lon | Read | Float | Co-ordinates of segment start
source.lat | Read | Float | " "
target.lon | Read | Float | Co-ordinates of segment end
target.lat | Read | Float | " "
target.distance | Read | Float | Length of segment
weight | Read/write | Float | Routing weight for this segment
duration | Read/write | Float | Duration for this segment
## turn_function
The following attributes can be read and set on the result in turn_function:
Attribute | Read/write? | Type | Notes
-------------------|-------------|---------|------------------------------------------------------
direction_modifier | Read | Enum | Geometry of turn. Defined in include/extractor/guidance/turn_instruction.hpp
turn_type | Read | Enum | Priority of turn. Defined in include/extractor/guidance/turn_instruction.hpp
has_traffic_light | Read | Boolean | Is a traffic light present at this turn?
source_restricted | Read | Boolean | Is it from a restricted access road? (See definition in way_function)
target_restricted | Read | Boolean | Is it to a restricted access road? (See definition in way_function)
angle | Read | Float | Angle of turn in degrees (0-360: 0=u-turn, 180=straight on)
duration | Read/write | Float | Penalty to be applied for this turn (duration in deciseconds)
weight | Read/write | Float | Penalty to be applied for this turn (routing weight)
+13 -9
View File
@@ -32,21 +32,25 @@ We may introduce forward-compatible changes: query parameters and response prope
- The `master` branch is for the bleeding edge development
- We create and maintain release branches `x.y` to control the release flow
- We create the release branch once we tagged the final version `x.y.0` version, RCs go on master
- We create the release branch once we create release branches once we want to release the first RC
- RCs go in the release branch, commits needs to be cherry-picked from master
- No minor or major version will be released without a code-equal release candidates
- For quality assurance, release candidates will be run on the demo server for 24 hours before releaseing the version proper
- For quality assurance, release candidates need to be staged beforing tagging a final release
- Patch versions may be released without a release candidate
- We may backport fixes to older versions and release them as patch versions
## Releasing a version
1. Check out the appropriate release branch `x.y`
2. Make sure all tests are passing (e.g. Travis CI gives you a :thumbs_up:)
3. Make sure `CHANGELOG.md` is up to date.
4. Make sure the OSRM version in `CMakeLists.txt` is up to date
5. Use an annotated tag to mark the release: `git tag vx.y.z -a` Body of the tag description should be the changelog entries.
6. Use `npm run build-api-docs` to generate the API documentation. Copy `build/docs/*` to `https://github.com/Project-OSRM/project-osrm.github.com` in the `docs/vN.N.N/api` directory
6. Push tags and commits: `git push; git push --tags`
8. Proceede with the `node-osrm` release as [outlined in the repository](https://github.com/Project-OSRM/node-osrm/blob/master/docs/releasing.md).
2. Make sure `CHANGELOG.md` is up to date.
3. Make sure the OSRM version in `CMakeLists.txt` is up to date
4. Make sure the `package.json` is up to date.
5. Make sure all tests are passing (e.g. Travis CI gives you a :thumbs_up:)
6. Use an annotated tag to mark the release: `git tag vx.y.z -a` Body of the tag description should be the changelog entries.
7. Use `npm run build-api-docs` to generate the API documentation. Copy `build/docs/*` to `https://github.com/Project-OSRM/project-osrm.github.com` in the `docs/vN.N.N/api` directory
8. Push tags and commits: `git push; git push --tags`
9. If not a release-candidate: Write a mailing-list post to osrm-talk@openstreetmap.org to announce the release
10. Wait until the travis build has been completed and check if the node binaries were published by doing:
`rm -rf node_modules && npm install` locally.
11. For final releases run `npm publish` or `npm publish --tag next` for release candidates.
+16
View File
@@ -79,3 +79,19 @@ Feature: Bike - Cycle tracks/lanes
| residential | lane | yes | x | x |
| footway | lane | yes | x | x |
| cycleway | lane | yes | x | x |
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 |
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 |
+3 -3
View File
@@ -10,11 +10,11 @@ Feature: osrm-partition command line options: help
And stdout should contain "--help"
And stdout should contain "Configuration:"
And stdout should contain "--threads"
And stdout should contain "--min-cell-size"
And stdout should contain "--balance"
And stdout should contain "--boundary"
And stdout should contain "--optimizing-cuts"
And stdout should contain "--small-component-size"
And stdout should contain "--max-cell-sizes"
And it should exit with an error
Scenario: osrm-partition - Help, short
@@ -26,11 +26,11 @@ Feature: osrm-partition command line options: help
And stdout should contain "--help"
And stdout should contain "Configuration:"
And stdout should contain "--threads"
And stdout should contain "--min-cell-size"
And stdout should contain "--balance"
And stdout should contain "--boundary"
And stdout should contain "--optimizing-cuts"
And stdout should contain "--small-component-size"
And stdout should contain "--max-cell-sizes"
And it should exit successfully
Scenario: osrm-partition - Help, long
@@ -42,9 +42,9 @@ Feature: osrm-partition command line options: help
And stdout should contain "--help"
And stdout should contain "Configuration:"
And stdout should contain "--threads"
And stdout should contain "--min-cell-size"
And stdout should contain "--balance"
And stdout should contain "--boundary"
And stdout should contain "--optimizing-cuts"
And stdout should contain "--small-component-size"
And stdout should contain "--max-cell-sizes"
And it should exit successfully
@@ -18,3 +18,15 @@ Feature: osrm-partition command line options: invalid options
And stderr should contain "option"
And stderr should contain "fly-me-to-the-moon"
And it should exit with an error
Scenario: osrm-partition - Check invalid values
When I try to run "osrm-partition --max-cell-sizes 4,6@4,16 fly-me-to-the-moon.osrm"
Then stdout should be empty
And stderr should contain "is invalid"
And it should exit with an error
Scenario: osrm-partition - Check non-descending order
When I try to run "osrm-partition --max-cell-sizes 4,64,16 fly-me-to-the-moon.osrm"
Then stdout should be empty
And stderr should contain "must be sorted in non-descending order"
And it should exit with an error
+6 -4
View File
@@ -2,10 +2,10 @@
Feature: osrm-extract with a profile containing raster source
Scenario: osrm-extract on a valid profile
Given the profile "rasterbot"
And the node map
"""
a b
"""
And the node locations
| node | lat | lon |
| a | 0.1 | 0.1 |
| b | 0.05 | 0.1 |
And the ways
| nodes |
| ab |
@@ -20,4 +20,6 @@ Feature: osrm-extract with a profile containing raster source
And the data has been saved to disk
When I run "osrm-extract {osm_file} -p {profile_file}"
Then stdout should contain "source loader"
Then stdout should contain "slope: 0.0899"
Then stdout should contain "slope: -0.0899"
And it should exit successfully
+3 -2
View File
@@ -50,8 +50,9 @@ Feature: Raster - weights
And I route I should get
| from | to | route | speed |
| a | b | ab,ab | 8 km/h |
| a | c | ad,dc,dc | 15 km/h |
| b | c | bc,bc | 8 km/h |
| b | a | ab,ab | 22 km/h |
| a | c | ab,bc,bc | 12 km/h |
| b | c | bc,bc | 22 km/h |
| a | d | ad,ad | 15 km/h |
| d | c | dc,dc | 15 km/h |
| d | e | de,de | 10 km/h |
+78
View File
@@ -40,6 +40,84 @@ Feature: Basic Map Matching
| trace | timestamps | matchings |
| abcd | 0 1 62 63 | ab,cd |
Scenario: Testbot - Map matching with trace splitting suppression
Given the query options
| gaps | ignore |
Given the node map
"""
a b c d
e
"""
And the ways
| nodes | oneway |
| abcd | no |
When I match I should get
| trace | timestamps | matchings |
| abcd | 0 1 62 63 | abcd |
Scenario: Testbot - Map matching with trace tidying. Clean case.
Given a grid size of 100 meters
Given the query options
| tidy | true |
Given the node map
"""
a b c d
e
"""
And the ways
| nodes | oneway |
| abcd | no |
When I match I should get
| trace | timestamps | matchings |
| abcd | 0 10 20 30 | abcd |
Scenario: Testbot - Map matching with trace tidying. Dirty case by ts.
Given a grid size of 100 meters
Given the query options
| tidy | true |
Given the node map
"""
a b c d
e
"""
And the ways
| nodes | oneway |
| abcd | no |
When I match I should get
| trace | timestamps | matchings |
| abacd | 0 10 12 20 30 | abcd |
Scenario: Testbot - Map matching with trace tidying. Dirty case by dist.
Given a grid size of 8 meters
Given the query options
| tidy | true |
Given the node map
"""
a q b c d
e
"""
And the ways
| nodes | oneway |
| aqbcd | no |
When I match I should get
| trace | matchings |
| abcbd | abbd |
Scenario: Testbot - Map matching with core factor
Given the contract extra arguments "--core 0.8"
Given the node map
+3 -5
View File
@@ -3,7 +3,7 @@ Feature: Multi level routing
Background:
Given the profile "testbot"
And the partition extra arguments "--min-cell-size 4 --small-component-size 1"
And the partition extra arguments "--small-component-size 1 --max-cell-sizes 4,16,64"
Scenario: Testbot - Multi level routing check partition
Given the node map
@@ -31,7 +31,7 @@ Feature: Multi level routing
| be | primary |
And the data has been extracted
When I run "osrm-partition --min-cell-size 4 --small-component-size 1 {processed_file}"
When I run "osrm-partition --max-cell-sizes 4,16 --small-component-size 1 {processed_file}"
Then it should exit successfully
And stdout should not contain "level 1 #cells 1 bit size 1"
@@ -57,7 +57,6 @@ Feature: Multi level routing
| cm | primary |
| hj | primary |
| kp | primary |
And the partition extra arguments "--min-cell-size 4 --small-component-size 1"
When I route I should get
| from | to | route | time |
@@ -88,7 +87,6 @@ Feature: Multi level routing
| dim | primary |
| glr | primary |
| ot | secondary |
And the partition extra arguments "--min-cell-size 4 --small-component-size 1"
When I route I should get
| from | to | route | time |
@@ -113,6 +111,7 @@ Feature: Multi level routing
lk
"""
And the partition extra arguments "--small-component-size 1 --max-cell-sizes 4,16"
And the ways
| nodes | maxspeed |
| abcda | 5 |
@@ -124,7 +123,6 @@ Feature: Multi level routing
| fi | 15 |
| gi | 15 |
| hf | 100 |
And the partition extra arguments "--min-cell-size 4 --small-component-size 1"
When I route I should get
| from | to | route | time |
+2 -3
View File
@@ -39,9 +39,9 @@ class CellCustomizer
const EdgeWeight weight = heap.GetKey(node);
if (level == 1)
RelaxNode<true>(graph, cells, heap, level, id, node, weight);
RelaxNode<true>(graph, cells, heap, level, node, weight);
else
RelaxNode<false>(graph, cells, heap, level, id, node, weight);
RelaxNode<false>(graph, cells, heap, level, node, weight);
destinations_set.erase(node);
}
@@ -85,7 +85,6 @@ class CellCustomizer
const partition::CellStorage &cells,
Heap &heap,
LevelID level,
CellID id,
NodeID node,
EdgeWeight weight) const
{
+7 -4
View File
@@ -7,6 +7,8 @@
#include "util/static_graph.hpp"
#include "util/typedefs.hpp"
#include "storage/shared_memory_ownership.hpp"
#include <boost/filesystem/path.hpp>
namespace osrm
@@ -16,16 +18,17 @@ namespace customizer
using EdgeBasedGraphEdgeData = partition::EdgeBasedGraphEdgeData;
struct MultiLevelEdgeBasedGraph : public partition::MultiLevelGraph<EdgeBasedGraphEdgeData, false>
struct MultiLevelEdgeBasedGraph
: public partition::MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::Container>
{
using Base = partition::MultiLevelGraph<EdgeBasedGraphEdgeData, false>;
using Base = partition::MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::Container>;
using Base::Base;
};
struct MultiLevelEdgeBasedGraphView
: public partition::MultiLevelGraph<EdgeBasedGraphEdgeData, true>
: public partition::MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::View>
{
using Base = partition::MultiLevelGraph<EdgeBasedGraphEdgeData, true>;
using Base = partition::MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::View>;
using Base::Base;
};
+14 -3
View File
@@ -2,6 +2,7 @@
#define ENGINE_API_MATCH_HPP
#include "engine/api/match_parameters.hpp"
#include "engine/api/match_parameters_tidy.hpp"
#include "engine/api/route_api.hpp"
#include "engine/datafacade/datafacade_base.hpp"
@@ -21,8 +22,10 @@ namespace api
class MatchAPI final : public RouteAPI
{
public:
MatchAPI(const datafacade::BaseDataFacade &facade_, const MatchParameters &parameters_)
: RouteAPI(facade_, parameters_), parameters(parameters_)
MatchAPI(const datafacade::BaseDataFacade &facade_,
const MatchParameters &parameters_,
const tidy::Result &tidy_result_)
: RouteAPI(facade_, parameters_), parameters(parameters_), tidy_result(tidy_result_)
{
}
@@ -83,13 +86,20 @@ class MatchAPI final : public RouteAPI
for (auto point_index : util::irange(
0u, static_cast<unsigned>(sub_matchings[sub_matching_index].indices.size())))
{
trace_idx_to_matching_idx[sub_matchings[sub_matching_index].indices[point_index]] =
trace_idx_to_matching_idx[tidy_result
.tidied_to_original[sub_matchings[sub_matching_index]
.indices[point_index]]] =
MatchingIndex{sub_matching_index, point_index};
}
}
for (auto trace_index : util::irange<std::size_t>(0UL, parameters.coordinates.size()))
{
if (tidy_result.can_be_removed[trace_index])
{
waypoints.values.push_back(util::json::Null());
continue;
}
auto matching_index = trace_idx_to_matching_idx[trace_index];
if (matching_index.NotMatched())
{
@@ -111,6 +121,7 @@ class MatchAPI final : public RouteAPI
}
const MatchParameters &parameters;
const tidy::Result &tidy_result;
};
} // ns api
+14 -3
View File
@@ -50,23 +50,34 @@ namespace api
*/
struct MatchParameters : public RouteParameters
{
enum class GapsType
{
Split,
Ignore
};
MatchParameters()
: RouteParameters(false,
false,
false,
RouteParameters::GeometriesType::Polyline,
RouteParameters::OverviewType::Simplified,
{})
{}),
gaps(GapsType::Split), tidy(false)
{
}
template <typename... Args>
MatchParameters(std::vector<unsigned> timestamps_, Args... args_)
: RouteParameters{std::forward<Args>(args_)...}, timestamps{std::move(timestamps_)}
MatchParameters(std::vector<unsigned> timestamps_, GapsType gaps_, bool tidy_, Args... args_)
: RouteParameters{std::forward<Args>(args_)...}, timestamps{std::move(timestamps_)},
gaps(gaps_), tidy(tidy_)
{
}
std::vector<unsigned> timestamps;
GapsType gaps;
bool tidy;
bool IsValid() const
{
return RouteParameters::IsValid() &&
@@ -0,0 +1,170 @@
#ifndef COORDINATE_TIDY
#define COORDINATE_TIDY
#include <algorithm>
#include <cstdint>
#include <iterator>
#include "engine/api/match_parameters.hpp"
#include "util/coordinate_calculation.hpp"
#include <boost/assert.hpp>
#include <boost/dynamic_bitset.hpp>
namespace osrm
{
namespace engine
{
namespace api
{
namespace tidy
{
struct Thresholds
{
double distance_in_meters;
std::int32_t duration_in_seconds;
};
using Mask = boost::dynamic_bitset<>;
using Mapping = std::vector<std::size_t>;
struct Result
{
// Tidied parameters
MatchParameters parameters;
// Masking the MatchParameter parallel arrays for items which should be removed.
Mask can_be_removed;
// Maps the MatchParameter's original items to items which should not be removed.
Mapping tidied_to_original;
};
inline Result keep_all(const MatchParameters &params)
{
Result result;
result.can_be_removed.resize(params.coordinates.size(), false);
result.tidied_to_original.reserve(params.coordinates.size());
for (std::size_t current = 0; current < params.coordinates.size(); ++current)
{
result.tidied_to_original.push_back(current);
}
BOOST_ASSERT(result.can_be_removed.size() == params.coordinates.size());
// We have to filter parallel arrays that may be empty or the exact same size.
// result.parameters contains an empty MatchParameters at this point: conditionally fill.
for (std::size_t i = 0; i < result.can_be_removed.size(); ++i)
{
if (!result.can_be_removed[i])
{
result.parameters.coordinates.push_back(params.coordinates[i]);
if (!params.hints.empty())
result.parameters.hints.push_back(params.hints[i]);
if (!params.radiuses.empty())
result.parameters.radiuses.push_back(params.radiuses[i]);
if (!params.bearings.empty())
result.parameters.bearings.push_back(params.bearings[i]);
if (!params.timestamps.empty())
result.parameters.timestamps.push_back(params.timestamps[i]);
}
}
return result;
}
inline Result tidy(const MatchParameters &params, Thresholds cfg = {15., 5})
{
Result result;
result.can_be_removed.resize(params.coordinates.size(), false);
result.tidied_to_original.push_back(0);
std::size_t last_good = 0;
const auto uses_timestamps = !params.timestamps.empty();
Thresholds running{0., 0};
// Walk over adjacent (coord, ts)-pairs, with rhs being the candidate to discard or keep
for (std::size_t current = 0; current < params.coordinates.size() - 1; ++current)
{
const auto next = current + 1;
auto distance_delta = util::coordinate_calculation::haversineDistance(
params.coordinates[current], params.coordinates[next]);
running.distance_in_meters += distance_delta;
const auto over_distance = running.distance_in_meters >= cfg.distance_in_meters;
if (uses_timestamps)
{
auto duration_delta = params.timestamps[next] - params.timestamps[current];
running.duration_in_seconds += duration_delta;
const auto over_duration = running.duration_in_seconds >= cfg.duration_in_seconds;
if (over_distance && over_duration)
{
last_good = next;
result.tidied_to_original.push_back(next);
running = {0., 0}; // reset running distance and time
}
else
{
result.can_be_removed.set(next, true);
}
}
else
{
if (over_distance)
{
last_good = next;
result.tidied_to_original.push_back(next);
running = {0., 0}; // reset running distance and time
}
else
{
result.can_be_removed.set(next, true);
}
}
}
BOOST_ASSERT(result.can_be_removed.size() == params.coordinates.size());
// We have to filter parallel arrays that may be empty or the exact same size.
// result.parameters contains an empty MatchParameters at this point: conditionally fill.
for (std::size_t i = 0; i < result.can_be_removed.size(); ++i)
{
if (!result.can_be_removed[i])
{
result.parameters.coordinates.push_back(params.coordinates[i]);
if (!params.hints.empty())
result.parameters.hints.push_back(params.hints[i]);
if (!params.radiuses.empty())
result.parameters.radiuses.push_back(params.radiuses[i]);
if (!params.bearings.empty())
result.parameters.bearings.push_back(params.bearings[i]);
if (!params.timestamps.empty())
result.parameters.timestamps.push_back(params.timestamps[i]);
}
}
BOOST_ASSERT(result.tidied_to_original.size() == result.parameters.coordinates.size());
return result;
}
} // ns tidy
} // ns api
} // ns engine
} // ns osrm
#endif
@@ -20,6 +20,7 @@
#include "partition/multi_level_partition.hpp"
#include "storage/shared_datatype.hpp"
#include "storage/shared_memory_ownership.hpp"
#include "util/exception.hpp"
#include "util/exception_utils.hpp"
@@ -61,7 +62,7 @@ class ContiguousInternalMemoryAlgorithmDataFacade<algorithm::CH>
: public datafacade::AlgorithmDataFacade<algorithm::CH>
{
private:
using QueryGraph = util::StaticGraph<EdgeData, true>;
using QueryGraph = util::StaticGraph<EdgeData, storage::Ownership::View>;
using GraphNode = QueryGraph::NodeArrayEntry;
using GraphEdge = QueryGraph::EdgeArrayEntry;
@@ -78,9 +79,9 @@ class ContiguousInternalMemoryAlgorithmDataFacade<algorithm::CH>
auto graph_edges_ptr = data_layout.GetBlockPtr<GraphEdge>(
memory_block, storage::DataLayout::CH_GRAPH_EDGE_LIST);
util::ShM<GraphNode, true>::vector node_list(
util::vector_view<GraphNode> node_list(
graph_nodes_ptr, data_layout.num_entries[storage::DataLayout::CH_GRAPH_NODE_LIST]);
util::ShM<GraphEdge, true>::vector edge_list(
util::vector_view<GraphEdge> edge_list(
graph_edges_ptr, data_layout.num_entries[storage::DataLayout::CH_GRAPH_EDGE_LIST]);
m_query_graph.reset(new QueryGraph(node_list, edge_list));
}
@@ -154,7 +155,7 @@ class ContiguousInternalMemoryAlgorithmDataFacade<algorithm::CoreCH>
: public datafacade::AlgorithmDataFacade<algorithm::CoreCH>
{
private:
util::ShM<bool, true>::vector m_is_core_node;
util::vector_view<bool> m_is_core_node;
// allocator that keeps the allocation data
std::shared_ptr<ContiguousBlockAllocator> allocator;
@@ -163,7 +164,7 @@ class ContiguousInternalMemoryAlgorithmDataFacade<algorithm::CoreCH>
{
auto core_marker_ptr =
data_layout.GetBlockPtr<unsigned>(memory_block, storage::DataLayout::CH_CORE_MARKER);
util::ShM<bool, true>::vector is_core_node(
util::vector_view<bool> is_core_node(
core_marker_ptr, data_layout.num_entries[storage::DataLayout::CH_CORE_MARKER]);
m_is_core_node = std::move(is_core_node);
}
@@ -199,10 +200,10 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
{
private:
using super = BaseDataFacade;
using IndexBlock = util::RangeTable<16, true>::BlockT;
using IndexBlock = util::RangeTable<16, storage::Ownership::View>::BlockT;
using RTreeLeaf = super::RTreeLeaf;
using SharedRTree =
util::StaticRTree<RTreeLeaf, util::ShM<util::Coordinate, true>::vector, true>;
util::StaticRTree<RTreeLeaf, util::vector_view<util::Coordinate>, storage::Ownership::View>;
using SharedGeospatialQuery = GeospatialQuery<SharedRTree, BaseDataFacade>;
using RTreeNode = SharedRTree::TreeNode;
@@ -211,28 +212,28 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
extractor::Datasources *m_datasources;
unsigned m_check_sum;
util::ShM<util::Coordinate, true>::vector m_coordinate_list;
util::PackedVector<OSMNodeID, true> m_osmnodeid_list;
util::ShM<GeometryID, true>::vector m_via_geometry_list;
util::ShM<NameID, true>::vector m_name_ID_list;
util::ShM<LaneDataID, true>::vector m_lane_data_id;
util::ShM<extractor::guidance::TurnInstruction, true>::vector m_turn_instruction_list;
util::ShM<extractor::TravelMode, true>::vector m_travel_mode_list;
util::ShM<util::guidance::TurnBearing, true>::vector m_pre_turn_bearing;
util::ShM<util::guidance::TurnBearing, true>::vector m_post_turn_bearing;
util::vector_view<util::Coordinate> m_coordinate_list;
util::PackedVector<OSMNodeID, storage::Ownership::View> m_osmnodeid_list;
util::vector_view<GeometryID> m_via_geometry_list;
util::vector_view<NameID> m_name_ID_list;
util::vector_view<LaneDataID> m_lane_data_id;
util::vector_view<extractor::guidance::TurnInstruction> m_turn_instruction_list;
util::vector_view<extractor::TravelMode> m_travel_mode_list;
util::vector_view<util::guidance::TurnBearing> m_pre_turn_bearing;
util::vector_view<util::guidance::TurnBearing> m_post_turn_bearing;
util::NameTable m_names_table;
util::ShM<unsigned, true>::vector m_name_begin_indices;
util::ShM<bool, true>::vector m_is_core_node;
util::ShM<std::uint32_t, true>::vector m_lane_description_offsets;
util::ShM<extractor::guidance::TurnLaneType::Mask, true>::vector m_lane_description_masks;
util::ShM<TurnPenalty, true>::vector m_turn_weight_penalties;
util::ShM<TurnPenalty, true>::vector m_turn_duration_penalties;
util::vector_view<unsigned> m_name_begin_indices;
util::vector_view<bool> m_is_core_node;
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;
util::vector_view<TurnPenalty> m_turn_duration_penalties;
extractor::SegmentDataView segment_data;
util::ShM<char, true>::vector m_datasource_name_data;
util::ShM<std::size_t, true>::vector m_datasource_name_offsets;
util::ShM<std::size_t, true>::vector m_datasource_name_lengths;
util::ShM<util::guidance::LaneTupleIdPair, true>::vector m_lane_tupel_id_pairs;
util::vector_view<char> m_datasource_name_data;
util::vector_view<std::size_t> m_datasource_name_offsets;
util::vector_view<std::size_t> m_datasource_name_lengths;
util::vector_view<util::guidance::LaneTupleIdPair> m_lane_tupel_id_pairs;
std::unique_ptr<SharedRTree> m_static_rtree;
std::unique_ptr<SharedGeospatialQuery> m_geospatial_query;
@@ -240,17 +241,17 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
util::NameTable m_name_table;
// bearing classes by node based node
util::ShM<BearingClassID, true>::vector m_bearing_class_id_table;
util::vector_view<BearingClassID> m_bearing_class_id_table;
// entry class IDs
util::ShM<EntryClassID, true>::vector m_entry_class_id_list;
util::vector_view<EntryClassID> m_entry_class_id_list;
// 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::ShM<util::guidance::EntryClass, true>::vector m_entry_class_table;
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, true>> m_bearing_ranges_table;
util::ShM<DiscreteBearing, true>::vector m_bearing_values_table;
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;
@@ -326,52 +327,52 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
const auto travel_mode_list_ptr = data_layout.GetBlockPtr<extractor::TravelMode>(
memory_block, storage::DataLayout::TRAVEL_MODE);
util::ShM<extractor::TravelMode, true>::vector travel_mode_list(
util::vector_view<extractor::TravelMode> travel_mode_list(
travel_mode_list_ptr, data_layout.num_entries[storage::DataLayout::TRAVEL_MODE]);
m_travel_mode_list = std::move(travel_mode_list);
const auto lane_data_id_ptr =
data_layout.GetBlockPtr<LaneDataID>(memory_block, storage::DataLayout::LANE_DATA_ID);
util::ShM<LaneDataID, true>::vector lane_data_id(
util::vector_view<LaneDataID> lane_data_id(
lane_data_id_ptr, data_layout.num_entries[storage::DataLayout::LANE_DATA_ID]);
m_lane_data_id = std::move(lane_data_id);
const auto lane_tupel_id_pair_ptr =
data_layout.GetBlockPtr<util::guidance::LaneTupleIdPair>(
memory_block, storage::DataLayout::TURN_LANE_DATA);
util::ShM<util::guidance::LaneTupleIdPair, true>::vector lane_tupel_id_pair(
util::vector_view<util::guidance::LaneTupleIdPair> lane_tupel_id_pair(
lane_tupel_id_pair_ptr, data_layout.num_entries[storage::DataLayout::TURN_LANE_DATA]);
m_lane_tupel_id_pairs = std::move(lane_tupel_id_pair);
const auto turn_instruction_list_ptr =
data_layout.GetBlockPtr<extractor::guidance::TurnInstruction>(
memory_block, storage::DataLayout::TURN_INSTRUCTION);
util::ShM<extractor::guidance::TurnInstruction, true>::vector turn_instruction_list(
util::vector_view<extractor::guidance::TurnInstruction> turn_instruction_list(
turn_instruction_list_ptr,
data_layout.num_entries[storage::DataLayout::TURN_INSTRUCTION]);
m_turn_instruction_list = std::move(turn_instruction_list);
const auto name_id_list_ptr =
data_layout.GetBlockPtr<NameID>(memory_block, storage::DataLayout::NAME_ID_LIST);
util::ShM<NameID, true>::vector name_id_list(
util::vector_view<NameID> name_id_list(
name_id_list_ptr, data_layout.num_entries[storage::DataLayout::NAME_ID_LIST]);
m_name_ID_list = std::move(name_id_list);
const auto entry_class_id_list_ptr =
data_layout.GetBlockPtr<EntryClassID>(memory_block, storage::DataLayout::ENTRY_CLASSID);
typename util::ShM<EntryClassID, true>::vector entry_class_id_list(
typename util::vector_view<EntryClassID> entry_class_id_list(
entry_class_id_list_ptr, data_layout.num_entries[storage::DataLayout::ENTRY_CLASSID]);
m_entry_class_id_list = std::move(entry_class_id_list);
const auto pre_turn_bearing_ptr = data_layout.GetBlockPtr<util::guidance::TurnBearing>(
memory_block, storage::DataLayout::PRE_TURN_BEARING);
typename util::ShM<util::guidance::TurnBearing, true>::vector pre_turn_bearing(
typename util::vector_view<util::guidance::TurnBearing> pre_turn_bearing(
pre_turn_bearing_ptr, data_layout.num_entries[storage::DataLayout::PRE_TURN_BEARING]);
m_pre_turn_bearing = std::move(pre_turn_bearing);
const auto post_turn_bearing_ptr = data_layout.GetBlockPtr<util::guidance::TurnBearing>(
memory_block, storage::DataLayout::POST_TURN_BEARING);
typename util::ShM<util::guidance::TurnBearing, true>::vector post_turn_bearing(
typename util::vector_view<util::guidance::TurnBearing> post_turn_bearing(
post_turn_bearing_ptr, data_layout.num_entries[storage::DataLayout::POST_TURN_BEARING]);
m_post_turn_bearing = std::move(post_turn_bearing);
}
@@ -380,7 +381,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
{
auto via_geometry_list_ptr =
data_layout.GetBlockPtr<GeometryID>(memory_block, storage::DataLayout::VIA_NODE_LIST);
util::ShM<GeometryID, true>::vector via_geometry_list(
util::vector_view<GeometryID> via_geometry_list(
via_geometry_list_ptr, data_layout.num_entries[storage::DataLayout::VIA_NODE_LIST]);
m_via_geometry_list = std::move(via_geometry_list);
}
@@ -398,14 +399,14 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
{
auto offsets_ptr = data_layout.GetBlockPtr<std::uint32_t>(
memory_block, storage::DataLayout::LANE_DESCRIPTION_OFFSETS);
util::ShM<std::uint32_t, true>::vector offsets(
util::vector_view<std::uint32_t> offsets(
offsets_ptr, data_layout.num_entries[storage::DataLayout::LANE_DESCRIPTION_OFFSETS]);
m_lane_description_offsets = std::move(offsets);
auto masks_ptr = data_layout.GetBlockPtr<extractor::guidance::TurnLaneType::Mask>(
memory_block, storage::DataLayout::LANE_DESCRIPTION_MASKS);
util::ShM<extractor::guidance::TurnLaneType::Mask, true>::vector masks(
util::vector_view<extractor::guidance::TurnLaneType::Mask> masks(
masks_ptr, data_layout.num_entries[storage::DataLayout::LANE_DESCRIPTION_MASKS]);
m_lane_description_masks = std::move(masks);
}
@@ -414,12 +415,12 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
{
auto turn_weight_penalties_ptr = data_layout.GetBlockPtr<TurnPenalty>(
memory_block, storage::DataLayout::TURN_WEIGHT_PENALTIES);
m_turn_weight_penalties = util::ShM<TurnPenalty, true>::vector(
m_turn_weight_penalties = util::vector_view<TurnPenalty>(
turn_weight_penalties_ptr,
data_layout.num_entries[storage::DataLayout::TURN_WEIGHT_PENALTIES]);
auto turn_duration_penalties_ptr = data_layout.GetBlockPtr<TurnPenalty>(
memory_block, storage::DataLayout::TURN_DURATION_PENALTIES);
m_turn_duration_penalties = util::ShM<TurnPenalty, true>::vector(
m_turn_duration_penalties = util::vector_view<TurnPenalty>(
turn_duration_penalties_ptr,
data_layout.num_entries[storage::DataLayout::TURN_DURATION_PENALTIES]);
}
@@ -428,42 +429,42 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
{
auto geometries_index_ptr =
data_layout.GetBlockPtr<unsigned>(memory_block, storage::DataLayout::GEOMETRIES_INDEX);
util::ShM<unsigned, true>::vector geometry_begin_indices(
util::vector_view<unsigned> geometry_begin_indices(
geometries_index_ptr, data_layout.num_entries[storage::DataLayout::GEOMETRIES_INDEX]);
auto geometries_node_list_ptr = data_layout.GetBlockPtr<NodeID>(
memory_block, storage::DataLayout::GEOMETRIES_NODE_LIST);
util::ShM<NodeID, true>::vector geometry_node_list(
util::vector_view<NodeID> geometry_node_list(
geometries_node_list_ptr,
data_layout.num_entries[storage::DataLayout::GEOMETRIES_NODE_LIST]);
auto geometries_fwd_weight_list_ptr = data_layout.GetBlockPtr<EdgeWeight>(
memory_block, storage::DataLayout::GEOMETRIES_FWD_WEIGHT_LIST);
util::ShM<EdgeWeight, true>::vector geometry_fwd_weight_list(
util::vector_view<EdgeWeight> geometry_fwd_weight_list(
geometries_fwd_weight_list_ptr,
data_layout.num_entries[storage::DataLayout::GEOMETRIES_FWD_WEIGHT_LIST]);
auto geometries_rev_weight_list_ptr = data_layout.GetBlockPtr<EdgeWeight>(
memory_block, storage::DataLayout::GEOMETRIES_REV_WEIGHT_LIST);
util::ShM<EdgeWeight, true>::vector geometry_rev_weight_list(
util::vector_view<EdgeWeight> geometry_rev_weight_list(
geometries_rev_weight_list_ptr,
data_layout.num_entries[storage::DataLayout::GEOMETRIES_REV_WEIGHT_LIST]);
auto geometries_fwd_duration_list_ptr = data_layout.GetBlockPtr<EdgeWeight>(
memory_block, storage::DataLayout::GEOMETRIES_FWD_DURATION_LIST);
util::ShM<EdgeWeight, true>::vector geometry_fwd_duration_list(
util::vector_view<EdgeWeight> geometry_fwd_duration_list(
geometries_fwd_duration_list_ptr,
data_layout.num_entries[storage::DataLayout::GEOMETRIES_FWD_DURATION_LIST]);
auto geometries_rev_duration_list_ptr = data_layout.GetBlockPtr<EdgeWeight>(
memory_block, storage::DataLayout::GEOMETRIES_REV_DURATION_LIST);
util::ShM<EdgeWeight, true>::vector geometry_rev_duration_list(
util::vector_view<EdgeWeight> geometry_rev_duration_list(
geometries_rev_duration_list_ptr,
data_layout.num_entries[storage::DataLayout::GEOMETRIES_REV_DURATION_LIST]);
auto datasources_list_ptr = data_layout.GetBlockPtr<DatasourceID>(
memory_block, storage::DataLayout::DATASOURCES_LIST);
util::ShM<DatasourceID, true>::vector datasources_list(
util::vector_view<DatasourceID> datasources_list(
datasources_list_ptr, data_layout.num_entries[storage::DataLayout::DATASOURCES_LIST]);
segment_data = extractor::SegmentDataView{std::move(geometry_begin_indices),
@@ -482,13 +483,13 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
{
auto bearing_class_id_ptr = data_layout.GetBlockPtr<BearingClassID>(
memory_block, storage::DataLayout::BEARING_CLASSID);
typename util::ShM<BearingClassID, true>::vector bearing_class_id_table(
typename util::vector_view<BearingClassID> bearing_class_id_table(
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>(
memory_block, storage::DataLayout::BEARING_VALUES);
typename util::ShM<DiscreteBearing, true>::vector bearing_class_table(
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);
@@ -496,17 +497,17 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
data_layout.GetBlockPtr<unsigned>(memory_block, storage::DataLayout::BEARING_OFFSETS);
auto blocks_ptr =
data_layout.GetBlockPtr<IndexBlock>(memory_block, storage::DataLayout::BEARING_BLOCKS);
util::ShM<unsigned, true>::vector bearing_offsets(
util::vector_view<unsigned> bearing_offsets(
offsets_ptr, data_layout.num_entries[storage::DataLayout::BEARING_OFFSETS]);
util::ShM<IndexBlock, true>::vector bearing_blocks(
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, true>>(
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()));
auto entry_class_ptr = data_layout.GetBlockPtr<util::guidance::EntryClass>(
memory_block, storage::DataLayout::ENTRY_CLASS);
typename util::ShM<util::guidance::EntryClass, true>::vector entry_class_table(
typename 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);
}
@@ -929,15 +930,13 @@ class ContiguousInternalMemoryAlgorithmDataFacade<algorithm::MLD>
memory_block, storage::DataLayout::MLD_PARTITION);
auto partition_entries_count =
data_layout.GetBlockEntries(storage::DataLayout::MLD_PARTITION);
util::ShM<PartitionID, true>::vector partition(mld_partition_ptr,
partition_entries_count);
util::vector_view<PartitionID> partition(mld_partition_ptr, partition_entries_count);
auto mld_chilren_ptr = data_layout.GetBlockPtr<CellID>(
memory_block, storage::DataLayout::MLD_CELL_TO_CHILDREN);
auto children_entries_count =
data_layout.GetBlockEntries(storage::DataLayout::MLD_CELL_TO_CHILDREN);
util::ShM<CellID, true>::vector cell_to_children(mld_chilren_ptr,
children_entries_count);
util::vector_view<CellID> cell_to_children(mld_chilren_ptr, children_entries_count);
mld_partition =
partition::MultiLevelPartitionView{level_data, partition, cell_to_children};
@@ -969,15 +968,15 @@ class ContiguousInternalMemoryAlgorithmDataFacade<algorithm::MLD>
auto cell_level_offsets_entries_count =
data_layout.GetBlockEntries(storage::DataLayout::MLD_CELL_LEVEL_OFFSETS);
util::ShM<EdgeWeight, true>::vector weights(mld_cell_weights_ptr, weight_entries_count);
util::ShM<NodeID, true>::vector source_boundary(mld_source_boundary_ptr,
source_boundary_entries_count);
util::ShM<NodeID, true>::vector destination_boundary(
mld_destination_boundary_ptr, destination_boundary_entries_count);
util::ShM<partition::CellStorageView::CellData, true>::vector cells(
mld_cells_ptr, cells_entries_counts);
util::ShM<std::uint64_t, true>::vector level_offsets(mld_cell_level_offsets_ptr,
cell_level_offsets_entries_count);
util::vector_view<EdgeWeight> weights(mld_cell_weights_ptr, weight_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,
destination_boundary_entries_count);
util::vector_view<partition::CellStorageView::CellData> cells(mld_cells_ptr,
cells_entries_counts);
util::vector_view<std::uint64_t> level_offsets(mld_cell_level_offsets_ptr,
cell_level_offsets_entries_count);
mld_cell_storage = partition::CellStorageView{std::move(weights),
std::move(source_boundary),
@@ -997,11 +996,11 @@ class ContiguousInternalMemoryAlgorithmDataFacade<algorithm::MLD>
auto graph_node_to_offset_ptr = data_layout.GetBlockPtr<QueryGraph::EdgeOffset>(
memory_block, storage::DataLayout::MLD_GRAPH_NODE_TO_OFFSET);
util::ShM<GraphNode, true>::vector node_list(
util::vector_view<GraphNode> node_list(
graph_nodes_ptr, data_layout.num_entries[storage::DataLayout::MLD_GRAPH_NODE_LIST]);
util::ShM<GraphEdge, true>::vector edge_list(
util::vector_view<GraphEdge> edge_list(
graph_edges_ptr, data_layout.num_entries[storage::DataLayout::MLD_GRAPH_EDGE_LIST]);
util::ShM<QueryGraph::EdgeOffset, true>::vector node_to_offset(
util::vector_view<QueryGraph::EdgeOffset> node_to_offset(
graph_node_to_offset_ptr,
data_layout.num_entries[storage::DataLayout::MLD_GRAPH_NODE_TO_OFFSET]);
+19 -10
View File
@@ -38,7 +38,8 @@ class RoutingAlgorithmsInterface
MapMatching(const routing_algorithms::CandidateLists &candidates_list,
const std::vector<util::Coordinate> &trace_coordinates,
const std::vector<unsigned> &trace_timestamps,
const std::vector<boost::optional<double>> &trace_gps_precision) const = 0;
const std::vector<boost::optional<double>> &trace_gps_precision,
const bool allow_splitting) const = 0;
virtual std::vector<routing_algorithms::TurnData>
GetTileTurns(const std::vector<datafacade::BaseDataFacade::RTreeLeaf> &edges,
@@ -79,11 +80,12 @@ template <typename AlgorithmT> class RoutingAlgorithms final : public RoutingAlg
const std::vector<std::size_t> &source_indices,
const std::vector<std::size_t> &target_indices) const final override;
routing_algorithms::SubMatchingList MapMatching(
const routing_algorithms::CandidateLists &candidates_list,
const std::vector<util::Coordinate> &trace_coordinates,
const std::vector<unsigned> &trace_timestamps,
const std::vector<boost::optional<double>> &trace_gps_precision) const final override;
routing_algorithms::SubMatchingList
MapMatching(const routing_algorithms::CandidateLists &candidates_list,
const std::vector<util::Coordinate> &trace_coordinates,
const std::vector<unsigned> &trace_timestamps,
const std::vector<boost::optional<double>> &trace_gps_precision,
const bool allow_splitting) const final override;
std::vector<routing_algorithms::TurnData>
GetTileTurns(const std::vector<datafacade::BaseDataFacade::RTreeLeaf> &edges,
@@ -163,10 +165,16 @@ inline routing_algorithms::SubMatchingList RoutingAlgorithms<AlgorithmT>::MapMat
const routing_algorithms::CandidateLists &candidates_list,
const std::vector<util::Coordinate> &trace_coordinates,
const std::vector<unsigned> &trace_timestamps,
const std::vector<boost::optional<double>> &trace_gps_precision) const
const std::vector<boost::optional<double>> &trace_gps_precision,
const bool allow_splitting) const
{
return routing_algorithms::mapMatching(
heaps, facade, candidates_list, trace_coordinates, trace_timestamps, trace_gps_precision);
return routing_algorithms::mapMatching(heaps,
facade,
candidates_list,
trace_coordinates,
trace_timestamps,
trace_gps_precision,
allow_splitting);
}
template <typename AlgorithmT>
@@ -207,7 +215,8 @@ inline routing_algorithms::SubMatchingList
RoutingAlgorithms<algorithm::MLD>::MapMatching(const routing_algorithms::CandidateLists &,
const std::vector<util::Coordinate> &,
const std::vector<unsigned> &,
const std::vector<boost::optional<double>> &) const
const std::vector<boost::optional<double>> &,
const bool) const
{
throw util::exception("MapMatching is not implemented");
}
@@ -28,7 +28,8 @@ mapMatching(SearchEngineData &engine_working_data,
const CandidateLists &candidates_list,
const std::vector<util::Coordinate> &trace_coordinates,
const std::vector<unsigned> &trace_timestamps,
const std::vector<boost::optional<double>> &trace_gps_precision);
const std::vector<boost::optional<double>> &trace_gps_precision,
const bool allow_splitting);
SubMatchingList
mapMatching(SearchEngineData &engine_working_data,
@@ -36,7 +37,8 @@ mapMatching(SearchEngineData &engine_working_data,
const CandidateLists &candidates_list,
const std::vector<util::Coordinate> &trace_coordinates,
const std::vector<unsigned> &trace_timestamps,
const std::vector<boost::optional<double>> &trace_gps_precision);
const std::vector<boost::optional<double>> &trace_gps_precision,
const bool allow_splitting);
}
}
}
+6 -13
View File
@@ -62,13 +62,6 @@ struct ExtractionWay
forward_restricted = false;
}
// These accessors exists because it's not possible to take the address of a bitfield,
// and LUA therefore cannot read/write the mode attributes directly.
void set_forward_mode(const TravelMode m) { forward_travel_mode = m; }
TravelMode get_forward_mode() const { return forward_travel_mode; }
void set_backward_mode(const TravelMode m) { backward_travel_mode = m; }
TravelMode get_backward_mode() const { return backward_travel_mode; }
// wrappers to allow assigning nil (nullptr) to string values
void SetName(const char *value) { detail::maybeSetString(name, value); }
const char *GetName() const { return name.c_str(); }
@@ -105,14 +98,14 @@ struct ExtractionWay
std::string destinations;
std::string turn_lanes_forward;
std::string turn_lanes_backward;
bool roundabout;
bool circular;
bool is_startpoint;
bool backward_restricted;
bool forward_restricted;
guidance::RoadClassification road_classification;
TravelMode forward_travel_mode : 4;
TravelMode backward_travel_mode : 4;
guidance::RoadClassification road_classification;
bool roundabout : 1;
bool circular : 1;
bool is_startpoint : 1;
bool forward_restricted : 1;
bool backward_restricted : 1;
};
}
}
@@ -63,6 +63,7 @@ class ExtractorCallbacks
guidance::LaneDescriptionMap lane_description_map;
ExtractionContainers &external_memory;
bool fallback_to_duration;
bool force_split_edges;
public:
explicit ExtractorCallbacks(ExtractionContainers &extraction_containers,
+1
View File
@@ -87,6 +87,7 @@ struct ProfileProperties
//! stores the name of the weight (e.g. 'duration', 'distance', 'safety')
char weight_name[MAX_WEIGHT_NAME_LENGTH + 1];
unsigned weight_precision = 1;
bool force_split_edges = false;
};
}
}
+15 -14
View File
@@ -4,6 +4,8 @@
#include "util/shared_memory_vector_wrapper.hpp"
#include "util/typedefs.hpp"
#include "storage/shared_memory_ownership.hpp"
#include <boost/filesystem/path.hpp>
#include <boost/range/adaptor/reversed.hpp>
#include <boost/range/iterator_range.hpp>
@@ -22,24 +24,24 @@ class CompressedEdgeContainer;
namespace detail
{
template <bool UseShareMemory> class SegmentDataContainerImpl;
template <storage::Ownership Ownership> class SegmentDataContainerImpl;
}
namespace io
{
template <bool UseShareMemory>
template <storage::Ownership Ownership>
inline void read(const boost::filesystem::path &path,
detail::SegmentDataContainerImpl<UseShareMemory> &segment_data);
template <bool UseShareMemory>
detail::SegmentDataContainerImpl<Ownership> &segment_data);
template <storage::Ownership Ownership>
inline void write(const boost::filesystem::path &path,
const detail::SegmentDataContainerImpl<UseShareMemory> &segment_data);
const detail::SegmentDataContainerImpl<Ownership> &segment_data);
}
namespace detail
{
template <bool UseShareMemory> class SegmentDataContainerImpl
template <storage::Ownership Ownership> class SegmentDataContainerImpl
{
template <typename T> using Vector = typename util::ShM<T, UseShareMemory>::vector;
template <typename T> using Vector = typename util::ShM<T, Ownership>::vector;
friend CompressedEdgeContainer;
@@ -188,12 +190,11 @@ template <bool UseShareMemory> class SegmentDataContainerImpl
auto GetNumberOfGeometries() const { return index.size() - 1; }
auto GetNumberOfSegments() const { return fwd_weights.size(); }
friend void io::read<Ownership>(const boost::filesystem::path &path,
detail::SegmentDataContainerImpl<Ownership> &segment_data);
friend void
io::read<UseShareMemory>(const boost::filesystem::path &path,
detail::SegmentDataContainerImpl<UseShareMemory> &segment_data);
friend void
io::write<UseShareMemory>(const boost::filesystem::path &path,
const detail::SegmentDataContainerImpl<UseShareMemory> &segment_data);
io::write<Ownership>(const boost::filesystem::path &path,
const detail::SegmentDataContainerImpl<Ownership> &segment_data);
private:
Vector<std::uint32_t> index;
@@ -206,8 +207,8 @@ template <bool UseShareMemory> class SegmentDataContainerImpl
};
}
using SegmentDataView = detail::SegmentDataContainerImpl<true>;
using SegmentDataContainer = detail::SegmentDataContainerImpl<false>;
using SegmentDataView = detail::SegmentDataContainerImpl<storage::Ownership::View>;
using SegmentDataContainer = detail::SegmentDataContainerImpl<storage::Ownership::Container>;
}
}
+76
View File
@@ -112,7 +112,13 @@ inline engine_config_ptr argumentsToEngineConfig(const Nan::FunctionCallbackInfo
auto params = Nan::To<v8::Object>(args[0]).ToLocalChecked();
auto path = params->Get(Nan::New("path").ToLocalChecked());
if (path.IsEmpty())
return engine_config_ptr();
auto shared_memory = params->Get(Nan::New("shared_memory").ToLocalChecked());
if (shared_memory.IsEmpty())
return engine_config_ptr();
if (!path->IsUndefined())
{
engine_config->storage_config =
@@ -140,6 +146,9 @@ inline engine_config_ptr argumentsToEngineConfig(const Nan::FunctionCallbackInfo
}
auto algorithm = params->Get(Nan::New("algorithm").ToLocalChecked());
if (algorithm.IsEmpty())
return engine_config_ptr();
if (algorithm->IsString())
{
auto algorithm_str = Nan::To<v8::String>(algorithm).ToLocalChecked();
@@ -180,6 +189,8 @@ parseCoordinateArray(const v8::Local<v8::Array> &coordinates_array)
for (uint32_t i = 0; i < coordinates_array->Length(); ++i)
{
v8::Local<v8::Value> coordinate = coordinates_array->Get(i);
if (coordinate.IsEmpty())
return resulting_coordinates;
if (!coordinate->IsArray())
{
@@ -247,6 +258,9 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
v8::Local<v8::Object> obj = Nan::To<v8::Object>(args[0]).ToLocalChecked();
v8::Local<v8::Value> coordinates = obj->Get(Nan::New("coordinates").ToLocalChecked());
if (coordinates.IsEmpty())
return false;
if (coordinates->IsUndefined())
{
Nan::ThrowError("Must provide a coordinates property");
@@ -287,6 +301,8 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
if (obj->Has(Nan::New("bearings").ToLocalChecked()))
{
v8::Local<v8::Value> bearings = obj->Get(Nan::New("bearings").ToLocalChecked());
if (bearings.IsEmpty())
return false;
if (!bearings->IsArray())
{
@@ -305,6 +321,8 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
for (uint32_t i = 0; i < bearings_array->Length(); ++i)
{
v8::Local<v8::Value> bearing_raw = bearings_array->Get(i);
if (bearing_raw.IsEmpty())
return false;
if (bearing_raw->IsNull())
{
@@ -349,6 +367,8 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
if (obj->Has(Nan::New("hints").ToLocalChecked()))
{
v8::Local<v8::Value> hints = obj->Get(Nan::New("hints").ToLocalChecked());
if (hints.IsEmpty())
return false;
if (!hints->IsArray())
{
@@ -367,6 +387,9 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
for (uint32_t i = 0; i < hints_array->Length(); ++i)
{
v8::Local<v8::Value> hint = hints_array->Get(i);
if (hint.IsEmpty())
return false;
if (hint->IsString())
{
if (hint->ToString()->Length() == 0)
@@ -393,6 +416,8 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
if (obj->Has(Nan::New("radiuses").ToLocalChecked()))
{
v8::Local<v8::Value> radiuses = obj->Get(Nan::New("radiuses").ToLocalChecked());
if (radiuses.IsEmpty())
return false;
if (!radiuses->IsArray())
{
@@ -411,6 +436,9 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
for (uint32_t i = 0; i < radiuses_array->Length(); ++i)
{
v8::Local<v8::Value> radius = radiuses_array->Get(i);
if (radius.IsEmpty())
return false;
if (radius->IsNull())
{
params->radiuses.emplace_back();
@@ -430,6 +458,8 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
if (obj->Has(Nan::New("generate_hints").ToLocalChecked()))
{
v8::Local<v8::Value> generate_hints = obj->Get(Nan::New("generate_hints").ToLocalChecked());
if (generate_hints.IsEmpty())
return false;
if (!generate_hints->IsBoolean())
{
@@ -449,6 +479,9 @@ inline bool parseCommonParameters(const v8::Local<v8::Object> &obj, ParamType &p
if (obj->Has(Nan::New("steps").ToLocalChecked()))
{
auto steps = obj->Get(Nan::New("steps").ToLocalChecked());
if (steps.IsEmpty())
return false;
if (steps->IsBoolean())
{
params->steps = steps->BooleanValue();
@@ -463,6 +496,9 @@ inline bool parseCommonParameters(const v8::Local<v8::Object> &obj, ParamType &p
if (obj->Has(Nan::New("annotations").ToLocalChecked()))
{
auto annotations = obj->Get(Nan::New("annotations").ToLocalChecked());
if (annotations.IsEmpty())
return false;
if (annotations->IsBoolean())
{
params->annotations = annotations->BooleanValue();
@@ -523,6 +559,8 @@ inline bool parseCommonParameters(const v8::Local<v8::Object> &obj, ParamType &p
if (obj->Has(Nan::New("geometries").ToLocalChecked()))
{
v8::Local<v8::Value> geometries = obj->Get(Nan::New("geometries").ToLocalChecked());
if (geometries.IsEmpty())
return false;
if (!geometries->IsString())
{
@@ -555,6 +593,8 @@ inline bool parseCommonParameters(const v8::Local<v8::Object> &obj, ParamType &p
if (obj->Has(Nan::New("overview").ToLocalChecked()))
{
v8::Local<v8::Value> overview = obj->Get(Nan::New("overview").ToLocalChecked());
if (overview.IsEmpty())
return false;
if (!overview->IsString())
{
@@ -601,9 +641,13 @@ argumentsToRouteParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
if (obj->Has(Nan::New("continue_straight").ToLocalChecked()))
{
auto value = obj->Get(Nan::New("continue_straight").ToLocalChecked());
if (value.IsEmpty())
return route_parameters_ptr();
if (!value->IsBoolean() && !value->IsNull())
{
Nan::ThrowError("'continue_straight' parama must be boolean or null");
return route_parameters_ptr();
}
if (value->IsBoolean())
{
@@ -614,9 +658,13 @@ argumentsToRouteParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
if (obj->Has(Nan::New("alternatives").ToLocalChecked()))
{
auto value = obj->Get(Nan::New("alternatives").ToLocalChecked());
if (value.IsEmpty())
return route_parameters_ptr();
if (!value->IsBoolean())
{
Nan::ThrowError("'alternatives' parama must be boolean");
return route_parameters_ptr();
}
params->alternatives = value->BooleanValue();
}
@@ -658,6 +706,8 @@ argumentsToTileParameters(const Nan::FunctionCallbackInfo<v8::Value> &args, bool
v8::Local<v8::Value> x = array->Get(0);
v8::Local<v8::Value> y = array->Get(1);
v8::Local<v8::Value> z = array->Get(2);
if (x.IsEmpty() || y.IsEmpty() || z.IsEmpty())
return tile_parameters_ptr();
if (!x->IsUint32() && !x->IsUndefined())
{
@@ -698,6 +748,8 @@ argumentsToNearestParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
return nearest_parameters_ptr();
v8::Local<v8::Object> obj = Nan::To<v8::Object>(args[0]).ToLocalChecked();
if (obj.IsEmpty())
return nearest_parameters_ptr();
if (obj->Has(Nan::New("number").ToLocalChecked()))
{
@@ -735,10 +787,14 @@ argumentsToTableParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
return table_parameters_ptr();
v8::Local<v8::Object> obj = Nan::To<v8::Object>(args[0]).ToLocalChecked();
if (obj.IsEmpty())
return table_parameters_ptr();
if (obj->Has(Nan::New("sources").ToLocalChecked()))
{
v8::Local<v8::Value> sources = obj->Get(Nan::New("sources").ToLocalChecked());
if (sources.IsEmpty())
return table_parameters_ptr();
if (!sources->IsArray())
{
@@ -750,6 +806,9 @@ argumentsToTableParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
for (uint32_t i = 0; i < sources_array->Length(); ++i)
{
v8::Local<v8::Value> source = sources_array->Get(i);
if (source.IsEmpty())
return table_parameters_ptr();
if (source->IsUint32())
{
size_t source_value = static_cast<size_t>(source->NumberValue());
@@ -773,6 +832,8 @@ argumentsToTableParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
if (obj->Has(Nan::New("destinations").ToLocalChecked()))
{
v8::Local<v8::Value> destinations = obj->Get(Nan::New("destinations").ToLocalChecked());
if (destinations.IsEmpty())
return table_parameters_ptr();
if (!destinations->IsArray())
{
@@ -784,6 +845,9 @@ argumentsToTableParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
for (uint32_t i = 0; i < destinations_array->Length(); ++i)
{
v8::Local<v8::Value> destination = destinations_array->Get(i);
if (destination.IsEmpty())
return table_parameters_ptr();
if (destination->IsUint32())
{
size_t destination_value = static_cast<size_t>(destination->NumberValue());
@@ -827,6 +891,9 @@ argumentsToTripParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
if (obj->Has(Nan::New("roundtrip").ToLocalChecked()))
{
auto roundtrip = obj->Get(Nan::New("roundtrip").ToLocalChecked());
if (roundtrip.IsEmpty())
return trip_parameters_ptr();
if (roundtrip->IsBoolean())
{
params->roundtrip = roundtrip->BooleanValue();
@@ -841,6 +908,8 @@ argumentsToTripParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
if (obj->Has(Nan::New("source").ToLocalChecked()))
{
v8::Local<v8::Value> source = obj->Get(Nan::New("source").ToLocalChecked());
if (source.IsEmpty())
return trip_parameters_ptr();
if (!source->IsString())
{
@@ -868,6 +937,8 @@ argumentsToTripParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
if (obj->Has(Nan::New("destination").ToLocalChecked()))
{
v8::Local<v8::Value> destination = obj->Get(Nan::New("destination").ToLocalChecked());
if (destination.IsEmpty())
return trip_parameters_ptr();
if (!destination->IsString())
{
@@ -909,6 +980,8 @@ argumentsToMatchParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
if (obj->Has(Nan::New("timestamps").ToLocalChecked()))
{
v8::Local<v8::Value> timestamps = obj->Get(Nan::New("timestamps").ToLocalChecked());
if (timestamps.IsEmpty())
return match_parameters_ptr();
if (!timestamps->IsArray())
{
@@ -928,6 +1001,9 @@ argumentsToMatchParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
for (uint32_t i = 0; i < timestamps_array->Length(); ++i)
{
v8::Local<v8::Value> timestamp = timestamps_array->Get(i);
if (timestamp.IsEmpty())
return match_parameters_ptr();
if (!timestamp->IsNumber())
{
Nan::ThrowError("Timestamps array items must be numbers");
+19 -17
View File
@@ -10,6 +10,7 @@
#include "util/typedefs.hpp"
#include "storage/io.hpp"
#include "storage/shared_memory_ownership.hpp"
#include <boost/iterator/iterator_facade.hpp>
#include <boost/range/iterator_range.hpp>
@@ -26,24 +27,23 @@ namespace partition
{
namespace detail
{
template <bool UseShareMemory> class CellStorageImpl;
template <storage::Ownership Ownership> class CellStorageImpl;
}
using CellStorage = detail::CellStorageImpl<false>;
using CellStorageView = detail::CellStorageImpl<true>;
using CellStorage = detail::CellStorageImpl<storage::Ownership::Container>;
using CellStorageView = detail::CellStorageImpl<storage::Ownership::View>;
namespace io
{
template <bool UseShareMemory>
inline void read(const boost::filesystem::path &path,
detail::CellStorageImpl<UseShareMemory> &storage);
template <bool UseShareMemory>
template <storage::Ownership Ownership>
inline void read(const boost::filesystem::path &path, detail::CellStorageImpl<Ownership> &storage);
template <storage::Ownership Ownership>
inline void write(const boost::filesystem::path &path,
const detail::CellStorageImpl<UseShareMemory> &storage);
const detail::CellStorageImpl<Ownership> &storage);
}
namespace detail
{
template <bool UseShareMemory> class CellStorageImpl
template <storage::Ownership Ownership> class CellStorageImpl
{
public:
using WeightOffset = std::uint32_t;
@@ -65,7 +65,7 @@ template <bool UseShareMemory> class CellStorageImpl
};
private:
template <typename T> using Vector = typename util::ShM<T, UseShareMemory>::vector;
template <typename T> using Vector = typename util::ShM<T, Ownership>::vector;
// 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.
@@ -185,7 +185,8 @@ template <bool UseShareMemory> class CellStorageImpl
CellStorageImpl() {}
template <typename GraphT, typename = std::enable_if<!UseShareMemory>>
template <typename GraphT,
typename = std::enable_if<Ownership == storage::Ownership::Container>>
CellStorageImpl(const partition::MultiLevelPartition &partition, const GraphT &base_graph)
{
// pre-allocate storge for CellData so we can have random access to it by cell id
@@ -314,7 +315,7 @@ template <bool UseShareMemory> class CellStorageImpl
weights.resize(weight_offset + 1, INVALID_EDGE_WEIGHT);
}
template <typename = std::enable_if<UseShareMemory>>
template <typename = std::enable_if<Ownership == storage::Ownership::View>>
CellStorageImpl(Vector<EdgeWeight> weights_,
Vector<NodeID> source_boundary_,
Vector<NodeID> destination_boundary_,
@@ -339,7 +340,8 @@ template <bool UseShareMemory> class CellStorageImpl
destination_boundary.empty() ? nullptr : destination_boundary.data()};
}
template <typename = std::enable_if<!UseShareMemory>> Cell GetCell(LevelID level, CellID id)
template <typename = std::enable_if<Ownership == storage::Ownership::Container>>
Cell GetCell(LevelID level, CellID id)
{
const auto level_index = LevelIDToIndex(level);
BOOST_ASSERT(level_index < level_to_cell_offset.size());
@@ -350,10 +352,10 @@ template <bool UseShareMemory> class CellStorageImpl
cells[cell_index], weights.data(), source_boundary.data(), destination_boundary.data()};
}
friend void io::read<UseShareMemory>(const boost::filesystem::path &path,
detail::CellStorageImpl<UseShareMemory> &storage);
friend void io::write<UseShareMemory>(const boost::filesystem::path &path,
const detail::CellStorageImpl<UseShareMemory> &storage);
friend void io::read<Ownership>(const boost::filesystem::path &path,
detail::CellStorageImpl<Ownership> &storage);
friend void io::write<Ownership>(const boost::filesystem::path &path,
const detail::CellStorageImpl<Ownership> &storage);
private:
Vector<EdgeWeight> weights;
+5 -5
View File
@@ -7,6 +7,7 @@
#include "partition/multi_level_partition.hpp"
#include "storage/io.hpp"
#include "storage/shared_memory_ownership.hpp"
namespace osrm
{
@@ -15,9 +16,8 @@ namespace partition
namespace io
{
template <typename EdgeDataT, bool UseSharedMemory>
inline void read(const boost::filesystem::path &path,
MultiLevelGraph<EdgeDataT, UseSharedMemory> &graph)
template <typename EdgeDataT, storage::Ownership Ownership>
inline void read(const boost::filesystem::path &path, MultiLevelGraph<EdgeDataT, Ownership> &graph)
{
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
storage::io::FileReader reader{path, fingerprint};
@@ -27,9 +27,9 @@ inline void read(const boost::filesystem::path &path,
reader.DeserializeVector(graph.edge_to_level);
}
template <typename EdgeDataT, bool UseSharedMemory>
template <typename EdgeDataT, storage::Ownership Ownership>
inline void write(const boost::filesystem::path &path,
const MultiLevelGraph<EdgeDataT, UseSharedMemory> &graph)
const MultiLevelGraph<EdgeDataT, Ownership> &graph)
{
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint;
storage::io::FileWriter writer{path, fingerprint};
+24 -17
View File
@@ -3,6 +3,8 @@
#include "partition/multi_level_partition.hpp"
#include "storage/shared_memory_ownership.hpp"
#include "util/static_graph.hpp"
#include <tbb/parallel_sort.h>
@@ -14,24 +16,23 @@ namespace osrm
{
namespace partition
{
template <typename EdgeDataT, bool UseSharedMemory> class MultiLevelGraph;
template <typename EdgeDataT, storage::Ownership Ownership> class MultiLevelGraph;
namespace io
{
template <typename EdgeDataT, bool UseSharedMemory>
void read(const boost::filesystem::path &path, MultiLevelGraph<EdgeDataT, UseSharedMemory> &graph);
template <typename EdgeDataT, storage::Ownership Ownership>
void read(const boost::filesystem::path &path, MultiLevelGraph<EdgeDataT, Ownership> &graph);
template <typename EdgeDataT, bool UseSharedMemory>
void write(const boost::filesystem::path &path,
const MultiLevelGraph<EdgeDataT, UseSharedMemory> &graph);
template <typename EdgeDataT, storage::Ownership Ownership>
void write(const boost::filesystem::path &path, const MultiLevelGraph<EdgeDataT, Ownership> &graph);
}
template <typename EdgeDataT, bool UseSharedMemory>
class MultiLevelGraph : public util::StaticGraph<EdgeDataT, UseSharedMemory>
template <typename EdgeDataT, storage::Ownership Ownership>
class MultiLevelGraph : public util::StaticGraph<EdgeDataT, Ownership>
{
private:
using SuperT = util::StaticGraph<EdgeDataT, UseSharedMemory>;
template <typename T> using Vector = typename util::ShM<T, UseSharedMemory>::vector;
using SuperT = util::StaticGraph<EdgeDataT, Ownership>;
template <typename T> using Vector = typename util::ShM<T, Ownership>::vector;
public:
// We limit each node to have 255 edges
@@ -110,9 +111,17 @@ class MultiLevelGraph : public util::StaticGraph<EdgeDataT, UseSharedMemory>
// which can be smaller then the total number of nodes.
// this will save memory in case we sort the border nodes first
if (index >= node_to_edge_offset.size() - 1)
return SuperT::BeginEdges(node);
{
// On level 0 all edges are border edges
if (level == 0)
return SuperT::BeginEdges(node);
else
return SuperT::EndEdges(node);
}
else
{
return SuperT::BeginEdges(node) + node_to_edge_offset[index + level];
}
}
// We save the level as sentinel at the end
@@ -181,12 +190,10 @@ class MultiLevelGraph : public util::StaticGraph<EdgeDataT, UseSharedMemory>
node_to_edge_offset.push_back(mlp.GetNumberOfLevels());
}
friend void
io::read<EdgeDataT, UseSharedMemory>(const boost::filesystem::path &path,
MultiLevelGraph<EdgeDataT, UseSharedMemory> &graph);
friend void
io::write<EdgeDataT, UseSharedMemory>(const boost::filesystem::path &path,
const MultiLevelGraph<EdgeDataT, UseSharedMemory> &graph);
friend void io::read<EdgeDataT, Ownership>(const boost::filesystem::path &path,
MultiLevelGraph<EdgeDataT, Ownership> &graph);
friend void io::write<EdgeDataT, Ownership>(const boost::filesystem::path &path,
const MultiLevelGraph<EdgeDataT, Ownership> &graph);
Vector<EdgeOffset> node_to_edge_offset;
};
+16 -16
View File
@@ -8,6 +8,7 @@
#include "util/typedefs.hpp"
#include "storage/io.hpp"
#include "storage/shared_memory_ownership.hpp"
#include <algorithm>
#include <array>
@@ -25,31 +26,30 @@ namespace partition
{
namespace detail
{
template <bool UseShareMemory> class MultiLevelPartitionImpl;
template <storage::Ownership Ownership> class MultiLevelPartitionImpl;
}
using MultiLevelPartition = detail::MultiLevelPartitionImpl<false>;
using MultiLevelPartitionView = detail::MultiLevelPartitionImpl<true>;
using MultiLevelPartition = detail::MultiLevelPartitionImpl<storage::Ownership::Container>;
using MultiLevelPartitionView = detail::MultiLevelPartitionImpl<storage::Ownership::View>;
namespace io
{
template <bool UseShareMemory>
void read(const boost::filesystem::path &file,
detail::MultiLevelPartitionImpl<UseShareMemory> &mlp);
template <bool UseShareMemory>
template <storage::Ownership Ownership>
void read(const boost::filesystem::path &file, detail::MultiLevelPartitionImpl<Ownership> &mlp);
template <storage::Ownership Ownership>
void write(const boost::filesystem::path &file,
const detail::MultiLevelPartitionImpl<UseShareMemory> &mlp);
const detail::MultiLevelPartitionImpl<Ownership> &mlp);
}
namespace detail
{
template <bool UseShareMemory> class MultiLevelPartitionImpl final
template <storage::Ownership Ownership> class MultiLevelPartitionImpl final
{
// we will support at most 16 levels
static const constexpr std::uint8_t MAX_NUM_LEVEL = 16;
static const constexpr std::uint8_t NUM_PARTITION_BITS = sizeof(PartitionID) * CHAR_BIT;
template <typename T> using Vector = typename util::ShM<T, UseShareMemory>::vector;
template <typename T> using Vector = typename util::ShM<T, Ownership>::vector;
public:
// Contains all data necessary to describe the level hierarchy
@@ -68,7 +68,7 @@ template <bool UseShareMemory> class MultiLevelPartitionImpl final
// cell_sizes is index by level (starting at 0, the base graph).
// However level 0 always needs to have cell size 1, since it is the
// basegraph.
template <typename = typename std::enable_if<!UseShareMemory>>
template <typename = typename std::enable_if<Ownership == storage::Ownership::Container>>
MultiLevelPartitionImpl(const std::vector<std::vector<CellID>> &partitions,
const std::vector<std::uint32_t> &lidx_to_num_cells)
: level_data(MakeLevelData(lidx_to_num_cells))
@@ -76,7 +76,7 @@ template <bool UseShareMemory> class MultiLevelPartitionImpl final
InitializePartitionIDs(partitions);
}
template <typename = typename std::enable_if<UseShareMemory>>
template <typename = typename std::enable_if<Ownership == storage::Ownership::View>>
MultiLevelPartitionImpl(LevelData level_data,
Vector<PartitionID> partition_,
Vector<CellID> cell_to_children_)
@@ -134,10 +134,10 @@ template <bool UseShareMemory> class MultiLevelPartitionImpl final
return cell_to_children[offset + cell + 1];
}
friend void io::read<UseShareMemory>(const boost::filesystem::path &file,
MultiLevelPartitionImpl &mlp);
friend void io::write<UseShareMemory>(const boost::filesystem::path &file,
const MultiLevelPartitionImpl &mlp);
friend void io::read<Ownership>(const boost::filesystem::path &file,
MultiLevelPartitionImpl &mlp);
friend void io::write<Ownership>(const boost::filesystem::path &file,
const MultiLevelPartitionImpl &mlp);
private:
auto MakeLevelData(const std::vector<std::uint32_t> &lidx_to_num_cells)
+7 -2
View File
@@ -13,7 +13,12 @@ namespace partition
struct PartitionConfig
{
PartitionConfig() : requested_num_threads(0) {}
PartitionConfig()
: requested_num_threads(0), balance(1.2), boundary_factor(0.25), num_optimizing_cuts(10),
small_component_size(1000),
max_cell_sizes{128, 128 * 32, 128 * 32 * 16, 128 * 32 * 16 * 32}
{
}
void UseDefaults()
{
@@ -49,11 +54,11 @@ struct PartitionConfig
unsigned requested_num_threads;
std::size_t minimum_cell_size;
double balance;
double boundary_factor;
std::size_t num_optimizing_cuts;
std::size_t small_component_size;
std::vector<std::size_t> max_cell_sizes;
};
}
}
+13 -2
View File
@@ -33,13 +33,24 @@ struct MatchParametersGrammar final : public RouteParametersGrammar<Iterator, Si
(qi::uint_ %
';')[ph::bind(&engine::api::MatchParameters::timestamps, qi::_r1) = qi::_1];
root_rule = BaseGrammar::query_rule(qi::_r1) > -qi::lit(".json") >
-('?' > (timestamps_rule(qi::_r1) | BaseGrammar::base_rule(qi::_r1)) % '&');
gaps_type.add("split", engine::api::MatchParameters::GapsType::Split)(
"ignore", engine::api::MatchParameters::GapsType::Ignore);
root_rule =
BaseGrammar::query_rule(qi::_r1) > -qi::lit(".json") >
-('?' > (timestamps_rule(qi::_r1) | BaseGrammar::base_rule(qi::_r1) |
(qi::lit("gaps=") >
gaps_type[ph::bind(&engine::api::MatchParameters::gaps, qi::_r1) = qi::_1]) |
(qi::lit("tidy=") >
qi::bool_[ph::bind(&engine::api::MatchParameters::tidy, qi::_r1) = qi::_1])) %
'&');
}
private:
qi::rule<Iterator, Signature> root_rule;
qi::rule<Iterator, Signature> timestamps_rule;
qi::symbols<char, engine::api::MatchParameters::GapsType> gaps_type;
};
}
}
+5 -3
View File
@@ -25,6 +25,8 @@
#include <exception>
#include <thread>
#include "storage/shared_memory_ownership.hpp"
namespace osrm
{
namespace storage
@@ -151,7 +153,7 @@ class SharedMemory
#else
void WaitForDetach()
{
util::Log(logWARNING)
util::Log(logDEBUG)
<< "Shared memory support for non-Linux systems does not wait for clients to "
"dettach. Going to sleep for 50ms.";
std::this_thread::sleep_for(std::chrono::milliseconds(50));
@@ -245,8 +247,8 @@ class SharedMemory
void WaitForDetach()
{
// FIXME this needs an implementation for Windows
util::Log(logWARNING) << "Shared memory support for Windows does not wait for clients to "
"dettach. Going to sleep for 50ms.";
util::Log(logDEBUG) << "Shared memory support for Windows does not wait for clients to "
"dettach. Going to sleep for 50ms.";
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
@@ -0,0 +1,17 @@
#ifndef SHARED_MEMORY_OWNERSHIP_HPP
#define SHARED_MEMORY_OWNERSHIP_HPP
namespace osrm
{
namespace storage
{
enum class Ownership
{
Container,
View
};
}
}
#endif // SHARED_MEMORY_OWNERSHIP_HPP
+14 -11
View File
@@ -4,6 +4,8 @@
#include "util/shared_memory_vector_wrapper.hpp"
#include "util/typedefs.hpp"
#include "storage/shared_memory_ownership.hpp"
#include <cmath>
#include <vector>
@@ -20,7 +22,8 @@ namespace util
* NOTE: this type is templated for future use, but will require a slight refactor to
* configure BITSIZE and ELEMSIZE
*/
template <typename T, bool UseSharedMemory = false> class PackedVector
template <typename T, storage::Ownership Ownership = storage::Ownership::Container>
class PackedVector
{
static const constexpr std::size_t BITSIZE = 33;
static const constexpr std::size_t ELEMSIZE = 64;
@@ -120,20 +123,20 @@ template <typename T, bool UseSharedMemory = false> class PackedVector
std::size_t size() const { return num_elements; }
template <bool enabled = UseSharedMemory>
template <bool enabled = (Ownership == storage::Ownership::View)>
void reserve(typename std::enable_if<!enabled, std::size_t>::type capacity)
{
vec.reserve(elements_to_blocks(capacity));
}
template <bool enabled = UseSharedMemory>
template <bool enabled = (Ownership == storage::Ownership::View)>
void reset(typename std::enable_if<enabled, std::uint64_t>::type *ptr,
typename std::enable_if<enabled, std::size_t>::type size)
{
vec.reset(ptr, size);
}
template <bool enabled = UseSharedMemory>
template <bool enabled = (Ownership == storage::Ownership::View)>
void set_number_of_entries(typename std::enable_if<enabled, std::size_t>::type count)
{
num_elements = count;
@@ -145,44 +148,44 @@ template <typename T, bool UseSharedMemory = false> class PackedVector
}
private:
typename util::ShM<std::uint64_t, UseSharedMemory>::vector vec;
typename util::ShM<std::uint64_t, Ownership>::vector vec;
std::size_t num_elements = 0;
signed cursor = -1;
template <bool enabled = UseSharedMemory>
template <bool enabled = (Ownership == storage::Ownership::View)>
void replace_last_elem(typename std::enable_if<enabled, std::uint64_t>::type last_elem)
{
vec[cursor] = last_elem;
}
template <bool enabled = UseSharedMemory>
template <bool enabled = (Ownership == storage::Ownership::View)>
void replace_last_elem(typename std::enable_if<!enabled, std::uint64_t>::type last_elem)
{
vec.back() = last_elem;
}
template <bool enabled = UseSharedMemory>
template <bool enabled = (Ownership == storage::Ownership::View)>
void add_last_elem(typename std::enable_if<enabled, std::uint64_t>::type last_elem)
{
vec[cursor + 1] = last_elem;
cursor++;
}
template <bool enabled = UseSharedMemory>
template <bool enabled = (Ownership == storage::Ownership::View)>
void add_last_elem(typename std::enable_if<!enabled, std::uint64_t>::type last_elem)
{
vec.push_back(last_elem);
}
template <bool enabled = UseSharedMemory>
template <bool enabled = (Ownership == storage::Ownership::View)>
std::uint64_t vec_back(typename std::enable_if<enabled>::type * = nullptr)
{
return vec[cursor];
}
template <bool enabled = UseSharedMemory>
template <bool enabled = (Ownership == storage::Ownership::View)>
std::uint64_t vec_back(typename std::enable_if<!enabled>::type * = nullptr)
{
return vec.back();
+18 -17
View File
@@ -2,6 +2,7 @@
#define RANGE_TABLE_HPP
#include "storage/io.hpp"
#include "storage/shared_memory_ownership.hpp"
#include "util/integer_range.hpp"
#include "util/shared_memory_vector_wrapper.hpp"
@@ -18,13 +19,14 @@ namespace util
* and otherwise the compiler gets confused.
*/
template <unsigned BLOCK_SIZE = 16, bool USE_SHARED_MEMORY = false> class RangeTable;
template <unsigned BLOCK_SIZE = 16, storage::Ownership Ownership = storage::Ownership::Container>
class RangeTable;
template <unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::ostream &operator<<(std::ostream &out, const RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table);
template <unsigned BLOCK_SIZE, storage::Ownership Ownership>
std::ostream &operator<<(std::ostream &out, const RangeTable<BLOCK_SIZE, Ownership> &table);
template <unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::istream &operator>>(std::istream &in, RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table);
template <unsigned BLOCK_SIZE, storage::Ownership Ownership>
std::istream &operator>>(std::istream &in, RangeTable<BLOCK_SIZE, Ownership> &table);
/**
* Stores adjacent ranges in a compressed format.
@@ -35,12 +37,12 @@ std::istream &operator>>(std::istream &in, RangeTable<BLOCK_SIZE, USE_SHARED_MEM
* But each block consists of an absolute value and BLOCK_SIZE differential values.
* So the effective block size is sizeof(unsigned) + BLOCK_SIZE.
*/
template <unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY> class RangeTable
template <unsigned BLOCK_SIZE, storage::Ownership Ownership> class RangeTable
{
public:
using BlockT = std::array<unsigned char, BLOCK_SIZE>;
using BlockContainerT = typename ShM<BlockT, USE_SHARED_MEMORY>::vector;
using OffsetContainerT = typename ShM<unsigned, USE_SHARED_MEMORY>::vector;
using BlockContainerT = typename ShM<BlockT, Ownership>::vector;
using OffsetContainerT = typename ShM<unsigned, Ownership>::vector;
using RangeT = range<unsigned>;
friend std::ostream &operator<<<>(std::ostream &out, const RangeTable &table);
@@ -139,7 +141,7 @@ template <unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY> class RangeTable
sum_lengths = lengths_prefix_sum;
}
void Write(osrm::storage::io::FileWriter &filewriter)
void Write(storage::io::FileWriter &filewriter)
{
unsigned number_of_blocks = diff_blocks.size();
@@ -151,7 +153,7 @@ template <unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY> class RangeTable
filewriter.WriteFrom(diff_blocks.data(), number_of_blocks);
}
void Read(osrm::storage::io::FileReader &filereader)
void Read(storage::io::FileReader &filereader)
{
unsigned number_of_blocks = filereader.ReadElementCount32();
// read total length
@@ -212,9 +214,8 @@ template <unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY> class RangeTable
unsigned sum_lengths;
};
template <unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
unsigned RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY>::PrefixSumAtIndex(int index,
const BlockT &block) const
template <unsigned BLOCK_SIZE, storage::Ownership Ownership>
unsigned RangeTable<BLOCK_SIZE, Ownership>::PrefixSumAtIndex(int index, const BlockT &block) const
{
// this loop looks inefficent, but a modern compiler
// will emit nice SIMD here, at least for sensible block sizes. (I checked.)
@@ -227,8 +228,8 @@ unsigned RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY>::PrefixSumAtIndex(int index,
return sum;
}
template <unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::ostream &operator<<(std::ostream &out, const RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table)
template <unsigned BLOCK_SIZE, storage::Ownership Ownership>
std::ostream &operator<<(std::ostream &out, const RangeTable<BLOCK_SIZE, Ownership> &table)
{
// write number of block
const unsigned number_of_blocks = table.diff_blocks.size();
@@ -243,8 +244,8 @@ std::ostream &operator<<(std::ostream &out, const RangeTable<BLOCK_SIZE, USE_SHA
return out;
}
template <unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::istream &operator>>(std::istream &in, RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table)
template <unsigned BLOCK_SIZE, storage::Ownership Ownership>
std::istream &operator>>(std::istream &in, RangeTable<BLOCK_SIZE, Ownership> &table)
{
// read number of block
unsigned number_of_blocks;
+15 -16
View File
@@ -3,6 +3,8 @@
#include "util/log.hpp"
#include "storage/shared_memory_ownership.hpp"
#include <boost/assert.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/reverse_iterator.hpp>
@@ -52,7 +54,7 @@ class ShMemIterator
DataT *m_value;
};
template <typename DataT> class SharedMemoryWrapper
template <typename DataT> class vector_view
{
private:
DataT *m_ptr;
@@ -64,9 +66,9 @@ template <typename DataT> class SharedMemoryWrapper
using const_iterator = ShMemIterator<const DataT>;
using reverse_iterator = boost::reverse_iterator<iterator>;
SharedMemoryWrapper() : m_ptr(nullptr), m_size(0) {}
vector_view() : m_ptr(nullptr), m_size(0) {}
SharedMemoryWrapper(DataT *ptr, std::size_t size) : m_ptr(ptr), m_size(size) {}
vector_view(DataT *ptr, std::size_t size) : m_ptr(ptr), m_size(size) {}
void reset(DataT *ptr, std::size_t size)
{
@@ -126,20 +128,19 @@ template <typename DataT> class SharedMemoryWrapper
auto data() const { return m_ptr; }
template <typename T>
friend void swap(SharedMemoryWrapper<T> &, SharedMemoryWrapper<T> &) noexcept;
template <typename T> friend void swap(vector_view<T> &, vector_view<T> &) noexcept;
};
template <> class SharedMemoryWrapper<bool>
template <> class vector_view<bool>
{
private:
unsigned *m_ptr;
std::size_t m_size;
public:
SharedMemoryWrapper() : m_ptr(nullptr), m_size(0) {}
vector_view() : m_ptr(nullptr), m_size(0) {}
SharedMemoryWrapper(unsigned *ptr, std::size_t size) : m_ptr(ptr), m_size(size) {}
vector_view(unsigned *ptr, std::size_t size) : m_ptr(ptr), m_size(size) {}
bool at(const std::size_t index) const
{
@@ -161,22 +162,20 @@ template <> class SharedMemoryWrapper<bool>
bool operator[](const unsigned index) const { return at(index); }
template <typename T>
friend void swap(SharedMemoryWrapper<T> &, SharedMemoryWrapper<T> &) noexcept;
template <typename T> friend void swap(vector_view<T> &, vector_view<T> &) noexcept;
};
// Both SharedMemoryWrapper<T> and the SharedMemoryWrapper<bool> specializations share this impl.
template <typename DataT>
void swap(SharedMemoryWrapper<DataT> &lhs, SharedMemoryWrapper<DataT> &rhs) noexcept
// Both vector_view<T> and the vector_view<bool> specializations share this impl.
template <typename DataT> void swap(vector_view<DataT> &lhs, vector_view<DataT> &rhs) noexcept
{
std::swap(lhs.m_ptr, rhs.m_ptr);
std::swap(lhs.m_size, rhs.m_size);
}
template <typename DataT, bool UseSharedMemory> struct ShM
template <typename DataT, storage::Ownership Ownership> struct ShM
{
using vector = typename std::conditional<UseSharedMemory,
SharedMemoryWrapper<DataT>,
using vector = typename std::conditional<Ownership == storage::Ownership::View,
vector_view<DataT>,
std::vector<DataT>>::type;
};
}
+8 -5
View File
@@ -7,6 +7,8 @@
#include "util/shared_memory_vector_wrapper.hpp"
#include "util/typedefs.hpp"
#include "storage/shared_memory_ownership.hpp"
#include <boost/assert.hpp>
#include <algorithm>
@@ -97,7 +99,8 @@ EntryT edgeToEntry(const OtherEdge &from, std::false_type)
} // namespace static_graph_details
template <typename EdgeDataT, bool UseSharedMemory = false> class StaticGraph
template <typename EdgeDataT, storage::Ownership Ownership = storage::Ownership::Container>
class StaticGraph
{
public:
using InputEdge = static_graph_details::SortableEdgeWithData<EdgeDataT>;
@@ -122,8 +125,8 @@ template <typename EdgeDataT, bool UseSharedMemory = false> class StaticGraph
InitializeFromSortedEdgeRange(nodes, edges.begin(), edges.end());
}
StaticGraph(typename ShM<NodeArrayEntry, UseSharedMemory>::vector node_array_,
typename ShM<EdgeArrayEntry, UseSharedMemory>::vector edge_array_)
StaticGraph(typename util::ShM<NodeArrayEntry, Ownership>::vector node_array_,
typename util::ShM<EdgeArrayEntry, Ownership>::vector edge_array_)
: node_array(std::move(node_array_)), edge_array(std::move(edge_array_))
{
BOOST_ASSERT(!node_array.empty());
@@ -258,8 +261,8 @@ template <typename EdgeDataT, bool UseSharedMemory = false> class StaticGraph
NodeIterator number_of_nodes;
EdgeIterator number_of_edges;
typename ShM<NodeArrayEntry, UseSharedMemory>::vector node_array;
typename ShM<EdgeArrayEntry, UseSharedMemory>::vector edge_array;
typename ShM<NodeArrayEntry, Ownership>::vector node_array;
typename ShM<EdgeArrayEntry, Ownership>::vector edge_array;
};
} // namespace util
+5 -3
View File
@@ -15,6 +15,8 @@
#include "osrm/coordinate.hpp"
#include "storage/shared_memory_ownership.hpp"
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
@@ -52,7 +54,7 @@ namespace util
// are computed, this means the internal distance metric doesn not represent meters!
template <class EdgeDataT,
class CoordinateListT = std::vector<Coordinate>,
bool UseSharedMemory = false,
storage::Ownership Ownership = storage::Ownership::Container,
std::uint32_t BRANCHING_FACTOR = 128,
std::uint32_t LEAF_PAGE_SIZE = 4096>
class StaticRTree
@@ -152,12 +154,12 @@ class StaticRTree
Coordinate fixed_projected_coordinate;
};
typename ShM<TreeNode, UseSharedMemory>::vector m_search_tree;
typename ShM<TreeNode, Ownership>::vector m_search_tree;
const CoordinateListT &m_coordinate_list;
boost::iostreams::mapped_file_source m_leaves_region;
// read-only view of leaves
typename ShM<const LeafNode, true>::vector m_leaves;
typename ShM<const LeafNode, storage::Ownership::View>::vector m_leaves;
public:
StaticRTree(const StaticRTree &) = delete;
+17 -20
View File
@@ -1,24 +1,12 @@
{
"name": "osrm",
"version": "5.7.0-alpha.1",
"private": true,
"version": "5.7.0-latest.3",
"private": false,
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.",
"dependencies": {
"chalk": "^1.1.3",
"cucumber": "^1.2.1",
"d3-queue": "^2.0.3",
"mkdirp": "^0.5.1",
"nan": "^2.1.0",
"node-cmake": "^1.2.1",
"node-pre-gyp": "^0.6.34",
"node-timeout": "0.0.4",
"polyline": "^0.2.0",
"request": "^2.69.0",
"rimraf": "^2.5.4",
"xmlbuilder": "^4.2.1"
},
"bin": {
"cucumber": "./node_modules/cucumber/bin/cucumber.js"
"node-pre-gyp": "^0.6.34"
},
"browserify": {
"transform": [
@@ -29,10 +17,10 @@
"scripts": {
"lint": "eslint -c ./.eslintrc features/step_definitions/ features/support/",
"test": "npm run lint && node ./node_modules/cucumber/bin/cucumber.js features/ -p verify && node ./node_modules/cucumber/bin/cucumber.js features/ -p mld",
"clean-test": "rm -rf test/cache",
"cucumber": "./node_modules/cucumber/bin/cucumber.js",
"clean": "rm -rf test/cache",
"docs": "./scripts/build_api_docs.sh",
"install": "node-pre-gyp install --fallback-to-build=false"
"install": "node-pre-gyp install --fallback-to-build=false",
"nodejs-tests": "make -C test/data && ./lib/binding/osrm-datastore test/data/ch/monaco.osrm && node test/nodejs/index.js | faucet"
},
"repository": {
"type": "git",
@@ -51,9 +39,18 @@
"docbox": "^1.0.5",
"documentation": "^4.0.0-beta.18",
"eslint": "^2.4.0",
"chalk": "^1.1.3",
"cucumber": "^1.2.1",
"d3-queue": "^2.0.3",
"mkdirp": "^0.5.1",
"aws-sdk": "~2.0.31",
"tape": "^4.2.2"
"tape": "^4.2.2",
"faucet": "^0.0.1",
"node-timeout": "0.0.4",
"polyline": "^0.2.0",
"request": "^2.69.0",
"rimraf": "^2.5.4",
"xmlbuilder": "^4.2.1"
},
"bundleDependencies": [
"node-pre-gyp"
+16 -4
View File
@@ -444,17 +444,29 @@ function way_function (way, result)
end
-- cycleways
local has_cycleway_left, has_cycleway_right
if cycleway and profile.cycleway_tags[cycleway] then
result.forward_speed = profile.bicycle_speeds["cycleway"]
result.backward_speed = profile.bicycle_speeds["cycleway"]
has_cycleway_left = true
has_cycleway_right = true
elseif cycleway_left and profile.cycleway_tags[cycleway_left] then
result.forward_speed = profile.bicycle_speeds["cycleway"]
result.backward_speed = profile.bicycle_speeds["cycleway"]
has_cycleway_left = true
has_cycleway_right = true
elseif cycleway_right and profile.cycleway_tags[cycleway_right] then
has_cycleway_left = true
has_cycleway_right = true
end
if has_cycleway_right and
(result.forward_mode == mode.inaccessible or
result.forward_mode == mode.cycling) then
result.forward_speed = profile.bicycle_speeds["cycleway"]
end
if has_cycleway_left and
(result.backward_mode == mode.inaccessible or
result.backward_mode == mode.cycling) then
result.backward_speed = profile.bicycle_speeds["cycleway"]
end
-- dismount
if bicycle == "dismount" then
result.forward_mode = mode.pushing_bike
+1
View File
@@ -33,6 +33,7 @@ local profile = {
'sally_port',
'gate',
'no',
'kerb',
'block'
},
+3 -1
View File
@@ -1,6 +1,8 @@
api_version = 1
-- Rasterbot profile
properties.force_split_edges = true
-- Minimalist node_ and way_functions in order to test source_ and segment_functions
function node_function (node, result)
@@ -46,7 +48,7 @@ function segment_function (segment)
local scaled_duration = segment.duration
if sourceData.datum ~= invalid and targetData.datum ~= invalid then
local slope = math.abs(sourceData.datum - targetData.datum) / segment.distance
local slope = (targetData.datum - sourceData.datum) / segment.distance
scaled_weight = scaled_weight / (1.0 - (slope * 5.0))
scaled_duration = scaled_duration / (1.0 - (slope * 5.0))
io.write(" slope: " .. slope .. "\n")
-99
View File
@@ -1,99 +0,0 @@
#!/usr/bin/env bash
set -eu
set -o pipefail
# defaults
export ENABLE_COVERAGE=${ENABLE_COVERAGE:-"Off"}
export BUILD_TYPE=${BUILD_TYPE:-"Release"}
export NODE=${NODE:-4}
export CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
export DEPS_DIR="$(pwd)/deps"
export PATH=${DEPS_DIR}/bin:${PATH}
mkdir -p ${DEPS_DIR}
export CLANG_VERSION="${CLANG_VERSION:-4.0.0}"
export CCACHE_VERSION=3.3.1
export CMAKE_VERSION=3.7.2
source ${CURRENT_DIR}/travis_helper.sh
# ensure we start inside the root directory (two level up)
cd ${CURRENT_DIR}/../../
if [[ ! $(which wget) ]]; then
echo "echo wget must be installed";
exit 1;
fi;
SYSTEM_NAME=$(uname -s)
if [[ "${SYSTEM_NAME}" == "Darwin" ]]; then
OS_NAME="osx"
elif [[ "${SYSTEM_NAME}" == "Linux" ]]; then
OS_NAME="linux"
fi
# FIXME This should be replaced by proper calls to mason but we currently have a chicken-egg problem
# since we rely on osrm-backend to ship mason for us. Once we merged this into osrm-backend this will not be needed.
CMAKE_URL="https://s3.amazonaws.com/mason-binaries/${OS_NAME}-x86_64/cmake/${CMAKE_VERSION}.tar.gz"
echo "Downloading cmake from ${CMAKE_URL} ..."
wget --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C ${DEPS_DIR} || exit 1
CCACHE_URL="https://s3.amazonaws.com/mason-binaries/${OS_NAME}-x86_64/ccache/${CCACHE_VERSION}.tar.gz"
echo "Downloading ccache from ${CCACHE_URL} ..."
wget --quiet -O - ${CCACHE_URL} | tar --strip-components=1 -xz -C ${DEPS_DIR} || exit 1
# install clang for linux but use the xcode version on OSX
if [[ "${OS_NAME}" != "osx" ]]; then
CLANG_URL="https://s3.amazonaws.com/mason-binaries/${OS_NAME}-x86_64/clang++/${CLANG_VERSION}.tar.gz"
echo "Downloading clang from ${CLANG_URL} ..."
wget --quiet -O - ${CLANG_URL} | tar --strip-components=1 -xz -C ${DEPS_DIR} || exit 1
export CCOMPILER='clang'
export CXXCOMPILER='clang++'
export CC='clang'
export CXX='clang++'
fi
if [[ "${OS_NAME}" == "osx" ]]; then
if [[ -f /etc/sysctl.conf ]] && [[ $(grep shmmax /etc/sysctl.conf) ]]; then
echo "Note: found shmmax setting in /etc/sysctl.conf, not modifying"
else
echo "WARNING: Did not find shmmax setting in /etc/sysctl.conf, adding now (requires sudo and restarting)..."
sudo sysctl -w kern.sysv.shmmax=4294967296
sudo sysctl -w kern.sysv.shmall=1048576
sudo sysctl -w kern.sysv.shmseg=128
fi
fi
echo "Now build node-osrm and dependencies"
export VERBOSE=1
if [[ "${ENABLE_COVERAGE}" == "On" ]]; then
mapbox_time "make" make -j4 coverage
else
mkdir -p build
pushd build
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DENABLE_NODE_BINDINGS=On -DENABLE_MASON=On
mapbox_time "make" make -j4
popd
fi
## run tests, with backtrace support
#if [[ "${OS_NAME}" == "linux" ]]; then
# ulimit -c unlimited -S
# RESULT=0
# mapbox_time "make-test" make tests || RESULT=$?
# for i in $(find ./ -maxdepth 1 -name 'core*' -print);
# do gdb $(which node) $i -ex "thread apply all bt" -ex "set pagination 0" -batch;
# done;
# if [[ ${RESULT} != 0 ]]; then exit $RESULT; fi
#else
# # todo: coredump support on OS X
# RESULT=0
# mapbox_time "make-test" make tests || RESULT=$?
# if [[ ${RESULT} != 0 ]]; then exit $RESULT; fi
#fi
set +eu
set +o pipefail
+21 -39
View File
@@ -3,49 +3,31 @@
set -eu
set -o pipefail
# should be set for debug builds
export NPM_FLAGS=${NPM_FLAGS:-}
if [[ ${PUBLISH} == 'On' ]]; then
echo "PUBLISH is set to '${PUBLISH}', publishing!"
echo "node version is:"
which node
node -v
echo "node version is:"
which node
node -v
echo "dumping binary meta..."
./node_modules/.bin/node-pre-gyp reveal ${NPM_FLAGS}
echo "dumping binary meta..."
./node_modules/.bin/node-pre-gyp reveal
# enforce that binary has proper ORIGIN flags so that
# it can portably find libtbb.so in the same directory
if [[ $(uname -s) == 'Linux' ]]; then
readelf -d ./lib/binding/node-osrm.node > readelf-output.txt
if grep -q 'Flags: ORIGIN' readelf-output.txt; then
echo "Found ORIGIN flag in readelf output"
cat readelf-output.txt
else
echo "*** Error: Could not found ORIGIN flag in readelf output"
cat readelf-output.txt
exit 1
# enforce that binary has proper ORIGIN flags so that
# it can portably find libtbb.so in the same directory
if [[ $(uname -s) == 'Linux' ]]; then
readelf -d ./lib/binding/node-osrm.node > readelf-output.txt
if grep -q 'Flags: ORIGIN' readelf-output.txt; then
echo "Found ORIGIN flag in readelf output"
cat readelf-output.txt
else
echo "*** Error: Could not found ORIGIN flag in readelf output"
cat readelf-output.txt
exit 1
fi
fi
fi
echo "determining publishing status..."
if [[ $(./scripts/travis/is_pr_merge.sh) ]]; then
echo "Skipping publishing because this is a PR merge commit"
./node_modules/.bin/node-pre-gyp package publish info
else
echo "This is a push commit, continuing to package..."
./node_modules/.bin/node-pre-gyp package ${NPM_FLAGS}
export COMMIT_MESSAGE=$(git log --format=%B --no-merges | head -n 1 | tr -d '\n')
echo "Commit message: ${COMMIT_MESSAGE}"
if [[ ${COMMIT_MESSAGE} =~ "[publish binary]" ]]; then
echo "Publishing"
./node_modules/.bin/node-pre-gyp publish ${NPM_FLAGS}
elif [[ ${COMMIT_MESSAGE} =~ "[republish binary]" ]]; then
echo "*** Error: Republishing is disallowed for this repository"
exit 1
#./node_modules/.bin/node-pre-gyp unpublish publish ${NPM_FLAGS}
else
echo "Skipping publishing"
fi;
echo "PUBLISH is set to '${PUBLISH}', skipping."
fi
+5 -3
View File
@@ -28,12 +28,14 @@ constexpr int32_t WORLD_MAX_LON = 180 * COORDINATE_PRECISION;
using RTreeLeaf = extractor::EdgeBasedNode;
using BenchStaticRTree =
util::StaticRTree<RTreeLeaf, util::ShM<util::Coordinate, false>::vector, false>;
util::StaticRTree<RTreeLeaf,
util::ShM<util::Coordinate, storage::Ownership::Container>::vector,
storage::Ownership::Container>;
std::vector<util::Coordinate> loadCoordinates(const boost::filesystem::path &nodes_file)
{
osrm::storage::io::FileReader nodes_path_file_reader(
nodes_file, osrm::storage::io::FileReader::HasNoFingerprint);
storage::io::FileReader nodes_path_file_reader(nodes_file,
storage::io::FileReader::HasNoFingerprint);
extractor::QueryNode current_node;
unsigned coordinate_count = nodes_path_file_reader.ReadElementCount32();
+5 -3
View File
@@ -8,6 +8,8 @@
#include "partition/io.hpp"
#include "partition/multi_level_partition.hpp"
#include "storage/shared_memory_ownership.hpp"
#include "updater/updater.hpp"
#include "util/log.hpp"
@@ -82,9 +84,9 @@ auto LoadAndUpdateEdgeExpandedGraph(const CustomizationConfig &config,
auto directed = partition::splitBidirectionalEdges(edge_based_edge_list);
auto tidied =
partition::prepareEdgesForUsageInGraph<StaticEdgeBasedGraphEdge>(std::move(directed));
auto edge_based_graph =
std::make_unique<partition::MultiLevelGraph<EdgeBasedGraphEdgeData, false>>(
mlp, num_nodes, std::move(tidied));
auto edge_based_graph = std::make_unique<
partition::MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::Container>>(
mlp, num_nodes, std::move(tidied));
util::Log() << "Loaded edge based graph for mapping partition ids: "
<< edge_based_graph->GetNumberOfEdges() << " edges, "
+28 -10
View File
@@ -3,6 +3,7 @@
#include "engine/api/match_api.hpp"
#include "engine/api/match_parameters.hpp"
#include "engine/api/match_parameters_tidy.hpp"
#include "engine/map_matching/bayes_classifier.hpp"
#include "engine/map_matching/sub_matching.hpp"
#include "util/coordinate_calculation.hpp"
@@ -145,20 +146,33 @@ Status MatchPlugin::HandleRequest(const datafacade::ContiguousInternalMemoryData
"InvalidValue", "Timestamps need to be monotonically increasing.", json_result);
}
SubMatchingList sub_matchings;
api::tidy::Result tidied;
if (parameters.tidy)
{
// Transparently tidy match parameters, do map matching on tidied parameters.
// Then use the mapping to restore the original <-> tidied relationship.
tidied = api::tidy::tidy(parameters);
}
else
{
tidied = api::tidy::keep_all(parameters);
}
// assuming radius is the standard deviation of a normal distribution
// that models GPS noise (in this model), x3 should give us the correct
// search radius with > 99% confidence
std::vector<double> search_radiuses;
if (parameters.radiuses.empty())
if (tidied.parameters.radiuses.empty())
{
search_radiuses.resize(parameters.coordinates.size(),
search_radiuses.resize(tidied.parameters.coordinates.size(),
routing_algorithms::DEFAULT_GPS_PRECISION * RADIUS_MULTIPLIER);
}
else
{
search_radiuses.resize(parameters.coordinates.size());
std::transform(parameters.radiuses.begin(),
parameters.radiuses.end(),
search_radiuses.resize(tidied.parameters.coordinates.size());
std::transform(tidied.parameters.radiuses.begin(),
tidied.parameters.radiuses.end(),
search_radiuses.begin(),
[](const boost::optional<double> &maybe_radius) {
if (maybe_radius)
@@ -173,9 +187,9 @@ Status MatchPlugin::HandleRequest(const datafacade::ContiguousInternalMemoryData
});
}
auto candidates_lists = GetPhantomNodesInRange(facade, parameters, search_radiuses);
auto candidates_lists = GetPhantomNodesInRange(facade, tidied.parameters, search_radiuses);
filterCandidates(parameters.coordinates, candidates_lists);
filterCandidates(tidied.parameters.coordinates, candidates_lists);
if (std::all_of(candidates_lists.begin(),
candidates_lists.end(),
[](const std::vector<PhantomNodeWithDistance> &candidates) {
@@ -188,8 +202,12 @@ Status MatchPlugin::HandleRequest(const datafacade::ContiguousInternalMemoryData
}
// call the actual map matching
SubMatchingList sub_matchings = algorithms.MapMatching(
candidates_lists, parameters.coordinates, parameters.timestamps, parameters.radiuses);
sub_matchings =
algorithms.MapMatching(candidates_lists,
tidied.parameters.coordinates,
tidied.parameters.timestamps,
tidied.parameters.radiuses,
parameters.gaps == api::MatchParameters::GapsType::Split);
if (sub_matchings.size() == 0)
{
@@ -220,7 +238,7 @@ Status MatchPlugin::HandleRequest(const datafacade::ContiguousInternalMemoryData
BOOST_ASSERT(sub_routes[index].shortest_path_length != INVALID_EDGE_WEIGHT);
}
api::MatchAPI match_api{facade, parameters};
api::MatchAPI match_api{facade, parameters, tidied};
match_api.MakeResponse(sub_matchings, sub_routes, json_result);
return Status::Ok;
+24 -11
View File
@@ -54,7 +54,8 @@ mapMatchingImpl(SearchEngineData &engine_working_data,
const CandidateLists &candidates_list,
const std::vector<util::Coordinate> &trace_coordinates,
const std::vector<unsigned> &trace_timestamps,
const std::vector<boost::optional<double>> &trace_gps_precision)
const std::vector<boost::optional<double>> &trace_gps_precision,
const bool allow_splitting)
{
map_matching::MatchingConfidence confidence;
map_matching::EmissionLogProbability default_emission_log_probability(DEFAULT_GPS_PRECISION);
@@ -156,16 +157,24 @@ mapMatchingImpl(SearchEngineData &engine_working_data,
for (auto t = initial_timestamp + 1; t < candidates_list.size(); ++t)
{
const bool gap_in_trace = [&, use_timestamps]() {
// use temporal information if available to determine a split
if (use_timestamps)
const bool gap_in_trace = [&]() {
// do not determine split if wasn't asked about it
if (allow_splitting)
{
return trace_timestamps[t] - trace_timestamps[prev_unbroken_timestamps.back()] >
max_broken_time;
// use temporal information if available to determine a split
if (use_timestamps)
{
return trace_timestamps[t] - trace_timestamps[prev_unbroken_timestamps.back()] >
max_broken_time;
}
else
{
return t - prev_unbroken_timestamps.back() > MAX_BROKEN_STATES;
}
}
else
{
return t - prev_unbroken_timestamps.back() > MAX_BROKEN_STATES;
return false;
}
}();
@@ -416,14 +425,16 @@ mapMatching(SearchEngineData &engine_working_data,
const CandidateLists &candidates_list,
const std::vector<util::Coordinate> &trace_coordinates,
const std::vector<unsigned> &trace_timestamps,
const std::vector<boost::optional<double>> &trace_gps_precision)
const std::vector<boost::optional<double>> &trace_gps_precision,
const bool use_tidying)
{
return mapMatchingImpl(engine_working_data,
facade,
candidates_list,
trace_coordinates,
trace_timestamps,
trace_gps_precision);
trace_gps_precision,
use_tidying);
}
SubMatchingList
@@ -432,7 +443,8 @@ mapMatching(SearchEngineData &engine_working_data,
const CandidateLists &candidates_list,
const std::vector<util::Coordinate> &trace_coordinates,
const std::vector<unsigned> &trace_timestamps,
const std::vector<boost::optional<double>> &trace_gps_precision)
const std::vector<boost::optional<double>> &trace_gps_precision,
const bool use_tidying)
{
return mapMatchingImpl(engine_working_data,
@@ -440,7 +452,8 @@ mapMatching(SearchEngineData &engine_working_data,
candidates_list,
trace_coordinates,
trace_timestamps,
trace_gps_precision);
trace_gps_precision,
use_tidying);
}
} // namespace routing_algorithms
+14 -11
View File
@@ -388,21 +388,24 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
BOOST_ASSERT(edge_iterator->source_coordinate.lon !=
util::FixedLongitude{std::numeric_limits<std::int32_t>::min()});
const util::Coordinate target_coord{node_iterator->lon, node_iterator->lat};
const double distance = util::coordinate_calculation::greatCircleDistance(
edge_iterator->source_coordinate, target_coord);
util::Coordinate source_coord(edge_iterator->source_coordinate);
util::Coordinate target_coord{node_iterator->lon, node_iterator->lat};
auto weight = edge_iterator->weight_data(distance);
auto duration = edge_iterator->duration_data(distance);
// flip source and target coordinates if segment is in backward direction only
if (!edge_iterator->result.forward && edge_iterator->result.backward)
std::swap(source_coord, target_coord);
ExtractionSegment extracted_segment(
edge_iterator->source_coordinate, target_coord, distance, weight, duration);
scripting_environment.ProcessSegment(extracted_segment);
const auto distance =
util::coordinate_calculation::greatCircleDistance(source_coord, target_coord);
const auto weight = edge_iterator->weight_data(distance);
const auto duration = edge_iterator->duration_data(distance);
ExtractionSegment segment(source_coord, target_coord, distance, weight, duration);
scripting_environment.ProcessSegment(segment);
auto &edge = edge_iterator->result;
edge.weight =
std::max<EdgeWeight>(1, std::round(extracted_segment.weight * weight_multiplier));
edge.duration = std::max<EdgeWeight>(1, std::round(extracted_segment.duration * 10.));
edge.weight = std::max<EdgeWeight>(1, std::round(segment.weight * weight_multiplier));
edge.duration = std::max<EdgeWeight>(1, std::round(segment.duration * 10.));
// assign new node id
auto id_iter = external_to_internal_node_id_map.find(node_iterator->node_id);
+12 -9
View File
@@ -35,7 +35,9 @@ namespace TurnLaneType = guidance::TurnLaneType;
ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers &extraction_containers_,
const ProfileProperties &properties)
: external_memory(extraction_containers_), fallback_to_duration(properties.fallback_to_duration)
: external_memory(extraction_containers_),
fallback_to_duration(properties.fallback_to_duration),
force_split_edges(properties.force_split_edges)
{
// we reserved 0, 1, 2, 3 for the empty case
string_map[MapKey("", "", "", "")] = 0;
@@ -323,14 +325,15 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
(parsed_way.backward_travel_mode != TRAVEL_MODE_INACCESSIBLE);
// split an edge into two edges if forwards/backwards behavior differ
const bool split_edge = in_forward_direction && in_backward_direction &&
((parsed_way.forward_rate != parsed_way.backward_rate) ||
(parsed_way.forward_speed != parsed_way.backward_speed) ||
(parsed_way.forward_travel_mode != parsed_way.backward_travel_mode) ||
(turn_lane_id_forward != turn_lane_id_backward));
const bool split_edge =
in_forward_direction && in_backward_direction &&
(force_split_edges || (parsed_way.forward_rate != parsed_way.backward_rate) ||
(parsed_way.forward_speed != parsed_way.backward_speed) ||
(parsed_way.forward_travel_mode != parsed_way.backward_travel_mode) ||
(turn_lane_id_forward != turn_lane_id_backward));
if (in_forward_direction)
{
{ // add (forward) segments or (forward,backward) for non-split edges in backward direction
util::for_each_pair(
nodes.cbegin(),
nodes.cend(),
@@ -355,8 +358,8 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
});
}
if (in_backward_direction || split_edge)
{
if (in_backward_direction && (!in_forward_direction || split_edge))
{ // add (backward) segments for split edges or not in forward direction
util::for_each_pair(
nodes.cbegin(),
nodes.cend(),
+20 -11
View File
@@ -247,7 +247,9 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
"weight_name",
sol::property(&ProfileProperties::SetWeightName, &ProfileProperties::GetWeightName),
"max_turn_weight",
sol::property(&ProfileProperties::GetMaxTurnWeight));
sol::property(&ProfileProperties::GetMaxTurnWeight),
"force_split_edges",
&ProfileProperties::force_split_edges);
context.state.new_usertype<std::vector<std::string>>(
"vector",
@@ -330,12 +332,6 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
sol::property(&ExtractionWay::GetTurnLanesForward, &ExtractionWay::SetTurnLanesForward),
"turn_lanes_backward",
sol::property(&ExtractionWay::GetTurnLanesBackward, &ExtractionWay::SetTurnLanesBackward),
"roundabout",
&ExtractionWay::roundabout,
"circular",
&ExtractionWay::circular,
"is_startpoint",
&ExtractionWay::is_startpoint,
"duration",
&ExtractionWay::duration,
"weight",
@@ -343,13 +339,26 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
"road_classification",
&ExtractionWay::road_classification,
"forward_mode",
sol::property(&ExtractionWay::get_forward_mode, &ExtractionWay::set_forward_mode),
sol::property([](const ExtractionWay &way) { return way.forward_travel_mode; },
[](ExtractionWay &way, TravelMode mode) { way.forward_travel_mode = mode; }),
"backward_mode",
sol::property(&ExtractionWay::get_backward_mode, &ExtractionWay::set_backward_mode),
sol::property([](const ExtractionWay &way) { return way.backward_travel_mode; },
[](ExtractionWay &way, TravelMode mode) { way.backward_travel_mode = mode; }),
"roundabout",
sol::property([](const ExtractionWay &way) { return way.roundabout; },
[](ExtractionWay &way, bool flag) { way.roundabout = flag; }),
"circular",
sol::property([](const ExtractionWay &way) { return way.circular; },
[](ExtractionWay &way, bool flag) { way.circular = flag; }),
"is_startpoint",
sol::property([](const ExtractionWay &way) { return way.is_startpoint; },
[](ExtractionWay &way, bool flag) { way.is_startpoint = flag; }),
"forward_restricted",
&ExtractionWay::forward_restricted,
sol::property([](const ExtractionWay &way) { return way.forward_restricted; },
[](ExtractionWay &way, bool flag) { way.forward_restricted = flag; }),
"backward_restricted",
&ExtractionWay::backward_restricted);
sol::property([](const ExtractionWay &way) { return way.backward_restricted; },
[](ExtractionWay &way, bool flag) { way.backward_restricted = flag; }));
context.state.new_usertype<ExtractionSegment>("ExtractionSegment",
"source",
+3 -1
View File
@@ -7,12 +7,14 @@ message(STATUS "Building node-osrm")
set(BINDING_DIR "${PROJECT_SOURCE_DIR}/lib/binding")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/nodejs")
include(FindNodeJS)
set(NodeJS_CXX_STANDARD 14 CACHE INTERNAL "Use C++14" FORCE)
set(NodeJS_DOWNLOAD ON CACHE INTERNAL "Download node.js sources" FORCE)
set(NodeJS_USE_CLANG_STDLIB OFF CACHE BOOL "Don't use libc++ by default" FORCE)
# ^ Make sure to set NodeJs options before including and requiring the NodeJs module.
# Otherwise the module will use defaults (which - among many bad choices - means libc++).
include(FindNodeJS)
find_package(NodeJS REQUIRED)
add_nodejs_module(node-osrm node_osrm.cpp)
target_link_libraries(node-osrm osrm)
+3 -7
View File
@@ -108,12 +108,12 @@ int Partitioner::Run(const PartitionConfig &config)
makeBisectionGraph(compressed_node_based_graph.coordinates,
adaptToBisectionEdge(std::move(compressed_node_based_graph.edges)));
util::Log() << " running partition: " << config.minimum_cell_size << " " << config.balance
util::Log() << " running partition: " << config.max_cell_sizes.front() << " " << config.balance
<< " " << config.boundary_factor << " " << config.num_optimizing_cuts << " "
<< config.small_component_size
<< " # max_cell_size balance boundary cuts small_component_size";
RecursiveBisection recursive_bisection(graph,
config.minimum_cell_size,
config.max_cell_sizes.front(),
config.balance,
config.boundary_factor,
config.num_optimizing_cuts,
@@ -161,11 +161,7 @@ int Partitioner::Run(const PartitionConfig &config)
std::vector<Partition> partitions;
std::vector<std::uint32_t> level_to_num_cells;
std::tie(partitions, level_to_num_cells) =
bisectionToPartition(edge_based_partition_ids,
{config.minimum_cell_size,
config.minimum_cell_size * 32,
config.minimum_cell_size * 32 * 16,
config.minimum_cell_size * 32 * 16 * 32});
bisectionToPartition(edge_based_partition_ids, config.max_cell_sizes);
auto num_unconnected = removeUnconnectedBoundaryNodes(*edge_based_graph, partitions);
util::Log() << "Fixed " << num_unconnected << " unconnected nodes";
+13 -10
View File
@@ -16,6 +16,7 @@
#include "storage/serialization.hpp"
#include "storage/shared_datatype.hpp"
#include "storage/shared_memory.hpp"
#include "storage/shared_memory_ownership.hpp"
#include "storage/shared_monitor.hpp"
#include "engine/datafacade/datafacade_base.hpp"
#include "util/coordinate.hpp"
@@ -55,8 +56,9 @@ namespace storage
{
using RTreeLeaf = engine::datafacade::BaseDataFacade::RTreeLeaf;
using RTreeNode =
util::StaticRTree<RTreeLeaf, util::ShM<util::Coordinate, true>::vector, true>::TreeNode;
using RTreeNode = util::StaticRTree<RTreeLeaf,
util::vector_view<util::Coordinate>,
storage::Ownership::View>::TreeNode;
using QueryGraph = util::StaticGraph<contractor::QueryEdge::EdgeData>;
using EdgeBasedGraph = util::StaticGraph<extractor::EdgeBasedEdge::EdgeData>;
@@ -364,12 +366,13 @@ void Storage::PopulateLayout(DataLayout &layout)
intersection_file.Skip<std::uint32_t>(1); // sum_lengths
layout.SetBlockSize<unsigned>(DataLayout::BEARING_OFFSETS, bearing_blocks);
layout.SetBlockSize<typename util::RangeTable<16, true>::BlockT>(DataLayout::BEARING_BLOCKS,
bearing_blocks);
layout.SetBlockSize<typename util::RangeTable<16, storage::Ownership::View>::BlockT>(
DataLayout::BEARING_BLOCKS, bearing_blocks);
// No need to read the data
intersection_file.Skip<unsigned>(bearing_blocks);
intersection_file.Skip<typename util::RangeTable<16, true>::BlockT>(bearing_blocks);
intersection_file.Skip<typename util::RangeTable<16, storage::Ownership::View>::BlockT>(
bearing_blocks);
const auto num_bearings = intersection_file.ReadElementCount64();
@@ -694,7 +697,7 @@ void Storage::PopulateData(const DataLayout &layout, char *memory_ptr)
layout.GetBlockPtr<util::Coordinate, true>(memory_ptr, DataLayout::COORDINATE_LIST);
const auto osmnodeid_ptr =
layout.GetBlockPtr<std::uint64_t, true>(memory_ptr, DataLayout::OSM_NODE_ID_LIST);
util::PackedVector<OSMNodeID, true> osmnodeid_list;
util::PackedVector<OSMNodeID, storage::Ownership::View> osmnodeid_list;
osmnodeid_list.reset(osmnodeid_ptr, layout.num_entries[DataLayout::OSM_NODE_ID_LIST]);
@@ -803,8 +806,8 @@ void Storage::PopulateData(const DataLayout &layout, char *memory_ptr)
intersection_file.Skip<std::uint32_t>(1); // sum_lengths
std::vector<unsigned> bearing_offsets_data(bearing_blocks);
std::vector<typename util::RangeTable<16, true>::BlockT> bearing_blocks_data(
bearing_blocks);
std::vector<typename util::RangeTable<16, storage::Ownership::View>::BlockT>
bearing_blocks_data(bearing_blocks);
intersection_file.ReadInto(bearing_offsets_data.data(), bearing_blocks);
intersection_file.ReadInto(bearing_blocks_data.data(), bearing_blocks);
@@ -844,8 +847,8 @@ void Storage::PopulateData(const DataLayout &layout, char *memory_ptr)
if (layout.GetBlockSize(DataLayout::BEARING_BLOCKS) > 0)
{
const auto bearing_blocks_ptr =
layout.GetBlockPtr<typename util::RangeTable<16, true>::BlockT, true>(
memory_ptr, DataLayout::BEARING_BLOCKS);
layout.GetBlockPtr<typename util::RangeTable<16, storage::Ownership::View>::BlockT,
true>(memory_ptr, DataLayout::BEARING_BLOCKS);
BOOST_ASSERT(
static_cast<std::size_t>(layout.GetBlockSize(DataLayout::BEARING_BLOCKS)) >=
std::distance(bearing_blocks_data.begin(), bearing_blocks_data.end()) *
+74 -16
View File
@@ -8,11 +8,15 @@
#include <tbb/task_scheduler_init.h>
#include <boost/algorithm/string/join.hpp>
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <iostream>
#include <iterator>
#include <regex>
using namespace osrm;
@@ -23,7 +27,48 @@ enum class return_code : unsigned
exit
};
return_code parseArguments(int argc, char *argv[], partition::PartitionConfig &partition_config)
struct MaxCellSizesArgument
{
std::vector<size_t> value;
};
std::ostream &operator<<(std::ostream &os, const MaxCellSizesArgument &arg)
{
auto to_string = [](std::size_t x) { return std::to_string(x); };
return os << boost::algorithm::join(arg.value | boost::adaptors::transformed(to_string), ",");
}
void validate(boost::any &v, const std::vector<std::string> &values, MaxCellSizesArgument *, int)
{
using namespace boost::program_options;
using namespace boost::adaptors;
// Make sure no previous assignment to 'v' was made.
validators::check_first_occurrence(v);
// Extract the first string from 'values'. If there is more than
// one string, it's an error, and exception will be thrown.
const std::string &s = validators::get_single_string(values);
std::regex re(",");
std::vector<size_t> output;
std::transform(std::sregex_token_iterator(s.begin(), s.end(), re, -1),
std::sregex_token_iterator(),
std::back_inserter(output),
[](const auto &x) {
try
{
return boost::lexical_cast<std::size_t>(x);
}
catch (const boost::bad_lexical_cast &)
{
throw validation_error(validation_error::invalid_option_value);
}
});
v = boost::any(MaxCellSizesArgument{output});
}
return_code parseArguments(int argc, char *argv[], partition::PartitionConfig &config)
{
// declare a group of options that will be allowed only on command line
boost::program_options::options_description generic_options("Options");
@@ -34,40 +79,41 @@ return_code parseArguments(int argc, char *argv[], partition::PartitionConfig &p
config_options.add_options()
//
("threads,t",
boost::program_options::value<unsigned int>(&partition_config.requested_num_threads)
boost::program_options::value<unsigned int>(&config.requested_num_threads)
->default_value(tbb::task_scheduler_init::default_num_threads()),
"Number of threads to use")
//
("min-cell-size",
boost::program_options::value<std::size_t>(&partition_config.minimum_cell_size)
->default_value(128),
"Bisection termination citerion based on cell size")
//
("balance",
boost::program_options::value<double>(&partition_config.balance)->default_value(1.2),
boost::program_options::value<double>(&config.balance)->default_value(config.balance),
"Balance for left and right side in single bisection")
//
("boundary",
boost::program_options::value<double>(&partition_config.boundary_factor)
->default_value(0.25),
boost::program_options::value<double>(&config.boundary_factor)
->default_value(config.boundary_factor),
"Percentage of embedded nodes to contract as sources and sinks")
//
("optimizing-cuts",
boost::program_options::value<std::size_t>(&partition_config.num_optimizing_cuts)
->default_value(10),
boost::program_options::value<std::size_t>(&config.num_optimizing_cuts)
->default_value(config.num_optimizing_cuts),
"Number of cuts to use for optimizing a single bisection")
//
("small-component-size",
boost::program_options::value<std::size_t>(&partition_config.small_component_size)
->default_value(1000),
"Size threshold for small components.");
boost::program_options::value<std::size_t>(&config.small_component_size)
->default_value(config.small_component_size),
"Size threshold for small components.")
//
("max-cell-sizes",
boost::program_options::value<MaxCellSizesArgument>()->default_value(
MaxCellSizesArgument{config.max_cell_sizes}),
"Maximum cell sizes starting from the level 1. The first cell size value is a bisection "
"termination citerion");
// hidden options, will be allowed on command line, but will not be
// shown to the user
boost::program_options::options_description hidden_options("Hidden options");
hidden_options.add_options()(
"input,i",
boost::program_options::value<boost::filesystem::path>(&partition_config.base_path),
boost::program_options::value<boost::filesystem::path>(&config.base_path),
"Input file in .osrm format");
// positional option
@@ -119,6 +165,18 @@ return_code parseArguments(int argc, char *argv[], partition::PartitionConfig &p
return return_code::fail;
}
if (option_variables.count("max-cell-sizes"))
{
config.max_cell_sizes = option_variables["max-cell-sizes"].as<MaxCellSizesArgument>().value;
if (!std::is_sorted(config.max_cell_sizes.begin(), config.max_cell_sizes.end()))
{
util::Log(logERROR)
<< "The maximum cell sizes array must be sorted in non-descending order.";
return return_code::fail;
}
}
return return_code::ok;
}
+1 -1
View File
@@ -14,7 +14,7 @@
using namespace osrm;
void removeLocks() { osrm::storage::SharedMonitor<osrm::storage::SharedDataTimestamp>::remove(); }
void removeLocks() { storage::SharedMonitor<storage::SharedDataTimestamp>::remove(); }
void deleteRegion(const storage::SharedDataType region)
{
+1 -1
View File
@@ -81,7 +81,7 @@ void checkWeightsConsistency(
const UpdaterConfig &config,
const std::vector<osrm::extractor::EdgeBasedEdge> &edge_based_edge_list)
{
using Reader = osrm::storage::io::FileReader;
using Reader = storage::io::FileReader;
using OriginalEdgeData = osrm::extractor::OriginalEdgeData;
extractor::SegmentDataContainer segment_data;
+26
View File
@@ -0,0 +1,26 @@
var path = require('path');
// Constants and fixtures for nodejs tests on our Monaco dataset.
// Somewhere in Monaco
// http://www.openstreetmap.org/#map=18/43.73185/7.41772
exports.three_test_coordinates = [[7.41337, 43.72956],
[7.41546, 43.73077],
[7.41862, 43.73216]];
exports.two_test_coordinates = exports.three_test_coordinates.slice(0, 2)
exports.test_tile = {'at': [17059, 11948, 15], 'size': 114000};
// Test files generated by the routing engine; check test/data
if (process.env.OSRM_DATA_PATH !== undefined) {
exports.data_path = path.join(path.resolve(process.env.OSRM_DATA_PATH), "ch/monaco.osrm");
exports.mld_data_path = path.join(path.resolve(process.env.OSRM_DATA_PATH), "mld/monaco.osrm");
exports.corech_data_path = path.join(path.resolve(process.env.OSRM_DATA_PATH), "corech/monaco.osrm");
console.log('Setting custom data path to ' + exports.data_path);
} else {
exports.data_path = path.resolve(path.join(__dirname, "../data/ch/monaco.osrm"));
exports.mld_data_path = path.resolve(path.join(__dirname, "../data/mld/monaco.osrm"));
exports.corech_data_path = path.resolve(path.join(__dirname, "../data/corech/monaco.osrm"));
}
+8 -8
View File
@@ -1,8 +1,8 @@
var OSRM = require('../../');
var test = require('tape');
var berlin_path = require('./osrm-data-path').data_path;
var berlin_mld_path = require('./osrm-data-path').mld_data_path;
var berlin_corech_path = require('./osrm-data-path').corech_data_path;
var monaco_path = require('./constants').data_path;
var monaco_mld_path = require('./constants').mld_data_path;
var monaco_corech_path = require('./constants').corech_data_path;
test('constructor: throws if new keyword is not used', function(assert) {
assert.plan(1);
@@ -30,7 +30,7 @@ test('constructor: throws if necessary files do not exist', function(assert) {
test('constructor: takes a shared memory argument', function(assert) {
assert.plan(1);
var osrm = new OSRM({path: berlin_path, shared_memory: false});
var osrm = new OSRM({path: monaco_path, shared_memory: false});
assert.ok(osrm);
});
@@ -42,7 +42,7 @@ test('constructor: throws if shared_memory==false with no path defined', functio
test('constructor: throws if given a non-bool shared_memory option', function(assert) {
assert.plan(1);
assert.throws(function() { new OSRM({path: berlin_path, shared_memory: 'a'}); },
assert.throws(function() { new OSRM({path: monaco_path, shared_memory: 'a'}); },
/Shared_memory option must be a boolean/);
});
@@ -66,19 +66,19 @@ test('constructor: throws if given an invalid algorithm', function(assert) {
test('constructor: loads MLD if given as algorithm', function(assert) {
assert.plan(1);
var osrm = new OSRM({algorithm: 'MLD', path: berlin_mld_path});
var osrm = new OSRM({algorithm: 'MLD', path: monaco_mld_path});
assert.ok(osrm);
});
test('constructor: loads CH if given as algorithm', function(assert) {
assert.plan(1);
var osrm = new OSRM({algorithm: 'CH', path: berlin_path});
var osrm = new OSRM({algorithm: 'CH', path: monaco_path});
assert.ok(osrm);
});
test('constructor: loads CoreCH if given as algorithm', function(assert) {
assert.plan(1);
var osrm = new OSRM({algorithm: 'CoreCH', path: berlin_corech_path});
var osrm = new OSRM({algorithm: 'CoreCH', path: monaco_corech_path});
assert.ok(osrm);
});
+33 -30
View File
@@ -1,12 +1,14 @@
var OSRM = require('../../');
var test = require('tape');
var berlin_path = require('./osrm-data-path').data_path;
var data_path = require('./constants').data_path;
var three_test_coordinates = require('./constants').three_test_coordinates;
var two_test_coordinates = require('./constants').two_test_coordinates;
test('match: match in Berlin', function(assert) {
test('match: match in Monaco', function(assert) {
assert.plan(5);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
var options = {
coordinates: [[13.393252,52.542648],[13.39478,52.543079],[13.397389,52.542107]],
coordinates: three_test_coordinates,
timestamps: [1424684612, 1424684616, 1424684620]
};
osrm.match(options, function(err, response) {
@@ -22,11 +24,11 @@ test('match: match in Berlin', function(assert) {
});
});
test('match: match in Berlin without timestamps', function(assert) {
test('match: match in Monaco without timestamps', function(assert) {
assert.plan(3);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
var options = {
coordinates: [[13.393252,52.542648],[13.39478,52.543079],[13.397389,52.542107]]
coordinates: three_test_coordinates
};
osrm.match(options, function(err, response) {
assert.ifError(err);
@@ -35,11 +37,11 @@ test('match: match in Berlin without timestamps', function(assert) {
});
});
test('match: match in Berlin without geometry compression', function(assert) {
test('match: match in Monaco without geometry compression', function(assert) {
assert.plan(4);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
var options = {
coordinates: [[13.393252,52.542648],[13.39478,52.543079],[13.397389,52.542107]],
coordinates: three_test_coordinates,
geometries: 'geojson'
};
osrm.match(options, function(err, response) {
@@ -50,11 +52,11 @@ test('match: match in Berlin without geometry compression', function(assert) {
});
});
test('match: match in Berlin with geometry compression', function(assert) {
test('match: match in Monaco with geometry compression', function(assert) {
assert.plan(3);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
var options = {
coordinates: [[13.393252,52.542648],[13.39478,52.543079],[13.397389,52.542107]]
coordinates: three_test_coordinates,
};
osrm.match(options, function(err, response) {
assert.ifError(err);
@@ -63,11 +65,11 @@ test('match: match in Berlin with geometry compression', function(assert) {
});
});
test('match: match in Berlin with speed annotations options', function(assert) {
test('match: match in Monaco with speed annotations options', function(assert) {
assert.plan(12);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
var options = {
coordinates: [[13.393252,52.542648],[13.39478,52.543079],[13.397389,52.542107]],
coordinates: three_test_coordinates,
timestamps: [1424684612, 1424684616, 1424684620],
radiuses: [4.07, 4.07, 4.07],
steps: true,
@@ -92,11 +94,12 @@ test('match: match in Berlin with speed annotations options', function(assert) {
});
test('match: match in Berlin with several (duration, distance, nodes) annotations options', function(assert) {
test('match: match in Monaco with several (duration, distance, nodes) annotations options', function(assert) {
assert.plan(12);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
var options = {
coordinates: [[13.393252,52.542648],[13.39478,52.543079],[13.397389,52.542107]],
timestamps: [1424684612, 1424684616, 1424684620],
coordinates: three_test_coordinates,
timestamps: [1424684612, 1424684616, 1424684620],
radiuses: [4.07, 4.07, 4.07],
steps: true,
@@ -120,11 +123,11 @@ test('match: match in Berlin with several (duration, distance, nodes) annotation
});
});
test('match: match in Berlin with all options', function(assert) {
test('match: match in Monaco with all options', function(assert) {
assert.plan(8);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
var options = {
coordinates: [[13.393252,52.542648],[13.39478,52.543079],[13.397389,52.542107]],
coordinates: three_test_coordinates,
timestamps: [1424684612, 1424684616, 1424684620],
radiuses: [4.07, 4.07, 4.07],
steps: true,
@@ -146,42 +149,42 @@ test('match: match in Berlin with all options', function(assert) {
test('match: throws on missing arguments', function(assert) {
assert.plan(1);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
assert.throws(function() { osrm.match({}) },
/Two arguments required/);
});
test('match: throws on non-object arg', function(assert) {
assert.plan(1);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
assert.throws(function() { osrm.match(null, function(err, response) {}) },
/First arg must be an object/);
});
test('match: throws on invalid coordinates param', function(assert) {
assert.plan(4);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
var options = {
coordinates: ''
};
assert.throws(function() { osrm.match(options, function(err, response) {}) },
/Coordinates must be an array of \(lon\/lat\) pairs/);
options.coordinates = [[13.393252,52.542648]];
options.coordinates = [three_test_coordinates[0]];
assert.throws(function() { osrm.match(options, function(err, response) {}) },
/At least two coordinates must be provided/);
options.coordinates = [13.393252,52.542648];
options.coordinates = three_test_coordinates[0]
assert.throws(function() { osrm.match(options, function(err, response) {}) },
/Coordinates must be an array of \(lon\/lat\) pairs/);
options.coordinates = [[13.393252],[52.542648]];
options.coordinates = [three_test_coordinates[0][0], three_test_coordinates[0][1]];
assert.throws(function() { osrm.match(options, function(err, response) {}) },
/Coordinates must be an array of \(lon\/lat\) pairs/);
});
test('match: throws on invalid timestamps param', function(assert) {
assert.plan(3);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
var options = {
coordinates: [[13.393252,52.542648],[13.39478,52.543079],[13.397389,52.542107]],
coordinates: three_test_coordinates,
timestamps: 'timestamps'
};
assert.throws(function() { osrm.match(options, function(err, response) {}) },
+12 -9
View File
@@ -1,12 +1,15 @@
var OSRM = require('../../');
var test = require('tape');
var berlin_path = require('./osrm-data-path').data_path;
var data_path = require('./constants').data_path;
var three_test_coordinates = require('./constants').three_test_coordinates;
var two_test_coordinates = require('./constants').two_test_coordinates;
test('nearest', function(assert) {
assert.plan(4);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
osrm.nearest({
coordinates: [[13.333086, 52.4224]]
coordinates: [three_test_coordinates[0]]
}, function(err, result) {
assert.ifError(err);
assert.equal(result.waypoints.length, 1);
@@ -17,9 +20,9 @@ test('nearest', function(assert) {
test('nearest: can ask for multiple nearest pts', function(assert) {
assert.plan(2);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
osrm.nearest({
coordinates: [[13.333086, 52.4224]],
coordinates: [three_test_coordinates[0]],
number: 3
}, function(err, result) {
assert.ifError(err);
@@ -29,19 +32,19 @@ test('nearest: can ask for multiple nearest pts', function(assert) {
test('nearest: throws on invalid args', function(assert) {
assert.plan(6);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
var options = {};
assert.throws(function() { osrm.nearest(options); },
/Two arguments required/);
assert.throws(function() { osrm.nearest(null, function(err, res) {}); },
/First arg must be an object/);
options.coordinates = [52.4224];
options.coordinates = [43.73072];
assert.throws(function() { osrm.nearest(options, function(err, res) {}); },
/Coordinates must be an array of /);
options.coordinates = [[13.333086, 52.4224],[13.333086, 52.5224]];
options.coordinates = [three_test_coordinates[0], three_test_coordinates[1]];
assert.throws(function() { osrm.nearest(options, function(err, res) {}); },
/Exactly one coordinate pair must be provided/);
options.coordinates = [[13.333086, 52.4224]];
options.coordinates = [three_test_coordinates[0]];
options.number = 3.14159;
assert.throws(function() { osrm.nearest(options, function(err, res) {}); },
/Number must be an integer greater than or equal to 1/);
-12
View File
@@ -1,12 +0,0 @@
var path = require('path');
if (process.env.OSRM_DATA_PATH !== undefined) {
exports.data_path = path.join(path.resolve(process.env.OSRM_DATA_PATH), "ch/berlin.osrm");
exports.mld_data_path = path.join(path.resolve(process.env.OSRM_DATA_PATH), "mld/berlin.osrm");
exports.corech_data_path = path.join(path.resolve(process.env.OSRM_DATA_PATH), "corech/berlin.osrm");
console.log('Setting custom data path to ' + exports.data_path);
} else {
exports.data_path = path.resolve(path.join(__dirname, "../data/ch/berlin.osrm"));
exports.mld_data_path = path.resolve(path.join(__dirname, "../data/mld/berlin.osrm"));
exports.corech_data_path = path.resolve(path.join(__dirname, "../data/corech/berlin.osrm"));
}
+96 -93
View File
@@ -1,12 +1,27 @@
var OSRM = require('../../');
var test = require('tape');
var berlin_path = require('./osrm-data-path').data_path;
var berlin_mld_path = require('./osrm-data-path').mld_data_path;
var berlin_corech_path = require('./osrm-data-path').corech_data_path;
var monaco_path = require('./constants').data_path;
var monaco_mld_path = require('./constants').mld_data_path;
var monaco_corech_path = require('./constants').corech_data_path;
var three_test_coordinates = require('./constants').three_test_coordinates;
var two_test_coordinates = require('./constants').two_test_coordinates;
test('route: routes Berlin', function(assert) {
test('route: routes Monaco', function(assert) {
assert.plan(5);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(monaco_path);
osrm.route({coordinates: two_test_coordinates}, function(err, route) {
assert.ifError(err);
assert.ok(route.waypoints);
assert.ok(route.routes);
assert.ok(route.routes.length);
assert.ok(route.routes[0].geometry);
});
});
test('route: routes Monaco on MLD', function(assert) {
assert.plan(5);
var osrm = new OSRM({path: monaco_mld_path, algorithm: 'MLD'});
osrm.route({coordinates: [[13.43864,52.51993],[13.415852,52.513191]]}, function(err, route) {
assert.ifError(err);
assert.ok(route.waypoints);
@@ -16,21 +31,9 @@ test('route: routes Berlin', function(assert) {
});
});
test('route: routes Berlin on MLD', function(assert) {
test('route: routes Monaco on CoreCH', function(assert) {
assert.plan(5);
var osrm = new OSRM({path: berlin_mld_path, algorithm: 'MLD'});
osrm.route({coordinates: [[13.43864,52.51993],[13.415852,52.513191]]}, function(err, route) {
assert.ifError(err);
assert.ok(route.waypoints);
assert.ok(route.routes);
assert.ok(route.routes.length);
assert.ok(route.routes[0].geometry);
});
});
test('route: routes Berlin on CoreCH', function(assert) {
assert.plan(5);
var osrm = new OSRM({path: berlin_corech_path, algorithm: 'CoreCH'});
var osrm = new OSRM({path: monaco_corech_path, algorithm: 'CoreCH'});
osrm.route({coordinates: [[13.43864,52.51993],[13.415852,52.513191]]}, function(err, route) {
assert.ifError(err);
assert.ok(route.waypoints);
@@ -42,19 +45,19 @@ test('route: routes Berlin on CoreCH', function(assert) {
test('route: throws with too few or invalid args', function(assert) {
assert.plan(3);
var osrm = new OSRM(berlin_path);
assert.throws(function() { osrm.route({coordinates: [[13.43864,52.51993],[13.415852,52.513191]]}) },
var osrm = new OSRM(monaco_path);
assert.throws(function() { osrm.route({coordinates: two_test_coordinates}) },
/Two arguments required/);
assert.throws(function() { osrm.route(null, function(err, route) {}) },
/First arg must be an object/);
assert.throws(function() { osrm.route({coordinates: [[13.43864,52.51993],[13.415852,52.513191]]}, true)},
assert.throws(function() { osrm.route({coordinates: two_test_coordinates}, true)},
/last argument must be a callback function/);
});
test('route: provides no alternatives by default, but when requested', function(assert) {
test('route: provides no alternatives by default, but when requested it may (not guaranteed)', function(assert) {
assert.plan(6);
var osrm = new OSRM(berlin_path);
var options = {coordinates: [[13.302383,52.490516], [13.418427,52.522070]]};
var osrm = new OSRM(monaco_path);
var options = {coordinates: two_test_coordinates};
osrm.route(options, function(err, route) {
assert.ifError(err);
@@ -65,53 +68,53 @@ test('route: provides no alternatives by default, but when requested', function(
osrm.route(options, function(err, route) {
assert.ifError(err);
assert.ok(route.routes);
assert.equal(route.routes.length, 2);
assert.ok(route.routes.length >= 1);
});
});
test('route: throws with bad params', function(assert) {
assert.plan(11);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(monaco_path);
assert.throws(function () { osrm.route({coordinates: []}, function(err) {}) });
assert.throws(function() { osrm.route({}, function(err, route) {}) },
/Must provide a coordinates property/);
assert.throws(function() { osrm.route({coordinates: null}, function(err, route) {}) },
/Coordinates must be an array of \(lon\/lat\) pairs/);
assert.throws(function() { osrm.route({coordinates: [13.438640, 52.519930]}, function(err, route) {}) },
assert.throws(function() { osrm.route({coordinates: [[three_test_coordinates[0]], [three_test_coordinates[1]]]}, function(err, route) {}) },
/Coordinates must be an array of \(lon\/lat\) pairs/);
assert.throws(function() { osrm.route({coordinates: [[true, '52.519930'], [13.438640, 52.519930]]}, function(err, route) {}) },
assert.throws(function() { osrm.route({coordinates: [[true, 'stringish'], three_test_coordinates[1]]}, function(err, route) {}) },
/Each member of a coordinate pair must be a number/);
assert.throws(function() { osrm.route({coordinates: [[213.43864,252.51993],[413.415852,552.513191]]}, function(err, route) {}) },
/Lng\/Lat coordinates must be within world bounds \(-180 < lng < 180, -90 < lat < 90\)/);
assert.throws(function() { osrm.route({coordinates: [[13.438640], [52.519930]]}, function(err, route) {}) },
/Coordinates must be an array of \(lon\/lat\) pairs/);
assert.throws(function() { osrm.route({coordinates: [[13.43864,52.51993],[13.415852,52.513191]], hints: null}, function(err, route) {}) },
assert.throws(function() { osrm.route({coordinates: two_test_coordinates, hints: null}, function(err, route) {}) },
/Hints must be an array of strings\/null/);
assert.throws(function() { osrm.route({coordinates: [[13.43864,52.51993],[13.415852,52.513191]], steps: null}, function(err, route) {}) });
assert.throws(function() { osrm.route({coordinates: [[13.43864,52.51993],[13.415852,52.513191]], annotations: null}, function(err, route) {}) });
assert.throws(function() { osrm.route({coordinates: two_test_coordinates, steps: null}, function(err, route) {}) });
assert.throws(function() { osrm.route({coordinates: two_test_coordinates, annotations: null}, function(err, route) {}) });
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
alternateRoute: false,
hints: [13.438640, 52.519930]
hints: three_test_coordinates[0]
};
assert.throws(function() { osrm.route(options, function(err, route) {}) },
/Hint must be null or string/);
});
test('route: routes Berlin using shared memory', function(assert) {
test('route: routes Monaco using shared memory', function(assert) {
assert.plan(2);
var osrm = new OSRM();
osrm.route({coordinates: [[13.43864,52.51993],[13.415852,52.513191]]}, function(err, route) {
osrm.route({coordinates: two_test_coordinates}, function(err, route) {
assert.ifError(err);
assert.ok(Array.isArray(route.routes));
});
});
test('route: routes Berlin with geometry compression', function(assert) {
test('route: routes Monaco with geometry compression', function(assert) {
assert.plan(2);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(monaco_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
};
osrm.route(options, function(err, route) {
assert.ifError(err);
@@ -119,11 +122,11 @@ test('route: routes Berlin with geometry compression', function(assert) {
});
});
test('route: routes Berlin without geometry compression', function(assert) {
test('route: routes Monaco without geometry compression', function(assert) {
assert.plan(4);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(monaco_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
geometries: 'geojson'
};
osrm.route(options, function(err, route) {
@@ -136,9 +139,9 @@ test('route: routes Berlin without geometry compression', function(assert) {
test('Test polyline6 geometries option', function(assert) {
assert.plan(6);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(monaco_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
continue_straight: false,
overview: 'false',
geometries: 'polyline6',
@@ -154,11 +157,11 @@ test('Test polyline6 geometries option', function(assert) {
});
});
test('route: routes Berlin with speed annotations options', function(assert) {
test('route: routes Monaco with speed annotations options', function(assert) {
assert.plan(17);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(monaco_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
continue_straight: false,
overview: 'false',
geometries: 'polyline',
@@ -193,16 +196,16 @@ test('route: routes Berlin with speed annotations options', function(assert) {
});
});
test('route: routes Berlin with several (duration, distance, nodes) annotations options', function(assert) {
test('route: routes Monaco with several (duration, distance, nodes) annotations options', function(assert) {
assert.plan(17);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(monaco_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
continue_straight: false,
overview: 'false',
geometries: 'polyline',
steps: true,
annotations: ['duration','distance','nodes']
annotations: ['duration', 'distance', 'nodes']
};
osrm.route(options, function(err, first) {
assert.ifError(err);
@@ -232,11 +235,11 @@ test('route: routes Berlin with several (duration, distance, nodes) annotations
});
});
test('route: routes Berlin with options', function(assert) {
test('route: routes Monaco with options', function(assert) {
assert.plan(11);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(monaco_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
continue_straight: false,
overview: 'false',
geometries: 'polyline',
@@ -265,11 +268,11 @@ test('route: routes Berlin with options', function(assert) {
});
});
test('route: routes Berlin with options', function(assert) {
test('route: routes Monaco with options', function(assert) {
assert.plan(11);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(monaco_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
continue_straight: false,
overview: 'false',
geometries: 'polyline',
@@ -300,39 +303,39 @@ test('route: routes Berlin with options', function(assert) {
test('route: invalid route options', function(assert) {
assert.plan(8);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(monaco_path);
assert.throws(function() { osrm.route({
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
continue_straight: []
}, function(err, route) {}); },
/must be boolean/);
assert.throws(function() { osrm.route({
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
alternatives: []
}, function(err, route) {}); },
/must be boolean/);
assert.throws(function() { osrm.route({
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
geometries: true
}, function(err, route) {}); },
/Geometries must be a string: \[polyline, polyline6, geojson\]/);
assert.throws(function() { osrm.route({
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
overview: false
}, function(err, route) {}); },
/Overview must be a string: \[simplified, full, false\]/);
assert.throws(function() { osrm.route({
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
overview: false
}, function(err, route) {}); },
/Overview must be a string: \[simplified, full, false\]/);
assert.throws(function() { osrm.route({
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
overview: 'maybe'
}, function(err, route) {}); },
/'overview' param must be one of \[simplified, full, false\]/);
assert.throws(function() { osrm.route({
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
geometries: 'maybe'
}, function(err, route) {}); },
/'geometries' param must be one of \[polyline, polyline6, geojson\]/);
@@ -344,9 +347,9 @@ test('route: invalid route options', function(assert) {
test('route: integer bearing values no longer supported', function(assert) {
assert.plan(1);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(monaco_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
bearings: [200, 250],
};
assert.throws(function() { osrm.route(options, function(err, route) {}); },
@@ -355,9 +358,9 @@ test('route: integer bearing values no longer supported', function(assert) {
test('route: valid bearing values', function(assert) {
assert.plan(4);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(monaco_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
bearings: [[200, 180], [250, 180]],
};
osrm.route(options, function(err, route) {
@@ -373,44 +376,44 @@ test('route: valid bearing values', function(assert) {
test('route: invalid bearing values', function(assert) {
assert.plan(6);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(monaco_path);
assert.throws(function() { osrm.route({
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
bearings: [[400, 180], [-250, 180]],
}, function(err, route) {}) },
/Bearing values need to be in range 0..360, 0..180/);
assert.throws(function() { osrm.route({
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
bearings: [[200], [250, 180]],
}, function(err, route) {}) },
/Bearing must be an array of/);
assert.throws(function() { osrm.route({
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
bearings: [[400, 109], [100, 720]],
}, function(err, route) {}) },
/Bearing values need to be in range 0..360, 0..180/);
assert.throws(function() { osrm.route({
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
bearings: 400,
}, function(err, route) {}) },
/Bearings must be an array of arrays of numbers/);
assert.throws(function() { osrm.route({
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
bearings: [[100, 100]],
}, function(err, route) {}) },
/Bearings array must have the same length as coordinates array/);
assert.throws(function() { osrm.route({
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
bearings: [Infinity, Infinity],
}, function(err, route) {}) },
/Bearing must be an array of \[bearing, range\] or null/);
});
test('route: routes Berlin with hints', function(assert) {
test('route: routes Monaco with hints', function(assert) {
assert.plan(5);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(monaco_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]]
coordinates: two_test_coordinates,
};
osrm.route(options, function(err, first) {
assert.ifError(err);
@@ -427,11 +430,11 @@ test('route: routes Berlin with hints', function(assert) {
});
});
test('route: routes Berlin with null hints', function(assert) {
test('route: routes Monaco with null hints', function(assert) {
assert.plan(1);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(monaco_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
hints: [null, null]
};
osrm.route(options, function(err, route) {
@@ -441,22 +444,22 @@ test('route: routes Berlin with null hints', function(assert) {
test('route: throws on bad hints', function(assert) {
assert.plan(2);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(monaco_path);
assert.throws(function() { osrm.route({
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
hints: ['', '']
}, function(err, route) {})}, /Hint cannot be an empty string/);
assert.throws(function() { osrm.route({
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
hints: [null]
}, function(err, route) {})}, /Hints array must have the same length as coordinates array/);
});
test('route: routes Berlin with valid radius values', function(assert) {
test('route: routes Monaco with valid radius values', function(assert) {
assert.plan(3);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(monaco_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
radiuses: [100, 100]
};
osrm.route(options, function(err, route) {
@@ -474,23 +477,23 @@ test('route: routes Berlin with valid radius values', function(assert) {
test('route: throws on bad radiuses', function(assert) {
assert.plan(3);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(monaco_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
radiuses: [10, 10]
};
assert.throws(function() { osrm.route({
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
radiuses: 10
}, function(err, route) {}) },
/Radiuses must be an array of non-negative doubles or null/);
assert.throws(function() { osrm.route({
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
radiuses: ['magic', 'numbers']
}, function(err, route) {}) },
/Radius must be non-negative double or null/);
assert.throws(function() { osrm.route({
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
radiuses: [10]
}, function(err, route) {}) },
/Radiuses array must have the same length as coordinates array/);
+29 -22
View File
@@ -1,12 +1,15 @@
var OSRM = require('../../');
var test = require('tape');
var berlin_path = require('./osrm-data-path').data_path;
var data_path = require('./constants').data_path;
var three_test_coordinates = require('./constants').three_test_coordinates;
var two_test_coordinates = require('./constants').two_test_coordinates;
test('table: distance table in Berlin', function(assert) {
assert.plan(9);
var osrm = new OSRM(berlin_path);
test('table: distance table in Monaco', function(assert) {
assert.plan(11);
var osrm = new OSRM(data_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]]
coordinates: [three_test_coordinates[0], three_test_coordinates[1]]
};
osrm.table(options, function(err, table) {
assert.ifError(err);
@@ -23,6 +26,8 @@ test('table: distance table in Berlin', function(assert) {
} else {
// everything else is non-zero
assert.notEqual(0, column[j], 'other entries must be non-zero');
// and finite (not nan, inf etc.)
assert.ok(Number.isFinite(column[j]), 'distance is finite number');
}
}
}
@@ -30,11 +35,11 @@ test('table: distance table in Berlin', function(assert) {
});
});
test('table: distance table in Berlin with sources/destinations', function(assert) {
assert.plan(6);
var osrm = new OSRM(berlin_path);
test('table: distance table in Monaco with sources/destinations', function(assert) {
assert.plan(7);
var osrm = new OSRM(data_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: [three_test_coordinates[0], three_test_coordinates[1]],
sources: [0],
destinations: [0,1]
};
@@ -53,6 +58,8 @@ test('table: distance table in Berlin with sources/destinations', function(asser
} else {
// everything else is non-zero
assert.notEqual(0, column[j], 'other entries must be non-zero');
// and finite (not nan, inf etc.)
assert.ok(Number.isFinite(column[j]), 'distance is finite number');
}
}
}
@@ -62,24 +69,24 @@ test('table: distance table in Berlin with sources/destinations', function(asser
test('table: throws on invalid arguments', function(assert) {
assert.plan(14);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
var options = {};
assert.throws(function() { osrm.table(options); },
/Two arguments required/);
options.coordinates = null;
assert.throws(function() { osrm.table(options, function() {}); },
/Coordinates must be an array of \(lon\/lat\) pairs/);
options.coordinates = [[13.393252,52.542648]];
options.coordinates = [three_test_coordinates[0]];
assert.throws(function() { osrm.table(options, function(err, response) {}) },
/At least two coordinates must be provided/);
options.coordinates = [13.393252,52.542648];
options.coordinates = three_test_coordinates[0];
assert.throws(function() { osrm.table(options, function(err, response) {}) },
/Coordinates must be an array of \(lon\/lat\) pairs/);
options.coordinates = [[13.393252],[52.542648]];
options.coordinates = [three_test_coordinates[0][0], three_test_coordinates[0][1]];
assert.throws(function() { osrm.table(options, function(err, response) {}) },
/Coordinates must be an array of \(lon\/lat\) pairs/);
options.coordinates = [[13.393252,52.542648],[13.393252,52.542648]];
options.coordinates = two_test_coordinates;
options.sources = true;
assert.throws(function() { osrm.table(options, function(err, response) {}) },
/Sources must be an array of indices \(or undefined\)/);
@@ -110,22 +117,22 @@ test('table: throws on invalid arguments', function(assert) {
assert.doesNotThrow(function() { osrm.table(options, function(err, response) {}) },
/You can either specify sources and destinations, or coordinates/);
assert.throws(function() { osrm.route({coordinates: [[13.43864,52.51993],[13.415852,52.513191]], generate_hints: null}, function(err, route) {}) },
assert.throws(function() { osrm.route({coordinates: two_test_coordinates, generate_hints: null}, function(err, route) {}) },
/generate_hints must be of type Boolean/);
});
test('table: throws on invalid arguments', function(assert) {
assert.plan(1);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
assert.throws(function() { osrm.table(null, function() {}); },
/First arg must be an object/);
});
test('table: distance table in Berlin with hints', function(assert) {
test('table: distance table in Monaco with hints', function(assert) {
assert.plan(5);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
generate_hints: true // true is default but be explicit here
};
osrm.table(options, function(err, table) {
@@ -141,11 +148,11 @@ test('table: distance table in Berlin with hints', function(assert) {
});
});
test('table: distance table in Berlin without hints', function(assert) {
test('table: distance table in Monaco without hints', function(assert) {
assert.plan(5);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
generate_hints: false // true is default
};
osrm.table(options, function(err, table) {
+15 -13
View File
@@ -1,23 +1,25 @@
var OSRM = require('../../');
var test = require('tape');
var berlin_path = "test/data/berlin-latest.osrm";
var data_path = require('./constants').data_path;
var tile = require('./constants').test_tile;
test.test('tile check size coarse', function(assert) {
assert.plan(2);
var osrm = new OSRM(berlin_path);
osrm.tile([17603, 10747, 15], function(err, result) {
var osrm = new OSRM(data_path);
osrm.tile(tile.at, function(err, result) {
assert.ifError(err);
assert.ok(result.length > 35000);
assert.ok(result.length > tile.size);
});
});
// FIXME the size of the tile that is returned depends on the architecture
// See issue #3343 in osrm-backend
test.skip('tile', function(assert) {
assert.plan(2);
var osrm = new OSRM(berlin_path);
osrm.tile([17603, 10747, 15], function(err, result) {
assert.ifError(err);
assert.equal(result.length, 35970);
});
test.test('tile interface pre-conditions', function(assert) {
assert.plan(6);
var osrm = new OSRM(data_path);
assert.throws(function() { osrm.tile(null, function(err, result) {}) }, /must be an array \[x, y, z\]/);
assert.throws(function() { osrm.tile([], function(err, result) {}) }, /must be an array \[x, y, z\]/);
assert.throws(function() { osrm.tile([[]], function(err, result) {}) }, /must be an array \[x, y, z\]/);
assert.throws(function() { osrm.tile(undefined, function(err, result) {}) }, /must be an array \[x, y, z\]/);
assert.throws(function() { osrm.tile(17059, 11948, 15, function(err, result) {}) }, /must be an array \[x, y, z\]/);
assert.throws(function() { osrm.tile([17059, 11948, -15], function(err, result) {}) }, /must be unsigned/);
});
+50 -56
View File
@@ -1,11 +1,14 @@
var OSRM = require('../../');
var test = require('tape');
var berlin_path = require('./osrm-data-path').data_path;
var data_path = require('./constants').data_path;
var three_test_coordinates = require('./constants').three_test_coordinates;
var two_test_coordinates = require('./constants').two_test_coordinates;
test('trip: trip in Berlin', function(assert) {
test('trip: trip in Monaco', function(assert) {
assert.plan(2);
var osrm = new OSRM(berlin_path);
osrm.trip({coordinates: [[13.36761474609375,52.51663871100423],[13.374481201171875,52.506191342034576]]}, function(err, trip) {
var osrm = new OSRM(data_path);
osrm.trip({coordinates: two_test_coordinates}, function(err, trip) {
assert.ifError(err);
for (t = 0; t < trip.trips.length; t++) {
assert.ok(trip.trips[t].geometry);
@@ -13,28 +16,25 @@ test('trip: trip in Berlin', function(assert) {
});
});
test('trip: trip with many locations in Berlin', function(assert) {
assert.plan(4);
var osrm = new OSRM(berlin_path);
var opts = {coordinates: [[13.36761474609375,52.51663871100423],[13.374481201171875,52.506191342034576],[13.404693603515625,52.50535544522142],[13.388900756835938,52.50159371284434],[13.386840820312498,52.518727886767266],[13.4088134765625,52.528754547664185],[13.41156005859375,52.51705655410405],[13.420486450195312,52.512042174642346],[13.413619995117188,52.50368360390624],[13.36212158203125,52.504101570196205],[13.35113525390625,52.52248815280757],[13.36761474609375,52.53460237630516],[13.383407592773438,52.53710835019913],[13.392333984375,52.536690697815736],[13.42529296875,52.532931647583325],[13.399200439453125,52.52415927884915],[13.390960693359375,52.51956352925745],[13.375167846679688,52.533349335723294],[13.37860107421875,52.520399155853454],[13.355255126953125,52.52081696319122],[13.385467529296875,52.5143405029259],[13.398857116699219,52.513086884218325],[13.399200439453125,52.50744515744915],[13.409500122070312,52.49783165855699],[13.424949645996094,52.500339730516934],[13.440055847167969,52.50786308797268],[13.428382873535156,52.511624283857785],[13.437652587890625,52.50451953251202],[13.443145751953125,52.5199813445422],[13.431129455566406,52.52520370034151],[13.418426513671875,52.52896341209634],[13.429069519042969,52.517474393230245],[13.418083190917969,52.528127948407935],[13.405036926269531,52.52833681581998],[13.384437561035156,52.53084314728766],[13.374481201171875,52.53084314728766],[13.3978271484375,52.532305107923925],[13.418769836425781,52.526039219655445],[13.441085815429688,52.51642978796417],[13.448638916015625,52.51601193890388],[13.44623565673828,52.50535544522142],[13.430442810058594,52.502638670794546],[13.358688354492188,52.520190250694526],[13.358001708984375,52.531887409851336],[13.367271423339842,52.528545682238736],[13.387870788574219,52.52958999943304],[13.406410217285156,52.53961418106945],[13.399543762207031,52.50556442091497],[13.374824523925781,52.50389258754797],[13.386154174804688,52.51099744023003],[13.40229034423828,52.49657756892365]]
};
test('trip: trip with many locations in Monaco', function(assert) {
assert.plan(2);
var many = 5;
var osrm = new OSRM(data_path);
var opts = {coordinates: three_test_coordinates.slice(0, many)};
osrm.trip(opts, function(err, trip) {
assert.ifError(err);
for (t = 0; t < trip.trips.length; t++) {
assert.ok(trip.trips[t].geometry);
}
assert.equal(opts.coordinates.length, trip.waypoints.length);
var indexMap = trip.waypoints.map(function(wp, i) {
return [i, wp.waypoint_index];
});
assert.ok(!indexMap.every(function(tuple) { return tuple[0] === tuple[1]; }));
});
});
test('trip: throws with too few or invalid args', function(assert) {
assert.plan(2);
var osrm = new OSRM(berlin_path);
assert.throws(function() { osrm.trip({coordinates: [[13.43864,52.51993],[13.415852,52.513191]]}) },
var osrm = new OSRM(data_path);
assert.throws(function() { osrm.trip({coordinates: two_test_coordinates}) },
/Two arguments required/);
assert.throws(function() { osrm.trip(null, function(err, trip) {}) },
/First arg must be an object/);
@@ -42,7 +42,7 @@ test('trip: throws with too few or invalid args', function(assert) {
test('trip: throws with bad params', function(assert) {
assert.plan(14);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
assert.throws(function () { osrm.trip({coordinates: []}, function(err) {}) });
assert.throws(function() { osrm.trip({}, function(err, trip) {}) },
/Must provide a coordinates property/);
@@ -51,22 +51,21 @@ test('trip: throws with bad params', function(assert) {
}, function(err, trip) {}) },
/Coordinates must be an array of \(lon\/lat\) pairs/);
assert.throws(function() { osrm.trip({
coordinates: [13.438640, 52.519930]
coordinates: three_test_coordinates[0]
}, function(err, trip) {}) },
/Coordinates must be an array of \(lon\/lat\) pairs/);
assert.throws(function() { osrm.trip({
coordinates: [[13.438640], [52.519930]]
coordinates: [three_test_coordinates[0][0], three_test_coordinates[0][1]]
}, function(err, trip) {}) },
/Coordinates must be an array of \(lon\/lat\) pairs/);
assert.throws(function() { osrm.trip({
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
hints: null
}, function(err, trip) {}) },
/Hints must be an array of strings\/null/);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
printInstructions: false,
hints: [13.438640, 52.519930]
coordinates: [three_test_coordinates[0], three_test_coordinates[1]],
hints: three_test_coordinates[0]
};
assert.throws(function() { osrm.trip(options, function(err, trip) {}); },
/Hint must be null or string/);
@@ -96,10 +95,10 @@ test('trip: throws with bad params', function(assert) {
/'roundtrip' param must be a boolean/);
});
test('trip: routes Berlin using shared memory', function(assert) {
test('trip: routes Monaco using shared memory', function(assert) {
assert.plan(2);
var osrm = new OSRM();
osrm.trip({coordinates: [[13.43864,52.51993],[13.415852,52.513191]]}, function(err, trip) {
osrm.trip({coordinates: two_test_coordinates}, function(err, trip) {
assert.ifError(err);
for (t = 0; t < trip.trips.length; t++) {
assert.ok(trip.trips[t].geometry);
@@ -107,11 +106,11 @@ test('trip: routes Berlin using shared memory', function(assert) {
});
});
test('trip: routes Berlin with hints', function(assert) {
test('trip: routes Monaco with hints', function(assert) {
assert.plan(5);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
steps: false
};
osrm.trip(options, function(err, first) {
@@ -130,11 +129,11 @@ test('trip: routes Berlin with hints', function(assert) {
});
});
test('trip: trip through Berlin with geometry compression', function(assert) {
test('trip: trip through Monaco with geometry compression', function(assert) {
assert.plan(2);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]]
coordinates: [three_test_coordinates[0], three_test_coordinates[1]]
};
osrm.trip(options, function(err, trip) {
assert.ifError(err);
@@ -144,11 +143,11 @@ test('trip: trip through Berlin with geometry compression', function(assert) {
});
});
test('trip: trip through Berlin without geometry compression', function(assert) {
test('trip: trip through Monaco without geometry compression', function(assert) {
assert.plan(2);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
geometries: 'geojson'
};
osrm.trip(options, function(err, trip) {
@@ -159,11 +158,11 @@ test('trip: trip through Berlin without geometry compression', function(assert)
});
});
test('trip: trip through Berlin with speed annotations options', function(assert) {
test('trip: trip through Monaco with speed annotations options', function(assert) {
assert.plan(12);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
steps: true,
annotations: ['speed'],
overview: 'false'
@@ -186,11 +185,11 @@ test('trip: trip through Berlin with speed annotations options', function(assert
});
});
test('trip: trip through Berlin with several (duration, distance, nodes) annotations options', function(assert) {
test('trip: trip through Monaco with several (duration, distance, nodes) annotations options', function(assert) {
assert.plan(12);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
steps: true,
annotations: ['duration', 'distance', 'nodes'],
overview: 'false'
@@ -213,11 +212,11 @@ test('trip: trip through Berlin with several (duration, distance, nodes) annotat
});
});
test('trip: trip through Berlin with options', function(assert) {
test('trip: trip through Monaco with options', function(assert) {
assert.plan(6);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
steps: true,
annotations: true,
overview: 'false'
@@ -234,12 +233,11 @@ test('trip: trip through Berlin with options', function(assert) {
});
});
test('trip: routes Berlin with null hints', function(assert) {
test('trip: routes Monaco with null hints', function(assert) {
assert.plan(1);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
printInstructions: false,
coordinates: [three_test_coordinates[0], three_test_coordinates[1]],
hints: [null, null]
};
osrm.trip(options, function(err, second) {
@@ -249,11 +247,11 @@ test('trip: routes Berlin with null hints', function(assert) {
test('trip: service combinations that are not implemented', function(assert) {
assert.plan(3);
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
// fixed start, non-roundtrip
var options = {
coordinates: [[13.43864,52.51993],[13.415852,52.513191]],
coordinates: two_test_coordinates,
source: 'first',
roundtrip: false
};
@@ -278,10 +276,10 @@ test('trip: service combinations that are not implemented', function(assert) {
});
test('trip: fixed start and end combinations', function(assert) {
var osrm = new OSRM(berlin_path);
var osrm = new OSRM(data_path);
var options = {
coordinates: [[13.36761474609375,52.51663871100423],[13.374481201171875,52.506191342034576]],
coordinates: two_test_coordinates,
source: 'first',
destination: 'last',
roundtrip: false,
@@ -291,10 +289,8 @@ test('trip: fixed start and end combinations', function(assert) {
// fixed start and end, non-roundtrip
osrm.trip(options, function(err, fseTrip) {
assert.ifError(err);
assert.equal(206.8, fseTrip.trips[0].duration);
assert.equal(1, fseTrip.trips.length);
var coordinates = fseTrip.trips[0].geometry.coordinates;
assert.equal(15, coordinates.length);
assert.notEqual(JSON.stringify(coordinates[0]), JSON.stringify(coordinates[coordinates.length - 1]));
});
@@ -304,9 +300,7 @@ test('trip: fixed start and end combinations', function(assert) {
osrm.trip(options, function(err, trip) {
assert.ifError(err);
assert.equal(1, trip.trips.length);
assert.equal(422, Math.round(trip.trips[0].duration));
var coordinates = trip.trips[0].geometry.coordinates;
assert.equal(29, coordinates.length);
assert.equal(JSON.stringify(coordinates[0]), JSON.stringify(coordinates[coordinates.length - 1]));
});
}
+2 -1
View File
@@ -38,7 +38,8 @@ auto makeGraph(const MultiLevelPartition &mlp, const std::vector<MockEdge> &mock
edges.push_back(Edge{m.target, m.start, m.weight, false, true});
}
std::sort(edges.begin(), edges.end());
return partition::MultiLevelGraph<EdgeData, false>(mlp, max_id + 1, edges);
return partition::MultiLevelGraph<EdgeData, osrm::storage::Ownership::Container>(
mlp, max_id + 1, edges);
}
}
+132
View File
@@ -0,0 +1,132 @@
#include "engine/api/match_parameters_tidy.hpp"
#include <boost/test/test_case_template.hpp>
#include <boost/test/unit_test.hpp>
#include <algorithm>
#include <iterator>
#include <vector>
BOOST_AUTO_TEST_SUITE(tidy_test)
using namespace osrm;
using namespace osrm::util;
using namespace osrm::engine::api;
BOOST_AUTO_TEST_CASE(two_item_trace_already_tidied_test)
{
MatchParameters params;
params.coordinates.emplace_back(FloatLongitude{13.207993}, FloatLatitude{52.446379});
params.coordinates.emplace_back(FloatLongitude{13.231658}, FloatLatitude{52.465416});
params.timestamps.emplace_back(1477090402);
params.timestamps.emplace_back(1477090663);
tidy::Thresholds thresholds;
thresholds.distance_in_meters = 15.;
thresholds.duration_in_seconds = 5;
auto result = tidy::tidy(params, thresholds);
BOOST_CHECK_EQUAL(result.can_be_removed.size(), 2);
BOOST_CHECK_EQUAL(result.tidied_to_original.size(), 2);
BOOST_CHECK(result.can_be_removed[0] == false);
BOOST_CHECK(result.can_be_removed[1] == false);
BOOST_CHECK_EQUAL(result.tidied_to_original[0], 0);
BOOST_CHECK_EQUAL(result.tidied_to_original[1], 1);
}
BOOST_AUTO_TEST_CASE(two_item_trace_needs_tidiying_test)
{
MatchParameters params;
params.coordinates.emplace_back(FloatLongitude{13.207993}, FloatLatitude{52.446379});
params.coordinates.emplace_back(FloatLongitude{13.231658}, FloatLatitude{52.465416});
params.timestamps.emplace_back(1477090402);
params.timestamps.emplace_back(1477090663);
tidy::Thresholds thresholds;
thresholds.distance_in_meters = 5000;
thresholds.duration_in_seconds = 5 * 60;
auto result = tidy::tidy(params, thresholds);
BOOST_CHECK_EQUAL(result.can_be_removed.size(), 2);
BOOST_CHECK_EQUAL(result.tidied_to_original.size(), 1);
BOOST_CHECK_EQUAL(result.can_be_removed[0], false);
BOOST_CHECK_EQUAL(result.can_be_removed[1], true);
BOOST_CHECK_EQUAL(result.tidied_to_original[0], 0);
}
BOOST_AUTO_TEST_CASE(two_blobs_in_traces_needs_tidiying_test)
{
MatchParameters params;
params.coordinates.emplace_back(FloatLongitude{13.207993}, FloatLatitude{52.446379});
params.coordinates.emplace_back(FloatLongitude{13.207994}, FloatLatitude{52.446380});
params.coordinates.emplace_back(FloatLongitude{13.207995}, FloatLatitude{52.446381});
params.coordinates.emplace_back(FloatLongitude{13.231658}, FloatLatitude{52.465416});
params.coordinates.emplace_back(FloatLongitude{13.231659}, FloatLatitude{52.465417});
params.coordinates.emplace_back(FloatLongitude{13.231660}, FloatLatitude{52.465417});
params.timestamps.emplace_back(1477090402);
params.timestamps.emplace_back(1477090403);
params.timestamps.emplace_back(1477090404);
params.timestamps.emplace_back(1477090661);
params.timestamps.emplace_back(1477090662);
params.timestamps.emplace_back(1477090663);
tidy::Thresholds thresholds;
thresholds.distance_in_meters = 15;
thresholds.duration_in_seconds = 5;
auto result = tidy::tidy(params, thresholds);
BOOST_CHECK_EQUAL(result.can_be_removed.size(), params.coordinates.size());
BOOST_CHECK_EQUAL(result.tidied_to_original.size(), 2);
BOOST_CHECK_EQUAL(result.tidied_to_original[0], 0);
BOOST_CHECK_EQUAL(result.tidied_to_original[1], 3);
const auto redundant = result.can_be_removed.count();
BOOST_CHECK_EQUAL(redundant, params.coordinates.size() - 2);
BOOST_CHECK_EQUAL(result.can_be_removed[0], false);
BOOST_CHECK_EQUAL(result.can_be_removed[3], false);
}
BOOST_AUTO_TEST_CASE(two_blobs_in_traces_needs_tidiying_no_timestamps_test)
{
MatchParameters params;
params.coordinates.emplace_back(FloatLongitude{13.207993}, FloatLatitude{52.446379});
params.coordinates.emplace_back(FloatLongitude{13.207994}, FloatLatitude{52.446380});
params.coordinates.emplace_back(FloatLongitude{13.207995}, FloatLatitude{52.446381});
params.coordinates.emplace_back(FloatLongitude{13.231658}, FloatLatitude{52.465416});
params.coordinates.emplace_back(FloatLongitude{13.231659}, FloatLatitude{52.465417});
params.coordinates.emplace_back(FloatLongitude{13.231660}, FloatLatitude{52.465417});
tidy::Thresholds thresholds;
thresholds.distance_in_meters = 15;
thresholds.duration_in_seconds = 5;
auto result = tidy::tidy(params, thresholds);
BOOST_CHECK_EQUAL(result.can_be_removed.size(), params.coordinates.size());
BOOST_CHECK_EQUAL(result.tidied_to_original.size(), 2);
BOOST_CHECK_EQUAL(result.tidied_to_original[0], 0);
BOOST_CHECK_EQUAL(result.tidied_to_original[1], 3);
const auto redundant = result.can_be_removed.count();
BOOST_CHECK_EQUAL(redundant, params.coordinates.size() - 2);
BOOST_CHECK_EQUAL(result.can_be_removed[0], false);
BOOST_CHECK_EQUAL(result.can_be_removed[3], false);
}
BOOST_AUTO_TEST_SUITE_END()
+34 -8
View File
@@ -38,7 +38,7 @@ auto makeGraph(const MultiLevelPartition &mlp, const std::vector<MockEdge> &mock
edges.push_back(Edge{m.target, m.source, false, true});
}
std::sort(edges.begin(), edges.end());
return MultiLevelGraph<EdgeData, false>(mlp, max_id + 1, edges);
return MultiLevelGraph<EdgeData, osrm::storage::Ownership::Container>(mlp, max_id + 1, edges);
}
}
@@ -46,11 +46,11 @@ BOOST_AUTO_TEST_SUITE(multi_level_graph)
BOOST_AUTO_TEST_CASE(check_edges_sorting)
{
// node: 0 1 2 3 4 5 6 7 8 9 10 11 12
std::vector<CellID> l1{{0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6}};
std::vector<CellID> l2{{0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 4}};
std::vector<CellID> l3{{0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2}};
std::vector<CellID> l4{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}};
// node: 0 1 2 3 4 5 6 7 8 9 10 11 12 13
std::vector<CellID> l1{{0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6}};
std::vector<CellID> l2{{0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4}};
std::vector<CellID> l3{{0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2}};
std::vector<CellID> l4{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1}};
MultiLevelPartition mlp{{l1, l2, l3, l4}, {7, 5, 3, 2}};
std::vector<MockEdge> edges = {
@@ -69,7 +69,8 @@ BOOST_AUTO_TEST_CASE(check_edges_sorting)
{9, 8}, // i i i i
{10, 11}, // i i i i
{11, 10}, // i i i i
{11, 12} // b b b b
{11, 12}, // b b b b
{12, 13} // i i i i
};
auto graph = makeGraph(mlp, edges);
@@ -97,7 +98,7 @@ BOOST_AUTO_TEST_CASE(check_edges_sorting)
// the union of border and internal edge needs to equal the adjacent edges
for (auto level : util::irange<LevelID>(0, 4))
{
for (auto node : util::irange<NodeID>(0, 13))
for (auto node : util::irange<NodeID>(0, 14))
{
const auto adjacent = graph.GetAdjacentEdgeRange(node);
const auto border = graph.GetBorderEdgeRange(level, node);
@@ -122,6 +123,7 @@ BOOST_AUTO_TEST_CASE(check_edges_sorting)
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(1, 10).size(), 0);
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(1, 11).size(), 2);
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(1, 12).size(), 1);
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(1, 13).size(), 0);
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(2, 0).size(), 1);
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(2, 1).size(), 0);
@@ -136,6 +138,7 @@ BOOST_AUTO_TEST_CASE(check_edges_sorting)
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(2, 10).size(), 0);
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(2, 11).size(), 2);
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(2, 12).size(), 1);
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(2, 13).size(), 0);
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(3, 0).size(), 1);
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(3, 1).size(), 0);
@@ -150,6 +153,7 @@ BOOST_AUTO_TEST_CASE(check_edges_sorting)
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(3, 10).size(), 0);
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(3, 11).size(), 1);
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(3, 12).size(), 1);
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(3, 13).size(), 0);
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(4, 0).size(), 0);
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(4, 1).size(), 0);
@@ -164,6 +168,7 @@ BOOST_AUTO_TEST_CASE(check_edges_sorting)
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(4, 10).size(), 0);
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(4, 11).size(), 1);
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(3, 12).size(), 1);
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(4, 13).size(), 0);
CHECK_EQUAL_RANGE(graph.GetBorderEdgeRange(1, 0), graph.FindEdge(0, 4));
CHECK_EQUAL_RANGE(graph.GetBorderEdgeRange(1, 3), graph.FindEdge(3, 7));
@@ -194,4 +199,25 @@ BOOST_AUTO_TEST_CASE(check_edges_sorting)
CHECK_EQUAL_RANGE(graph.GetBorderEdgeRange(4, 12), graph.FindEdge(12, 11));
}
BOOST_AUTO_TEST_CASE(check_last_internal_edge)
{
// a--b--c--d
std::vector<CellID> l1{{0, 0, 1, 1}};
std::vector<CellID> l2{{0, 0, 1, 1}};
MultiLevelPartition mlp{{l1, l2}, {2, 2}};
std::vector<MockEdge> edges = {{0, 1}, {1, 0}, {1, 2}, {2, 1}, {2, 3}, {3, 2}};
auto graph = makeGraph(mlp, edges);
auto all_edges = graph.GetAdjacentEdgeRange(3);
CHECK_EQUAL_COLLECTIONS(graph.GetBorderEdgeRange(0, 3), all_edges);
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(1, 3).size(), 0);
BOOST_CHECK_EQUAL(graph.GetBorderEdgeRange(2, 3).size(), 0);
BOOST_CHECK_EQUAL(graph.GetInternalEdgeRange(0, 3).size(), 0);
CHECK_EQUAL_COLLECTIONS(graph.GetInternalEdgeRange(1, 3), all_edges);
CHECK_EQUAL_COLLECTIONS(graph.GetInternalEdgeRange(2, 3), all_edges);
}
BOOST_AUTO_TEST_SUITE_END()
+2 -2
View File
@@ -12,7 +12,7 @@ using namespace osrm::util;
// Verify that the packed vector behaves as expected
BOOST_AUTO_TEST_CASE(insert_and_retrieve_packed_test)
{
PackedVector<OSMNodeID, false> packed_ids;
PackedVector<OSMNodeID, osrm::storage::Ownership::Container> packed_ids;
std::vector<OSMNodeID> original_ids;
const constexpr std::size_t num_test_cases = 399;
@@ -33,7 +33,7 @@ BOOST_AUTO_TEST_CASE(insert_and_retrieve_packed_test)
BOOST_AUTO_TEST_CASE(packed_vector_capacity_test)
{
PackedVector<OSMNodeID, false> packed_vec;
PackedVector<OSMNodeID, osrm::storage::Ownership::Container> packed_vec;
const std::size_t original_size = packed_vec.capacity();
std::vector<OSMNodeID> dummy_vec;
+1 -1
View File
@@ -13,7 +13,7 @@ using namespace osrm;
using namespace osrm::util;
constexpr unsigned BLOCK_SIZE = 16;
typedef RangeTable<BLOCK_SIZE, false> TestRangeTable;
typedef RangeTable<BLOCK_SIZE, osrm::storage::Ownership::Container> TestRangeTable;
void ConstructionTest(stxxl::vector<unsigned> lengths, std::vector<unsigned> offsets)
{
+2 -2
View File
@@ -70,8 +70,8 @@ template <unsigned NUM_NODES, unsigned NUM_EDGES> struct RandomArrayEntryFixture
std::shuffle(order.begin(), order.end(), g);
}
typename ShM<TestNodeArrayEntry, false>::vector nodes;
typename ShM<TestEdgeArrayEntry, false>::vector edges;
std::vector<TestNodeArrayEntry> nodes;
std::vector<TestEdgeArrayEntry> edges;
std::vector<unsigned> lengths;
std::vector<unsigned> order;
};
+5 -3
View File
@@ -42,10 +42,11 @@ constexpr uint32_t TEST_LEAF_NODE_SIZE = 64;
using TestData = extractor::EdgeBasedNode;
using TestStaticRTree = StaticRTree<TestData,
std::vector<Coordinate>,
false,
osrm::storage::Ownership::Container,
TEST_BRANCHING_FACTOR,
TEST_LEAF_NODE_SIZE>;
using MiniStaticRTree = StaticRTree<TestData, std::vector<Coordinate>, false, 2, 128>;
using MiniStaticRTree =
StaticRTree<TestData, std::vector<Coordinate>, osrm::storage::Ownership::Container, 2, 128>;
// Choosen by a fair W20 dice roll (this value is completely arbitrary)
constexpr unsigned RANDOM_SEED = 42;
@@ -273,7 +274,8 @@ void construction_test(const std::string &prefix, FixtureT *fixture)
BOOST_FIXTURE_TEST_CASE(construct_tiny, TestRandomGraphFixture_10_30)
{
using TinyTestTree = StaticRTree<TestData, std::vector<Coordinate>, false, 2, 64>;
using TinyTestTree =
StaticRTree<TestData, std::vector<Coordinate>, osrm::storage::Ownership::Container, 2, 64>;
construction_test<TinyTestTree>("test_tiny", this);
}