Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 04ee126297 | |||
| 3f7a629db8 | |||
| 750826215f | |||
| ee008e75e5 | |||
| 3080be59ed | |||
| a7142ee737 | |||
| eb72ca4941 | |||
| b887e72d0b | |||
| be1b86657c | |||
| 62298cf409 | |||
| afe34456b9 | |||
| 2f75d6f22b | |||
| c28a6832d7 | |||
| 061f0a1f14 | |||
| 60e283312c | |||
| f97e18d285 | |||
| 7b73b977ff | |||
| 97883178fa | |||
| 350862d177 | |||
| 4432756de1 | |||
| 3558ec9db4 | |||
| 36f3a5eec8 | |||
| 5d468f2897 | |||
| 72ea34f3b7 | |||
| 7f635f2ed6 | |||
| 8a4af59838 | |||
| 16685d0de9 | |||
| 82897791d1 | |||
| 9ad432c5b2 | |||
| c1d2c15995 | |||
| fb1bb7a15b | |||
| d65e8c7d1e | |||
| 5e5f1f4add | |||
| 9d160a9b5d |
+460
-511
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,20 @@
|
|||||||
# Unreleased
|
# Unreleased
|
||||||
|
- Changes from 5.27.1
|
||||||
|
- Build:
|
||||||
|
- CHANGED: Update actions/cache to v3. [#6420](https://github.com/Project-OSRM/osrm-backend/pull/6420)
|
||||||
|
- Misc:
|
||||||
|
- FIXED: Handle snapping parameter for all plugins in NodeJs bindings, but not for Route only. [#6417](https://github.com/Project-OSRM/osrm-backend/pull/6417)
|
||||||
|
- FIXED: Fix annotations=true handling in NodeJS bindings & libosrm. [#6415](https://github.com/Project-OSRM/osrm-backend/pull/6415/)
|
||||||
|
- FIXED: Fix bindings compilation issue on the latest Node. Update NAN to 2.17.0. [#6416](https://github.com/Project-OSRM/osrm-backend/pull/6416)
|
||||||
|
- CHANGED: Make edge metrics strongly typed [#6420](https://github.com/Project-OSRM/osrm-backend/pull/6420)
|
||||||
|
- FIXED: Typo in file name src/util/timed_historgram.cpp -> src/util/timed_histogram.cpp [#6428](https://github.com/Project-OSRM/osrm-backend/issues/6428)
|
||||||
|
- Routing:
|
||||||
|
- ADDED: Stop and give way signs are now taken into account in car profile. [#6426](https://github.com/Project-OSRM/osrm-backend/pull/6426)
|
||||||
|
- FIXED: Fix adding traffic signal penalties during compression [#6419](https://github.com/Project-OSRM/osrm-backend/pull/6419)
|
||||||
|
# 5.27.1
|
||||||
- Changes from 5.27.0
|
- Changes from 5.27.0
|
||||||
- Misc:
|
- Misc:
|
||||||
|
- FIXED: Revert back to using custom HTTP parser instead of Boost.Beast. [#6407](https://github.com/Project-OSRM/osrm-backend/pull/6407)
|
||||||
- FIXED: Fix bug with large HTTP requests leading to Bad Request in osrm-routed. [#6403](https://github.com/Project-OSRM/osrm-backend/pull/6403)
|
- FIXED: Fix bug with large HTTP requests leading to Bad Request in osrm-routed. [#6403](https://github.com/Project-OSRM/osrm-backend/pull/6403)
|
||||||
- Routing:
|
- Routing:
|
||||||
- CHANGED: Add support for surface=metal,grass_paver,woodchips in bicyle profile. [#6395](https://github.com/Project-OSRM/osrm-backend/pull/6395)
|
- CHANGED: Add support for surface=metal,grass_paver,woodchips in bicyle profile. [#6395](https://github.com/Project-OSRM/osrm-backend/pull/6395)
|
||||||
|
|||||||
+2
-6
@@ -492,9 +492,6 @@ if(ENABLE_CONAN)
|
|||||||
set(TBB_SHARED True)
|
set(TBB_SHARED True)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT CONAN_CMAKE_SYSTEM_PROCESSOR)
|
|
||||||
set(CONAN_CMAKE_SYSTEM_PROCESSOR ${CMAKE_SYSTEM_PROCESSOR})
|
|
||||||
endif()
|
|
||||||
set(CONAN_ARGS
|
set(CONAN_ARGS
|
||||||
REQUIRES
|
REQUIRES
|
||||||
"boost/${CONAN_BOOST_VERSION}"
|
"boost/${CONAN_BOOST_VERSION}"
|
||||||
@@ -506,7 +503,6 @@ if(ENABLE_CONAN)
|
|||||||
GENERATORS cmake_find_package json # json generator generates a conanbuildinfo.json in the build folder so (non-CMake) projects can easily parse OSRM's dependencies
|
GENERATORS cmake_find_package json # json generator generates a conanbuildinfo.json in the build folder so (non-CMake) projects can easily parse OSRM's dependencies
|
||||||
KEEP_RPATHS
|
KEEP_RPATHS
|
||||||
NO_OUTPUT_DIRS
|
NO_OUTPUT_DIRS
|
||||||
ENV CONAN_CMAKE_SYSTEM_PROCESSOR=aarch64
|
|
||||||
OPTIONS boost:filesystem_version=3 # https://stackoverflow.com/questions/73392648/error-with-boost-filesystem-version-in-cmake
|
OPTIONS boost:filesystem_version=3 # https://stackoverflow.com/questions/73392648/error-with-boost-filesystem-version-in-cmake
|
||||||
onetbb:shared=${TBB_SHARED}
|
onetbb:shared=${TBB_SHARED}
|
||||||
boost:without_stacktrace=True # Apple Silicon cross-compilation fails without it
|
boost:without_stacktrace=True # Apple Silicon cross-compilation fails without it
|
||||||
@@ -515,8 +511,8 @@ if(ENABLE_CONAN)
|
|||||||
# explicitly say Conan to use x86 dependencies if build for x86 platforms (https://github.com/conan-io/cmake-conan/issues/141)
|
# explicitly say Conan to use x86 dependencies if build for x86 platforms (https://github.com/conan-io/cmake-conan/issues/141)
|
||||||
if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
|
if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
conan_cmake_run("${CONAN_ARGS};ARCH;x86")
|
conan_cmake_run("${CONAN_ARGS};ARCH;x86")
|
||||||
# cross-compilation for arm64 processors
|
# cross-compilation for Apple Silicon
|
||||||
elseif((CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") AND CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64")
|
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64" AND CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64")
|
||||||
conan_cmake_run("${CONAN_ARGS};ARCH;armv8")
|
conan_cmake_run("${CONAN_ARGS};ARCH;armv8")
|
||||||
else()
|
else()
|
||||||
conan_cmake_run("${CONAN_ARGS}")
|
conan_cmake_run("${CONAN_ARGS}")
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
## Open Source Routing Machine
|
## Open Source Routing Machine
|
||||||
|
|
||||||
| Linux / macOS / Windows | Code Coverage |
|
|
||||||
| ----------------------- | ------------- |
|
[](https://github.com/Project-OSRM/osrm-backend/actions/workflows/osrm-backend.yml) [](https://codecov.io/gh/Project-OSRM/osrm-backend) [](https://discord.gg/es9CdcCXcb)
|
||||||
| [](https://github.com/Project-OSRM/osrm-backend/actions/workflows/osrm-backend.yml) | [](https://codecov.io/gh/Project-OSRM/osrm-backend) |
|
|
||||||
|
|
||||||
High performance routing engine written in C++14 designed to run on OpenStreetMap data.
|
High performance routing engine written in C++14 designed to run on OpenStreetMap data.
|
||||||
|
|
||||||
@@ -33,6 +32,7 @@ Related [Project-OSRM](https://github.com/Project-OSRM) repositories:
|
|||||||
|
|
||||||
## Contact
|
## Contact
|
||||||
|
|
||||||
|
- Discord: [https://discord.gg/es9CdcCXcb](join)
|
||||||
- IRC: `irc.oftc.net`, channel: `#osrm` ([Webchat](https://webchat.oftc.net))
|
- IRC: `irc.oftc.net`, channel: `#osrm` ([Webchat](https://webchat.oftc.net))
|
||||||
- Mailinglist: `https://lists.openstreetmap.org/listinfo/osrm-talk`
|
- Mailinglist: `https://lists.openstreetmap.org/listinfo/osrm-talk`
|
||||||
|
|
||||||
|
|||||||
@@ -1,75 +0,0 @@
|
|||||||
{
|
|
||||||
"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"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
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')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
@routing @car @give_way_sign
|
||||||
|
Feature: Car - Handle give way signs
|
||||||
|
|
||||||
|
Background:
|
||||||
|
Given the profile "car"
|
||||||
|
|
||||||
|
Scenario: Car - Encounters a give way sign
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a-1-b-2-c
|
||||||
|
|
||||||
|
d-3-e-4-f
|
||||||
|
|
||||||
|
g-h-i k-l-m
|
||||||
|
| |
|
||||||
|
j n
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| def | primary |
|
||||||
|
| ghi | primary |
|
||||||
|
| klm | primary |
|
||||||
|
| hj | primary |
|
||||||
|
| ln | primary |
|
||||||
|
|
||||||
|
And the nodes
|
||||||
|
| node | highway |
|
||||||
|
| e | give_way |
|
||||||
|
| l | give_way |
|
||||||
|
|
||||||
|
# TODO: give way signs with no direction has no any impact on routing at the moment
|
||||||
|
When I route I should get
|
||||||
|
| from | to | time | # |
|
||||||
|
| 1 | 2 | 11.1s | no turn with no give way |
|
||||||
|
| 3 | 4 | 11.1s | no turn with give way |
|
||||||
|
| g | j | 18.7s | turn with no give way |
|
||||||
|
| k | n | 18.7s | turn with give way |
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: Car - Give way direction
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a-1-b-2-c
|
||||||
|
|
||||||
|
d-3-e-4-f
|
||||||
|
|
||||||
|
g-5-h-6-i
|
||||||
|
|
||||||
|
j-7-k-8-l
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| def | primary |
|
||||||
|
| ghi | primary |
|
||||||
|
| jkl | primary |
|
||||||
|
|
||||||
|
And the nodes
|
||||||
|
| node | highway | direction |
|
||||||
|
| e | give_way | |
|
||||||
|
| h | give_way | forward |
|
||||||
|
| k | give_way | backward |
|
||||||
|
When I route I should get
|
||||||
|
| from | to | time | weight | # |
|
||||||
|
| 1 | 2 | 11.1s | 11.1 | no turn with no give way |
|
||||||
|
| 2 | 1 | 11.1s | 11.1 | no turn with no give way |
|
||||||
|
| 3 | 4 | 11.1s | 11.1 | no turn with give way |
|
||||||
|
| 4 | 3 | 11.1s | 11.1 | no turn with give way |
|
||||||
|
| 5 | 6 | 12.6s | 12.6 | no turn with give way |
|
||||||
|
| 6 | 5 | 11.1s | 11.1 | no turn with no give way |
|
||||||
|
| 7 | 8 | 11.1s | 11.1 | no turn with no give way |
|
||||||
|
| 8 | 7 | 12.6s | 12.6 | no turn with give way |
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
@routing @car @stop_sign
|
||||||
|
Feature: Car - Handle stop signs
|
||||||
|
|
||||||
|
Background:
|
||||||
|
Given the profile "car"
|
||||||
|
|
||||||
|
Scenario: Car - Encounters a stop sign
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a-1-b-2-c
|
||||||
|
|
||||||
|
d-3-e-4-f
|
||||||
|
|
||||||
|
g-h-i k-l-m
|
||||||
|
| |
|
||||||
|
j n
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| def | primary |
|
||||||
|
| ghi | primary |
|
||||||
|
| klm | primary |
|
||||||
|
| hj | primary |
|
||||||
|
| ln | primary |
|
||||||
|
|
||||||
|
And the nodes
|
||||||
|
| node | highway |
|
||||||
|
| e | stop |
|
||||||
|
| l | stop |
|
||||||
|
|
||||||
|
# TODO: stop signs with no direction has no any impact on routing at the moment
|
||||||
|
When I route I should get
|
||||||
|
| from | to | time | # |
|
||||||
|
| 1 | 2 | 11.1s | no turn with no stop sign |
|
||||||
|
| 3 | 4 | 11.1s | no turn with stop sign |
|
||||||
|
| g | j | 18.7s | turn with no stop sign |
|
||||||
|
| k | n | 18.7s | turn with stop sign |
|
||||||
|
|
||||||
|
Scenario: Car - Stop sign direction
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a-1-b-2-c
|
||||||
|
|
||||||
|
d-3-e-4-f
|
||||||
|
|
||||||
|
g-5-h-6-i
|
||||||
|
|
||||||
|
j-7-k-8-l
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| def | primary |
|
||||||
|
| ghi | primary |
|
||||||
|
| jkl | primary |
|
||||||
|
|
||||||
|
And the nodes
|
||||||
|
| node | highway | direction |
|
||||||
|
| e | stop | |
|
||||||
|
| h | stop | forward |
|
||||||
|
| k | stop | backward |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | time | weight | # |
|
||||||
|
| 1 | 2 | 11.1s | 11.1 | no turn with no stop sign |
|
||||||
|
| 2 | 1 | 11.1s | 11.1 | no turn with no stop sign |
|
||||||
|
| 3 | 4 | 11.1s | 11.1 | no turn with stop sign |
|
||||||
|
| 4 | 3 | 11.1s | 11.1 | no turn with stop sign |
|
||||||
|
| 5 | 6 | 13.1s | 13.1 | no turn with stop sign |
|
||||||
|
| 6 | 5 | 11.1s | 11.1 | no turn with no stop sign |
|
||||||
|
| 7 | 8 | 11.1s | 11.1 | no turn with no stop sign |
|
||||||
|
| 8 | 7 | 13.1s | 13.1 | no turn with stop sign |
|
||||||
@@ -66,15 +66,50 @@ Feature: Car - Handle traffic lights
|
|||||||
| k | traffic_signals | backward |
|
| k | traffic_signals | backward |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | time | # |
|
| from | to | time | weight | # |
|
||||||
| 1 | 2 | 11.1s | no turn with no traffic light |
|
| 1 | 2 | 11.1s | 11.1 | no turn with no traffic light |
|
||||||
| 2 | 1 | 11.1s | no turn with no traffic light |
|
| 2 | 1 | 11.1s | 11.1 | no turn with no traffic light |
|
||||||
| 3 | 4 | 13.1s | no turn with traffic light |
|
| 3 | 4 | 13.1s | 13.1 | no turn with traffic light |
|
||||||
| 4 | 3 | 13.1s | no turn with traffic light |
|
| 4 | 3 | 13.1s | 13.1 | no turn with traffic light |
|
||||||
| 5 | 6 | 13.1s | no turn with traffic light |
|
| 5 | 6 | 13.1s | 13.1 | no turn with traffic light |
|
||||||
| 6 | 5 | 11.1s | no turn with no traffic light |
|
| 6 | 5 | 11.1s | 11.1 | no turn with no traffic light |
|
||||||
| 7 | 8 | 11.1s | no turn with no traffic light |
|
| 7 | 8 | 11.1s | 11.1 | no turn with no traffic light |
|
||||||
| 8 | 7 | 13.1s | no turn with traffic light |
|
| 8 | 7 | 13.1s | 13.1 | no turn with traffic light |
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: Car - Traffic signal direction with distance weight
|
||||||
|
Given the profile file "car" initialized with
|
||||||
|
"""
|
||||||
|
profile.properties.weight_name = 'distance'
|
||||||
|
profile.properties.traffic_light_penalty = 100000
|
||||||
|
"""
|
||||||
|
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a---b---c
|
||||||
|
1 2
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
d-------f
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| adfc | primary |
|
||||||
|
|
||||||
|
And the nodes
|
||||||
|
| node | highway |
|
||||||
|
| b | traffic_signals |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | time | distances | weight | # |
|
||||||
|
| 1 | 2 | 100033.2s | 599.9m,0m | 599.8 | goes via the expensive traffic signal |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Scenario: Car - Encounters a traffic light
|
Scenario: Car - Encounters a traffic light
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
@routing @testbot @turn_function
|
@routing @testbot @turn_function
|
||||||
Feature: Turn Function Information
|
Feature: Turn Function Information
|
||||||
|
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the profile file
|
Given the profile file
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -55,4 +55,4 @@ module.exports = function () {
|
|||||||
assert.equal(this.processError.process, binary);
|
assert.equal(this.processError.process, binary);
|
||||||
assert.equal(parseInt(this.processError.code), parseInt(code));
|
assert.equal(parseInt(this.processError.code), parseInt(code));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
+2
-1
@@ -38,7 +38,8 @@ if (ENABLE_FUZZING)
|
|||||||
"table_parameters"
|
"table_parameters"
|
||||||
"tile_parameters"
|
"tile_parameters"
|
||||||
"trip_parameters"
|
"trip_parameters"
|
||||||
"url_parser")
|
"url_parser"
|
||||||
|
"request_parser")
|
||||||
|
|
||||||
foreach (target ${ServerTargets})
|
foreach (target ${ServerTargets})
|
||||||
add_fuzz_target(${target})
|
add_fuzz_target(${target})
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#include "server/request_parser.hpp"
|
||||||
|
#include "server/http/request.hpp"
|
||||||
|
|
||||||
|
#include "util.hpp"
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using osrm::server::RequestParser;
|
||||||
|
using osrm::server::http::request;
|
||||||
|
|
||||||
|
extern "C" int LLVMFuzzerTestOneInput(const unsigned char *data, unsigned long size)
|
||||||
|
{
|
||||||
|
std::string in(reinterpret_cast<const char *>(data), size);
|
||||||
|
|
||||||
|
auto first = begin(in);
|
||||||
|
auto last = end(in);
|
||||||
|
|
||||||
|
RequestParser parser;
|
||||||
|
request req;
|
||||||
|
|
||||||
|
// &(*it) is needed to go from iterator to underlying item to pointer to underlying item
|
||||||
|
parser.parse(req, &(*first), &(*last));
|
||||||
|
|
||||||
|
escape(&req);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -12,12 +12,12 @@ namespace contractor
|
|||||||
struct ContractorEdgeData
|
struct ContractorEdgeData
|
||||||
{
|
{
|
||||||
ContractorEdgeData()
|
ContractorEdgeData()
|
||||||
: weight(0), duration(0), distance(0), id(0), originalEdges(0), shortcut(0), forward(0),
|
: weight{0}, duration{0}, distance{0}, id(0), originalEdges(0), shortcut(0), forward(0),
|
||||||
backward(0)
|
backward(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
ContractorEdgeData(EdgeWeight weight,
|
ContractorEdgeData(EdgeWeight weight,
|
||||||
EdgeWeight duration,
|
EdgeDuration duration,
|
||||||
EdgeDistance distance,
|
EdgeDistance distance,
|
||||||
unsigned original_edges,
|
unsigned original_edges,
|
||||||
unsigned id,
|
unsigned id,
|
||||||
@@ -30,7 +30,7 @@ struct ContractorEdgeData
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
EdgeWeight weight;
|
EdgeWeight weight;
|
||||||
EdgeWeight duration;
|
EdgeDuration duration;
|
||||||
EdgeDistance distance;
|
EdgeDistance distance;
|
||||||
unsigned id;
|
unsigned id;
|
||||||
unsigned originalEdges : 29;
|
unsigned originalEdges : 29;
|
||||||
|
|||||||
@@ -29,18 +29,20 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
|
|||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
const unsigned int constexpr DAY_IN_DECI_SECONDS = 24 * 60 * 60 * 10;
|
const unsigned int constexpr DAY_IN_DECI_SECONDS = 24 * 60 * 60 * 10;
|
||||||
if (static_cast<unsigned int>(std::max(input_edge.data.weight, 1)) > DAY_IN_DECI_SECONDS)
|
if (from_alias<unsigned int>(std::max(input_edge.data.weight, EdgeWeight{1})) >
|
||||||
|
DAY_IN_DECI_SECONDS)
|
||||||
{
|
{
|
||||||
util::Log(logWARNING) << "Edge weight large -> "
|
util::Log(logWARNING) << "Edge weight large -> "
|
||||||
<< static_cast<unsigned int>(std::max(input_edge.data.weight, 1))
|
<< from_alias<unsigned int>(
|
||||||
|
std::max(input_edge.data.weight, EdgeWeight{1}))
|
||||||
<< " : " << static_cast<unsigned int>(input_edge.source) << " -> "
|
<< " : " << static_cast<unsigned int>(input_edge.source) << " -> "
|
||||||
<< static_cast<unsigned int>(input_edge.target);
|
<< static_cast<unsigned int>(input_edge.target);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
edges.emplace_back(input_edge.source,
|
edges.emplace_back(input_edge.source,
|
||||||
input_edge.target,
|
input_edge.target,
|
||||||
std::max(input_edge.data.weight, 1),
|
std::max(input_edge.data.weight, {1}),
|
||||||
input_edge.data.duration,
|
to_alias<EdgeDuration>(input_edge.data.duration),
|
||||||
input_edge.data.distance,
|
input_edge.data.distance,
|
||||||
1,
|
1,
|
||||||
input_edge.data.turn_id,
|
input_edge.data.turn_id,
|
||||||
@@ -50,8 +52,8 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
|
|||||||
|
|
||||||
edges.emplace_back(input_edge.target,
|
edges.emplace_back(input_edge.target,
|
||||||
input_edge.source,
|
input_edge.source,
|
||||||
std::max(input_edge.data.weight, 1),
|
std::max(input_edge.data.weight, {1}),
|
||||||
input_edge.data.duration,
|
to_alias<EdgeDuration>(input_edge.data.duration),
|
||||||
input_edge.data.distance,
|
input_edge.data.distance,
|
||||||
1,
|
1,
|
||||||
input_edge.data.turn_id,
|
input_edge.data.turn_id,
|
||||||
@@ -109,7 +111,7 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
|
|||||||
// merge edges (s,t) and (t,s) into bidirectional edge
|
// merge edges (s,t) and (t,s) into bidirectional edge
|
||||||
if (forward_edge.data.weight == reverse_edge.data.weight)
|
if (forward_edge.data.weight == reverse_edge.data.weight)
|
||||||
{
|
{
|
||||||
if ((int)forward_edge.data.weight != INVALID_EDGE_WEIGHT)
|
if (forward_edge.data.weight != INVALID_EDGE_WEIGHT)
|
||||||
{
|
{
|
||||||
forward_edge.data.backward = true;
|
forward_edge.data.backward = true;
|
||||||
edges[edge++] = forward_edge;
|
edges[edge++] = forward_edge;
|
||||||
@@ -117,11 +119,11 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // insert seperate edges
|
{ // insert seperate edges
|
||||||
if (((int)forward_edge.data.weight) != INVALID_EDGE_WEIGHT)
|
if (forward_edge.data.weight != INVALID_EDGE_WEIGHT)
|
||||||
{
|
{
|
||||||
edges[edge++] = forward_edge;
|
edges[edge++] = forward_edge;
|
||||||
}
|
}
|
||||||
if ((int)reverse_edge.data.weight != INVALID_EDGE_WEIGHT)
|
if (reverse_edge.data.weight != INVALID_EDGE_WEIGHT)
|
||||||
{
|
{
|
||||||
edges[edge++] = reverse_edge;
|
edges[edge++] = reverse_edge;
|
||||||
}
|
}
|
||||||
@@ -157,7 +159,7 @@ template <class Edge, typename GraphT> inline std::vector<Edge> toEdges(GraphT g
|
|||||||
new_edge.target = target;
|
new_edge.target = target;
|
||||||
BOOST_ASSERT_MSG(SPECIAL_NODEID != new_edge.target, "Target id invalid");
|
BOOST_ASSERT_MSG(SPECIAL_NODEID != new_edge.target, "Target id invalid");
|
||||||
new_edge.data.weight = data.weight;
|
new_edge.data.weight = data.weight;
|
||||||
new_edge.data.duration = data.duration;
|
new_edge.data.duration = from_alias<EdgeDuration::value_type>(data.duration);
|
||||||
new_edge.data.distance = data.distance;
|
new_edge.data.distance = data.distance;
|
||||||
new_edge.data.shortcut = data.shortcut;
|
new_edge.data.shortcut = data.shortcut;
|
||||||
new_edge.data.turn_id = data.id;
|
new_edge.data.turn_id = data.id;
|
||||||
|
|||||||
@@ -17,15 +17,15 @@ struct QueryEdge
|
|||||||
struct EdgeData
|
struct EdgeData
|
||||||
{
|
{
|
||||||
explicit EdgeData()
|
explicit EdgeData()
|
||||||
: turn_id(0), shortcut(false), weight(0), duration(0), forward(false), backward(false),
|
: turn_id(0), shortcut(false), weight{0}, duration(0), forward(false),
|
||||||
distance(0)
|
backward(false), distance{0}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
EdgeData(const NodeID turn_id,
|
EdgeData(const NodeID turn_id,
|
||||||
const bool shortcut,
|
const bool shortcut,
|
||||||
const EdgeWeight weight,
|
const EdgeWeight weight,
|
||||||
const EdgeWeight duration,
|
const EdgeDuration duration,
|
||||||
const EdgeDistance distance,
|
const EdgeDistance distance,
|
||||||
const bool forward,
|
const bool forward,
|
||||||
const bool backward)
|
const bool backward)
|
||||||
@@ -50,7 +50,7 @@ struct QueryEdge
|
|||||||
NodeID turn_id : 31;
|
NodeID turn_id : 31;
|
||||||
bool shortcut : 1;
|
bool shortcut : 1;
|
||||||
EdgeWeight weight;
|
EdgeWeight weight;
|
||||||
EdgeWeight duration : 30;
|
EdgeDuration::value_type duration : 30;
|
||||||
std::uint32_t forward : 1;
|
std::uint32_t forward : 1;
|
||||||
std::uint32_t backward : 1;
|
std::uint32_t backward : 1;
|
||||||
EdgeDistance distance;
|
EdgeDistance distance;
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ class CellCustomizer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
heap.Clear();
|
heap.Clear();
|
||||||
heap.Insert(source, 0, {false, 0, 0});
|
heap.Insert(source, {0}, {false, {0}, {0}});
|
||||||
|
|
||||||
// explore search space
|
// explore search space
|
||||||
while (!heap.Empty() && !destinations_set.empty())
|
while (!heap.Empty() && !destinations_set.empty())
|
||||||
@@ -216,12 +216,11 @@ class CellCustomizer
|
|||||||
partition.GetCell(level - 1, to)))
|
partition.GetCell(level - 1, to)))
|
||||||
{
|
{
|
||||||
const EdgeWeight to_weight = weight + data.weight;
|
const EdgeWeight to_weight = weight + data.weight;
|
||||||
const EdgeDuration to_duration = duration + data.duration;
|
const EdgeDuration to_duration = duration + to_alias<EdgeDuration>(data.duration);
|
||||||
const EdgeDistance to_distance = distance + data.distance;
|
const EdgeDistance to_distance = distance + data.distance;
|
||||||
if (!heap.WasInserted(to))
|
if (!heap.WasInserted(to))
|
||||||
{
|
{
|
||||||
heap.Insert(
|
heap.Insert(to, to_weight, {false, to_duration, to_distance});
|
||||||
to, to_weight, {false, duration + data.duration, distance + data.distance});
|
|
||||||
}
|
}
|
||||||
else if (std::tie(to_weight, to_duration, to_distance) <
|
else if (std::tie(to_weight, to_duration, to_distance) <
|
||||||
std::tie(
|
std::tie(
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ class MultiLevelGraph : public partitioner::MultiLevelGraph<EdgeDataT, Ownership
|
|||||||
|
|
||||||
EdgeWeight GetNodeWeight(NodeID node) const { return node_weights[node]; }
|
EdgeWeight GetNodeWeight(NodeID node) const { return node_weights[node]; }
|
||||||
|
|
||||||
EdgeWeight GetNodeDuration(NodeID node) const { return node_durations[node]; }
|
EdgeDuration GetNodeDuration(NodeID node) const { return node_durations[node]; }
|
||||||
|
|
||||||
EdgeDistance GetNodeDistance(NodeID node) const { return node_distances[node]; }
|
EdgeDistance GetNodeDistance(NodeID node) const { return node_distances[node]; }
|
||||||
|
|
||||||
|
|||||||
@@ -439,7 +439,7 @@ class RouteAPI : public BaseAPI
|
|||||||
{
|
{
|
||||||
// AnnotationsType uses bit flags, & operator checks if a property is set
|
// AnnotationsType uses bit flags, & operator checks if a property is set
|
||||||
flatbuffers::Offset<flatbuffers::Vector<float>> speed;
|
flatbuffers::Offset<flatbuffers::Vector<float>> speed;
|
||||||
if (parameters.annotations_type & RouteParameters::AnnotationsType::Speed)
|
if (requested_annotations & RouteParameters::AnnotationsType::Speed)
|
||||||
{
|
{
|
||||||
double prev_speed = 0;
|
double prev_speed = 0;
|
||||||
speed =
|
speed =
|
||||||
@@ -778,7 +778,7 @@ class RouteAPI : public BaseAPI
|
|||||||
util::json::Object annotation;
|
util::json::Object annotation;
|
||||||
|
|
||||||
// AnnotationsType uses bit flags, & operator checks if a property is set
|
// AnnotationsType uses bit flags, & operator checks if a property is set
|
||||||
if (parameters.annotations_type & RouteParameters::AnnotationsType::Speed)
|
if (requested_annotations & RouteParameters::AnnotationsType::Speed)
|
||||||
{
|
{
|
||||||
double prev_speed = 0;
|
double prev_speed = 0;
|
||||||
annotation.values["speed"] = GetAnnotations(
|
annotation.values["speed"] = GetAnnotations(
|
||||||
|
|||||||
@@ -133,7 +133,8 @@ class TableAPI final : public BaseAPI
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool have_speed_cells =
|
bool have_speed_cells =
|
||||||
parameters.fallback_speed != INVALID_FALLBACK_SPEED && parameters.fallback_speed > 0;
|
parameters.fallback_speed != from_alias<double>(INVALID_FALLBACK_SPEED) &&
|
||||||
|
parameters.fallback_speed > 0;
|
||||||
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> speed_cells;
|
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> speed_cells;
|
||||||
if (have_speed_cells)
|
if (have_speed_cells)
|
||||||
{
|
{
|
||||||
@@ -223,7 +224,8 @@ class TableAPI final : public BaseAPI
|
|||||||
MakeDistanceTable(tables.second, number_of_sources, number_of_destinations);
|
MakeDistanceTable(tables.second, number_of_sources, number_of_destinations);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameters.fallback_speed != INVALID_FALLBACK_SPEED && parameters.fallback_speed > 0)
|
if (parameters.fallback_speed != from_alias<double>(INVALID_FALLBACK_SPEED) &&
|
||||||
|
parameters.fallback_speed > 0)
|
||||||
{
|
{
|
||||||
response.values["fallback_speed_cells"] = MakeEstimatesTable(fallback_speed_cells);
|
response.values["fallback_speed_cells"] = MakeEstimatesTable(fallback_speed_cells);
|
||||||
}
|
}
|
||||||
@@ -272,17 +274,17 @@ class TableAPI final : public BaseAPI
|
|||||||
|
|
||||||
virtual flatbuffers::Offset<flatbuffers::Vector<float>>
|
virtual flatbuffers::Offset<flatbuffers::Vector<float>>
|
||||||
MakeDurationTable(flatbuffers::FlatBufferBuilder &builder,
|
MakeDurationTable(flatbuffers::FlatBufferBuilder &builder,
|
||||||
const std::vector<EdgeWeight> &values) const
|
const std::vector<EdgeDuration> &values) const
|
||||||
{
|
{
|
||||||
std::vector<float> distance_table;
|
std::vector<float> distance_table;
|
||||||
distance_table.resize(values.size());
|
distance_table.resize(values.size());
|
||||||
std::transform(
|
std::transform(
|
||||||
values.begin(), values.end(), distance_table.begin(), [](const EdgeWeight duration) {
|
values.begin(), values.end(), distance_table.begin(), [](const EdgeDuration duration) {
|
||||||
if (duration == MAXIMAL_EDGE_DURATION)
|
if (duration == MAXIMAL_EDGE_DURATION)
|
||||||
{
|
{
|
||||||
return 0.;
|
return 0.;
|
||||||
}
|
}
|
||||||
return duration / 10.;
|
return from_alias<double>(duration) / 10.;
|
||||||
});
|
});
|
||||||
return builder.CreateVector(distance_table);
|
return builder.CreateVector(distance_table);
|
||||||
}
|
}
|
||||||
@@ -299,7 +301,7 @@ class TableAPI final : public BaseAPI
|
|||||||
{
|
{
|
||||||
return 0.;
|
return 0.;
|
||||||
}
|
}
|
||||||
return std::round(distance * 10) / 10.;
|
return std::round(from_alias<double>(distance) * 10) / 10.;
|
||||||
});
|
});
|
||||||
return builder.CreateVector(duration_table);
|
return builder.CreateVector(duration_table);
|
||||||
}
|
}
|
||||||
@@ -347,7 +349,7 @@ class TableAPI final : public BaseAPI
|
|||||||
return json_waypoints;
|
return json_waypoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual util::json::Array MakeDurationTable(const std::vector<EdgeWeight> &values,
|
virtual util::json::Array MakeDurationTable(const std::vector<EdgeDuration> &values,
|
||||||
std::size_t number_of_rows,
|
std::size_t number_of_rows,
|
||||||
std::size_t number_of_columns) const
|
std::size_t number_of_columns) const
|
||||||
{
|
{
|
||||||
@@ -361,13 +363,14 @@ class TableAPI final : public BaseAPI
|
|||||||
std::transform(row_begin_iterator,
|
std::transform(row_begin_iterator,
|
||||||
row_end_iterator,
|
row_end_iterator,
|
||||||
json_row.values.begin(),
|
json_row.values.begin(),
|
||||||
[](const EdgeWeight duration) {
|
[](const EdgeDuration duration) {
|
||||||
if (duration == MAXIMAL_EDGE_DURATION)
|
if (duration == MAXIMAL_EDGE_DURATION)
|
||||||
{
|
{
|
||||||
return util::json::Value(util::json::Null());
|
return util::json::Value(util::json::Null());
|
||||||
}
|
}
|
||||||
// division by 10 because the duration is in deciseconds (10s)
|
// division by 10 because the duration is in deciseconds (10s)
|
||||||
return util::json::Value(util::json::Number(duration / 10.));
|
return util::json::Value(
|
||||||
|
util::json::Number(from_alias<double>(duration) / 10.));
|
||||||
});
|
});
|
||||||
json_table.values.push_back(std::move(json_row));
|
json_table.values.push_back(std::move(json_row));
|
||||||
}
|
}
|
||||||
@@ -394,8 +397,8 @@ class TableAPI final : public BaseAPI
|
|||||||
return util::json::Value(util::json::Null());
|
return util::json::Value(util::json::Null());
|
||||||
}
|
}
|
||||||
// round to single decimal place
|
// round to single decimal place
|
||||||
return util::json::Value(
|
return util::json::Value(util::json::Number(
|
||||||
util::json::Number(std::round(distance * 10) / 10.));
|
std::round(from_alias<double>(distance) * 10) / 10.));
|
||||||
});
|
});
|
||||||
json_table.values.push_back(std::move(json_row));
|
json_table.values.push_back(std::move(json_row));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ struct TableParameters : public BaseParameters
|
|||||||
{
|
{
|
||||||
std::vector<std::size_t> sources;
|
std::vector<std::size_t> sources;
|
||||||
std::vector<std::size_t> destinations;
|
std::vector<std::size_t> destinations;
|
||||||
double fallback_speed = INVALID_FALLBACK_SPEED;
|
double fallback_speed = from_alias<double>(INVALID_FALLBACK_SPEED);
|
||||||
|
|
||||||
enum class FallbackCoordinateType
|
enum class FallbackCoordinateType
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ template <> class AlgorithmDataFacade<MLD>
|
|||||||
|
|
||||||
virtual EdgeWeight GetNodeWeight(const NodeID edge_based_node_id) const = 0;
|
virtual EdgeWeight GetNodeWeight(const NodeID edge_based_node_id) const = 0;
|
||||||
|
|
||||||
virtual EdgeWeight
|
virtual EdgeDuration
|
||||||
GetNodeDuration(const NodeID edge_based_node_id) const = 0; // TODO: to be removed
|
GetNodeDuration(const NodeID edge_based_node_id) const = 0; // TODO: to be removed
|
||||||
|
|
||||||
virtual EdgeDistance GetNodeDistance(const NodeID edge_based_node_id) const = 0;
|
virtual EdgeDistance GetNodeDistance(const NodeID edge_based_node_id) const = 0;
|
||||||
|
|||||||
@@ -320,75 +320,84 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
|
|
||||||
const auto forward_weight_offset =
|
const auto forward_weight_offset =
|
||||||
// NOLINTNEXTLINE(bugprone-fold-init-type)
|
// NOLINTNEXTLINE(bugprone-fold-init-type)
|
||||||
std::accumulate(forward_weights.begin(),
|
alias_cast<EdgeWeight>(
|
||||||
forward_weights.begin() + data.fwd_segment_position,
|
std::accumulate(forward_weights.begin(),
|
||||||
EdgeWeight{0});
|
forward_weights.begin() + data.fwd_segment_position,
|
||||||
|
SegmentWeight{0}));
|
||||||
|
|
||||||
const auto forward_duration_offset =
|
const auto forward_duration_offset =
|
||||||
// NOLINTNEXTLINE(bugprone-fold-init-type)
|
// NOLINTNEXTLINE(bugprone-fold-init-type)
|
||||||
std::accumulate(forward_durations.begin(),
|
alias_cast<EdgeDuration>(
|
||||||
forward_durations.begin() + data.fwd_segment_position,
|
std::accumulate(forward_durations.begin(),
|
||||||
EdgeDuration{0});
|
forward_durations.begin() + data.fwd_segment_position,
|
||||||
|
SegmentDuration{0}));
|
||||||
|
|
||||||
EdgeDistance forward_distance_offset = 0;
|
EdgeDistance forward_distance_offset = {0};
|
||||||
// Sum up the distance from the start to the fwd_segment_position
|
// Sum up the distance from the start to the fwd_segment_position
|
||||||
for (auto current = forward_geometry.begin();
|
for (auto current = forward_geometry.begin();
|
||||||
current < forward_geometry.begin() + data.fwd_segment_position;
|
current < forward_geometry.begin() + data.fwd_segment_position;
|
||||||
++current)
|
++current)
|
||||||
{
|
{
|
||||||
forward_distance_offset += util::coordinate_calculation::greatCircleDistance(
|
forward_distance_offset +=
|
||||||
datafacade.GetCoordinateOfNode(*current),
|
to_alias<EdgeDistance>(util::coordinate_calculation::greatCircleDistance(
|
||||||
datafacade.GetCoordinateOfNode(*std::next(current)));
|
datafacade.GetCoordinateOfNode(*current),
|
||||||
|
datafacade.GetCoordinateOfNode(*std::next(current))));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_ASSERT(data.fwd_segment_position <
|
BOOST_ASSERT(data.fwd_segment_position <
|
||||||
std::distance(forward_durations.begin(), forward_durations.end()));
|
std::distance(forward_durations.begin(), forward_durations.end()));
|
||||||
|
|
||||||
EdgeWeight forward_weight = forward_weights[data.fwd_segment_position];
|
EdgeWeight forward_weight =
|
||||||
EdgeDuration forward_duration = forward_durations[data.fwd_segment_position];
|
alias_cast<EdgeWeight>(forward_weights[data.fwd_segment_position]);
|
||||||
EdgeDistance forward_distance = util::coordinate_calculation::greatCircleDistance(
|
EdgeDuration forward_duration =
|
||||||
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position)),
|
alias_cast<EdgeDuration>(forward_durations[data.fwd_segment_position]);
|
||||||
point_on_segment);
|
EdgeDistance forward_distance =
|
||||||
|
to_alias<EdgeDistance>(util::coordinate_calculation::greatCircleDistance(
|
||||||
|
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position)),
|
||||||
|
point_on_segment));
|
||||||
|
|
||||||
const auto reverse_weight_offset =
|
const auto reverse_weight_offset = alias_cast<EdgeWeight>(
|
||||||
std::accumulate(reverse_weights.begin(),
|
std::accumulate(reverse_weights.begin(),
|
||||||
reverse_weights.end() - data.fwd_segment_position - 1,
|
reverse_weights.end() - data.fwd_segment_position - 1,
|
||||||
EdgeWeight{0});
|
SegmentWeight{0}));
|
||||||
|
|
||||||
const auto reverse_duration_offset =
|
const auto reverse_duration_offset = alias_cast<EdgeDuration>(
|
||||||
std::accumulate(reverse_durations.begin(),
|
std::accumulate(reverse_durations.begin(),
|
||||||
reverse_durations.end() - data.fwd_segment_position - 1,
|
reverse_durations.end() - data.fwd_segment_position - 1,
|
||||||
EdgeDuration{0});
|
SegmentDuration{0}));
|
||||||
|
|
||||||
EdgeDistance reverse_distance_offset = 0;
|
EdgeDistance reverse_distance_offset = {0};
|
||||||
// Sum up the distance from just after the fwd_segment_position to the end
|
// Sum up the distance from just after the fwd_segment_position to the end
|
||||||
for (auto current = forward_geometry.begin() + data.fwd_segment_position + 1;
|
for (auto current = forward_geometry.begin() + data.fwd_segment_position + 1;
|
||||||
current != std::prev(forward_geometry.end());
|
current != std::prev(forward_geometry.end());
|
||||||
++current)
|
++current)
|
||||||
{
|
{
|
||||||
reverse_distance_offset += util::coordinate_calculation::greatCircleDistance(
|
reverse_distance_offset +=
|
||||||
datafacade.GetCoordinateOfNode(*current),
|
to_alias<EdgeDistance>(util::coordinate_calculation::greatCircleDistance(
|
||||||
datafacade.GetCoordinateOfNode(*std::next(current)));
|
datafacade.GetCoordinateOfNode(*current),
|
||||||
|
datafacade.GetCoordinateOfNode(*std::next(current))));
|
||||||
}
|
}
|
||||||
|
|
||||||
EdgeWeight reverse_weight =
|
EdgeWeight reverse_weight = alias_cast<EdgeWeight>(
|
||||||
reverse_weights[reverse_weights.size() - data.fwd_segment_position - 1];
|
reverse_weights[reverse_weights.size() - data.fwd_segment_position - 1]);
|
||||||
EdgeDuration reverse_duration =
|
EdgeDuration reverse_duration = alias_cast<EdgeDuration>(
|
||||||
reverse_durations[reverse_durations.size() - data.fwd_segment_position - 1];
|
reverse_durations[reverse_durations.size() - data.fwd_segment_position - 1]);
|
||||||
EdgeDistance reverse_distance = util::coordinate_calculation::greatCircleDistance(
|
EdgeDistance reverse_distance =
|
||||||
point_on_segment,
|
to_alias<EdgeDistance>(util::coordinate_calculation::greatCircleDistance(
|
||||||
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position + 1)));
|
point_on_segment,
|
||||||
|
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position + 1))));
|
||||||
|
|
||||||
ratio = std::min(1.0, std::max(0.0, ratio));
|
ratio = std::min(1.0, std::max(0.0, ratio));
|
||||||
if (data.forward_segment_id.id != SPECIAL_SEGMENTID)
|
if (data.forward_segment_id.id != SPECIAL_SEGMENTID)
|
||||||
{
|
{
|
||||||
forward_weight = static_cast<EdgeWeight>(forward_weight * ratio);
|
forward_weight = to_alias<EdgeWeight>(from_alias<double>(forward_weight) * ratio);
|
||||||
forward_duration = static_cast<EdgeDuration>(forward_duration * ratio);
|
forward_duration = to_alias<EdgeDuration>(from_alias<double>(forward_duration) * ratio);
|
||||||
}
|
}
|
||||||
if (data.reverse_segment_id.id != SPECIAL_SEGMENTID)
|
if (data.reverse_segment_id.id != SPECIAL_SEGMENTID)
|
||||||
{
|
{
|
||||||
reverse_weight -= static_cast<EdgeWeight>(reverse_weight * ratio);
|
reverse_weight -= to_alias<EdgeWeight>(from_alias<double>(reverse_weight) * ratio);
|
||||||
reverse_duration -= static_cast<EdgeDuration>(reverse_duration * ratio);
|
reverse_duration -=
|
||||||
|
to_alias<EdgeDuration>(from_alias<double>(reverse_duration) * ratio);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check phantom node segments validity
|
// check phantom node segments validity
|
||||||
|
|||||||
@@ -95,8 +95,9 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
|
|||||||
// the duration_of_turn/weight_of_turn value, which is 0 for
|
// the duration_of_turn/weight_of_turn value, which is 0 for
|
||||||
// non-preceeding-turn segments, but contains the turn value
|
// non-preceeding-turn segments, but contains the turn value
|
||||||
// for segments before a turn.
|
// for segments before a turn.
|
||||||
(path_point.duration_until_turn - path_point.duration_of_turn) / 10.,
|
from_alias<double>(path_point.duration_until_turn - path_point.duration_of_turn) /
|
||||||
(path_point.weight_until_turn - path_point.weight_of_turn) /
|
10.,
|
||||||
|
from_alias<double>(path_point.weight_until_turn - path_point.weight_of_turn) /
|
||||||
facade.GetWeightMultiplier(),
|
facade.GetWeightMultiplier(),
|
||||||
path_point.datasource_id});
|
path_point.datasource_id});
|
||||||
geometry.locations.push_back(coordinate);
|
geometry.locations.push_back(coordinate);
|
||||||
@@ -121,14 +122,15 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
|
|||||||
if (geometry.annotations.empty())
|
if (geometry.annotations.empty())
|
||||||
{
|
{
|
||||||
auto duration =
|
auto duration =
|
||||||
std::abs(
|
std::abs(from_alias<EdgeDuration::value_type>(
|
||||||
(reversed_target ? target_node.reverse_duration : target_node.forward_duration) -
|
(reversed_target ? target_node.reverse_duration : target_node.forward_duration) -
|
||||||
(reversed_source ? source_node.reverse_duration : source_node.forward_duration)) /
|
(reversed_source ? source_node.reverse_duration : source_node.forward_duration))) /
|
||||||
10.;
|
10.;
|
||||||
BOOST_ASSERT(duration >= 0);
|
BOOST_ASSERT(duration >= 0);
|
||||||
auto weight =
|
auto weight =
|
||||||
std::abs((reversed_target ? target_node.reverse_weight : target_node.forward_weight) -
|
std::abs(from_alias<EdgeWeight::value_type>(
|
||||||
(reversed_source ? source_node.reverse_weight : source_node.forward_weight)) /
|
(reversed_target ? target_node.reverse_weight : target_node.forward_weight) -
|
||||||
|
(reversed_source ? source_node.reverse_weight : source_node.forward_weight))) /
|
||||||
facade.GetWeightMultiplier();
|
facade.GetWeightMultiplier();
|
||||||
BOOST_ASSERT(weight >= 0);
|
BOOST_ASSERT(weight >= 0);
|
||||||
|
|
||||||
@@ -142,8 +144,11 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
|
|||||||
{
|
{
|
||||||
geometry.annotations.emplace_back(LegGeometry::Annotation{
|
geometry.annotations.emplace_back(LegGeometry::Annotation{
|
||||||
current_distance,
|
current_distance,
|
||||||
(reversed_target ? target_node.reverse_duration : target_node.forward_duration) / 10.,
|
from_alias<double>(reversed_target ? target_node.reverse_duration
|
||||||
(reversed_target ? target_node.reverse_weight : target_node.forward_weight) /
|
: target_node.forward_duration) /
|
||||||
|
10.,
|
||||||
|
from_alias<double>(reversed_target ? target_node.reverse_weight
|
||||||
|
: target_node.forward_weight) /
|
||||||
facade.GetWeightMultiplier(),
|
facade.GetWeightMultiplier(),
|
||||||
forward_datasources(target_node.fwd_segment_position)});
|
forward_datasources(target_node.fwd_segment_position)});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ namespace detail
|
|||||||
const constexpr std::size_t MAX_USED_SEGMENTS = 2;
|
const constexpr std::size_t MAX_USED_SEGMENTS = 2;
|
||||||
struct NamedSegment
|
struct NamedSegment
|
||||||
{
|
{
|
||||||
EdgeWeight duration;
|
EdgeDuration duration;
|
||||||
std::uint32_t position;
|
std::uint32_t position;
|
||||||
std::uint32_t name_id;
|
std::uint32_t name_id;
|
||||||
};
|
};
|
||||||
@@ -88,7 +88,7 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const datafacade::BaseDa
|
|||||||
target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration;
|
target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration;
|
||||||
const auto target_node_id = target_traversed_in_reverse ? target_node.reverse_segment_id.id
|
const auto target_node_id = target_traversed_in_reverse ? target_node.reverse_segment_id.id
|
||||||
: target_node.forward_segment_id.id;
|
: target_node.forward_segment_id.id;
|
||||||
if (target_duration > 1)
|
if (target_duration > EdgeDuration{1})
|
||||||
segments.push_back({target_duration, index++, facade.GetNameIndex(target_node_id)});
|
segments.push_back({target_duration, index++, facade.GetNameIndex(target_node_id)});
|
||||||
// this makes sure that the segment with the lowest position comes first
|
// this makes sure that the segment with the lowest position comes first
|
||||||
std::sort(
|
std::sort(
|
||||||
@@ -184,11 +184,11 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
|
|||||||
|
|
||||||
auto duration = std::accumulate(
|
auto duration = std::accumulate(
|
||||||
route_data.begin(), route_data.end(), 0, [](const double sum, const PathData &data) {
|
route_data.begin(), route_data.end(), 0, [](const double sum, const PathData &data) {
|
||||||
return sum + data.duration_until_turn;
|
return sum + from_alias<double>(data.duration_until_turn);
|
||||||
});
|
});
|
||||||
auto weight = std::accumulate(
|
auto weight = std::accumulate(
|
||||||
route_data.begin(), route_data.end(), 0, [](const double sum, const PathData &data) {
|
route_data.begin(), route_data.end(), 0, [](const double sum, const PathData &data) {
|
||||||
return sum + data.weight_until_turn;
|
return sum + from_alias<double>(data.weight_until_turn);
|
||||||
});
|
});
|
||||||
|
|
||||||
// s
|
// s
|
||||||
@@ -212,14 +212,14 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
|
|||||||
// caputed by the phantom node. So we need to add the target duration here.
|
// caputed by the phantom node. So we need to add the target duration here.
|
||||||
// On local segments, the target duration is already part of the duration, however.
|
// On local segments, the target duration is already part of the duration, however.
|
||||||
|
|
||||||
duration = duration + target_duration;
|
duration = duration + from_alias<double>(target_duration);
|
||||||
weight = weight + target_weight;
|
weight = weight + from_alias<double>(target_weight);
|
||||||
if (route_data.empty())
|
if (route_data.empty())
|
||||||
{
|
{
|
||||||
weight -=
|
weight -= from_alias<double>(target_traversed_in_reverse ? source_node.reverse_weight
|
||||||
(target_traversed_in_reverse ? source_node.reverse_weight : source_node.forward_weight);
|
: source_node.forward_weight);
|
||||||
duration -= (target_traversed_in_reverse ? source_node.reverse_duration
|
duration -= from_alias<double>(target_traversed_in_reverse ? source_node.reverse_duration
|
||||||
: source_node.forward_duration);
|
: source_node.forward_duration);
|
||||||
// use rectified linear unit function to avoid negative duration values
|
// use rectified linear unit function to avoid negative duration values
|
||||||
// due to flooring errors in phantom snapping
|
// due to flooring errors in phantom snapping
|
||||||
duration = std::max(0, duration);
|
duration = std::max(0, duration);
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
|||||||
const constexpr char *NO_ROTARY_NAME = "";
|
const constexpr char *NO_ROTARY_NAME = "";
|
||||||
const EdgeWeight source_weight =
|
const EdgeWeight source_weight =
|
||||||
source_traversed_in_reverse ? source_node.reverse_weight : source_node.forward_weight;
|
source_traversed_in_reverse ? source_node.reverse_weight : source_node.forward_weight;
|
||||||
const EdgeWeight source_duration =
|
const EdgeDuration source_duration =
|
||||||
source_traversed_in_reverse ? source_node.reverse_duration : source_node.forward_duration;
|
source_traversed_in_reverse ? source_node.reverse_duration : source_node.forward_duration;
|
||||||
const auto source_node_id = source_traversed_in_reverse ? source_node.reverse_segment_id.id
|
const auto source_node_id = source_traversed_in_reverse ? source_node.reverse_segment_id.id
|
||||||
: source_node.forward_segment_id.id;
|
: source_node.forward_segment_id.id;
|
||||||
@@ -61,7 +61,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
|||||||
const auto source_mode = facade.GetTravelMode(source_node_id);
|
const auto source_mode = facade.GetTravelMode(source_node_id);
|
||||||
auto source_classes = facade.GetClasses(facade.GetClassData(source_node_id));
|
auto source_classes = facade.GetClasses(facade.GetClassData(source_node_id));
|
||||||
|
|
||||||
const EdgeWeight target_duration =
|
const EdgeDuration target_duration =
|
||||||
target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration;
|
target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration;
|
||||||
const EdgeWeight target_weight =
|
const EdgeWeight target_weight =
|
||||||
target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight;
|
target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight;
|
||||||
@@ -103,8 +103,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
|||||||
// but a RouteStep is with regard to the segment after the turn.
|
// but a RouteStep is with regard to the segment after the turn.
|
||||||
// We need to skip the first segment because it is already covered by the
|
// We need to skip the first segment because it is already covered by the
|
||||||
// initial start of a route
|
// initial start of a route
|
||||||
EdgeWeight segment_duration = 0;
|
EdgeDuration segment_duration = {0};
|
||||||
EdgeWeight segment_weight = 0;
|
EdgeWeight segment_weight = {0};
|
||||||
|
|
||||||
// some name changes are not announced in our processing. For these, we have to keep the
|
// some name changes are not announced in our processing. For these, we have to keep the
|
||||||
// first name on the segment
|
// first name on the segment
|
||||||
@@ -121,7 +121,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
|||||||
: osrm::guidance::TurnInstruction::NO_TURN();
|
: osrm::guidance::TurnInstruction::NO_TURN();
|
||||||
if (turn_instruction.type != osrm::guidance::TurnType::NoTurn)
|
if (turn_instruction.type != osrm::guidance::TurnType::NoTurn)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(segment_weight >= 0);
|
BOOST_ASSERT(segment_weight >= EdgeWeight{0});
|
||||||
const auto name = facade.GetNameForID(step_name_id);
|
const auto name = facade.GetNameForID(step_name_id);
|
||||||
const auto ref = facade.GetRefForID(step_name_id);
|
const auto ref = facade.GetRefForID(step_name_id);
|
||||||
const auto pronunciation = facade.GetPronunciationForID(step_name_id);
|
const auto pronunciation = facade.GetPronunciationForID(step_name_id);
|
||||||
@@ -147,9 +147,9 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
|||||||
exits.to_string(),
|
exits.to_string(),
|
||||||
NO_ROTARY_NAME,
|
NO_ROTARY_NAME,
|
||||||
NO_ROTARY_NAME,
|
NO_ROTARY_NAME,
|
||||||
segment_duration / 10.,
|
from_alias<double>(segment_duration) / 10.,
|
||||||
distance,
|
distance,
|
||||||
segment_weight / weight_multiplier,
|
from_alias<double>(segment_weight) / weight_multiplier,
|
||||||
travel_mode,
|
travel_mode,
|
||||||
maneuver,
|
maneuver,
|
||||||
leg_geometry.FrontIndex(segment_index),
|
leg_geometry.FrontIndex(segment_index),
|
||||||
@@ -228,16 +228,16 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
|||||||
WaypointType::None,
|
WaypointType::None,
|
||||||
0};
|
0};
|
||||||
segment_index++;
|
segment_index++;
|
||||||
segment_duration = 0;
|
segment_duration = {0};
|
||||||
segment_weight = 0;
|
segment_weight = {0};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const auto distance = leg_geometry.segment_distances[segment_index];
|
const auto distance = leg_geometry.segment_distances[segment_index];
|
||||||
const EdgeWeight duration = segment_duration + target_duration;
|
const EdgeDuration duration = segment_duration + target_duration;
|
||||||
const EdgeWeight weight = segment_weight + target_weight;
|
const EdgeWeight weight = segment_weight + target_weight;
|
||||||
// intersections contain the classes of exiting road
|
// intersections contain the classes of exiting road
|
||||||
intersection.classes = facade.GetClasses(facade.GetClassData(target_node_id));
|
intersection.classes = facade.GetClasses(facade.GetClassData(target_node_id));
|
||||||
BOOST_ASSERT(duration >= 0);
|
BOOST_ASSERT(duration >= EdgeDuration{0});
|
||||||
steps.push_back(RouteStep{leg_data[leg_data.size() - 1].from_edge_based_node,
|
steps.push_back(RouteStep{leg_data[leg_data.size() - 1].from_edge_based_node,
|
||||||
step_name_id,
|
step_name_id,
|
||||||
is_segregated,
|
is_segregated,
|
||||||
@@ -248,9 +248,9 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
|||||||
facade.GetExitsForID(step_name_id).to_string(),
|
facade.GetExitsForID(step_name_id).to_string(),
|
||||||
NO_ROTARY_NAME,
|
NO_ROTARY_NAME,
|
||||||
NO_ROTARY_NAME,
|
NO_ROTARY_NAME,
|
||||||
duration / 10.,
|
from_alias<double>(duration) / 10.,
|
||||||
distance,
|
distance,
|
||||||
weight / weight_multiplier,
|
from_alias<double>(weight) / weight_multiplier,
|
||||||
target_mode,
|
target_mode,
|
||||||
maneuver,
|
maneuver,
|
||||||
leg_geometry.FrontIndex(segment_index),
|
leg_geometry.FrontIndex(segment_index),
|
||||||
@@ -280,8 +280,9 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
|||||||
|
|
||||||
// use rectified linear unit function to avoid negative duration values
|
// use rectified linear unit function to avoid negative duration values
|
||||||
// due to flooring errors in phantom snapping
|
// due to flooring errors in phantom snapping
|
||||||
BOOST_ASSERT(target_duration >= source_duration || weight == 0);
|
BOOST_ASSERT(target_duration >= source_duration || weight == EdgeWeight{0});
|
||||||
const EdgeWeight duration = std::max(0, target_duration - source_duration);
|
const EdgeDuration duration =
|
||||||
|
std::max<EdgeDuration>({0}, target_duration - source_duration);
|
||||||
|
|
||||||
steps.push_back(RouteStep{source_node_id,
|
steps.push_back(RouteStep{source_node_id,
|
||||||
source_name_id,
|
source_name_id,
|
||||||
@@ -293,9 +294,9 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
|||||||
facade.GetExitsForID(source_name_id).to_string(),
|
facade.GetExitsForID(source_name_id).to_string(),
|
||||||
NO_ROTARY_NAME,
|
NO_ROTARY_NAME,
|
||||||
NO_ROTARY_NAME,
|
NO_ROTARY_NAME,
|
||||||
duration / 10.,
|
from_alias<double>(duration) / 10.,
|
||||||
leg_geometry.segment_distances[segment_index],
|
leg_geometry.segment_distances[segment_index],
|
||||||
weight / weight_multiplier,
|
from_alias<double>(weight) / weight_multiplier,
|
||||||
source_mode,
|
source_mode,
|
||||||
maneuver,
|
maneuver,
|
||||||
leg_geometry.FrontIndex(segment_index),
|
leg_geometry.FrontIndex(segment_index),
|
||||||
|
|||||||
@@ -37,10 +37,10 @@ struct PathData
|
|||||||
EdgeWeight weight_of_turn;
|
EdgeWeight weight_of_turn;
|
||||||
// duration that is traveled on the segment until the turn is reached,
|
// duration that is traveled on the segment until the turn is reached,
|
||||||
// including a turn if the segment precedes one.
|
// including a turn if the segment precedes one.
|
||||||
EdgeWeight duration_until_turn;
|
EdgeDuration duration_until_turn;
|
||||||
// If this segment immediately precedes a turn, then duration_of_turn
|
// If this segment immediately precedes a turn, then duration_of_turn
|
||||||
// will contain the duration of the turn. Otherwise it will be 0.
|
// will contain the duration of the turn. Otherwise it will be 0.
|
||||||
EdgeWeight duration_of_turn;
|
EdgeDuration duration_of_turn;
|
||||||
// Source of the speed value on this road segment
|
// Source of the speed value on this road segment
|
||||||
DatasourceID datasource_id;
|
DatasourceID datasource_id;
|
||||||
// If segment precedes a turn, ID of the turn itself
|
// If segment precedes a turn, ID of the turn itself
|
||||||
@@ -63,9 +63,9 @@ struct InternalRouteResult
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Note: includes duration for turns, except for at start and end node.
|
// Note: includes duration for turns, except for at start and end node.
|
||||||
EdgeWeight duration() const
|
EdgeDuration duration() const
|
||||||
{
|
{
|
||||||
EdgeWeight ret{0};
|
EdgeDuration ret{0};
|
||||||
|
|
||||||
for (const auto &leg : unpacked_path_segments)
|
for (const auto &leg : unpacked_path_segments)
|
||||||
for (const auto &segment : leg)
|
for (const auto &segment : leg)
|
||||||
|
|||||||
@@ -48,12 +48,12 @@ struct PhantomNode
|
|||||||
PhantomNode()
|
PhantomNode()
|
||||||
: forward_segment_id{SPECIAL_SEGMENTID, false}, reverse_segment_id{SPECIAL_SEGMENTID,
|
: forward_segment_id{SPECIAL_SEGMENTID, false}, reverse_segment_id{SPECIAL_SEGMENTID,
|
||||||
false},
|
false},
|
||||||
forward_weight(INVALID_EDGE_WEIGHT), reverse_weight(INVALID_EDGE_WEIGHT),
|
forward_weight(INVALID_EDGE_WEIGHT),
|
||||||
forward_weight_offset(0), reverse_weight_offset(0),
|
reverse_weight(INVALID_EDGE_WEIGHT), forward_weight_offset{0}, reverse_weight_offset{0},
|
||||||
forward_distance(INVALID_EDGE_DISTANCE), reverse_distance(INVALID_EDGE_DISTANCE),
|
forward_distance(INVALID_EDGE_DISTANCE), reverse_distance(INVALID_EDGE_DISTANCE),
|
||||||
forward_distance_offset(0), reverse_distance_offset(0),
|
forward_distance_offset{0}, reverse_distance_offset{0},
|
||||||
forward_duration(MAXIMAL_EDGE_DURATION), reverse_duration(MAXIMAL_EDGE_DURATION),
|
forward_duration(MAXIMAL_EDGE_DURATION), reverse_duration(MAXIMAL_EDGE_DURATION),
|
||||||
forward_duration_offset(0), reverse_duration_offset(0),
|
forward_duration_offset{0}, reverse_duration_offset{0},
|
||||||
component({INVALID_COMPONENTID, 0}),
|
component({INVALID_COMPONENTID, 0}),
|
||||||
fwd_segment_position(0), is_valid_forward_source{false}, is_valid_forward_target{false},
|
fwd_segment_position(0), is_valid_forward_source{false}, is_valid_forward_target{false},
|
||||||
is_valid_reverse_source{false}, is_valid_reverse_target{false}, bearing(0)
|
is_valid_reverse_source{false}, is_valid_reverse_target{false}, bearing(0)
|
||||||
@@ -73,13 +73,13 @@ struct PhantomNode
|
|||||||
return reverse_weight_offset + reverse_weight;
|
return reverse_weight_offset + reverse_weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
EdgeWeight GetForwardDuration() const
|
EdgeDuration GetForwardDuration() const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(forward_segment_id.enabled);
|
BOOST_ASSERT(forward_segment_id.enabled);
|
||||||
return forward_duration + forward_duration_offset;
|
return forward_duration + forward_duration_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
EdgeWeight GetReverseDuration() const
|
EdgeDuration GetReverseDuration() const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(reverse_segment_id.enabled);
|
BOOST_ASSERT(reverse_segment_id.enabled);
|
||||||
return reverse_duration + reverse_duration_offset;
|
return reverse_duration + reverse_duration_offset;
|
||||||
@@ -168,10 +168,10 @@ struct PhantomNode
|
|||||||
EdgeDistance reverse_distance,
|
EdgeDistance reverse_distance,
|
||||||
EdgeDistance forward_distance_offset,
|
EdgeDistance forward_distance_offset,
|
||||||
EdgeDistance reverse_distance_offset,
|
EdgeDistance reverse_distance_offset,
|
||||||
EdgeWeight forward_duration,
|
EdgeDuration forward_duration,
|
||||||
EdgeWeight reverse_duration,
|
EdgeDuration reverse_duration,
|
||||||
EdgeWeight forward_duration_offset,
|
EdgeDuration forward_duration_offset,
|
||||||
EdgeWeight reverse_duration_offset,
|
EdgeDuration reverse_duration_offset,
|
||||||
bool is_valid_forward_source,
|
bool is_valid_forward_source,
|
||||||
bool is_valid_forward_target,
|
bool is_valid_forward_target,
|
||||||
bool is_valid_reverse_source,
|
bool is_valid_reverse_source,
|
||||||
@@ -206,10 +206,10 @@ struct PhantomNode
|
|||||||
EdgeDistance reverse_distance;
|
EdgeDistance reverse_distance;
|
||||||
EdgeDistance forward_distance_offset; // TODO: try to remove -> requires path unpacking changes
|
EdgeDistance forward_distance_offset; // TODO: try to remove -> requires path unpacking changes
|
||||||
EdgeDistance reverse_distance_offset; // TODO: try to remove -> requires path unpacking changes
|
EdgeDistance reverse_distance_offset; // TODO: try to remove -> requires path unpacking changes
|
||||||
EdgeWeight forward_duration;
|
EdgeDuration forward_duration;
|
||||||
EdgeWeight reverse_duration;
|
EdgeDuration reverse_duration;
|
||||||
EdgeWeight forward_duration_offset; // TODO: try to remove -> requires path unpacking changes
|
EdgeDuration forward_duration_offset; // TODO: try to remove -> requires path unpacking changes
|
||||||
EdgeWeight reverse_duration_offset; // TODO: try to remove -> requires path unpacking changes
|
EdgeDuration reverse_duration_offset; // TODO: try to remove -> requires path unpacking changes
|
||||||
ComponentID component;
|
ComponentID component;
|
||||||
|
|
||||||
util::Coordinate location; // this is the coordinate of x
|
util::Coordinate location; // this is the coordinate of x
|
||||||
|
|||||||
@@ -43,14 +43,14 @@ void insertSourceInForwardHeap(Heap &forward_heap, const PhantomNode &source)
|
|||||||
if (source.IsValidForwardSource())
|
if (source.IsValidForwardSource())
|
||||||
{
|
{
|
||||||
forward_heap.Insert(source.forward_segment_id.id,
|
forward_heap.Insert(source.forward_segment_id.id,
|
||||||
-source.GetForwardWeightPlusOffset(),
|
EdgeWeight{0} - source.GetForwardWeightPlusOffset(),
|
||||||
source.forward_segment_id.id);
|
source.forward_segment_id.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source.IsValidReverseSource())
|
if (source.IsValidReverseSource())
|
||||||
{
|
{
|
||||||
forward_heap.Insert(source.reverse_segment_id.id,
|
forward_heap.Insert(source.reverse_segment_id.id,
|
||||||
-source.GetReverseWeightPlusOffset(),
|
EdgeWeight{0} - source.GetReverseWeightPlusOffset(),
|
||||||
source.reverse_segment_id.id);
|
source.reverse_segment_id.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,18 +127,18 @@ void insertSourceInHeap(ManyToManyQueryHeap &heap, const PhantomNodeCandidates &
|
|||||||
if (phantom_node.IsValidForwardSource())
|
if (phantom_node.IsValidForwardSource())
|
||||||
{
|
{
|
||||||
heap.Insert(phantom_node.forward_segment_id.id,
|
heap.Insert(phantom_node.forward_segment_id.id,
|
||||||
-phantom_node.GetForwardWeightPlusOffset(),
|
EdgeWeight{0} - phantom_node.GetForwardWeightPlusOffset(),
|
||||||
{phantom_node.forward_segment_id.id,
|
{phantom_node.forward_segment_id.id,
|
||||||
-phantom_node.GetForwardDuration(),
|
EdgeDuration{0} - phantom_node.GetForwardDuration(),
|
||||||
-phantom_node.GetForwardDistance()});
|
EdgeDistance{0} - phantom_node.GetForwardDistance()});
|
||||||
}
|
}
|
||||||
if (phantom_node.IsValidReverseSource())
|
if (phantom_node.IsValidReverseSource())
|
||||||
{
|
{
|
||||||
heap.Insert(phantom_node.reverse_segment_id.id,
|
heap.Insert(phantom_node.reverse_segment_id.id,
|
||||||
-phantom_node.GetReverseWeightPlusOffset(),
|
EdgeWeight{0} - phantom_node.GetReverseWeightPlusOffset(),
|
||||||
{phantom_node.reverse_segment_id.id,
|
{phantom_node.reverse_segment_id.id,
|
||||||
-phantom_node.GetReverseDuration(),
|
EdgeDuration{0} - phantom_node.GetReverseDuration(),
|
||||||
-phantom_node.GetReverseDistance()});
|
EdgeDistance{0} - phantom_node.GetReverseDistance()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -251,25 +251,24 @@ void annotatePath(const FacadeT &facade,
|
|||||||
BOOST_ASSERT(start_index < end_index);
|
BOOST_ASSERT(start_index < end_index);
|
||||||
for (std::size_t segment_idx = start_index; segment_idx < end_index; ++segment_idx)
|
for (std::size_t segment_idx = start_index; segment_idx < end_index; ++segment_idx)
|
||||||
{
|
{
|
||||||
unpacked_path.push_back(
|
unpacked_path.push_back(PathData{node_id,
|
||||||
PathData{node_id,
|
id_vector[segment_idx + 1],
|
||||||
id_vector[segment_idx + 1],
|
alias_cast<EdgeWeight>(weight_vector[segment_idx]),
|
||||||
static_cast<EdgeWeight>(weight_vector[segment_idx]),
|
{0},
|
||||||
0,
|
alias_cast<EdgeDuration>(duration_vector[segment_idx]),
|
||||||
static_cast<EdgeDuration>(duration_vector[segment_idx]),
|
{0},
|
||||||
0,
|
datasource_vector[segment_idx],
|
||||||
datasource_vector[segment_idx],
|
boost::none});
|
||||||
boost::none});
|
|
||||||
}
|
}
|
||||||
BOOST_ASSERT(!unpacked_path.empty());
|
BOOST_ASSERT(!unpacked_path.empty());
|
||||||
|
|
||||||
const auto turn_duration = facade.GetDurationPenaltyForEdgeID(turn_id);
|
const auto turn_duration = facade.GetDurationPenaltyForEdgeID(turn_id);
|
||||||
const auto turn_weight = facade.GetWeightPenaltyForEdgeID(turn_id);
|
const auto turn_weight = facade.GetWeightPenaltyForEdgeID(turn_id);
|
||||||
|
|
||||||
unpacked_path.back().duration_until_turn += turn_duration;
|
unpacked_path.back().duration_until_turn += alias_cast<EdgeDuration>(turn_duration);
|
||||||
unpacked_path.back().duration_of_turn = turn_duration;
|
unpacked_path.back().duration_of_turn = alias_cast<EdgeDuration>(turn_duration);
|
||||||
unpacked_path.back().weight_until_turn += turn_weight;
|
unpacked_path.back().weight_until_turn += alias_cast<EdgeWeight>(turn_weight);
|
||||||
unpacked_path.back().weight_of_turn = turn_weight;
|
unpacked_path.back().weight_of_turn = alias_cast<EdgeWeight>(turn_weight);
|
||||||
unpacked_path.back().turn_edge = turn_id;
|
unpacked_path.back().turn_edge = turn_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,10 +310,10 @@ void annotatePath(const FacadeT &facade,
|
|||||||
unpacked_path.push_back(
|
unpacked_path.push_back(
|
||||||
PathData{target_node_id,
|
PathData{target_node_id,
|
||||||
id_vector[start_index < end_index ? segment_idx + 1 : segment_idx - 1],
|
id_vector[start_index < end_index ? segment_idx + 1 : segment_idx - 1],
|
||||||
static_cast<EdgeWeight>(weight_vector[segment_idx]),
|
alias_cast<EdgeWeight>(weight_vector[segment_idx]),
|
||||||
0,
|
{0},
|
||||||
static_cast<EdgeDuration>(duration_vector[segment_idx]),
|
alias_cast<EdgeDuration>(duration_vector[segment_idx]),
|
||||||
0,
|
{0},
|
||||||
datasource_vector[segment_idx],
|
datasource_vector[segment_idx],
|
||||||
boost::none});
|
boost::none});
|
||||||
}
|
}
|
||||||
@@ -341,9 +340,9 @@ void annotatePath(const FacadeT &facade,
|
|||||||
// node to the first turn would be the same as from end to end of a segment,
|
// node to the first turn would be the same as from end to end of a segment,
|
||||||
// which is obviously incorrect and not ideal...
|
// which is obviously incorrect and not ideal...
|
||||||
unpacked_path.front().weight_until_turn =
|
unpacked_path.front().weight_until_turn =
|
||||||
std::max(unpacked_path.front().weight_until_turn - source_weight, 0);
|
std::max(unpacked_path.front().weight_until_turn - source_weight, {0});
|
||||||
unpacked_path.front().duration_until_turn =
|
unpacked_path.front().duration_until_turn =
|
||||||
std::max(unpacked_path.front().duration_until_turn - source_duration, 0);
|
std::max(unpacked_path.front().duration_until_turn - source_duration, {0});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,7 +409,7 @@ template <typename FacadeT> EdgeDistance computeEdgeDistance(const FacadeT &faca
|
|||||||
{
|
{
|
||||||
const auto geometry_index = facade.GetGeometryIndex(node_id);
|
const auto geometry_index = facade.GetGeometryIndex(node_id);
|
||||||
|
|
||||||
EdgeDistance total_distance = 0.0;
|
EdgeDistance total_distance = {0};
|
||||||
|
|
||||||
auto geometry_range = facade.GetUncompressedForwardGeometry(geometry_index.id);
|
auto geometry_range = facade.GetUncompressedForwardGeometry(geometry_index.id);
|
||||||
for (auto current = geometry_range.begin(); current < geometry_range.end() - 1; ++current)
|
for (auto current = geometry_range.begin(); current < geometry_range.end() - 1; ++current)
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ bool stallAtNode(const DataFacade<Algorithm> &facade,
|
|||||||
{
|
{
|
||||||
const NodeID to = facade.GetTarget(edge);
|
const NodeID to = facade.GetTarget(edge);
|
||||||
const EdgeWeight edge_weight = data.weight;
|
const EdgeWeight edge_weight = data.weight;
|
||||||
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
|
BOOST_ASSERT_MSG(edge_weight > EdgeWeight{0}, "edge_weight invalid");
|
||||||
const auto toHeapNode = query_heap.GetHeapNodeIfWasInserted(to);
|
const auto toHeapNode = query_heap.GetHeapNodeIfWasInserted(to);
|
||||||
if (toHeapNode)
|
if (toHeapNode)
|
||||||
{
|
{
|
||||||
@@ -61,7 +61,7 @@ void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
|
|||||||
const NodeID to = facade.GetTarget(edge);
|
const NodeID to = facade.GetTarget(edge);
|
||||||
const EdgeWeight edge_weight = data.weight;
|
const EdgeWeight edge_weight = data.weight;
|
||||||
|
|
||||||
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
|
BOOST_ASSERT_MSG(edge_weight > EdgeWeight{0}, "edge_weight invalid");
|
||||||
const EdgeWeight to_weight = heapNode.weight + edge_weight;
|
const EdgeWeight to_weight = heapNode.weight + edge_weight;
|
||||||
|
|
||||||
const auto toHeapNode = heap.GetHeapNodeIfWasInserted(to);
|
const auto toHeapNode = heap.GetHeapNodeIfWasInserted(to);
|
||||||
@@ -135,7 +135,7 @@ void routingStep(const DataFacade<Algorithm> &facade,
|
|||||||
force_loop(force_loop_reverse_nodes, heapNode) ||
|
force_loop(force_loop_reverse_nodes, heapNode) ||
|
||||||
// in this case we are looking at a bi-directional way where the source
|
// in this case we are looking at a bi-directional way where the source
|
||||||
// and target phantom are on the same edge based node
|
// and target phantom are on the same edge based node
|
||||||
new_weight < 0)
|
new_weight < EdgeWeight{0})
|
||||||
{
|
{
|
||||||
// check whether there is a loop present at the node
|
// check whether there is a loop present at the node
|
||||||
for (const auto edge : facade.GetAdjacentEdgeRange(heapNode.node))
|
for (const auto edge : facade.GetAdjacentEdgeRange(heapNode.node))
|
||||||
@@ -148,7 +148,7 @@ void routingStep(const DataFacade<Algorithm> &facade,
|
|||||||
{
|
{
|
||||||
const EdgeWeight edge_weight = data.weight;
|
const EdgeWeight edge_weight = data.weight;
|
||||||
const EdgeWeight loop_weight = new_weight + edge_weight;
|
const EdgeWeight loop_weight = new_weight + edge_weight;
|
||||||
if (loop_weight >= 0 && loop_weight < upper_bound)
|
if (loop_weight >= EdgeWeight{0} && loop_weight < upper_bound)
|
||||||
{
|
{
|
||||||
middle_node_id = heapNode.node;
|
middle_node_id = heapNode.node;
|
||||||
upper_bound = loop_weight;
|
upper_bound = loop_weight;
|
||||||
@@ -159,7 +159,7 @@ void routingStep(const DataFacade<Algorithm> &facade,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(new_weight >= 0);
|
BOOST_ASSERT(new_weight >= EdgeWeight{0});
|
||||||
|
|
||||||
middle_node_id = heapNode.node;
|
middle_node_id = heapNode.node;
|
||||||
upper_bound = new_weight;
|
upper_bound = new_weight;
|
||||||
@@ -169,7 +169,7 @@ void routingStep(const DataFacade<Algorithm> &facade,
|
|||||||
|
|
||||||
// make sure we don't terminate too early if we initialize the weight
|
// make sure we don't terminate too early if we initialize the weight
|
||||||
// for the nodes in the forward heap with the forward/reverse offset
|
// for the nodes in the forward heap with the forward/reverse offset
|
||||||
BOOST_ASSERT(min_edge_offset <= 0);
|
BOOST_ASSERT(min_edge_offset <= EdgeWeight{0});
|
||||||
if (heapNode.weight + min_edge_offset > upper_bound)
|
if (heapNode.weight + min_edge_offset > upper_bound)
|
||||||
{
|
{
|
||||||
forward_heap.DeleteAll();
|
forward_heap.DeleteAll();
|
||||||
@@ -185,31 +185,6 @@ void routingStep(const DataFacade<Algorithm> &facade,
|
|||||||
relaxOutgoingEdges<DIRECTION>(facade, heapNode, forward_heap);
|
relaxOutgoingEdges<DIRECTION>(facade, heapNode, forward_heap);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool UseDuration>
|
|
||||||
std::tuple<EdgeWeight, EdgeDistance> getLoopWeight(const DataFacade<Algorithm> &facade, NodeID node)
|
|
||||||
{
|
|
||||||
EdgeWeight loop_weight = UseDuration ? MAXIMAL_EDGE_DURATION : INVALID_EDGE_WEIGHT;
|
|
||||||
EdgeDistance loop_distance = MAXIMAL_EDGE_DISTANCE;
|
|
||||||
for (auto edge : facade.GetAdjacentEdgeRange(node))
|
|
||||||
{
|
|
||||||
const auto &data = facade.GetEdgeData(edge);
|
|
||||||
if (data.forward)
|
|
||||||
{
|
|
||||||
const NodeID to = facade.GetTarget(edge);
|
|
||||||
if (to == node)
|
|
||||||
{
|
|
||||||
const auto value = UseDuration ? data.duration : data.weight;
|
|
||||||
if (value < loop_weight)
|
|
||||||
{
|
|
||||||
loop_weight = value;
|
|
||||||
loop_distance = data.distance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return std::make_tuple(loop_weight, loop_distance);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a sequence of connected `NodeID`s in the CH graph, performs a depth-first unpacking of
|
* Given a sequence of connected `NodeID`s in the CH graph, performs a depth-first unpacking of
|
||||||
* the shortcut
|
* the shortcut
|
||||||
@@ -301,7 +276,7 @@ EdgeDistance calculateEBGNodeAnnotations(const DataFacade<Algorithm> &facade,
|
|||||||
// Make sure we have at least something to unpack
|
// Make sure we have at least something to unpack
|
||||||
if (packed_path_begin == packed_path_end ||
|
if (packed_path_begin == packed_path_end ||
|
||||||
std::distance(packed_path_begin, packed_path_end) <= 1)
|
std::distance(packed_path_begin, packed_path_end) <= 1)
|
||||||
return 0;
|
return {0};
|
||||||
|
|
||||||
std::stack<std::tuple<NodeID, NodeID, bool>> recursion_stack;
|
std::stack<std::tuple<NodeID, NodeID, bool>> recursion_stack;
|
||||||
std::stack<EdgeDistance> distance_stack;
|
std::stack<EdgeDistance> distance_stack;
|
||||||
@@ -383,7 +358,7 @@ EdgeDistance calculateEBGNodeAnnotations(const DataFacade<Algorithm> &facade,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EdgeDistance total_distance = 0;
|
EdgeDistance total_distance = {0};
|
||||||
while (!distance_stack.empty())
|
while (!distance_stack.empty())
|
||||||
{
|
{
|
||||||
total_distance += distance_stack.top();
|
total_distance += distance_stack.top();
|
||||||
@@ -505,8 +480,48 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
|
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
|
||||||
const PhantomNode &source_phantom,
|
const PhantomNode &source_phantom,
|
||||||
const PhantomNode &target_phantom,
|
const PhantomNode &target_phantom,
|
||||||
int duration_upper_bound = INVALID_EDGE_WEIGHT);
|
EdgeWeight duration_upper_bound = INVALID_EDGE_WEIGHT);
|
||||||
|
|
||||||
|
template <typename EdgeMetric>
|
||||||
|
std::tuple<EdgeMetric, EdgeDistance> getLoopMetric(const DataFacade<Algorithm> &facade, NodeID node)
|
||||||
|
{
|
||||||
|
EdgeMetric loop_metric;
|
||||||
|
if constexpr (std::is_same<EdgeMetric, EdgeDuration>::value)
|
||||||
|
{
|
||||||
|
loop_metric = INVALID_EDGE_DURATION;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
loop_metric = INVALID_EDGE_WEIGHT;
|
||||||
|
}
|
||||||
|
EdgeDistance loop_distance = MAXIMAL_EDGE_DISTANCE;
|
||||||
|
for (auto edge : facade.GetAdjacentEdgeRange(node))
|
||||||
|
{
|
||||||
|
const auto &data = facade.GetEdgeData(edge);
|
||||||
|
if (data.forward)
|
||||||
|
{
|
||||||
|
const NodeID to = facade.GetTarget(edge);
|
||||||
|
if (to == node)
|
||||||
|
{
|
||||||
|
EdgeMetric value;
|
||||||
|
if constexpr (std::is_same<EdgeMetric, EdgeDuration>::value)
|
||||||
|
{
|
||||||
|
value = to_alias<EdgeDuration>(data.duration);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = data.weight;
|
||||||
|
}
|
||||||
|
if (value < loop_metric)
|
||||||
|
{
|
||||||
|
loop_metric = value;
|
||||||
|
loop_distance = data.distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::make_tuple(loop_metric, loop_distance);
|
||||||
|
}
|
||||||
} // namespace ch
|
} // namespace ch
|
||||||
} // namespace routing_algorithms
|
} // namespace routing_algorithms
|
||||||
} // namespace engine
|
} // namespace engine
|
||||||
|
|||||||
@@ -363,7 +363,8 @@ void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
|
|||||||
|
|
||||||
// TODO: BOOST_ASSERT(edge_data.weight == node_weight + turn_penalty);
|
// TODO: BOOST_ASSERT(edge_data.weight == node_weight + turn_penalty);
|
||||||
|
|
||||||
const EdgeWeight to_weight = heapNode.weight + node_weight + turn_penalty;
|
const EdgeWeight to_weight =
|
||||||
|
heapNode.weight + node_weight + alias_cast<EdgeWeight>(turn_penalty);
|
||||||
|
|
||||||
const auto toHeapNode = forward_heap.GetHeapNodeIfWasInserted(to);
|
const auto toHeapNode = forward_heap.GetHeapNodeIfWasInserted(to);
|
||||||
if (!toHeapNode)
|
if (!toHeapNode)
|
||||||
@@ -410,7 +411,7 @@ void routingStep(const DataFacade<Algorithm> &facade,
|
|||||||
// MLD uses loops forcing only to prune single node paths in forward and/or
|
// MLD uses loops forcing only to prune single node paths in forward and/or
|
||||||
// backward direction (there is no need to force loops in MLD but in CH)
|
// backward direction (there is no need to force loops in MLD but in CH)
|
||||||
if (!force_loop(force_loop_forward_nodes, heapNode) &&
|
if (!force_loop(force_loop_forward_nodes, heapNode) &&
|
||||||
!force_loop(force_loop_reverse_nodes, heapNode) && (path_weight >= 0) &&
|
!force_loop(force_loop_reverse_nodes, heapNode) && (path_weight >= EdgeWeight{0}) &&
|
||||||
(path_weight < path_upper_bound))
|
(path_weight < path_upper_bound))
|
||||||
{
|
{
|
||||||
middle_node = heapNode.node;
|
middle_node = heapNode.node;
|
||||||
@@ -529,8 +530,8 @@ UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
// Here heaps can be reused, let's go deeper!
|
// Here heaps can be reused, let's go deeper!
|
||||||
forward_heap.Clear();
|
forward_heap.Clear();
|
||||||
reverse_heap.Clear();
|
reverse_heap.Clear();
|
||||||
forward_heap.Insert(source, 0, {source});
|
forward_heap.Insert(source, {0}, {source});
|
||||||
reverse_heap.Insert(target, 0, {target});
|
reverse_heap.Insert(target, {0}, {target});
|
||||||
|
|
||||||
// TODO: when structured bindings will be allowed change to
|
// TODO: when structured bindings will be allowed change to
|
||||||
// auto [subpath_weight, subpath_source, subpath_target, subpath] = ...
|
// auto [subpath_weight, subpath_source, subpath_target, subpath] = ...
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ shortestPathWithWaypointUTurns(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
const std::vector<PhantomNodeCandidates> &waypoint_candidates)
|
const std::vector<PhantomNodeCandidates> &waypoint_candidates)
|
||||||
{
|
{
|
||||||
|
|
||||||
EdgeWeight total_weight = 0;
|
EdgeWeight total_weight = {0};
|
||||||
std::vector<NodeID> total_packed_path;
|
std::vector<NodeID> total_packed_path;
|
||||||
std::vector<std::size_t> packed_leg_begin;
|
std::vector<std::size_t> packed_leg_begin;
|
||||||
|
|
||||||
@@ -467,8 +467,8 @@ struct route_state
|
|||||||
route_state(const PhantomNodeCandidates &init_candidates)
|
route_state(const PhantomNodeCandidates &init_candidates)
|
||||||
: current_leg(0), previous_leg_path_offset(0)
|
: current_leg(0), previous_leg_path_offset(0)
|
||||||
{
|
{
|
||||||
last.total_weight_to_forward.resize(init_candidates.size(), 0);
|
last.total_weight_to_forward.resize(init_candidates.size(), {0});
|
||||||
last.total_weight_to_reverse.resize(init_candidates.size(), 0);
|
last.total_weight_to_reverse.resize(init_candidates.size(), {0});
|
||||||
// Initialize routability from source validity.
|
// Initialize routability from source validity.
|
||||||
std::transform(
|
std::transform(
|
||||||
init_candidates.begin(),
|
init_candidates.begin(),
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ struct TurnData final
|
|||||||
const int in_angle;
|
const int in_angle;
|
||||||
const int turn_angle;
|
const int turn_angle;
|
||||||
const EdgeWeight weight;
|
const EdgeWeight weight;
|
||||||
const EdgeWeight duration;
|
const EdgeDuration duration;
|
||||||
const guidance::TurnInstruction turn_instruction;
|
const guidance::TurnInstruction turn_instruction;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ struct HeapData
|
|||||||
|
|
||||||
struct ManyToManyHeapData : HeapData
|
struct ManyToManyHeapData : HeapData
|
||||||
{
|
{
|
||||||
EdgeWeight duration;
|
EdgeDuration duration;
|
||||||
EdgeDistance distance;
|
EdgeDistance distance;
|
||||||
ManyToManyHeapData(NodeID p, EdgeWeight duration, EdgeDistance distance)
|
ManyToManyHeapData(NodeID p, EdgeDuration duration, EdgeDistance distance)
|
||||||
: HeapData(p), duration(duration), distance(distance)
|
: HeapData(p), duration(duration), distance(distance)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -78,15 +78,15 @@ struct MultiLayerDijkstraHeapData
|
|||||||
|
|
||||||
struct ManyToManyMultiLayerDijkstraHeapData : MultiLayerDijkstraHeapData
|
struct ManyToManyMultiLayerDijkstraHeapData : MultiLayerDijkstraHeapData
|
||||||
{
|
{
|
||||||
EdgeWeight duration;
|
EdgeDuration duration;
|
||||||
EdgeDistance distance;
|
EdgeDistance distance;
|
||||||
ManyToManyMultiLayerDijkstraHeapData(NodeID p, EdgeWeight duration, EdgeDistance distance)
|
ManyToManyMultiLayerDijkstraHeapData(NodeID p, EdgeDuration duration, EdgeDistance distance)
|
||||||
: MultiLayerDijkstraHeapData(p), duration(duration), distance(distance)
|
: MultiLayerDijkstraHeapData(p), duration(duration), distance(distance)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
ManyToManyMultiLayerDijkstraHeapData(NodeID p,
|
ManyToManyMultiLayerDijkstraHeapData(NodeID p,
|
||||||
bool from,
|
bool from,
|
||||||
EdgeWeight duration,
|
EdgeDuration duration,
|
||||||
EdgeDistance distance)
|
EdgeDistance distance)
|
||||||
: MultiLayerDijkstraHeapData(p, from), duration(duration), distance(distance)
|
: MultiLayerDijkstraHeapData(p, from), duration(duration), distance(distance)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,12 +23,12 @@ namespace trip
|
|||||||
{
|
{
|
||||||
|
|
||||||
// computes the distance of a given permutation
|
// computes the distance of a given permutation
|
||||||
inline EdgeWeight ReturnDistance(const util::DistTableWrapper<EdgeWeight> &dist_table,
|
inline EdgeDuration ReturnDistance(const util::DistTableWrapper<EdgeDuration> &dist_table,
|
||||||
const std::vector<NodeID> &location_order,
|
const std::vector<NodeID> &location_order,
|
||||||
const EdgeWeight min_route_dist,
|
const EdgeDuration min_route_dist,
|
||||||
const std::size_t number_of_locations)
|
const std::size_t number_of_locations)
|
||||||
{
|
{
|
||||||
EdgeWeight route_dist = 0;
|
EdgeDuration route_dist = {0};
|
||||||
std::size_t current_index = 0;
|
std::size_t current_index = 0;
|
||||||
while (current_index < location_order.size() && (route_dist < min_route_dist))
|
while (current_index < location_order.size() && (route_dist < min_route_dist))
|
||||||
{
|
{
|
||||||
@@ -36,12 +36,13 @@ inline EdgeWeight ReturnDistance(const util::DistTableWrapper<EdgeWeight> &dist_
|
|||||||
std::size_t next_index = (current_index + 1) % number_of_locations;
|
std::size_t next_index = (current_index + 1) % number_of_locations;
|
||||||
auto edge_weight = dist_table(location_order[current_index], location_order[next_index]);
|
auto edge_weight = dist_table(location_order[current_index], location_order[next_index]);
|
||||||
|
|
||||||
// If the edge_weight is very large (INVALID_EDGE_WEIGHT) then the algorithm will not choose
|
// If the edge_weight is very large (INVALID_EDGE_DURATION) then the algorithm will not
|
||||||
// this edge in final minimal path. So instead of computing all the permutations after this
|
// choose this edge in final minimal path. So instead of computing all the permutations
|
||||||
// large edge, discard this edge right here and don't consider the path after this edge.
|
// after this large edge, discard this edge right here and don't consider the path after
|
||||||
if (edge_weight == INVALID_EDGE_WEIGHT)
|
// this edge.
|
||||||
|
if (edge_weight == INVALID_EDGE_DURATION)
|
||||||
{
|
{
|
||||||
return INVALID_EDGE_WEIGHT;
|
return INVALID_EDGE_DURATION;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -50,7 +51,7 @@ inline EdgeWeight ReturnDistance(const util::DistTableWrapper<EdgeWeight> &dist_
|
|||||||
|
|
||||||
// This boost assert should not be reached if TFSE table
|
// This boost assert should not be reached if TFSE table
|
||||||
BOOST_ASSERT_MSG(dist_table(location_order[current_index], location_order[next_index]) !=
|
BOOST_ASSERT_MSG(dist_table(location_order[current_index], location_order[next_index]) !=
|
||||||
INVALID_EDGE_WEIGHT,
|
INVALID_EDGE_DURATION,
|
||||||
"invalid route found");
|
"invalid route found");
|
||||||
++current_index;
|
++current_index;
|
||||||
}
|
}
|
||||||
@@ -60,14 +61,14 @@ inline EdgeWeight ReturnDistance(const util::DistTableWrapper<EdgeWeight> &dist_
|
|||||||
|
|
||||||
// computes the route by computing all permutations and selecting the shortest
|
// computes the route by computing all permutations and selecting the shortest
|
||||||
inline std::vector<NodeID> BruteForceTrip(const std::size_t number_of_locations,
|
inline std::vector<NodeID> BruteForceTrip(const std::size_t number_of_locations,
|
||||||
const util::DistTableWrapper<EdgeWeight> &dist_table)
|
const util::DistTableWrapper<EdgeDuration> &dist_table)
|
||||||
{
|
{
|
||||||
// set initial order in which nodes are visited to 0, 1, 2, 3, ...
|
// set initial order in which nodes are visited to 0, 1, 2, 3, ...
|
||||||
std::vector<NodeID> node_order(number_of_locations);
|
std::vector<NodeID> node_order(number_of_locations);
|
||||||
std::iota(std::begin(node_order), std::end(node_order), 0);
|
std::iota(std::begin(node_order), std::end(node_order), 0);
|
||||||
std::vector<NodeID> route = node_order;
|
std::vector<NodeID> route = node_order;
|
||||||
|
|
||||||
EdgeWeight min_route_dist = INVALID_EDGE_WEIGHT;
|
EdgeDuration min_route_dist = INVALID_EDGE_DURATION;
|
||||||
|
|
||||||
// check length of all possible permutation of the component ids
|
// check length of all possible permutation of the component ids
|
||||||
BOOST_ASSERT_MSG(node_order.size() > 0, "no order permutation given");
|
BOOST_ASSERT_MSG(node_order.size() > 0, "no order permutation given");
|
||||||
|
|||||||
@@ -23,15 +23,15 @@ namespace trip
|
|||||||
// given a route and a new location, find the best place of insertion and
|
// given a route and a new location, find the best place of insertion and
|
||||||
// check the distance of roundtrip when the new location is additionally visited
|
// check the distance of roundtrip when the new location is additionally visited
|
||||||
using NodeIDIter = std::vector<NodeID>::iterator;
|
using NodeIDIter = std::vector<NodeID>::iterator;
|
||||||
inline std::pair<EdgeWeight, NodeIDIter>
|
inline std::pair<EdgeDuration, NodeIDIter>
|
||||||
GetShortestRoundTrip(const NodeID new_loc,
|
GetShortestRoundTrip(const NodeID new_loc,
|
||||||
const util::DistTableWrapper<EdgeWeight> &dist_table,
|
const util::DistTableWrapper<EdgeDuration> &dist_table,
|
||||||
const std::size_t number_of_locations,
|
const std::size_t number_of_locations,
|
||||||
std::vector<NodeID> &route)
|
std::vector<NodeID> &route)
|
||||||
{
|
{
|
||||||
(void)number_of_locations; // unused
|
(void)number_of_locations; // unused
|
||||||
|
|
||||||
auto min_trip_distance = INVALID_EDGE_WEIGHT;
|
auto min_trip_distance = INVALID_EDGE_DURATION;
|
||||||
NodeIDIter next_insert_point_candidate;
|
NodeIDIter next_insert_point_candidate;
|
||||||
|
|
||||||
// for all nodes in the current trip find the best insertion resulting in the shortest path
|
// for all nodes in the current trip find the best insertion resulting in the shortest path
|
||||||
@@ -48,10 +48,11 @@ GetShortestRoundTrip(const NodeID new_loc,
|
|||||||
|
|
||||||
const auto dist_from = dist_table(*from_node, new_loc);
|
const auto dist_from = dist_table(*from_node, new_loc);
|
||||||
const auto dist_to = dist_table(new_loc, *to_node);
|
const auto dist_to = dist_table(new_loc, *to_node);
|
||||||
// If the edge_weight is very large (INVALID_EDGE_WEIGHT) then the algorithm will not choose
|
// If the edge_weight is very large (INVALID_EDGE_DURATION) then the algorithm will not
|
||||||
// this edge in final minimal path. So instead of computing all the permutations after this
|
// choose this edge in final minimal path. So instead of computing all the permutations
|
||||||
// large edge, discard this edge right here and don't consider the path after this edge.
|
// after this large edge, discard this edge right here and don't consider the path after
|
||||||
if (dist_from == INVALID_EDGE_WEIGHT || dist_to == INVALID_EDGE_WEIGHT)
|
// this edge.
|
||||||
|
if (dist_from == INVALID_EDGE_DURATION || dist_to == INVALID_EDGE_DURATION)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const auto trip_dist = dist_from + dist_to - dist_table(*from_node, *to_node);
|
const auto trip_dist = dist_from + dist_to - dist_table(*from_node, *to_node);
|
||||||
@@ -71,14 +72,14 @@ GetShortestRoundTrip(const NodeID new_loc,
|
|||||||
next_insert_point_candidate = to_node;
|
next_insert_point_candidate = to_node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BOOST_ASSERT_MSG(min_trip_distance != INVALID_EDGE_WEIGHT, "trip has invalid edge weight");
|
BOOST_ASSERT_MSG(min_trip_distance != INVALID_EDGE_DURATION, "trip has invalid edge weight");
|
||||||
|
|
||||||
return std::make_pair(min_trip_distance, next_insert_point_candidate);
|
return std::make_pair(min_trip_distance, next_insert_point_candidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
// given two initial start nodes, find a roundtrip route using the farthest insertion algorithm
|
// given two initial start nodes, find a roundtrip route using the farthest insertion algorithm
|
||||||
inline std::vector<NodeID> FindRoute(const std::size_t &number_of_locations,
|
inline std::vector<NodeID> FindRoute(const std::size_t &number_of_locations,
|
||||||
const util::DistTableWrapper<EdgeWeight> &dist_table,
|
const util::DistTableWrapper<EdgeDuration> &dist_table,
|
||||||
const NodeID &start1,
|
const NodeID &start1,
|
||||||
const NodeID &start2)
|
const NodeID &start2)
|
||||||
{
|
{
|
||||||
@@ -99,7 +100,7 @@ inline std::vector<NodeID> FindRoute(const std::size_t &number_of_locations,
|
|||||||
// two nodes are already in the initial start trip, so we need to add all other nodes
|
// two nodes are already in the initial start trip, so we need to add all other nodes
|
||||||
for (std::size_t added_nodes = 2; added_nodes < number_of_locations; ++added_nodes)
|
for (std::size_t added_nodes = 2; added_nodes < number_of_locations; ++added_nodes)
|
||||||
{
|
{
|
||||||
auto farthest_distance = std::numeric_limits<int>::min();
|
auto farthest_distance = EdgeDuration{std::numeric_limits<EdgeDuration::value_type>::min()};
|
||||||
auto next_node = -1;
|
auto next_node = -1;
|
||||||
NodeIDIter next_insert_point;
|
NodeIDIter next_insert_point;
|
||||||
|
|
||||||
@@ -112,7 +113,7 @@ inline std::vector<NodeID> FindRoute(const std::size_t &number_of_locations,
|
|||||||
const auto insert_candidate =
|
const auto insert_candidate =
|
||||||
GetShortestRoundTrip(id, dist_table, number_of_locations, route);
|
GetShortestRoundTrip(id, dist_table, number_of_locations, route);
|
||||||
|
|
||||||
BOOST_ASSERT_MSG(insert_candidate.first != INVALID_EDGE_WEIGHT,
|
BOOST_ASSERT_MSG(insert_candidate.first != INVALID_EDGE_DURATION,
|
||||||
"shortest round trip is invalid");
|
"shortest round trip is invalid");
|
||||||
|
|
||||||
// add the location to the current trip such that it results in the shortest total
|
// add the location to the current trip such that it results in the shortest total
|
||||||
@@ -137,7 +138,7 @@ inline std::vector<NodeID> FindRoute(const std::size_t &number_of_locations,
|
|||||||
|
|
||||||
inline std::vector<NodeID>
|
inline std::vector<NodeID>
|
||||||
FarthestInsertionTrip(const std::size_t number_of_locations,
|
FarthestInsertionTrip(const std::size_t number_of_locations,
|
||||||
const util::DistTableWrapper<EdgeWeight> &dist_table)
|
const util::DistTableWrapper<EdgeDuration> &dist_table)
|
||||||
{
|
{
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// START FARTHEST INSERTION HERE
|
// START FARTHEST INSERTION HERE
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ class CompressedEdgeContainer
|
|||||||
|
|
||||||
void AddUncompressedEdge(const EdgeID edge_id,
|
void AddUncompressedEdge(const EdgeID edge_id,
|
||||||
const NodeID target_node,
|
const NodeID target_node,
|
||||||
const SegmentWeight weight,
|
const EdgeWeight weight,
|
||||||
const SegmentWeight duration);
|
const EdgeDuration duration);
|
||||||
|
|
||||||
void InitializeBothwayVector();
|
void InitializeBothwayVector();
|
||||||
unsigned ZipEdges(const unsigned f_edge_pos, const unsigned r_edge_pos);
|
unsigned ZipEdges(const unsigned f_edge_pos, const unsigned r_edge_pos);
|
||||||
@@ -67,8 +67,8 @@ class CompressedEdgeContainer
|
|||||||
std::unique_ptr<SegmentDataContainer> ToSegmentData();
|
std::unique_ptr<SegmentDataContainer> ToSegmentData();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SegmentWeight ClipWeight(const SegmentWeight weight);
|
SegmentWeight ClipWeight(const EdgeWeight weight);
|
||||||
SegmentDuration ClipDuration(const SegmentDuration duration);
|
SegmentDuration ClipDuration(const EdgeDuration duration);
|
||||||
|
|
||||||
int free_list_maximum = 0;
|
int free_list_maximum = 0;
|
||||||
std::atomic_size_t clipped_weights{0};
|
std::atomic_size_t clipped_weights{0};
|
||||||
|
|||||||
@@ -16,14 +16,14 @@ struct EdgeBasedEdge
|
|||||||
struct EdgeData
|
struct EdgeData
|
||||||
{
|
{
|
||||||
EdgeData()
|
EdgeData()
|
||||||
: turn_id(0), weight(0), distance(0), duration(0), forward(false), backward(false)
|
: turn_id(0), weight{0}, distance{0}, duration(0), forward(false), backward(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
EdgeData(const NodeID turn_id,
|
EdgeData(const NodeID turn_id,
|
||||||
const EdgeWeight weight,
|
const EdgeWeight weight,
|
||||||
const EdgeDistance distance,
|
const EdgeDistance distance,
|
||||||
const EdgeWeight duration,
|
const EdgeDuration duration,
|
||||||
const bool forward,
|
const bool forward,
|
||||||
const bool backward)
|
const bool backward)
|
||||||
: turn_id(turn_id), weight(weight), distance(distance), duration(duration),
|
: turn_id(turn_id), weight(weight), distance(distance), duration(duration),
|
||||||
@@ -34,7 +34,7 @@ struct EdgeBasedEdge
|
|||||||
NodeID turn_id; // ID of the edge based node (node based edge)
|
NodeID turn_id; // ID of the edge based node (node based edge)
|
||||||
EdgeWeight weight;
|
EdgeWeight weight;
|
||||||
EdgeDistance distance;
|
EdgeDistance distance;
|
||||||
EdgeWeight duration : 30;
|
EdgeDuration::value_type duration : 30;
|
||||||
std::uint32_t forward : 1;
|
std::uint32_t forward : 1;
|
||||||
std::uint32_t backward : 1;
|
std::uint32_t backward : 1;
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ struct EdgeBasedEdge
|
|||||||
const NodeID target,
|
const NodeID target,
|
||||||
const NodeID edge_id,
|
const NodeID edge_id,
|
||||||
const EdgeWeight weight,
|
const EdgeWeight weight,
|
||||||
const EdgeWeight duration,
|
const EdgeDuration duration,
|
||||||
const EdgeDistance distance,
|
const EdgeDistance distance,
|
||||||
const bool forward,
|
const bool forward,
|
||||||
const bool backward);
|
const bool backward);
|
||||||
@@ -72,7 +72,7 @@ inline EdgeBasedEdge::EdgeBasedEdge(const NodeID source,
|
|||||||
const NodeID target,
|
const NodeID target,
|
||||||
const NodeID turn_id,
|
const NodeID turn_id,
|
||||||
const EdgeWeight weight,
|
const EdgeWeight weight,
|
||||||
const EdgeWeight duration,
|
const EdgeDuration duration,
|
||||||
const EdgeDistance distance,
|
const EdgeDistance distance,
|
||||||
const bool forward,
|
const bool forward,
|
||||||
const bool backward)
|
const bool backward)
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
|
|
||||||
#include "storage/io.hpp"
|
#include "storage/io.hpp"
|
||||||
#include "traffic_signals.hpp"
|
#include "traffic_flow_control_nodes.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
@@ -69,7 +69,9 @@ class EdgeBasedGraphFactory
|
|||||||
EdgeBasedNodeDataContainer &node_data_container,
|
EdgeBasedNodeDataContainer &node_data_container,
|
||||||
const CompressedEdgeContainer &compressed_edge_container,
|
const CompressedEdgeContainer &compressed_edge_container,
|
||||||
const std::unordered_set<NodeID> &barrier_nodes,
|
const std::unordered_set<NodeID> &barrier_nodes,
|
||||||
const TrafficSignals &traffic_signals,
|
const TrafficFlowControlNodes &traffic_signals,
|
||||||
|
const TrafficFlowControlNodes &stop_signs,
|
||||||
|
const TrafficFlowControlNodes &give_way_signs,
|
||||||
const std::vector<util::Coordinate> &coordinates,
|
const std::vector<util::Coordinate> &coordinates,
|
||||||
const NameTable &name_table,
|
const NameTable &name_table,
|
||||||
const std::unordered_set<EdgeID> &segregated_edges,
|
const std::unordered_set<EdgeID> &segregated_edges,
|
||||||
@@ -91,7 +93,7 @@ class EdgeBasedGraphFactory
|
|||||||
void GetEdgeBasedEdges(util::DeallocatingVector<EdgeBasedEdge> &edges);
|
void GetEdgeBasedEdges(util::DeallocatingVector<EdgeBasedEdge> &edges);
|
||||||
void GetEdgeBasedNodeSegments(std::vector<EdgeBasedNodeSegment> &nodes);
|
void GetEdgeBasedNodeSegments(std::vector<EdgeBasedNodeSegment> &nodes);
|
||||||
void GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &output_node_weights);
|
void GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &output_node_weights);
|
||||||
void GetEdgeBasedNodeDurations(std::vector<EdgeWeight> &output_node_durations);
|
void GetEdgeBasedNodeDurations(std::vector<EdgeDuration> &output_node_durations);
|
||||||
void GetEdgeBasedNodeDistances(std::vector<EdgeDistance> &output_node_distances);
|
void GetEdgeBasedNodeDistances(std::vector<EdgeDistance> &output_node_distances);
|
||||||
std::uint32_t GetConnectivityChecksum() const;
|
std::uint32_t GetConnectivityChecksum() const;
|
||||||
|
|
||||||
@@ -135,7 +137,10 @@ class EdgeBasedGraphFactory
|
|||||||
const util::NodeBasedDynamicGraph &m_node_based_graph;
|
const util::NodeBasedDynamicGraph &m_node_based_graph;
|
||||||
|
|
||||||
const std::unordered_set<NodeID> &m_barrier_nodes;
|
const std::unordered_set<NodeID> &m_barrier_nodes;
|
||||||
const TrafficSignals &m_traffic_signals;
|
const TrafficFlowControlNodes &m_traffic_signals;
|
||||||
|
const TrafficFlowControlNodes &m_stop_signs;
|
||||||
|
const TrafficFlowControlNodes &m_give_way_signs;
|
||||||
|
|
||||||
const CompressedEdgeContainer &m_compressed_edge_container;
|
const CompressedEdgeContainer &m_compressed_edge_container;
|
||||||
|
|
||||||
const NameTable &name_table;
|
const NameTable &name_table;
|
||||||
|
|||||||
@@ -8,8 +8,7 @@
|
|||||||
#include "extractor/scripting_environment.hpp"
|
#include "extractor/scripting_environment.hpp"
|
||||||
|
|
||||||
#include "storage/tar_fwd.hpp"
|
#include "storage/tar_fwd.hpp"
|
||||||
#include "traffic_lights.hpp"
|
#include "traffic_flow_control_nodes.hpp"
|
||||||
#include "traffic_signals.hpp"
|
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
@@ -27,20 +26,29 @@ namespace extractor
|
|||||||
*/
|
*/
|
||||||
class ExtractionContainers
|
class ExtractionContainers
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
using InputTrafficFlowControlNode = std::pair<OSMNodeID, TrafficFlowControlNodeDirection>;
|
||||||
|
|
||||||
|
private:
|
||||||
using ReferencedWays = std::unordered_map<OSMWayID, NodesOfWay>;
|
using ReferencedWays = std::unordered_map<OSMWayID, NodesOfWay>;
|
||||||
using ReferencedTrafficSignals =
|
using ReferencedTrafficFlowControlNodes =
|
||||||
std::pair<std::unordered_set<OSMNodeID>, std::unordered_multimap<OSMNodeID, OSMNodeID>>;
|
std::pair<std::unordered_set<OSMNodeID>, std::unordered_multimap<OSMNodeID, OSMNodeID>>;
|
||||||
// The relationship between way and nodes is lost during node preparation.
|
// The relationship between way and nodes is lost during node preparation.
|
||||||
// We identify the ways and nodes relevant to restrictions/overrides/signals prior to
|
// We identify the ways and nodes relevant to restrictions/overrides/signals prior to
|
||||||
// node processing so that they can be referenced in the preparation phase.
|
// node processing so that they can be referenced in the preparation phase.
|
||||||
ReferencedWays IdentifyRestrictionWays();
|
ReferencedWays IdentifyRestrictionWays();
|
||||||
ReferencedWays IdentifyManeuverOverrideWays();
|
ReferencedWays IdentifyManeuverOverrideWays();
|
||||||
ReferencedTrafficSignals IdentifyTrafficSignals();
|
|
||||||
|
ReferencedTrafficFlowControlNodes IdentifyTrafficFlowControlNodes(
|
||||||
|
const std::vector<InputTrafficFlowControlNode> &external_traffic_control_nodes);
|
||||||
|
|
||||||
void PrepareNodes();
|
void PrepareNodes();
|
||||||
void PrepareManeuverOverrides(const ReferencedWays &maneuver_override_ways);
|
void PrepareManeuverOverrides(const ReferencedWays &maneuver_override_ways);
|
||||||
void PrepareRestrictions(const ReferencedWays &restriction_ways);
|
void PrepareRestrictions(const ReferencedWays &restriction_ways);
|
||||||
void PrepareTrafficSignals(const ReferencedTrafficSignals &referenced_traffic_signals);
|
void PrepareTrafficFlowControlNodes(
|
||||||
|
const ReferencedTrafficFlowControlNodes &referenced_traffic_control_nodes,
|
||||||
|
TrafficFlowControlNodes &internal_traffic_control_nodes);
|
||||||
|
|
||||||
void PrepareEdges(ScriptingEnvironment &scripting_environment);
|
void PrepareEdges(ScriptingEnvironment &scripting_environment);
|
||||||
|
|
||||||
void WriteCharData(const std::string &file_name);
|
void WriteCharData(const std::string &file_name);
|
||||||
@@ -54,7 +62,6 @@ class ExtractionContainers
|
|||||||
using NameOffsets = std::vector<size_t>;
|
using NameOffsets = std::vector<size_t>;
|
||||||
using WayIDVector = std::vector<OSMWayID>;
|
using WayIDVector = std::vector<OSMWayID>;
|
||||||
using WayNodeIDOffsets = std::vector<size_t>;
|
using WayNodeIDOffsets = std::vector<size_t>;
|
||||||
using InputTrafficSignal = std::pair<OSMNodeID, TrafficLightClass::Direction>;
|
|
||||||
|
|
||||||
std::vector<OSMNodeID> barrier_nodes;
|
std::vector<OSMNodeID> barrier_nodes;
|
||||||
NodeIDVector used_node_id_list;
|
NodeIDVector used_node_id_list;
|
||||||
@@ -69,8 +76,14 @@ class ExtractionContainers
|
|||||||
|
|
||||||
unsigned max_internal_node_id;
|
unsigned max_internal_node_id;
|
||||||
|
|
||||||
std::vector<InputTrafficSignal> external_traffic_signals;
|
std::vector<InputTrafficFlowControlNode> external_traffic_signals;
|
||||||
TrafficSignals internal_traffic_signals;
|
TrafficFlowControlNodes internal_traffic_signals;
|
||||||
|
|
||||||
|
std::vector<InputTrafficFlowControlNode> external_stop_signs;
|
||||||
|
TrafficFlowControlNodes internal_stop_signs;
|
||||||
|
|
||||||
|
std::vector<InputTrafficFlowControlNode> external_give_ways;
|
||||||
|
TrafficFlowControlNodes internal_give_way_signs;
|
||||||
|
|
||||||
std::vector<NodeBasedEdge> used_edges;
|
std::vector<NodeBasedEdge> used_edges;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
#ifndef EXTRACTION_NODE_HPP
|
#ifndef EXTRACTION_NODE_HPP
|
||||||
#define EXTRACTION_NODE_HPP
|
#define EXTRACTION_NODE_HPP
|
||||||
|
|
||||||
#include "traffic_lights.hpp"
|
#include "traffic_flow_control_nodes.hpp"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
namespace osrm
|
namespace osrm
|
||||||
{
|
{
|
||||||
@@ -10,14 +11,19 @@ namespace extractor
|
|||||||
|
|
||||||
struct ExtractionNode
|
struct ExtractionNode
|
||||||
{
|
{
|
||||||
ExtractionNode() : traffic_lights(TrafficLightClass::NONE), barrier(false) {}
|
ExtractionNode() : traffic_lights(TrafficFlowControlNodeDirection::NONE), barrier(false) {}
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
traffic_lights = TrafficLightClass::NONE;
|
traffic_lights = TrafficFlowControlNodeDirection::NONE;
|
||||||
|
stop_sign = TrafficFlowControlNodeDirection::NONE;
|
||||||
|
give_way = TrafficFlowControlNodeDirection::NONE;
|
||||||
barrier = false;
|
barrier = false;
|
||||||
}
|
}
|
||||||
TrafficLightClass::Direction traffic_lights;
|
TrafficFlowControlNodeDirection traffic_lights;
|
||||||
bool barrier;
|
bool barrier;
|
||||||
|
|
||||||
|
TrafficFlowControlNodeDirection stop_sign;
|
||||||
|
TrafficFlowControlNodeDirection give_way;
|
||||||
};
|
};
|
||||||
} // namespace extractor
|
} // namespace extractor
|
||||||
} // namespace osrm
|
} // namespace osrm
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ struct ExtractionTurn
|
|||||||
int number_of_roads,
|
int number_of_roads,
|
||||||
bool is_u_turn,
|
bool is_u_turn,
|
||||||
bool has_traffic_light,
|
bool has_traffic_light,
|
||||||
|
bool has_stop_sign,
|
||||||
|
bool has_give_way_sign,
|
||||||
bool is_left_hand_driving,
|
bool is_left_hand_driving,
|
||||||
bool source_restricted,
|
bool source_restricted,
|
||||||
TravelMode source_mode,
|
TravelMode source_mode,
|
||||||
@@ -75,7 +77,8 @@ struct ExtractionTurn
|
|||||||
const std::vector<ExtractionTurnLeg> &roads_on_the_right,
|
const std::vector<ExtractionTurnLeg> &roads_on_the_right,
|
||||||
const std::vector<ExtractionTurnLeg> &roads_on_the_left)
|
const std::vector<ExtractionTurnLeg> &roads_on_the_left)
|
||||||
: angle(180. - angle), number_of_roads(number_of_roads), is_u_turn(is_u_turn),
|
: angle(180. - angle), number_of_roads(number_of_roads), is_u_turn(is_u_turn),
|
||||||
has_traffic_light(has_traffic_light), is_left_hand_driving(is_left_hand_driving),
|
has_traffic_light(has_traffic_light), has_stop_sign(has_stop_sign),
|
||||||
|
has_give_way_sign(has_give_way_sign), is_left_hand_driving(is_left_hand_driving),
|
||||||
|
|
||||||
source_restricted(source_restricted), source_mode(source_mode),
|
source_restricted(source_restricted), source_mode(source_mode),
|
||||||
source_is_motorway(source_is_motorway), source_is_link(source_is_link),
|
source_is_motorway(source_is_motorway), source_is_link(source_is_link),
|
||||||
@@ -100,6 +103,8 @@ struct ExtractionTurn
|
|||||||
const int number_of_roads;
|
const int number_of_roads;
|
||||||
const bool is_u_turn;
|
const bool is_u_turn;
|
||||||
const bool has_traffic_light;
|
const bool has_traffic_light;
|
||||||
|
const bool has_stop_sign;
|
||||||
|
const bool has_give_way_sign;
|
||||||
const bool is_left_hand_driving;
|
const bool is_left_hand_driving;
|
||||||
|
|
||||||
// source info
|
// source info
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "util/guidance/turn_lanes.hpp"
|
#include "util/guidance/turn_lanes.hpp"
|
||||||
|
|
||||||
#include "restriction_graph.hpp"
|
#include "restriction_graph.hpp"
|
||||||
#include "traffic_signals.hpp"
|
#include "traffic_flow_control_nodes.hpp"
|
||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
|
|
||||||
namespace osrm
|
namespace osrm
|
||||||
@@ -66,7 +66,9 @@ class Extractor
|
|||||||
LaneDescriptionMap turn_lane_map;
|
LaneDescriptionMap turn_lane_map;
|
||||||
std::vector<TurnRestriction> turn_restrictions;
|
std::vector<TurnRestriction> turn_restrictions;
|
||||||
std::vector<UnresolvedManeuverOverride> unresolved_maneuver_overrides;
|
std::vector<UnresolvedManeuverOverride> unresolved_maneuver_overrides;
|
||||||
TrafficSignals traffic_signals;
|
TrafficFlowControlNodes traffic_signals;
|
||||||
|
TrafficFlowControlNodes stop_signs;
|
||||||
|
TrafficFlowControlNodes give_way_signs;
|
||||||
std::unordered_set<NodeID> barriers;
|
std::unordered_set<NodeID> barriers;
|
||||||
std::vector<util::Coordinate> osm_coordinates;
|
std::vector<util::Coordinate> osm_coordinates;
|
||||||
extractor::PackedOSMIDs osm_node_ids;
|
extractor::PackedOSMIDs osm_node_ids;
|
||||||
@@ -86,7 +88,9 @@ class Extractor
|
|||||||
const std::vector<util::Coordinate> &coordinates,
|
const std::vector<util::Coordinate> &coordinates,
|
||||||
const CompressedEdgeContainer &compressed_edge_container,
|
const CompressedEdgeContainer &compressed_edge_container,
|
||||||
const std::unordered_set<NodeID> &barrier_nodes,
|
const std::unordered_set<NodeID> &barrier_nodes,
|
||||||
const TrafficSignals &traffic_signals,
|
const TrafficFlowControlNodes &traffic_signals,
|
||||||
|
const TrafficFlowControlNodes &stop_signs,
|
||||||
|
const TrafficFlowControlNodes &give_way_signs,
|
||||||
const RestrictionGraph &restriction_graph,
|
const RestrictionGraph &restriction_graph,
|
||||||
const std::unordered_set<EdgeID> &segregated_edges,
|
const std::unordered_set<EdgeID> &segregated_edges,
|
||||||
const NameTable &name_table,
|
const NameTable &name_table,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
namespace osmium
|
namespace osmium
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include "extractor/scripting_environment.hpp"
|
#include "extractor/scripting_environment.hpp"
|
||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
|
|
||||||
#include "traffic_signals.hpp"
|
#include "traffic_flow_control_nodes.hpp"
|
||||||
#include "util/node_based_graph.hpp"
|
#include "util/node_based_graph.hpp"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -26,7 +26,9 @@ class GraphCompressor
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
void Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
void Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||||
const TrafficSignals &traffic_signals,
|
const TrafficFlowControlNodes &traffic_signals,
|
||||||
|
const TrafficFlowControlNodes &stop_signs,
|
||||||
|
const TrafficFlowControlNodes &give_way_signs,
|
||||||
ScriptingEnvironment &scripting_environment,
|
ScriptingEnvironment &scripting_environment,
|
||||||
std::vector<TurnRestriction> &turn_restrictions,
|
std::vector<TurnRestriction> &turn_restrictions,
|
||||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ struct InternalExtractorEdge
|
|||||||
WeightData weight_data,
|
WeightData weight_data,
|
||||||
DurationData duration_data,
|
DurationData duration_data,
|
||||||
util::Coordinate source_coordinate)
|
util::Coordinate source_coordinate)
|
||||||
: result(source, target, 0, 0, 0, {}, -1, {}), weight_data(weight_data),
|
: result(source, target, {0}, {0}, {0}, {}, -1, {}), weight_data(weight_data),
|
||||||
duration_data(duration_data), source_coordinate(source_coordinate)
|
duration_data(duration_data), source_coordinate(source_coordinate)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ inline NodeBasedEdgeClassification::NodeBasedEdgeClassification()
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline NodeBasedEdge::NodeBasedEdge()
|
inline NodeBasedEdge::NodeBasedEdge()
|
||||||
: source(SPECIAL_NODEID), target(SPECIAL_NODEID), weight(0), duration(0), distance(0),
|
: source(SPECIAL_NODEID), target(SPECIAL_NODEID), weight{0}, duration{0}, distance{0},
|
||||||
annotation_data(-1)
|
annotation_data(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#include "extractor/packed_osm_ids.hpp"
|
#include "extractor/packed_osm_ids.hpp"
|
||||||
#include "extractor/scripting_environment.hpp"
|
#include "extractor/scripting_environment.hpp"
|
||||||
|
|
||||||
#include "traffic_signals.hpp"
|
#include "traffic_flow_control_nodes.hpp"
|
||||||
#include "util/coordinate.hpp"
|
#include "util/coordinate.hpp"
|
||||||
#include "util/node_based_graph.hpp"
|
#include "util/node_based_graph.hpp"
|
||||||
|
|
||||||
@@ -41,7 +41,9 @@ class NodeBasedGraphFactory
|
|||||||
NodeBasedGraphFactory(ScriptingEnvironment &scripting_environment,
|
NodeBasedGraphFactory(ScriptingEnvironment &scripting_environment,
|
||||||
std::vector<TurnRestriction> &turn_restrictions,
|
std::vector<TurnRestriction> &turn_restrictions,
|
||||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
||||||
const TrafficSignals &traffic_signals,
|
const TrafficFlowControlNodes &traffic_signals,
|
||||||
|
const TrafficFlowControlNodes &stop_signs,
|
||||||
|
const TrafficFlowControlNodes &give_way_signs,
|
||||||
std::unordered_set<NodeID> &&barriers,
|
std::unordered_set<NodeID> &&barriers,
|
||||||
std::vector<util::Coordinate> &&coordinates,
|
std::vector<util::Coordinate> &&coordinates,
|
||||||
extractor::PackedOSMIDs &&osm_node_ids,
|
extractor::PackedOSMIDs &&osm_node_ids,
|
||||||
@@ -73,7 +75,9 @@ class NodeBasedGraphFactory
|
|||||||
void Compress(ScriptingEnvironment &scripting_environment,
|
void Compress(ScriptingEnvironment &scripting_environment,
|
||||||
std::vector<TurnRestriction> &turn_restrictions,
|
std::vector<TurnRestriction> &turn_restrictions,
|
||||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
||||||
const TrafficSignals &traffic_signals);
|
const TrafficFlowControlNodes &traffic_signals,
|
||||||
|
const TrafficFlowControlNodes &stop_signs,
|
||||||
|
const TrafficFlowControlNodes &give_way_signs);
|
||||||
|
|
||||||
// Most ways are bidirectional, making the geometry in forward and backward direction the same,
|
// Most ways are bidirectional, making the geometry in forward and backward direction the same,
|
||||||
// except for reversal. We make use of this fact by keeping only one representation of the
|
// except for reversal. We make use of this fact by keeping only one representation of the
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
|
|
||||||
#include <boost/range/adaptor/filtered.hpp>
|
#include <boost/range/adaptor/filtered.hpp>
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ struct ProfileProperties
|
|||||||
|
|
||||||
double GetMaxTurnWeight() const
|
double GetMaxTurnWeight() const
|
||||||
{
|
{
|
||||||
return std::numeric_limits<TurnPenalty>::max() / GetWeightMultiplier();
|
return from_alias<double>(MAXIMAL_TURN_PENALTY) / GetWeightMultiplier();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! penalty to cross a traffic light in deci-seconds
|
//! penalty to cross a traffic light in deci-seconds
|
||||||
|
|||||||
@@ -2,11 +2,13 @@
|
|||||||
#define OSRM_EXTRACTOR_RESTRICTION_GRAPH_HPP_
|
#define OSRM_EXTRACTOR_RESTRICTION_GRAPH_HPP_
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
|
|
||||||
#include "util/node_based_graph.hpp"
|
#include "util/node_based_graph.hpp"
|
||||||
|
#include "util/std_hash.hpp"
|
||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace osrm
|
namespace osrm
|
||||||
{
|
{
|
||||||
namespace extractor
|
namespace extractor
|
||||||
@@ -112,10 +114,10 @@ struct RestrictionGraph
|
|||||||
RestrictionRange GetRestrictions(RestrictionID id) const;
|
RestrictionRange GetRestrictions(RestrictionID id) const;
|
||||||
|
|
||||||
// A compressed node-based edge can only have one start node in the restriction graph.
|
// A compressed node-based edge can only have one start node in the restriction graph.
|
||||||
boost::unordered_map<EdgeKey, RestrictionID> start_edge_to_node{};
|
std::unordered_map<EdgeKey, RestrictionID> start_edge_to_node{};
|
||||||
// A compressed node-based edge can have multiple via nodes in the restriction graph
|
// A compressed node-based edge can have multiple via nodes in the restriction graph
|
||||||
// (as the compressed edge can appear in paths with different prefixes).
|
// (as the compressed edge can appear in paths with different prefixes).
|
||||||
boost::unordered_multimap<EdgeKey, RestrictionID> via_edge_to_node{};
|
std::unordered_multimap<EdgeKey, RestrictionID> via_edge_to_node{};
|
||||||
std::vector<RestrictionNode> nodes;
|
std::vector<RestrictionNode> nodes;
|
||||||
// TODO: Investigate reusing DynamicGraph. Currently it requires specific attributes
|
// TODO: Investigate reusing DynamicGraph. Currently it requires specific attributes
|
||||||
// (e.g. reversed, weight) that would not make sense for restrictions.
|
// (e.g. reversed, weight) that would not make sense for restrictions.
|
||||||
|
|||||||
+16
-4
@@ -2,26 +2,38 @@
|
|||||||
#define OSRM_EXTRACTOR_TRAFFIC_SIGNALS_HPP
|
#define OSRM_EXTRACTOR_TRAFFIC_SIGNALS_HPP
|
||||||
|
|
||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
#include <unordered_set>
|
|
||||||
|
|
||||||
#include <boost/unordered_set.hpp>
|
#include <boost/functional/hash.hpp>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
namespace osrm
|
namespace osrm
|
||||||
{
|
{
|
||||||
namespace extractor
|
namespace extractor
|
||||||
{
|
{
|
||||||
|
|
||||||
struct TrafficSignals
|
// The direction annotation is extracted from node tags.
|
||||||
|
// The directions in which traffic flow object applies are relative to the way containing the node.
|
||||||
|
enum class TrafficFlowControlNodeDirection : std::uint8_t
|
||||||
|
{
|
||||||
|
NONE = 0,
|
||||||
|
ALL = 1,
|
||||||
|
FORWARD = 2,
|
||||||
|
REVERSE = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
// represents traffic lights, stop signs, give way signs, etc.
|
||||||
|
struct TrafficFlowControlNodes
|
||||||
{
|
{
|
||||||
std::unordered_set<NodeID> bidirectional_nodes;
|
std::unordered_set<NodeID> bidirectional_nodes;
|
||||||
std::unordered_set<std::pair<NodeID, NodeID>, boost::hash<std::pair<NodeID, NodeID>>>
|
std::unordered_set<std::pair<NodeID, NodeID>, boost::hash<std::pair<NodeID, NodeID>>>
|
||||||
unidirectional_segments;
|
unidirectional_segments;
|
||||||
|
|
||||||
inline bool HasSignal(NodeID from, NodeID to) const
|
inline bool Has(NodeID from, NodeID to) const
|
||||||
{
|
{
|
||||||
return bidirectional_nodes.count(to) > 0 || unidirectional_segments.count({from, to}) > 0;
|
return bidirectional_nodes.count(to) > 0 || unidirectional_segments.count({from, to}) > 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace extractor
|
} // namespace extractor
|
||||||
} // namespace osrm
|
} // namespace osrm
|
||||||
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#ifndef OSRM_EXTRACTOR_TRAFFIC_LIGHTS_DATA_HPP_
|
|
||||||
#define OSRM_EXTRACTOR_TRAFFIC_LIGHTS_DATA_HPP_
|
|
||||||
|
|
||||||
namespace osrm
|
|
||||||
{
|
|
||||||
namespace extractor
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace TrafficLightClass
|
|
||||||
{
|
|
||||||
// The traffic light annotation is extracted from node tags.
|
|
||||||
// The directions in which the traffic light applies are relative to the way containing the node.
|
|
||||||
enum Direction
|
|
||||||
{
|
|
||||||
NONE = 0,
|
|
||||||
DIRECTION_ALL = 1,
|
|
||||||
DIRECTION_FORWARD = 2,
|
|
||||||
DIRECTION_REVERSE = 3
|
|
||||||
};
|
|
||||||
} // namespace TrafficLightClass
|
|
||||||
|
|
||||||
} // namespace extractor
|
|
||||||
} // namespace osrm
|
|
||||||
|
|
||||||
#endif // OSRM_EXTRACTOR_TRAFFIC_LIGHTS_DATA_HPP_
|
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
|
|
||||||
#include <boost/unordered_map.hpp>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace osrm
|
namespace osrm
|
||||||
@@ -43,9 +43,9 @@ class TurnPathCompressor
|
|||||||
// via nodes are the same.
|
// via nodes are the same.
|
||||||
// Similarly, we do not compress the instruction via node in a maneuver override, as we need
|
// Similarly, we do not compress the instruction via node in a maneuver override, as we need
|
||||||
// this to identify the location of the maneuver during routing path-processing.
|
// this to identify the location of the maneuver during routing path-processing.
|
||||||
boost::unordered_multimap<NodeID, TurnPath *> starts;
|
std::unordered_multimap<NodeID, TurnPath *> starts;
|
||||||
boost::unordered_multimap<NodeID, TurnPath *> vias;
|
std::unordered_multimap<NodeID, TurnPath *> vias;
|
||||||
boost::unordered_multimap<NodeID, TurnPath *> ends;
|
std::unordered_multimap<NodeID, TurnPath *> ends;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace extractor
|
} // namespace extractor
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
#ifndef OSRM_EXTRACTOR_WAY_RESTRICTION_MAP_HPP_
|
#ifndef OSRM_EXTRACTOR_WAY_RESTRICTION_MAP_HPP_
|
||||||
#define OSRM_EXTRACTOR_WAY_RESTRICTION_MAP_HPP_
|
#define OSRM_EXTRACTOR_WAY_RESTRICTION_MAP_HPP_
|
||||||
|
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
// to access the turn restrictions
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
|
|
||||||
#include "extractor/restriction.hpp"
|
#include "extractor/restriction.hpp"
|
||||||
#include "extractor/restriction_graph.hpp"
|
#include "extractor/restriction_graph.hpp"
|
||||||
#include "util/integer_range.hpp"
|
#include "util/integer_range.hpp"
|
||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
|
|
||||||
|
// to access the turn restrictions
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace osrm
|
namespace osrm
|
||||||
{
|
{
|
||||||
namespace extractor
|
namespace extractor
|
||||||
|
|||||||
@@ -767,6 +767,37 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Nan::Has(obj, Nan::New("snapping").ToLocalChecked()).FromJust())
|
||||||
|
{
|
||||||
|
v8::Local<v8::Value> snapping =
|
||||||
|
Nan::Get(obj, Nan::New("snapping").ToLocalChecked()).ToLocalChecked();
|
||||||
|
if (snapping.IsEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!snapping->IsString())
|
||||||
|
{
|
||||||
|
Nan::ThrowError("Snapping must be a string: [default, any]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const Nan::Utf8String snapping_utf8str(snapping);
|
||||||
|
std::string snapping_str{*snapping_utf8str, *snapping_utf8str + snapping_utf8str.length()};
|
||||||
|
|
||||||
|
if (snapping_str == "default")
|
||||||
|
{
|
||||||
|
params->snapping = osrm::RouteParameters::SnappingType::Default;
|
||||||
|
}
|
||||||
|
else if (snapping_str == "any")
|
||||||
|
{
|
||||||
|
params->snapping = osrm::RouteParameters::SnappingType::Any;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Nan::ThrowError("'snapping' param must be one of [default, any]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -799,6 +830,9 @@ inline bool parseCommonParameters(const v8::Local<v8::Object> &obj, ParamType &p
|
|||||||
if (annotations->IsBoolean())
|
if (annotations->IsBoolean())
|
||||||
{
|
{
|
||||||
params->annotations = Nan::To<bool>(annotations).FromJust();
|
params->annotations = Nan::To<bool>(annotations).FromJust();
|
||||||
|
params->annotations_type = params->annotations
|
||||||
|
? osrm::RouteParameters::AnnotationsType::All
|
||||||
|
: osrm::RouteParameters::AnnotationsType::None;
|
||||||
}
|
}
|
||||||
else if (annotations->IsArray())
|
else if (annotations->IsArray())
|
||||||
{
|
{
|
||||||
@@ -845,6 +879,9 @@ inline bool parseCommonParameters(const v8::Local<v8::Object> &obj, ParamType &p
|
|||||||
Nan::ThrowError("this 'annotations' param is not supported");
|
Nan::ThrowError("this 'annotations' param is not supported");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
params->annotations =
|
||||||
|
params->annotations_type != osrm::RouteParameters::AnnotationsType::None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1109,36 +1146,6 @@ argumentsToRouteParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Nan::Has(obj, Nan::New("snapping").ToLocalChecked()).FromJust())
|
|
||||||
{
|
|
||||||
v8::Local<v8::Value> snapping =
|
|
||||||
Nan::Get(obj, Nan::New("snapping").ToLocalChecked()).ToLocalChecked();
|
|
||||||
if (snapping.IsEmpty())
|
|
||||||
return route_parameters_ptr();
|
|
||||||
|
|
||||||
if (!snapping->IsString())
|
|
||||||
{
|
|
||||||
Nan::ThrowError("Snapping must be a string: [default, any]");
|
|
||||||
return route_parameters_ptr();
|
|
||||||
}
|
|
||||||
const Nan::Utf8String snapping_utf8str(snapping);
|
|
||||||
std::string snapping_str{*snapping_utf8str, *snapping_utf8str + snapping_utf8str.length()};
|
|
||||||
|
|
||||||
if (snapping_str == "default")
|
|
||||||
{
|
|
||||||
params->snapping = osrm::RouteParameters::SnappingType::Default;
|
|
||||||
}
|
|
||||||
else if (snapping_str == "any")
|
|
||||||
{
|
|
||||||
params->snapping = osrm::RouteParameters::SnappingType::Any;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Nan::ThrowError("'snapping' param must be one of [default, any]");
|
|
||||||
return route_parameters_ptr();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool parsedSuccessfully = parseCommonParameters(obj, params);
|
bool parsedSuccessfully = parseCommonParameters(obj, params);
|
||||||
if (!parsedSuccessfully)
|
if (!parsedSuccessfully)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ splitBidirectionalEdges(const std::vector<extractor::EdgeBasedEdge> &edges)
|
|||||||
directed.emplace_back(edge.source,
|
directed.emplace_back(edge.source,
|
||||||
edge.target,
|
edge.target,
|
||||||
edge.data.turn_id,
|
edge.data.turn_id,
|
||||||
std::max(edge.data.weight, 1),
|
std::max(edge.data.weight, {1}),
|
||||||
edge.data.duration,
|
to_alias<EdgeDuration>(edge.data.duration),
|
||||||
edge.data.distance,
|
edge.data.distance,
|
||||||
edge.data.forward,
|
edge.data.forward,
|
||||||
edge.data.backward);
|
edge.data.backward);
|
||||||
@@ -50,8 +50,8 @@ splitBidirectionalEdges(const std::vector<extractor::EdgeBasedEdge> &edges)
|
|||||||
directed.emplace_back(edge.target,
|
directed.emplace_back(edge.target,
|
||||||
edge.source,
|
edge.source,
|
||||||
edge.data.turn_id,
|
edge.data.turn_id,
|
||||||
std::max(edge.data.weight, 1),
|
std::max(edge.data.weight, {1}),
|
||||||
edge.data.duration,
|
to_alias<EdgeDuration>(edge.data.duration),
|
||||||
edge.data.distance,
|
edge.data.distance,
|
||||||
edge.data.backward,
|
edge.data.backward,
|
||||||
edge.data.forward);
|
edge.data.forward);
|
||||||
|
|||||||
@@ -4,15 +4,14 @@
|
|||||||
#include "server/http/compression_type.hpp"
|
#include "server/http/compression_type.hpp"
|
||||||
#include "server/http/reply.hpp"
|
#include "server/http/reply.hpp"
|
||||||
#include "server/http/request.hpp"
|
#include "server/http/request.hpp"
|
||||||
|
#include "server/request_parser.hpp"
|
||||||
|
|
||||||
#include <boost/array.hpp>
|
#include <boost/array.hpp>
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
#include <boost/beast/core.hpp>
|
|
||||||
#include <boost/beast/http.hpp>
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <boost/version.hpp>
|
#include <boost/version.hpp>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
// workaround for incomplete std::shared_ptr compatibility in old boost versions
|
// workaround for incomplete std::shared_ptr compatibility in old boost versions
|
||||||
@@ -48,7 +47,6 @@ class Connection : public std::enable_shared_from_this<Connection>
|
|||||||
void start();
|
void start();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using RequestParser = boost::beast::http::request_parser<boost::beast::http::string_body>;
|
|
||||||
void handle_read(const boost::system::error_code &e, std::size_t bytes_transferred);
|
void handle_read(const boost::system::error_code &e, std::size_t bytes_transferred);
|
||||||
|
|
||||||
/// Handle completion of a write operation.
|
/// Handle completion of a write operation.
|
||||||
@@ -62,14 +60,12 @@ class Connection : public std::enable_shared_from_this<Connection>
|
|||||||
std::vector<char> compress_buffers(const std::vector<char> &uncompressed_data,
|
std::vector<char> compress_buffers(const std::vector<char> &uncompressed_data,
|
||||||
const http::compression_type compression_type);
|
const http::compression_type compression_type);
|
||||||
|
|
||||||
void fill_request(const RequestParser::value_type &httpMessage, http::request &request);
|
|
||||||
|
|
||||||
boost::asio::strand<boost::asio::io_context::executor_type> strand;
|
boost::asio::strand<boost::asio::io_context::executor_type> strand;
|
||||||
boost::asio::ip::tcp::socket TCP_socket;
|
boost::asio::ip::tcp::socket TCP_socket;
|
||||||
boost::asio::deadline_timer timer;
|
boost::asio::deadline_timer timer;
|
||||||
RequestHandler &request_handler;
|
RequestHandler &request_handler;
|
||||||
std::optional<RequestParser> http_request_parser;
|
RequestParser request_parser;
|
||||||
std::vector<char> incoming_data_buffer;
|
boost::array<char, 8192> incoming_data_buffer;
|
||||||
http::request current_request;
|
http::request current_request;
|
||||||
http::reply current_reply;
|
http::reply current_reply;
|
||||||
std::vector<char> compressed_output;
|
std::vector<char> compressed_output;
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
#ifndef REQUEST_PARSER_HPP
|
||||||
|
#define REQUEST_PARSER_HPP
|
||||||
|
|
||||||
|
#include "server/http/compression_type.hpp"
|
||||||
|
#include "server/http/header.hpp"
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
namespace osrm
|
||||||
|
{
|
||||||
|
namespace server
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace http
|
||||||
|
{
|
||||||
|
struct request;
|
||||||
|
}
|
||||||
|
|
||||||
|
class RequestParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RequestParser();
|
||||||
|
|
||||||
|
enum class RequestStatus : char
|
||||||
|
{
|
||||||
|
valid,
|
||||||
|
invalid,
|
||||||
|
indeterminate
|
||||||
|
};
|
||||||
|
|
||||||
|
std::tuple<RequestStatus, http::compression_type>
|
||||||
|
parse(http::request ¤t_request, char *begin, char *end);
|
||||||
|
|
||||||
|
private:
|
||||||
|
RequestStatus consume(http::request ¤t_request, const char input);
|
||||||
|
|
||||||
|
bool is_char(const int character) const;
|
||||||
|
|
||||||
|
bool is_CTL(const int character) const;
|
||||||
|
|
||||||
|
bool is_special(const int character) const;
|
||||||
|
|
||||||
|
bool is_digit(const int character) const;
|
||||||
|
|
||||||
|
enum class internal_state : unsigned char
|
||||||
|
{
|
||||||
|
method_start,
|
||||||
|
method,
|
||||||
|
uri_start,
|
||||||
|
uri,
|
||||||
|
http_version_h,
|
||||||
|
http_version_t_1,
|
||||||
|
http_version_t_2,
|
||||||
|
http_version_p,
|
||||||
|
http_version_slash,
|
||||||
|
http_version_major_start,
|
||||||
|
http_version_major,
|
||||||
|
http_version_minor_start,
|
||||||
|
http_version_minor,
|
||||||
|
expecting_newline_1,
|
||||||
|
header_line_start,
|
||||||
|
header_lws,
|
||||||
|
header_name,
|
||||||
|
header_value,
|
||||||
|
expecting_newline_2,
|
||||||
|
expecting_newline_3
|
||||||
|
} state;
|
||||||
|
|
||||||
|
http::header current_header;
|
||||||
|
http::compression_type selected_compression;
|
||||||
|
};
|
||||||
|
} // namespace server
|
||||||
|
} // namespace osrm
|
||||||
|
|
||||||
|
#endif // REQUEST_PARSER_HPP
|
||||||
@@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#ifndef OSRM_UTIL_ALIAS_HPP
|
#ifndef OSRM_UTIL_ALIAS_HPP
|
||||||
#define OSRM_UTIL_ALIAS_HPP
|
#define OSRM_UTIL_ALIAS_HPP
|
||||||
|
|
||||||
|
#include <boost/numeric/conversion/cast.hpp>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
@@ -125,6 +126,40 @@ template <typename From, typename Tag> struct Alias final
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename ToAlias, typename FromAlias> inline ToAlias alias_cast(const FromAlias &from)
|
||||||
|
{
|
||||||
|
static_assert(std::is_arithmetic<typename FromAlias::value_type>::value,
|
||||||
|
"Alias From needs to be based on an arithmetic type");
|
||||||
|
static_assert(std::is_arithmetic<typename ToAlias::value_type>::value,
|
||||||
|
"Alias Other needs to be based on an arithmetic type");
|
||||||
|
return {static_cast<typename ToAlias::value_type>(
|
||||||
|
static_cast<const typename FromAlias::value_type>(from))};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ToNumeric, typename FromAlias> inline ToNumeric from_alias(const FromAlias &from)
|
||||||
|
{
|
||||||
|
static_assert(std::is_arithmetic<typename FromAlias::value_type>::value,
|
||||||
|
"Alias From needs to be based on an arithmetic type");
|
||||||
|
static_assert(std::is_arithmetic<ToNumeric>::value, "Numeric needs to be an arithmetic type");
|
||||||
|
return {static_cast<ToNumeric>(static_cast<const typename FromAlias::value_type>(from))};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ToAlias,
|
||||||
|
typename FromNumeric,
|
||||||
|
typename = std::enable_if_t<!std::is_same<ToAlias, FromNumeric>::value>>
|
||||||
|
inline ToAlias to_alias(const FromNumeric &from)
|
||||||
|
{
|
||||||
|
static_assert(std::is_arithmetic<FromNumeric>::value, "Numeric needs to be an arithmetic type");
|
||||||
|
static_assert(std::is_arithmetic<typename ToAlias::value_type>::value,
|
||||||
|
"Alias needs to be based on an arithmetic type");
|
||||||
|
return {static_cast<typename ToAlias::value_type>(from)};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sometimes metrics are stored either as bitfields or the alias itself.
|
||||||
|
// So we'll try to convert to alias without knowing which is the case.
|
||||||
|
// Therefore, we need this no-op overload, otherwise it will fail on the arithmetic requirement.
|
||||||
|
template <typename ToAlias> inline ToAlias to_alias(const ToAlias &from) { return from; }
|
||||||
|
|
||||||
template <typename From, typename Tag>
|
template <typename From, typename Tag>
|
||||||
inline std::ostream &operator<<(std::ostream &stream, const Alias<From, Tag> &inst)
|
inline std::ostream &operator<<(std::ostream &stream, const Alias<From, Tag> &inst)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ template <typename T> class DistTableWrapper
|
|||||||
|
|
||||||
std::size_t size() const { return table_.size(); }
|
std::size_t size() const { return table_.size(); }
|
||||||
|
|
||||||
EdgeWeight operator()(NodeID from, NodeID to) const
|
T operator()(NodeID from, NodeID to) const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT_MSG(from < number_of_nodes_, "from ID is out of bound");
|
BOOST_ASSERT_MSG(from < number_of_nodes_, "from ID is out of bound");
|
||||||
BOOST_ASSERT_MSG(to < number_of_nodes_, "to ID is out of bound");
|
BOOST_ASSERT_MSG(to < number_of_nodes_, "to ID is out of bound");
|
||||||
@@ -46,7 +46,7 @@ template <typename T> class DistTableWrapper
|
|||||||
return table_[index];
|
return table_[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetValue(NodeID from, NodeID to, EdgeWeight value)
|
void SetValue(NodeID from, NodeID to, T value)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT_MSG(from < number_of_nodes_, "from ID is out of bound");
|
BOOST_ASSERT_MSG(from < number_of_nodes_, "from ID is out of bound");
|
||||||
BOOST_ASSERT_MSG(to < number_of_nodes_, "to ID is out of bound");
|
BOOST_ASSERT_MSG(to < number_of_nodes_, "to ID is out of bound");
|
||||||
|
|||||||
@@ -21,14 +21,14 @@ namespace util
|
|||||||
struct NodeBasedEdgeData
|
struct NodeBasedEdgeData
|
||||||
{
|
{
|
||||||
NodeBasedEdgeData()
|
NodeBasedEdgeData()
|
||||||
: weight(INVALID_EDGE_WEIGHT), duration(INVALID_EDGE_WEIGHT),
|
: weight(INVALID_EDGE_WEIGHT), duration(INVALID_EDGE_DURATION),
|
||||||
distance(INVALID_EDGE_DISTANCE), geometry_id({0, false}), reversed(false),
|
distance(INVALID_EDGE_DISTANCE), geometry_id({0, false}), reversed(false),
|
||||||
annotation_data(-1)
|
annotation_data(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeBasedEdgeData(EdgeWeight weight,
|
NodeBasedEdgeData(EdgeWeight weight,
|
||||||
EdgeWeight duration,
|
EdgeDuration duration,
|
||||||
EdgeDistance distance,
|
EdgeDistance distance,
|
||||||
GeometryID geometry_id,
|
GeometryID geometry_id,
|
||||||
bool reversed,
|
bool reversed,
|
||||||
@@ -40,7 +40,7 @@ struct NodeBasedEdgeData
|
|||||||
}
|
}
|
||||||
|
|
||||||
EdgeWeight weight;
|
EdgeWeight weight;
|
||||||
EdgeWeight duration;
|
EdgeDuration duration;
|
||||||
EdgeDistance distance;
|
EdgeDistance distance;
|
||||||
GeometryID geometry_id;
|
GeometryID geometry_id;
|
||||||
bool reversed : 1;
|
bool reversed : 1;
|
||||||
@@ -88,9 +88,9 @@ NodeBasedDynamicGraphFromEdges(NodeID number_of_nodes,
|
|||||||
output_edge.data.flags = input_edge.flags;
|
output_edge.data.flags = input_edge.flags;
|
||||||
output_edge.data.annotation_data = input_edge.annotation_data;
|
output_edge.data.annotation_data = input_edge.annotation_data;
|
||||||
|
|
||||||
BOOST_ASSERT(output_edge.data.weight > 0);
|
BOOST_ASSERT(output_edge.data.weight > EdgeWeight{0});
|
||||||
BOOST_ASSERT(output_edge.data.duration > 0);
|
BOOST_ASSERT(output_edge.data.duration > EdgeDuration{0});
|
||||||
BOOST_ASSERT(output_edge.data.distance >= 0);
|
BOOST_ASSERT(output_edge.data.distance >= EdgeDistance{0});
|
||||||
});
|
});
|
||||||
|
|
||||||
tbb::parallel_sort(edges_list.begin(), edges_list.end());
|
tbb::parallel_sort(edges_list.begin(), edges_list.end());
|
||||||
|
|||||||
@@ -83,19 +83,45 @@ inline T get_upper_half_value(WordT word,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename WordT, typename T>
|
template <typename WordT, typename T>
|
||||||
inline WordT set_lower_value(WordT word, WordT mask, std::uint8_t offset, T value)
|
inline WordT set_lower_value(WordT word,
|
||||||
|
WordT mask,
|
||||||
|
std::uint8_t offset,
|
||||||
|
T value,
|
||||||
|
typename std::enable_if_t<std::is_integral<T>::value> * = nullptr)
|
||||||
{
|
{
|
||||||
static_assert(std::is_unsigned<WordT>::value, "Only unsigned word types supported for now.");
|
static_assert(std::is_unsigned<WordT>::value, "Only unsigned word types supported for now.");
|
||||||
return (word & ~mask) | ((static_cast<WordT>(value) << offset) & mask);
|
return (word & ~mask) | ((static_cast<WordT>(value) << offset) & mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename WordT, typename T>
|
template <typename WordT, typename T>
|
||||||
inline WordT set_upper_value(WordT word, WordT mask, std::uint8_t offset, T value)
|
inline WordT set_upper_value(WordT word,
|
||||||
|
WordT mask,
|
||||||
|
std::uint8_t offset,
|
||||||
|
T value,
|
||||||
|
typename std::enable_if_t<std::is_integral<T>::value> * = nullptr)
|
||||||
{
|
{
|
||||||
static_assert(std::is_unsigned<WordT>::value, "Only unsigned word types supported for now.");
|
static_assert(std::is_unsigned<WordT>::value, "Only unsigned word types supported for now.");
|
||||||
return (word & ~mask) | ((static_cast<WordT>(value) >> offset) & mask);
|
return (word & ~mask) | ((static_cast<WordT>(value) >> offset) & mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename WordT, typename T>
|
||||||
|
inline WordT set_lower_value(
|
||||||
|
WordT word, WordT mask, std::uint8_t offset, T value, typename T::value_type * = nullptr)
|
||||||
|
{
|
||||||
|
static_assert(std::is_unsigned<WordT>::value, "Only unsigned word types supported for now.");
|
||||||
|
return (word & ~mask) |
|
||||||
|
((static_cast<WordT>(static_cast<typename T::value_type>(value)) << offset) & mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename WordT, typename T>
|
||||||
|
inline WordT set_upper_value(
|
||||||
|
WordT word, WordT mask, std::uint8_t offset, T value, typename T::value_type * = nullptr)
|
||||||
|
{
|
||||||
|
static_assert(std::is_unsigned<WordT>::value, "Only unsigned word types supported for now.");
|
||||||
|
return (word & ~mask) |
|
||||||
|
((static_cast<WordT>(static_cast<typename T::value_type>(value)) >> offset) & mask);
|
||||||
|
}
|
||||||
|
|
||||||
inline bool compare_and_swap(uint64_t *ptr, uint64_t old_value, uint64_t new_value)
|
inline bool compare_and_swap(uint64_t *ptr, uint64_t old_value, uint64_t new_value)
|
||||||
{
|
{
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
@@ -287,6 +313,12 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
|
|||||||
return &container == &other.container && internal_index == other.internal_index;
|
return &container == &other.container && internal_index == other.internal_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: This is needed for tests on Boost ranges to correctly compare Alias values.
|
||||||
|
template <typename F, typename U> bool operator!=(const osrm::Alias<F, U> value) const
|
||||||
|
{
|
||||||
|
return container.get_value(internal_index) != value;
|
||||||
|
}
|
||||||
|
|
||||||
friend std::ostream &operator<<(std::ostream &os, const internal_reference &rhs)
|
friend std::ostream &operator<<(std::ostream &os, const internal_reference &rhs)
|
||||||
{
|
{
|
||||||
return os << static_cast<T>(rhs);
|
return os << static_cast<T>(rhs);
|
||||||
|
|||||||
+50
-16
@@ -48,7 +48,26 @@ struct osm_way_id
|
|||||||
struct duplicated_node
|
struct duplicated_node
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
struct edge_weight
|
||||||
|
{
|
||||||
|
};
|
||||||
|
struct edge_duration
|
||||||
|
{
|
||||||
|
};
|
||||||
|
struct edge_distance
|
||||||
|
{
|
||||||
|
};
|
||||||
|
struct segment_weight
|
||||||
|
{
|
||||||
|
};
|
||||||
|
struct segment_duration
|
||||||
|
{
|
||||||
|
};
|
||||||
|
struct turn_penalty
|
||||||
|
{
|
||||||
|
};
|
||||||
} // namespace tag
|
} // namespace tag
|
||||||
|
|
||||||
using OSMNodeID = osrm::Alias<std::uint64_t, tag::osm_node_id>;
|
using OSMNodeID = osrm::Alias<std::uint64_t, tag::osm_node_id>;
|
||||||
// clang-tidy fires `bugprone-throw-keyword-missing` here for unknown reason
|
// clang-tidy fires `bugprone-throw-keyword-missing` here for unknown reason
|
||||||
// NOLINTNEXTLINE(bugprone-throw-keyword-missing)
|
// NOLINTNEXTLINE(bugprone-throw-keyword-missing)
|
||||||
@@ -77,12 +96,13 @@ using EdgeID = std::uint32_t;
|
|||||||
using NameID = std::uint32_t;
|
using NameID = std::uint32_t;
|
||||||
using AnnotationID = std::uint32_t;
|
using AnnotationID = std::uint32_t;
|
||||||
using PackedGeometryID = std::uint32_t;
|
using PackedGeometryID = std::uint32_t;
|
||||||
using EdgeWeight = std::int32_t;
|
|
||||||
using EdgeDuration = std::int32_t;
|
using EdgeWeight = osrm::Alias<std::int32_t, tag::edge_weight>;
|
||||||
using EdgeDistance = float;
|
using EdgeDuration = osrm::Alias<std::int32_t, tag::edge_duration>;
|
||||||
using SegmentWeight = std::uint32_t;
|
using EdgeDistance = osrm::Alias<float, tag::edge_distance>;
|
||||||
using SegmentDuration = std::uint32_t;
|
using SegmentWeight = osrm::Alias<std::uint32_t, tag::segment_weight>;
|
||||||
using TurnPenalty = std::int16_t; // turn penalty in 100ms units
|
using SegmentDuration = osrm::Alias<std::uint32_t, tag::segment_duration>;
|
||||||
|
using TurnPenalty = osrm::Alias<std::int16_t, tag::turn_penalty>; // turn penalty in 100ms units
|
||||||
|
|
||||||
static const std::size_t INVALID_INDEX = std::numeric_limits<std::size_t>::max();
|
static const std::size_t INVALID_INDEX = std::numeric_limits<std::size_t>::max();
|
||||||
|
|
||||||
@@ -109,16 +129,30 @@ static const NameID EMPTY_NAMEID = 0;
|
|||||||
static const unsigned INVALID_COMPONENTID = 0;
|
static const unsigned INVALID_COMPONENTID = 0;
|
||||||
static const std::size_t SEGMENT_WEIGHT_BITS = 22;
|
static const std::size_t SEGMENT_WEIGHT_BITS = 22;
|
||||||
static const std::size_t SEGMENT_DURATION_BITS = 22;
|
static const std::size_t SEGMENT_DURATION_BITS = 22;
|
||||||
static const SegmentWeight INVALID_SEGMENT_WEIGHT = (1u << SEGMENT_WEIGHT_BITS) - 1;
|
static const SegmentWeight INVALID_SEGMENT_WEIGHT = SegmentWeight{(1u << SEGMENT_WEIGHT_BITS) - 1};
|
||||||
static const SegmentDuration INVALID_SEGMENT_DURATION = (1u << SEGMENT_DURATION_BITS) - 1;
|
static const SegmentDuration INVALID_SEGMENT_DURATION =
|
||||||
static const SegmentWeight MAX_SEGMENT_WEIGHT = INVALID_SEGMENT_WEIGHT - 1;
|
SegmentDuration{(1u << SEGMENT_DURATION_BITS) - 1};
|
||||||
static const SegmentDuration MAX_SEGMENT_DURATION = INVALID_SEGMENT_DURATION - 1;
|
static const SegmentWeight MAX_SEGMENT_WEIGHT = INVALID_SEGMENT_WEIGHT - SegmentWeight{1};
|
||||||
static const EdgeWeight INVALID_EDGE_WEIGHT = std::numeric_limits<EdgeWeight>::max();
|
static const SegmentDuration MAX_SEGMENT_DURATION = INVALID_SEGMENT_DURATION - SegmentDuration{1};
|
||||||
static const EdgeDuration MAXIMAL_EDGE_DURATION = std::numeric_limits<EdgeDuration>::max();
|
static const EdgeWeight INVALID_EDGE_WEIGHT =
|
||||||
static const EdgeDistance MAXIMAL_EDGE_DISTANCE = std::numeric_limits<EdgeDistance>::max();
|
EdgeWeight{std::numeric_limits<EdgeWeight::value_type>::max()};
|
||||||
static const TurnPenalty INVALID_TURN_PENALTY = std::numeric_limits<TurnPenalty>::max();
|
static const EdgeDuration INVALID_EDGE_DURATION =
|
||||||
static const EdgeDistance INVALID_EDGE_DISTANCE = std::numeric_limits<EdgeDistance>::max();
|
EdgeDuration{std::numeric_limits<EdgeDuration::value_type>::max()};
|
||||||
static const EdgeDistance INVALID_FALLBACK_SPEED = std::numeric_limits<EdgeDistance>::max();
|
static const EdgeDistance INVALID_EDGE_DISTANCE =
|
||||||
|
EdgeDistance{std::numeric_limits<EdgeDistance::value_type>::max()};
|
||||||
|
static const TurnPenalty INVALID_TURN_PENALTY =
|
||||||
|
TurnPenalty{std::numeric_limits<TurnPenalty::value_type>::max()};
|
||||||
|
static const EdgeDistance INVALID_FALLBACK_SPEED =
|
||||||
|
EdgeDistance{std::numeric_limits<EdgeDistance::value_type>::max()};
|
||||||
|
// TODO: These are the same as the invalid values. Do we need both?
|
||||||
|
static const EdgeWeight MAXIMAL_EDGE_WEIGHT =
|
||||||
|
EdgeWeight{std::numeric_limits<EdgeWeight::value_type>::max()};
|
||||||
|
static const EdgeDuration MAXIMAL_EDGE_DURATION =
|
||||||
|
EdgeDuration{std::numeric_limits<EdgeDuration::value_type>::max()};
|
||||||
|
static const EdgeDistance MAXIMAL_EDGE_DISTANCE =
|
||||||
|
EdgeDistance{std::numeric_limits<EdgeDistance::value_type>::max()};
|
||||||
|
static const TurnPenalty MAXIMAL_TURN_PENALTY =
|
||||||
|
TurnPenalty{std::numeric_limits<TurnPenalty::value_type>::max()};
|
||||||
|
|
||||||
using DatasourceID = std::uint8_t;
|
using DatasourceID = std::uint8_t;
|
||||||
|
|
||||||
|
|||||||
Generated
+5
-5
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "osrm",
|
"name": "@project-osrm/osrm",
|
||||||
"version": "5.27.0-unreleased",
|
"version": "5.28.0-unreleased",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -10090,9 +10090,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"nan": {
|
"nan": {
|
||||||
"version": "2.16.0",
|
"version": "2.17.0",
|
||||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz",
|
"resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz",
|
||||||
"integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA=="
|
"integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ=="
|
||||||
},
|
},
|
||||||
"nanomatch": {
|
"nanomatch": {
|
||||||
"version": "1.2.13",
|
"version": "1.2.13",
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
"@mapbox/node-pre-gyp": "^1.0.9",
|
"@mapbox/node-pre-gyp": "^1.0.9",
|
||||||
"cheap-ruler": "^3.0.2",
|
"cheap-ruler": "^3.0.2",
|
||||||
"mkdirp": "^0.5.6",
|
"mkdirp": "^0.5.6",
|
||||||
"nan": "^2.16.0",
|
"nan": "^2.17.0",
|
||||||
"node-cmake": "^2.5.1",
|
"node-cmake": "^2.5.1",
|
||||||
"rimraf": "^2.7.1"
|
"rimraf": "^2.7.1"
|
||||||
},
|
},
|
||||||
|
|||||||
+16
-1
@@ -7,6 +7,8 @@ Sequence = require('lib/sequence')
|
|||||||
Handlers = require("lib/way_handlers")
|
Handlers = require("lib/way_handlers")
|
||||||
Relations = require("lib/relations")
|
Relations = require("lib/relations")
|
||||||
TrafficSignal = require("lib/traffic_signal")
|
TrafficSignal = require("lib/traffic_signal")
|
||||||
|
StopSign = require("lib/stop_sign")
|
||||||
|
GiveWay = require("lib/give_way")
|
||||||
find_access_tag = require("lib/access").find_access_tag
|
find_access_tag = require("lib/access").find_access_tag
|
||||||
limit = require("lib/maxspeed").limit
|
limit = require("lib/maxspeed").limit
|
||||||
Utils = require("lib/utils")
|
Utils = require("lib/utils")
|
||||||
@@ -28,6 +30,8 @@ function setup()
|
|||||||
use_turn_restrictions = true,
|
use_turn_restrictions = true,
|
||||||
left_hand_driving = false,
|
left_hand_driving = false,
|
||||||
traffic_light_penalty = 2,
|
traffic_light_penalty = 2,
|
||||||
|
stop_sign_penalty = 2,
|
||||||
|
give_way_sign_penalty = 1.5
|
||||||
},
|
},
|
||||||
|
|
||||||
default_mode = mode.driving,
|
default_mode = mode.driving,
|
||||||
@@ -362,6 +366,12 @@ function process_node(profile, node, result, relations)
|
|||||||
|
|
||||||
-- check if node is a traffic light
|
-- check if node is a traffic light
|
||||||
result.traffic_lights = TrafficSignal.get_value(node)
|
result.traffic_lights = TrafficSignal.get_value(node)
|
||||||
|
|
||||||
|
-- check if node is stop sign
|
||||||
|
result.stop_sign = StopSign.get_value(node)
|
||||||
|
|
||||||
|
-- check if node is a give way sign
|
||||||
|
result.give_way = GiveWay.get_value(node)
|
||||||
end
|
end
|
||||||
|
|
||||||
function process_way(profile, way, result, relations)
|
function process_way(profile, way, result, relations)
|
||||||
@@ -471,9 +481,14 @@ function process_turn(profile, turn)
|
|||||||
local turn_bias = turn.is_left_hand_driving and 1. / profile.turn_bias or profile.turn_bias
|
local turn_bias = turn.is_left_hand_driving and 1. / profile.turn_bias or profile.turn_bias
|
||||||
|
|
||||||
if turn.has_traffic_light then
|
if turn.has_traffic_light then
|
||||||
turn.duration = profile.properties.traffic_light_penalty
|
turn.duration = profile.properties.traffic_light_penalty
|
||||||
|
elseif turn.has_stop_sign then
|
||||||
|
turn.duration = profile.properties.stop_sign_penalty
|
||||||
|
elseif turn.has_give_way_sign then
|
||||||
|
turn.duration = profile.properties.give_way_sign_penalty
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
if turn.number_of_roads > 2 or turn.source_mode ~= turn.target_mode or turn.is_u_turn then
|
if turn.number_of_roads > 2 or turn.source_mode ~= turn.target_mode or turn.is_u_turn then
|
||||||
if turn.angle >= 0 then
|
if turn.angle >= 0 then
|
||||||
turn.duration = turn.duration + turn_penalty / (1 + math.exp( -((13 / turn_bias) * turn.angle/180 - 6.5*turn_bias)))
|
turn.duration = turn.duration + turn_penalty / (1 + math.exp( -((13 / turn_bias) * turn.angle/180 - 6.5*turn_bias)))
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
local GiveWay = {}
|
||||||
|
|
||||||
|
TrafficFlowControlNode = require("lib/traffic_flow_control_node")
|
||||||
|
|
||||||
|
function GiveWay.get_value(node)
|
||||||
|
return TrafficFlowControlNode.get_value(node, "give_way")
|
||||||
|
end
|
||||||
|
|
||||||
|
return GiveWay
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
local StopSign = {}
|
||||||
|
|
||||||
|
TrafficFlowControlNode = require("lib/traffic_flow_control_node")
|
||||||
|
|
||||||
|
function StopSign.get_value(node)
|
||||||
|
return TrafficFlowControlNode.get_value(node, "stop")
|
||||||
|
end
|
||||||
|
|
||||||
|
return StopSign
|
||||||
|
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
local TrafficFlowControlNode = {}
|
||||||
|
|
||||||
|
function TrafficFlowControlNode.get_value(node, tag_name)
|
||||||
|
local tag = node:get_value_by_key("highway")
|
||||||
|
if tag_name == tag then
|
||||||
|
local direction = node:get_value_by_key("direction")
|
||||||
|
if direction then
|
||||||
|
if "forward" == direction then
|
||||||
|
return traffic_flow_control_direction.direction_forward
|
||||||
|
end
|
||||||
|
if "backward" == direction then
|
||||||
|
return traffic_flow_control_direction.direction_reverse
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return traffic_flow_control_direction.direction_all
|
||||||
|
end
|
||||||
|
return traffic_flow_control_direction.none
|
||||||
|
end
|
||||||
|
|
||||||
|
return TrafficFlowControlNode
|
||||||
|
|
||||||
@@ -9,10 +9,10 @@ function TrafficSignal.get_value(node)
|
|||||||
local direction = node:get_value_by_key("traffic_signals:direction")
|
local direction = node:get_value_by_key("traffic_signals:direction")
|
||||||
if direction then
|
if direction then
|
||||||
if "forward" == direction then
|
if "forward" == direction then
|
||||||
return traffic_lights.direction_forward
|
return traffic_flow_control_direction.direction_forward
|
||||||
end
|
end
|
||||||
if "backward" == direction then
|
if "backward" == direction then
|
||||||
return traffic_lights.direction_reverse
|
return traffic_flow_control_direction.direction_reverse
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- return traffic_lights.direction_all
|
-- return traffic_lights.direction_all
|
||||||
|
|||||||
@@ -78,7 +78,8 @@ int Contractor::Run()
|
|||||||
// Convert node weights for oneway streets to INVALID_EDGE_WEIGHT
|
// Convert node weights for oneway streets to INVALID_EDGE_WEIGHT
|
||||||
for (auto &weight : node_weights)
|
for (auto &weight : node_weights)
|
||||||
{
|
{
|
||||||
weight = (weight & 0x80000000) ? INVALID_EDGE_WEIGHT : weight;
|
weight = (from_alias<EdgeWeight::value_type>(weight) & 0x80000000) ? INVALID_EDGE_WEIGHT
|
||||||
|
: weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Contracting the edge-expanded graph
|
// Contracting the edge-expanded graph
|
||||||
|
|||||||
@@ -170,8 +170,8 @@ void ContractNode(ContractorThreadData *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
heap.Clear();
|
heap.Clear();
|
||||||
heap.Insert(source, 0, ContractorHeapData{});
|
heap.Insert(source, {0}, ContractorHeapData{});
|
||||||
EdgeWeight max_weight = 0;
|
EdgeWeight max_weight = {0};
|
||||||
unsigned number_of_targets = 0;
|
unsigned number_of_targets = 0;
|
||||||
|
|
||||||
for (auto out_edge : graph.GetAdjacentEdgeRange(node))
|
for (auto out_edge : graph.GetAdjacentEdgeRange(node))
|
||||||
@@ -199,7 +199,7 @@ void ContractNode(ContractorThreadData *data,
|
|||||||
// CAREFUL: This only works due to the independent node-setting. This
|
// CAREFUL: This only works due to the independent node-setting. This
|
||||||
// guarantees that source is not connected to another node that is
|
// guarantees that source is not connected to another node that is
|
||||||
// contracted
|
// contracted
|
||||||
node_weights[source] = path_weight + 1;
|
node_weights[source] = path_weight + EdgeWeight{1};
|
||||||
BOOST_ASSERT(stats != nullptr);
|
BOOST_ASSERT(stats != nullptr);
|
||||||
stats->edges_added_count += 2;
|
stats->edges_added_count += 2;
|
||||||
stats->original_edges_added_count +=
|
stats->original_edges_added_count +=
|
||||||
|
|||||||
@@ -133,7 +133,8 @@ int Customizer::Run(const CustomizationConfig &config)
|
|||||||
auto graph = LoadAndUpdateEdgeExpandedGraph(
|
auto graph = LoadAndUpdateEdgeExpandedGraph(
|
||||||
config, mlp, node_weights, node_durations, node_distances, connectivity_checksum);
|
config, mlp, node_weights, node_durations, node_distances, connectivity_checksum);
|
||||||
BOOST_ASSERT(graph.GetNumberOfNodes() == node_weights.size());
|
BOOST_ASSERT(graph.GetNumberOfNodes() == node_weights.size());
|
||||||
std::for_each(node_weights.begin(), node_weights.end(), [](auto &w) { w &= 0x7fffffff; });
|
std::for_each(
|
||||||
|
node_weights.begin(), node_weights.end(), [](auto &w) { w &= EdgeWeight{0x7fffffff}; });
|
||||||
util::Log() << "Loaded edge based graph: " << graph.GetNumberOfEdges() << " edges, "
|
util::Log() << "Loaded edge based graph: " << graph.GetNumberOfEdges() << " edges, "
|
||||||
<< graph.GetNumberOfNodes() << " nodes";
|
<< graph.GetNumberOfNodes() << " nodes";
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -3,11 +3,11 @@
|
|||||||
#include "engine/datafacade/datafacade_base.hpp"
|
#include "engine/datafacade/datafacade_base.hpp"
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
namespace osrm
|
namespace osrm
|
||||||
{
|
{
|
||||||
@@ -106,8 +106,8 @@ bool Hint::IsValid(const util::Coordinate new_input_coordinates,
|
|||||||
|
|
||||||
// Check hints do not contain duplicate segment pairs
|
// Check hints do not contain duplicate segment pairs
|
||||||
// We can't allow duplicates as search heaps do not support it.
|
// We can't allow duplicates as search heaps do not support it.
|
||||||
boost::unordered_set<NodeID> forward_segments;
|
std::unordered_set<NodeID> forward_segments;
|
||||||
boost::unordered_set<NodeID> reverse_segments;
|
std::unordered_set<NodeID> reverse_segments;
|
||||||
for (const auto &seg_hint : segment_hints)
|
for (const auto &seg_hint : segment_hints)
|
||||||
{
|
{
|
||||||
const auto forward_res = forward_segments.insert(seg_hint.phantom.forward_segment_id.id);
|
const auto forward_res = forward_segments.insert(seg_hint.phantom.forward_segment_id.id);
|
||||||
|
|||||||
@@ -90,7 +90,8 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
|||||||
std::vector<api::TableAPI::TableCellRef> estimated_pairs;
|
std::vector<api::TableAPI::TableCellRef> estimated_pairs;
|
||||||
|
|
||||||
// Scan table for null results - if any exist, replace with distance estimates
|
// Scan table for null results - if any exist, replace with distance estimates
|
||||||
if (params.fallback_speed != INVALID_FALLBACK_SPEED || params.scale_factor != 1)
|
if (params.fallback_speed != from_alias<double>(INVALID_FALLBACK_SPEED) ||
|
||||||
|
params.scale_factor != 1)
|
||||||
{
|
{
|
||||||
for (std::size_t row = 0; row < num_sources; row++)
|
for (std::size_t row = 0; row < num_sources; row++)
|
||||||
{
|
{
|
||||||
@@ -98,7 +99,8 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
|||||||
{
|
{
|
||||||
const auto &table_index = row * num_destinations + column;
|
const auto &table_index = row * num_destinations + column;
|
||||||
BOOST_ASSERT(table_index < result_tables_pair.first.size());
|
BOOST_ASSERT(table_index < result_tables_pair.first.size());
|
||||||
if (params.fallback_speed != INVALID_FALLBACK_SPEED && params.fallback_speed > 0 &&
|
if (params.fallback_speed != from_alias<double>(INVALID_FALLBACK_SPEED) &&
|
||||||
|
params.fallback_speed > 0 &&
|
||||||
result_tables_pair.first[table_index] == MAXIMAL_EDGE_DURATION)
|
result_tables_pair.first[table_index] == MAXIMAL_EDGE_DURATION)
|
||||||
{
|
{
|
||||||
const auto &source =
|
const auto &source =
|
||||||
@@ -118,29 +120,32 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
|||||||
candidatesSnappedLocation(destination));
|
candidatesSnappedLocation(destination));
|
||||||
|
|
||||||
result_tables_pair.first[table_index] =
|
result_tables_pair.first[table_index] =
|
||||||
distance_estimate / (double)params.fallback_speed;
|
to_alias<EdgeDuration>(distance_estimate / params.fallback_speed);
|
||||||
if (!result_tables_pair.second.empty())
|
if (!result_tables_pair.second.empty())
|
||||||
{
|
{
|
||||||
result_tables_pair.second[table_index] = distance_estimate;
|
result_tables_pair.second[table_index] =
|
||||||
|
to_alias<EdgeDistance>(distance_estimate);
|
||||||
}
|
}
|
||||||
|
|
||||||
estimated_pairs.emplace_back(row, column);
|
estimated_pairs.emplace_back(row, column);
|
||||||
}
|
}
|
||||||
if (params.scale_factor > 0 && params.scale_factor != 1 &&
|
if (params.scale_factor > 0 && params.scale_factor != 1 &&
|
||||||
result_tables_pair.first[table_index] != MAXIMAL_EDGE_DURATION &&
|
result_tables_pair.first[table_index] != MAXIMAL_EDGE_DURATION &&
|
||||||
result_tables_pair.first[table_index] != 0)
|
result_tables_pair.first[table_index] != EdgeDuration{0})
|
||||||
{
|
{
|
||||||
EdgeDuration diff =
|
EdgeDuration diff =
|
||||||
MAXIMAL_EDGE_DURATION / result_tables_pair.first[table_index];
|
MAXIMAL_EDGE_DURATION / result_tables_pair.first[table_index];
|
||||||
|
|
||||||
if (params.scale_factor >= diff)
|
if (params.scale_factor >= from_alias<double>(diff))
|
||||||
{
|
{
|
||||||
result_tables_pair.first[table_index] = MAXIMAL_EDGE_DURATION - 1;
|
result_tables_pair.first[table_index] =
|
||||||
|
MAXIMAL_EDGE_DURATION - EdgeDuration{1};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result_tables_pair.first[table_index] = std::lround(
|
result_tables_pair.first[table_index] = to_alias<EdgeDuration>(
|
||||||
result_tables_pair.first[table_index] * params.scale_factor);
|
std::lround(from_alias<double>(result_tables_pair.first[table_index]) *
|
||||||
|
params.scale_factor));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-16
@@ -497,17 +497,17 @@ void encodeVectorTile(const DataFacadeBase &facade,
|
|||||||
auto name = facade.GetNameForID(name_id);
|
auto name = facade.GetNameForID(name_id);
|
||||||
|
|
||||||
// If this is a valid forward edge, go ahead and add it to the tile
|
// If this is a valid forward edge, go ahead and add it to the tile
|
||||||
if (forward_duration != 0 && edge.forward_segment_id.enabled)
|
if (forward_duration != SegmentDuration{0} && edge.forward_segment_id.enabled)
|
||||||
{
|
{
|
||||||
// Calculate the speed for this line
|
// Calculate the speed for this line
|
||||||
std::uint32_t speed_kmh_idx =
|
std::uint32_t speed_kmh_idx = static_cast<std::uint32_t>(
|
||||||
static_cast<std::uint32_t>(round(length / forward_duration * 10 * 3.6));
|
round(length / from_alias<double>(forward_duration) * 10 * 3.6));
|
||||||
|
|
||||||
// Rate values are in meters per weight-unit - and similar to speeds, we
|
// Rate values are in meters per weight-unit - and similar to speeds, we
|
||||||
// present 1 decimal place of precision (these values are added as
|
// present 1 decimal place of precision (these values are added as
|
||||||
// double/10) lower down
|
// double/10) lower down
|
||||||
std::uint32_t forward_rate =
|
std::uint32_t forward_rate = static_cast<std::uint32_t>(
|
||||||
static_cast<std::uint32_t>(round(length / forward_weight * 10.));
|
round(length / from_alias<double>(forward_weight) * 10.));
|
||||||
|
|
||||||
auto tile_line = coordinatesToTileLine(a, b, tile_bbox);
|
auto tile_line = coordinatesToTileLine(a, b, tile_bbox);
|
||||||
if (!tile_line.empty())
|
if (!tile_line.empty())
|
||||||
@@ -519,8 +519,8 @@ void encodeVectorTile(const DataFacadeBase &facade,
|
|||||||
fbuilder.set_is_small(component_id.is_tiny);
|
fbuilder.set_is_small(component_id.is_tiny);
|
||||||
fbuilder.set_datasource(
|
fbuilder.set_datasource(
|
||||||
facade.GetDatasourceName(forward_datasource_idx).to_string());
|
facade.GetDatasourceName(forward_datasource_idx).to_string());
|
||||||
fbuilder.set_weight(forward_weight / 10.0);
|
fbuilder.set_weight(from_alias<double>(forward_weight) / 10.0);
|
||||||
fbuilder.set_duration(forward_duration / 10.0);
|
fbuilder.set_duration(from_alias<double>(forward_duration) / 10.0);
|
||||||
fbuilder.set_name(name);
|
fbuilder.set_name(name);
|
||||||
fbuilder.set_rate(forward_rate / 10.0);
|
fbuilder.set_rate(forward_rate / 10.0);
|
||||||
fbuilder.set_is_startpoint(is_startpoint);
|
fbuilder.set_is_startpoint(is_startpoint);
|
||||||
@@ -531,17 +531,17 @@ void encodeVectorTile(const DataFacadeBase &facade,
|
|||||||
|
|
||||||
// Repeat the above for the coordinates reversed and using the `reverse`
|
// Repeat the above for the coordinates reversed and using the `reverse`
|
||||||
// properties
|
// properties
|
||||||
if (reverse_duration != 0 && edge.reverse_segment_id.enabled)
|
if (reverse_duration != SegmentDuration{0} && edge.reverse_segment_id.enabled)
|
||||||
{
|
{
|
||||||
// Calculate the speed for this line
|
// Calculate the speed for this line
|
||||||
std::uint32_t speed_kmh_idx =
|
std::uint32_t speed_kmh_idx = static_cast<std::uint32_t>(
|
||||||
static_cast<std::uint32_t>(round(length / reverse_duration * 10 * 3.6));
|
round(length / from_alias<double>(reverse_duration) * 10 * 3.6));
|
||||||
|
|
||||||
// Rate values are in meters per weight-unit - and similar to speeds, we
|
// Rate values are in meters per weight-unit - and similar to speeds, we
|
||||||
// present 1 decimal place of precision (these values are added as
|
// present 1 decimal place of precision (these values are added as
|
||||||
// double/10) lower down
|
// double/10) lower down
|
||||||
std::uint32_t reverse_rate =
|
std::uint32_t reverse_rate = static_cast<std::uint32_t>(
|
||||||
static_cast<std::uint32_t>(round(length / reverse_weight * 10.));
|
round(length / from_alias<double>(reverse_weight) * 10.));
|
||||||
|
|
||||||
auto tile_line = coordinatesToTileLine(b, a, tile_bbox);
|
auto tile_line = coordinatesToTileLine(b, a, tile_bbox);
|
||||||
if (!tile_line.empty())
|
if (!tile_line.empty())
|
||||||
@@ -553,8 +553,8 @@ void encodeVectorTile(const DataFacadeBase &facade,
|
|||||||
fbuilder.set_is_small(component_id.is_tiny);
|
fbuilder.set_is_small(component_id.is_tiny);
|
||||||
fbuilder.set_datasource(
|
fbuilder.set_datasource(
|
||||||
facade.GetDatasourceName(reverse_datasource_idx).to_string());
|
facade.GetDatasourceName(reverse_datasource_idx).to_string());
|
||||||
fbuilder.set_weight(reverse_weight / 10.0);
|
fbuilder.set_weight(from_alias<double>(reverse_weight) / 10.0);
|
||||||
fbuilder.set_duration(reverse_duration / 10.0);
|
fbuilder.set_duration(from_alias<double>(reverse_duration) / 10.0);
|
||||||
fbuilder.set_name(name);
|
fbuilder.set_name(name);
|
||||||
fbuilder.set_rate(reverse_rate / 10.0);
|
fbuilder.set_rate(reverse_rate / 10.0);
|
||||||
fbuilder.set_is_startpoint(is_startpoint);
|
fbuilder.set_is_startpoint(is_startpoint);
|
||||||
@@ -582,8 +582,8 @@ void encodeVectorTile(const DataFacadeBase &facade,
|
|||||||
|
|
||||||
fbuilder.set_bearing_in(turn_data.in_angle);
|
fbuilder.set_bearing_in(turn_data.in_angle);
|
||||||
fbuilder.set_turn_angle(turn_data.turn_angle);
|
fbuilder.set_turn_angle(turn_data.turn_angle);
|
||||||
fbuilder.set_cost(turn_data.duration / 10.0);
|
fbuilder.set_cost(from_alias<double>(turn_data.duration) / 10.0);
|
||||||
fbuilder.set_weight(turn_data.weight / 10.0);
|
fbuilder.set_weight(from_alias<double>(turn_data.weight) / 10.0);
|
||||||
fbuilder.set_turn(turn_data.turn_instruction);
|
fbuilder.set_turn(turn_data.turn_instruction);
|
||||||
|
|
||||||
fbuilder.commit();
|
fbuilder.commit();
|
||||||
|
|||||||
+12
-12
@@ -20,9 +20,9 @@ namespace engine
|
|||||||
namespace plugins
|
namespace plugins
|
||||||
{
|
{
|
||||||
|
|
||||||
bool IsStronglyConnectedComponent(const util::DistTableWrapper<EdgeWeight> &result_table)
|
bool IsStronglyConnectedComponent(const util::DistTableWrapper<EdgeDuration> &result_table)
|
||||||
{
|
{
|
||||||
return std::find(std::begin(result_table), std::end(result_table), INVALID_EDGE_WEIGHT) ==
|
return std::find(std::begin(result_table), std::end(result_table), INVALID_EDGE_DURATION) ==
|
||||||
std::end(result_table);
|
std::end(result_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ TripPlugin::ComputeRoute(const RoutingAlgorithmsInterface &algorithms,
|
|||||||
|
|
||||||
void ManipulateTableForFSE(const std::size_t source_id,
|
void ManipulateTableForFSE(const std::size_t source_id,
|
||||||
const std::size_t destination_id,
|
const std::size_t destination_id,
|
||||||
util::DistTableWrapper<EdgeWeight> &result_table)
|
util::DistTableWrapper<EdgeDuration> &result_table)
|
||||||
{
|
{
|
||||||
// ****************** Change Table *************************
|
// ****************** Change Table *************************
|
||||||
// The following code manipulates the table and produces the new table for
|
// The following code manipulates the table and produces the new table for
|
||||||
@@ -94,7 +94,7 @@ void ManipulateTableForFSE(const std::size_t source_id,
|
|||||||
{
|
{
|
||||||
if (i == source_id)
|
if (i == source_id)
|
||||||
continue;
|
continue;
|
||||||
result_table.SetValue(i, source_id, INVALID_EDGE_WEIGHT);
|
result_table.SetValue(i, source_id, INVALID_EDGE_DURATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
// change parameters.destination row
|
// change parameters.destination row
|
||||||
@@ -104,22 +104,22 @@ void ManipulateTableForFSE(const std::size_t source_id,
|
|||||||
{
|
{
|
||||||
if (i == destination_id)
|
if (i == destination_id)
|
||||||
continue;
|
continue;
|
||||||
result_table.SetValue(destination_id, i, INVALID_EDGE_WEIGHT);
|
result_table.SetValue(destination_id, i, INVALID_EDGE_DURATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set destination->source to zero so roundtrip treats source and
|
// set destination->source to zero so roundtrip treats source and
|
||||||
// destination as one location
|
// destination as one location
|
||||||
result_table.SetValue(destination_id, source_id, 0);
|
result_table.SetValue(destination_id, source_id, {0});
|
||||||
|
|
||||||
// set source->destination as very high number so algorithm is forced
|
// set source->destination as very high number so algorithm is forced
|
||||||
// to find another path to get to destination
|
// to find another path to get to destination
|
||||||
result_table.SetValue(source_id, destination_id, INVALID_EDGE_WEIGHT);
|
result_table.SetValue(source_id, destination_id, INVALID_EDGE_DURATION);
|
||||||
|
|
||||||
//********* End of changes to table *************************************
|
//********* End of changes to table *************************************
|
||||||
}
|
}
|
||||||
|
|
||||||
void ManipulateTableForNonRoundtripFS(const std::size_t source_id,
|
void ManipulateTableForNonRoundtripFS(const std::size_t source_id,
|
||||||
util::DistTableWrapper<EdgeWeight> &result_table)
|
util::DistTableWrapper<EdgeDuration> &result_table)
|
||||||
{
|
{
|
||||||
// We can use the round-trip calculation to simulate non-round-trip fixed start
|
// We can use the round-trip calculation to simulate non-round-trip fixed start
|
||||||
// by making all paths to the source location zero. Effectively finding an 'optimal'
|
// by making all paths to the source location zero. Effectively finding an 'optimal'
|
||||||
@@ -127,12 +127,12 @@ void ManipulateTableForNonRoundtripFS(const std::size_t source_id,
|
|||||||
// source.
|
// source.
|
||||||
for (const auto i : util::irange<size_t>(0, result_table.GetNumberOfNodes()))
|
for (const auto i : util::irange<size_t>(0, result_table.GetNumberOfNodes()))
|
||||||
{
|
{
|
||||||
result_table.SetValue(i, source_id, 0);
|
result_table.SetValue(i, source_id, {0});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ManipulateTableForNonRoundtripFE(const std::size_t destination_id,
|
void ManipulateTableForNonRoundtripFE(const std::size_t destination_id,
|
||||||
util::DistTableWrapper<EdgeWeight> &result_table)
|
util::DistTableWrapper<EdgeDuration> &result_table)
|
||||||
{
|
{
|
||||||
// We can use the round-trip calculation to simulate non-round-trip fixed end
|
// We can use the round-trip calculation to simulate non-round-trip fixed end
|
||||||
// by making all paths from the destination to other locations zero.
|
// by making all paths from the destination to other locations zero.
|
||||||
@@ -140,7 +140,7 @@ void ManipulateTableForNonRoundtripFE(const std::size_t destination_id,
|
|||||||
// from the destination to any source.
|
// from the destination to any source.
|
||||||
for (const auto i : util::irange<size_t>(0, result_table.GetNumberOfNodes()))
|
for (const auto i : util::irange<size_t>(0, result_table.GetNumberOfNodes()))
|
||||||
{
|
{
|
||||||
result_table.SetValue(destination_id, i, 0);
|
result_table.SetValue(destination_id, i, {0});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,7 +218,7 @@ Status TripPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
|||||||
BOOST_ASSERT(snapped_phantoms.size() == number_of_locations);
|
BOOST_ASSERT(snapped_phantoms.size() == number_of_locations);
|
||||||
|
|
||||||
// compute the duration table of all phantom nodes
|
// compute the duration table of all phantom nodes
|
||||||
auto result_duration_table = util::DistTableWrapper<EdgeWeight>(
|
auto result_duration_table = util::DistTableWrapper<EdgeDuration>(
|
||||||
algorithms.ManyToManySearch(snapped_phantoms, {}, {}, /*requestDistance*/ false).first,
|
algorithms.ManyToManySearch(snapped_phantoms, {}, {}, /*requestDistance*/ false).first,
|
||||||
number_of_locations);
|
number_of_locations);
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ struct RankedCandidateNode
|
|||||||
|
|
||||||
bool operator<(const RankedCandidateNode &other) const
|
bool operator<(const RankedCandidateNode &other) const
|
||||||
{
|
{
|
||||||
return (2 * weight + sharing) < (2 * other.weight + other.sharing);
|
return (EdgeWeight{2} * weight + sharing) < (EdgeWeight{2} * other.weight + other.sharing);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -66,8 +66,8 @@ void alternativeRoutingStep(const DataFacade<Algorithm> &facade,
|
|||||||
// toHeapNode is the same
|
// toHeapNode is the same
|
||||||
const auto heapNode = forward_heap.DeleteMinGetHeapNode();
|
const auto heapNode = forward_heap.DeleteMinGetHeapNode();
|
||||||
|
|
||||||
const auto scaled_weight =
|
const auto scaled_weight = to_alias<EdgeWeight>(
|
||||||
static_cast<EdgeWeight>((heapNode.weight + min_edge_offset) / (1. + VIAPATH_EPSILON));
|
from_alias<double>(heapNode.weight + min_edge_offset) / (1. + VIAPATH_EPSILON));
|
||||||
if ((INVALID_EDGE_WEIGHT != *upper_bound_to_shortest_path_weight) &&
|
if ((INVALID_EDGE_WEIGHT != *upper_bound_to_shortest_path_weight) &&
|
||||||
(scaled_weight > *upper_bound_to_shortest_path_weight))
|
(scaled_weight > *upper_bound_to_shortest_path_weight))
|
||||||
{
|
{
|
||||||
@@ -84,7 +84,7 @@ void alternativeRoutingStep(const DataFacade<Algorithm> &facade,
|
|||||||
const EdgeWeight new_weight = reverseHeapNode->weight + heapNode.weight;
|
const EdgeWeight new_weight = reverseHeapNode->weight + heapNode.weight;
|
||||||
if (new_weight < *upper_bound_to_shortest_path_weight)
|
if (new_weight < *upper_bound_to_shortest_path_weight)
|
||||||
{
|
{
|
||||||
if (new_weight >= 0)
|
if (new_weight >= EdgeWeight{0})
|
||||||
{
|
{
|
||||||
*middle_node = heapNode.node;
|
*middle_node = heapNode.node;
|
||||||
*upper_bound_to_shortest_path_weight = new_weight;
|
*upper_bound_to_shortest_path_weight = new_weight;
|
||||||
@@ -92,7 +92,8 @@ void alternativeRoutingStep(const DataFacade<Algorithm> &facade,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// check whether there is a loop present at the node
|
// check whether there is a loop present at the node
|
||||||
const auto loop_weight = std::get<0>(getLoopWeight<false>(facade, heapNode.node));
|
const auto loop_weight =
|
||||||
|
std::get<0>(getLoopMetric<EdgeWeight>(facade, heapNode.node));
|
||||||
const EdgeWeight new_weight_with_loop = new_weight + loop_weight;
|
const EdgeWeight new_weight_with_loop = new_weight + loop_weight;
|
||||||
if (loop_weight != INVALID_EDGE_WEIGHT &&
|
if (loop_weight != INVALID_EDGE_WEIGHT &&
|
||||||
new_weight_with_loop <= *upper_bound_to_shortest_path_weight)
|
new_weight_with_loop <= *upper_bound_to_shortest_path_weight)
|
||||||
@@ -112,7 +113,7 @@ void alternativeRoutingStep(const DataFacade<Algorithm> &facade,
|
|||||||
const NodeID to = facade.GetTarget(edge);
|
const NodeID to = facade.GetTarget(edge);
|
||||||
const EdgeWeight edge_weight = data.weight;
|
const EdgeWeight edge_weight = data.weight;
|
||||||
|
|
||||||
BOOST_ASSERT(edge_weight > 0);
|
BOOST_ASSERT(edge_weight > EdgeWeight{0});
|
||||||
const EdgeWeight to_weight = heapNode.weight + edge_weight;
|
const EdgeWeight to_weight = heapNode.weight + edge_weight;
|
||||||
|
|
||||||
const auto toHeapNode = forward_heap.GetHeapNodeIfWasInserted(to);
|
const auto toHeapNode = forward_heap.GetHeapNodeIfWasInserted(to);
|
||||||
@@ -180,7 +181,7 @@ void computeWeightAndSharingOfViaPath(SearchEngineData<Algorithm> &engine_workin
|
|||||||
|
|
||||||
NodeID s_v_middle = SPECIAL_NODEID;
|
NodeID s_v_middle = SPECIAL_NODEID;
|
||||||
EdgeWeight upper_bound_s_v_path_weight = INVALID_EDGE_WEIGHT;
|
EdgeWeight upper_bound_s_v_path_weight = INVALID_EDGE_WEIGHT;
|
||||||
new_reverse_heap.Insert(via_node, 0, via_node);
|
new_reverse_heap.Insert(via_node, {0}, via_node);
|
||||||
// compute path <s,..,v> by reusing forward search from s
|
// compute path <s,..,v> by reusing forward search from s
|
||||||
while (!new_reverse_heap.Empty())
|
while (!new_reverse_heap.Empty())
|
||||||
{
|
{
|
||||||
@@ -196,7 +197,7 @@ void computeWeightAndSharingOfViaPath(SearchEngineData<Algorithm> &engine_workin
|
|||||||
// compute path <v,..,t> by reusing backward search from node t
|
// compute path <v,..,t> by reusing backward search from node t
|
||||||
NodeID v_t_middle = SPECIAL_NODEID;
|
NodeID v_t_middle = SPECIAL_NODEID;
|
||||||
EdgeWeight upper_bound_of_v_t_path_weight = INVALID_EDGE_WEIGHT;
|
EdgeWeight upper_bound_of_v_t_path_weight = INVALID_EDGE_WEIGHT;
|
||||||
new_forward_heap.Insert(via_node, 0, via_node);
|
new_forward_heap.Insert(via_node, {0}, via_node);
|
||||||
while (!new_forward_heap.Empty())
|
while (!new_forward_heap.Empty())
|
||||||
{
|
{
|
||||||
routingStep<FORWARD_DIRECTION>(facade,
|
routingStep<FORWARD_DIRECTION>(facade,
|
||||||
@@ -342,7 +343,7 @@ bool viaNodeCandidatePassesTTest(SearchEngineData<Algorithm> &engine_working_dat
|
|||||||
*s_v_middle = SPECIAL_NODEID;
|
*s_v_middle = SPECIAL_NODEID;
|
||||||
EdgeWeight upper_bound_s_v_path_weight = INVALID_EDGE_WEIGHT;
|
EdgeWeight upper_bound_s_v_path_weight = INVALID_EDGE_WEIGHT;
|
||||||
// compute path <s,..,v> by reusing forward search from s
|
// compute path <s,..,v> by reusing forward search from s
|
||||||
new_reverse_heap.Insert(candidate.node, 0, candidate.node);
|
new_reverse_heap.Insert(candidate.node, {0}, candidate.node);
|
||||||
while (new_reverse_heap.Size() > 0)
|
while (new_reverse_heap.Size() > 0)
|
||||||
{
|
{
|
||||||
routingStep<REVERSE_DIRECTION>(facade,
|
routingStep<REVERSE_DIRECTION>(facade,
|
||||||
@@ -363,7 +364,7 @@ bool viaNodeCandidatePassesTTest(SearchEngineData<Algorithm> &engine_working_dat
|
|||||||
// compute path <v,..,t> by reusing backward search from t
|
// compute path <v,..,t> by reusing backward search from t
|
||||||
*v_t_middle = SPECIAL_NODEID;
|
*v_t_middle = SPECIAL_NODEID;
|
||||||
EdgeWeight upper_bound_of_v_t_path_weight = INVALID_EDGE_WEIGHT;
|
EdgeWeight upper_bound_of_v_t_path_weight = INVALID_EDGE_WEIGHT;
|
||||||
new_forward_heap.Insert(candidate.node, 0, candidate.node);
|
new_forward_heap.Insert(candidate.node, {0}, candidate.node);
|
||||||
while (new_forward_heap.Size() > 0)
|
while (new_forward_heap.Size() > 0)
|
||||||
{
|
{
|
||||||
routingStep<FORWARD_DIRECTION>(facade,
|
routingStep<FORWARD_DIRECTION>(facade,
|
||||||
@@ -400,8 +401,9 @@ bool viaNodeCandidatePassesTTest(SearchEngineData<Algorithm> &engine_working_dat
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const EdgeWeight T_threshold = static_cast<EdgeWeight>(VIAPATH_ALPHA * weight_of_shortest_path);
|
const EdgeWeight T_threshold =
|
||||||
EdgeWeight unpacked_until_weight = 0;
|
to_alias<EdgeWeight>(VIAPATH_ALPHA * from_alias<double>(weight_of_shortest_path));
|
||||||
|
EdgeWeight unpacked_until_weight = {0};
|
||||||
|
|
||||||
std::stack<SearchSpaceEdge> unpack_stack;
|
std::stack<SearchSpaceEdge> unpack_stack;
|
||||||
// Traverse path s-->v
|
// Traverse path s-->v
|
||||||
@@ -463,7 +465,7 @@ bool viaNodeCandidatePassesTTest(SearchEngineData<Algorithm> &engine_working_dat
|
|||||||
}
|
}
|
||||||
|
|
||||||
EdgeWeight t_test_path_weight = unpacked_until_weight;
|
EdgeWeight t_test_path_weight = unpacked_until_weight;
|
||||||
unpacked_until_weight = 0;
|
unpacked_until_weight = {0};
|
||||||
// Traverse path s-->v
|
// Traverse path s-->v
|
||||||
BOOST_ASSERT(!packed_v_t_path.empty());
|
BOOST_ASSERT(!packed_v_t_path.empty());
|
||||||
for (unsigned i = 0, packed_path_length = static_cast<unsigned>(packed_v_t_path.size() - 1);
|
for (unsigned i = 0, packed_path_length = static_cast<unsigned>(packed_v_t_path.size() - 1);
|
||||||
@@ -532,8 +534,8 @@ bool viaNodeCandidatePassesTTest(SearchEngineData<Algorithm> &engine_working_dat
|
|||||||
EdgeWeight upper_bound = INVALID_EDGE_WEIGHT;
|
EdgeWeight upper_bound = INVALID_EDGE_WEIGHT;
|
||||||
NodeID middle = SPECIAL_NODEID;
|
NodeID middle = SPECIAL_NODEID;
|
||||||
|
|
||||||
forward_heap3.Insert(s_P, 0, s_P);
|
forward_heap3.Insert(s_P, {0}, s_P);
|
||||||
reverse_heap3.Insert(t_P, 0, t_P);
|
reverse_heap3.Insert(t_P, {0}, t_P);
|
||||||
// exploration from s and t until deletemin/(1+epsilon) > _lengt_oO_sShortest_path
|
// exploration from s and t until deletemin/(1+epsilon) > _lengt_oO_sShortest_path
|
||||||
while ((forward_heap3.Size() + reverse_heap3.Size()) > 0)
|
while ((forward_heap3.Size() + reverse_heap3.Size()) > 0)
|
||||||
{
|
{
|
||||||
@@ -580,10 +582,11 @@ InternalManyRoutesResult alternativePathSearch(SearchEngineData<Algorithm> &engi
|
|||||||
|
|
||||||
insertNodesInHeaps(forward_heap1, reverse_heap1, endpoint_candidates);
|
insertNodesInHeaps(forward_heap1, reverse_heap1, endpoint_candidates);
|
||||||
// get offset to account for offsets on phantom nodes on compressed edges
|
// get offset to account for offsets on phantom nodes on compressed edges
|
||||||
EdgeWeight min_edge_offset = forward_heap1.Empty() ? 0 : std::min(0, forward_heap1.MinKey());
|
EdgeWeight min_edge_offset =
|
||||||
BOOST_ASSERT(min_edge_offset <= 0);
|
forward_heap1.Empty() ? EdgeWeight{0} : std::min<EdgeWeight>({0}, forward_heap1.MinKey());
|
||||||
|
BOOST_ASSERT(min_edge_offset <= EdgeWeight{0});
|
||||||
// we only every insert negative offsets for nodes in the forward heap
|
// we only every insert negative offsets for nodes in the forward heap
|
||||||
BOOST_ASSERT(reverse_heap1.Empty() || reverse_heap1.MinKey() >= 0);
|
BOOST_ASSERT(reverse_heap1.Empty() || reverse_heap1.MinKey() >= EdgeWeight{0});
|
||||||
|
|
||||||
// search from s and t till new_min/(1+epsilon) > weight_of_shortest_path
|
// search from s and t till new_min/(1+epsilon) > weight_of_shortest_path
|
||||||
while (0 < (forward_heap1.Size() + reverse_heap1.Size()))
|
while (0 < (forward_heap1.Size() + reverse_heap1.Size()))
|
||||||
@@ -701,22 +704,27 @@ InternalManyRoutesResult alternativePathSearch(SearchEngineData<Algorithm> &engi
|
|||||||
if (node == middle_node)
|
if (node == middle_node)
|
||||||
continue;
|
continue;
|
||||||
const auto fwd_iterator = approximated_forward_sharing.find(node);
|
const auto fwd_iterator = approximated_forward_sharing.find(node);
|
||||||
const EdgeWeight fwd_sharing =
|
const EdgeWeight fwd_sharing = (fwd_iterator != approximated_forward_sharing.end())
|
||||||
(fwd_iterator != approximated_forward_sharing.end()) ? fwd_iterator->second : 0;
|
? fwd_iterator->second
|
||||||
|
: EdgeWeight{0};
|
||||||
const auto rev_iterator = approximated_reverse_sharing.find(node);
|
const auto rev_iterator = approximated_reverse_sharing.find(node);
|
||||||
const EdgeWeight rev_sharing =
|
const EdgeWeight rev_sharing = (rev_iterator != approximated_reverse_sharing.end())
|
||||||
(rev_iterator != approximated_reverse_sharing.end()) ? rev_iterator->second : 0;
|
? rev_iterator->second
|
||||||
|
: EdgeWeight{0};
|
||||||
|
|
||||||
const EdgeWeight approximated_sharing = fwd_sharing + rev_sharing;
|
const EdgeWeight approximated_sharing = fwd_sharing + rev_sharing;
|
||||||
const EdgeWeight approximated_weight =
|
const EdgeWeight approximated_weight =
|
||||||
forward_heap1.GetKey(node) + reverse_heap1.GetKey(node);
|
forward_heap1.GetKey(node) + reverse_heap1.GetKey(node);
|
||||||
const bool weight_passes =
|
const bool weight_passes =
|
||||||
(approximated_weight < upper_bound_to_shortest_path_weight * (1 + VIAPATH_EPSILON));
|
(from_alias<double>(approximated_weight) <
|
||||||
|
from_alias<double>(upper_bound_to_shortest_path_weight) * (1 + VIAPATH_EPSILON));
|
||||||
const bool sharing_passes =
|
const bool sharing_passes =
|
||||||
(approximated_sharing <= upper_bound_to_shortest_path_weight * VIAPATH_GAMMA);
|
(from_alias<double>(approximated_sharing) <=
|
||||||
|
from_alias<double>(upper_bound_to_shortest_path_weight) * VIAPATH_GAMMA);
|
||||||
const bool stretch_passes =
|
const bool stretch_passes =
|
||||||
(approximated_weight - approximated_sharing) <
|
from_alias<double>(approximated_weight - approximated_sharing) <
|
||||||
((1. + VIAPATH_EPSILON) * (upper_bound_to_shortest_path_weight - approximated_sharing));
|
((1. + VIAPATH_EPSILON) *
|
||||||
|
from_alias<double>(upper_bound_to_shortest_path_weight - approximated_sharing));
|
||||||
|
|
||||||
if (weight_passes && sharing_passes && stretch_passes)
|
if (weight_passes && sharing_passes && stretch_passes)
|
||||||
{
|
{
|
||||||
@@ -737,7 +745,7 @@ InternalManyRoutesResult alternativePathSearch(SearchEngineData<Algorithm> &engi
|
|||||||
// prioritizing via nodes for deep inspection
|
// prioritizing via nodes for deep inspection
|
||||||
for (const NodeID node : preselected_node_list)
|
for (const NodeID node : preselected_node_list)
|
||||||
{
|
{
|
||||||
EdgeWeight weight_of_via_path = 0, sharing_of_via_path = 0;
|
EdgeWeight weight_of_via_path = {0}, sharing_of_via_path = {0};
|
||||||
computeWeightAndSharingOfViaPath(engine_working_data,
|
computeWeightAndSharingOfViaPath(engine_working_data,
|
||||||
facade,
|
facade,
|
||||||
node,
|
node,
|
||||||
@@ -745,10 +753,11 @@ InternalManyRoutesResult alternativePathSearch(SearchEngineData<Algorithm> &engi
|
|||||||
&sharing_of_via_path,
|
&sharing_of_via_path,
|
||||||
packed_shortest_path,
|
packed_shortest_path,
|
||||||
min_edge_offset);
|
min_edge_offset);
|
||||||
const EdgeWeight maximum_allowed_sharing =
|
const EdgeWeight maximum_allowed_sharing = to_alias<EdgeWeight>(
|
||||||
static_cast<EdgeWeight>(upper_bound_to_shortest_path_weight * VIAPATH_GAMMA);
|
from_alias<double>(upper_bound_to_shortest_path_weight) * VIAPATH_GAMMA);
|
||||||
if (sharing_of_via_path <= maximum_allowed_sharing &&
|
if (sharing_of_via_path <= maximum_allowed_sharing &&
|
||||||
weight_of_via_path <= upper_bound_to_shortest_path_weight * (1 + VIAPATH_EPSILON))
|
from_alias<double>(weight_of_via_path) <=
|
||||||
|
from_alias<double>(upper_bound_to_shortest_path_weight) * (1 + VIAPATH_EPSILON))
|
||||||
{
|
{
|
||||||
ranked_candidates_list.emplace_back(node, weight_of_via_path, sharing_of_via_path);
|
ranked_candidates_list.emplace_back(node, weight_of_via_path, sharing_of_via_path);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,9 +85,9 @@ struct WeightedViaNodeUnpackedPath
|
|||||||
// Scale the maximum allowed weight increase based on its magnitude:
|
// Scale the maximum allowed weight increase based on its magnitude:
|
||||||
// - Shortest path 10 minutes, alternative 13 minutes => Factor of 0.30 ok
|
// - Shortest path 10 minutes, alternative 13 minutes => Factor of 0.30 ok
|
||||||
// - Shortest path 10 hours, alternative 13 hours => Factor of 0.30 unreasonable
|
// - Shortest path 10 hours, alternative 13 hours => Factor of 0.30 unreasonable
|
||||||
double getLongerByFactorBasedOnDuration(const EdgeWeight duration)
|
double getLongerByFactorBasedOnDuration(const EdgeDuration duration)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(duration != INVALID_EDGE_WEIGHT);
|
BOOST_ASSERT(duration != INVALID_EDGE_DURATION);
|
||||||
|
|
||||||
// We only have generic weights here and no durations without unpacking.
|
// We only have generic weights here and no durations without unpacking.
|
||||||
// We also have restricted way penalties which are huge and will screw scaling here.
|
// We also have restricted way penalties which are huge and will screw scaling here.
|
||||||
@@ -118,19 +118,20 @@ double getLongerByFactorBasedOnDuration(const EdgeWeight duration)
|
|||||||
const constexpr auto c = 2.45437877e+09;
|
const constexpr auto c = 2.45437877e+09;
|
||||||
const constexpr auto d = -2.07944571e+03;
|
const constexpr auto d = -2.07944571e+03;
|
||||||
|
|
||||||
if (duration < EdgeWeight(5 * 60))
|
if (duration < EdgeDuration{5 * 60})
|
||||||
{
|
{
|
||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
else if (duration > EdgeWeight(10 * 60 * 60))
|
else if (duration > EdgeDuration{10 * 60 * 60})
|
||||||
{
|
{
|
||||||
return 0.20;
|
return 0.20;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bigger than 10 minutes but smaller than 10 hours
|
// Bigger than 10 minutes but smaller than 10 hours
|
||||||
BOOST_ASSERT(duration >= 5 * 60 && duration <= 10 * 60 * 60);
|
BOOST_ASSERT(duration >= EdgeDuration{5 * 60} && duration <= EdgeDuration{10 * 60 * 60});
|
||||||
|
|
||||||
return a + b / (duration - d) + c / std::pow(duration - d, 3);
|
return a + b / (from_alias<double>(duration) - d) +
|
||||||
|
c / std::pow(from_alias<double>(duration) - d, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
Parameters parametersFromRequest(const PhantomEndpointCandidates &endpoint_candidates)
|
Parameters parametersFromRequest(const PhantomEndpointCandidates &endpoint_candidates)
|
||||||
@@ -223,10 +224,11 @@ RandIt filterViaCandidatesByStretch(RandIt first,
|
|||||||
// Assumes weight roughly corresponds to duration-ish. If this is not the case e.g.
|
// Assumes weight roughly corresponds to duration-ish. If this is not the case e.g.
|
||||||
// because users are setting weight to be distance in the profiles, then we might
|
// because users are setting weight to be distance in the profiles, then we might
|
||||||
// either generate more candidates than we have to or not enough. But is okay.
|
// either generate more candidates than we have to or not enough. But is okay.
|
||||||
const auto stretch_weight_limit = (1. + parameters.kAtMostLongerBy) * weight;
|
const auto stretch_weight_limit =
|
||||||
|
(1. + parameters.kAtMostLongerBy) * from_alias<double>(weight);
|
||||||
|
|
||||||
const auto over_weight_limit = [=](const auto via) {
|
const auto over_weight_limit = [=](const auto via) {
|
||||||
return via.weight > stretch_weight_limit;
|
return from_alias<double>(via.weight) > stretch_weight_limit;
|
||||||
};
|
};
|
||||||
|
|
||||||
return std::remove_if(first, last, over_weight_limit);
|
return std::remove_if(first, last, over_weight_limit);
|
||||||
@@ -444,7 +446,8 @@ RandIt filterPackedPathsByLocalOptimality(const WeightedViaNodePackedPath &path,
|
|||||||
const auto detour_length = forward_heap.GetKey(via) - forward_heap.GetKey(a) +
|
const auto detour_length = forward_heap.GetKey(via) - forward_heap.GetKey(a) +
|
||||||
reverse_heap.GetKey(via) - reverse_heap.GetKey(b);
|
reverse_heap.GetKey(via) - reverse_heap.GetKey(b);
|
||||||
|
|
||||||
return plateaux_length < parameters.kAtLeastOptimalAroundViaBy * detour_length;
|
return from_alias<double>(plateaux_length) <
|
||||||
|
parameters.kAtLeastOptimalAroundViaBy * from_alias<double>(detour_length);
|
||||||
};
|
};
|
||||||
|
|
||||||
return std::remove_if(first, last, is_not_locally_optimal);
|
return std::remove_if(first, last, is_not_locally_optimal);
|
||||||
@@ -482,8 +485,8 @@ RandIt filterUnpackedPathsBySharing(RandIt first,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
EdgeWeight total_duration = 0;
|
EdgeDuration total_duration = {0};
|
||||||
const auto add_if_seen = [&](const EdgeWeight duration, const NodeID node) {
|
const auto add_if_seen = [&](const EdgeDuration duration, const NodeID node) {
|
||||||
auto node_duration = facade.GetNodeDuration(node);
|
auto node_duration = facade.GetNodeDuration(node);
|
||||||
total_duration += node_duration;
|
total_duration += node_duration;
|
||||||
if (nodes.count(node) > 0)
|
if (nodes.count(node) > 0)
|
||||||
@@ -496,7 +499,7 @@ RandIt filterUnpackedPathsBySharing(RandIt first,
|
|||||||
const auto shared_duration = std::accumulate(
|
const auto shared_duration = std::accumulate(
|
||||||
begin(unpacked.nodes), end(unpacked.nodes), EdgeDuration{0}, add_if_seen);
|
begin(unpacked.nodes), end(unpacked.nodes), EdgeDuration{0}, add_if_seen);
|
||||||
|
|
||||||
unpacked.sharing = shared_duration / static_cast<double>(total_duration);
|
unpacked.sharing = from_alias<double>(shared_duration) / from_alias<double>(total_duration);
|
||||||
BOOST_ASSERT(unpacked.sharing >= 0.);
|
BOOST_ASSERT(unpacked.sharing >= 0.);
|
||||||
BOOST_ASSERT(unpacked.sharing <= 1.);
|
BOOST_ASSERT(unpacked.sharing <= 1.);
|
||||||
|
|
||||||
@@ -531,10 +534,11 @@ RandIt filterAnnotatedRoutesByStretch(RandIt first,
|
|||||||
BOOST_ASSERT(shortest_route.is_valid());
|
BOOST_ASSERT(shortest_route.is_valid());
|
||||||
|
|
||||||
const auto shortest_route_duration = shortest_route.duration();
|
const auto shortest_route_duration = shortest_route.duration();
|
||||||
const auto stretch_duration_limit = (1. + parameters.kAtMostLongerBy) * shortest_route_duration;
|
const auto stretch_duration_limit =
|
||||||
|
(1. + parameters.kAtMostLongerBy) * from_alias<double>(shortest_route_duration);
|
||||||
|
|
||||||
const auto over_duration_limit = [=](const auto &route) {
|
const auto over_duration_limit = [=](const auto &route) {
|
||||||
return route.duration() > stretch_duration_limit;
|
return from_alias<double>(route.duration()) > stretch_duration_limit;
|
||||||
};
|
};
|
||||||
|
|
||||||
return std::remove_if(first, last, over_duration_limit);
|
return std::remove_if(first, last, over_duration_limit);
|
||||||
@@ -610,8 +614,8 @@ void unpackPackedPaths(InputIt first,
|
|||||||
// Here heaps can be reused, let's go deeper!
|
// Here heaps can be reused, let's go deeper!
|
||||||
forward_heap.Clear();
|
forward_heap.Clear();
|
||||||
reverse_heap.Clear();
|
reverse_heap.Clear();
|
||||||
forward_heap.Insert(source, 0, {source});
|
forward_heap.Insert(source, {0}, {source});
|
||||||
reverse_heap.Insert(target, 0, {target});
|
reverse_heap.Insert(target, {0}, {target});
|
||||||
|
|
||||||
BOOST_ASSERT(!facade.ExcludeNode(source));
|
BOOST_ASSERT(!facade.ExcludeNode(source));
|
||||||
BOOST_ASSERT(!facade.ExcludeNode(target));
|
BOOST_ASSERT(!facade.ExcludeNode(target));
|
||||||
@@ -694,7 +698,8 @@ makeCandidateVias(SearchEngineData<Algorithm> &search_engine_data,
|
|||||||
while (forward_heap.Size() + reverse_heap.Size() > 0)
|
while (forward_heap.Size() + reverse_heap.Size() > 0)
|
||||||
{
|
{
|
||||||
if (shortest_path_weight != INVALID_EDGE_WEIGHT)
|
if (shortest_path_weight != INVALID_EDGE_WEIGHT)
|
||||||
overlap_weight = shortest_path_weight * parameters.kSearchSpaceOverlapFactor;
|
overlap_weight = to_alias<EdgeWeight>(from_alias<double>(shortest_path_weight) *
|
||||||
|
parameters.kSearchSpaceOverlapFactor);
|
||||||
|
|
||||||
// Termination criteria - when we have a shortest path this will guarantee for our overlap.
|
// Termination criteria - when we have a shortest path this will guarantee for our overlap.
|
||||||
const bool keep_going = forward_heap_min + reverse_heap_min < overlap_weight;
|
const bool keep_going = forward_heap_min + reverse_heap_min < overlap_weight;
|
||||||
@@ -820,8 +825,10 @@ InternalManyRoutesResult alternativePathSearch(SearchEngineData<Algorithm> &sear
|
|||||||
NodeID shortest_path_via = shortest_path_via_it->node;
|
NodeID shortest_path_via = shortest_path_via_it->node;
|
||||||
EdgeWeight shortest_path_weight = shortest_path_via_it->weight;
|
EdgeWeight shortest_path_weight = shortest_path_via_it->weight;
|
||||||
|
|
||||||
const double duration_estimation = shortest_path_weight / facade.GetWeightMultiplier();
|
const double duration_estimation =
|
||||||
parameters.kAtMostLongerBy = getLongerByFactorBasedOnDuration(duration_estimation);
|
from_alias<double>(shortest_path_weight) / facade.GetWeightMultiplier();
|
||||||
|
parameters.kAtMostLongerBy =
|
||||||
|
getLongerByFactorBasedOnDuration(to_alias<EdgeDuration>(duration_estimation));
|
||||||
|
|
||||||
// Filters via candidate nodes with heuristics
|
// Filters via candidate nodes with heuristics
|
||||||
|
|
||||||
|
|||||||
@@ -24,16 +24,16 @@ inline bool addLoopWeight(const DataFacade<ch::Algorithm> &facade,
|
|||||||
EdgeDuration &duration,
|
EdgeDuration &duration,
|
||||||
EdgeDistance &distance)
|
EdgeDistance &distance)
|
||||||
{ // Special case for CH when contractor creates a loop edge node->node
|
{ // Special case for CH when contractor creates a loop edge node->node
|
||||||
BOOST_ASSERT(weight < 0);
|
BOOST_ASSERT(weight < EdgeWeight{0});
|
||||||
|
|
||||||
const auto loop_weight = ch::getLoopWeight<false>(facade, node);
|
const auto loop_weight = ch::getLoopMetric<EdgeWeight>(facade, node);
|
||||||
if (std::get<0>(loop_weight) != INVALID_EDGE_WEIGHT)
|
if (std::get<0>(loop_weight) != INVALID_EDGE_WEIGHT)
|
||||||
{
|
{
|
||||||
const auto new_weight_with_loop = weight + std::get<0>(loop_weight);
|
const auto new_weight_with_loop = weight + std::get<0>(loop_weight);
|
||||||
if (new_weight_with_loop >= 0)
|
if (new_weight_with_loop >= EdgeWeight{0})
|
||||||
{
|
{
|
||||||
weight = new_weight_with_loop;
|
weight = new_weight_with_loop;
|
||||||
auto result = ch::getLoopWeight<true>(facade, node);
|
auto result = ch::getLoopMetric<EdgeDuration>(facade, node);
|
||||||
duration += std::get<0>(result);
|
duration += std::get<0>(result);
|
||||||
distance += std::get<1>(result);
|
distance += std::get<1>(result);
|
||||||
return true;
|
return true;
|
||||||
@@ -67,9 +67,9 @@ void relaxOutgoingEdges(
|
|||||||
const auto edge_duration = data.duration;
|
const auto edge_duration = data.duration;
|
||||||
const auto edge_distance = data.distance;
|
const auto edge_distance = data.distance;
|
||||||
|
|
||||||
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
|
BOOST_ASSERT_MSG(edge_weight > EdgeWeight{0}, "edge_weight invalid");
|
||||||
const auto to_weight = heapNode.weight + edge_weight;
|
const auto to_weight = heapNode.weight + edge_weight;
|
||||||
const auto to_duration = heapNode.data.duration + edge_duration;
|
const auto to_duration = heapNode.data.duration + to_alias<EdgeDuration>(edge_duration);
|
||||||
const auto to_distance = heapNode.data.distance + edge_distance;
|
const auto to_distance = heapNode.data.distance + edge_distance;
|
||||||
|
|
||||||
const auto toHeapNode = query_heap.GetHeapNodeIfWasInserted(to);
|
const auto toHeapNode = query_heap.GetHeapNodeIfWasInserted(to);
|
||||||
@@ -120,7 +120,7 @@ void forwardRoutingStep(const DataFacade<Algorithm> &facade,
|
|||||||
|
|
||||||
auto ¤t_weight = weights_table[row_index * number_of_targets + column_index];
|
auto ¤t_weight = weights_table[row_index * number_of_targets + column_index];
|
||||||
|
|
||||||
EdgeDistance nulldistance = 0;
|
EdgeDistance nulldistance = {0};
|
||||||
|
|
||||||
auto ¤t_duration = durations_table[row_index * number_of_targets + column_index];
|
auto ¤t_duration = durations_table[row_index * number_of_targets + column_index];
|
||||||
auto ¤t_distance =
|
auto ¤t_distance =
|
||||||
@@ -132,7 +132,7 @@ void forwardRoutingStep(const DataFacade<Algorithm> &facade,
|
|||||||
auto new_duration = heapNode.data.duration + target_duration;
|
auto new_duration = heapNode.data.duration + target_duration;
|
||||||
auto new_distance = heapNode.data.distance + target_distance;
|
auto new_distance = heapNode.data.distance + target_distance;
|
||||||
|
|
||||||
if (new_weight < 0)
|
if (new_weight < EdgeWeight{0})
|
||||||
{
|
{
|
||||||
if (addLoopWeight(facade, heapNode.node, new_weight, new_duration, new_distance))
|
if (addLoopWeight(facade, heapNode.node, new_weight, new_duration, new_distance))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -62,10 +62,13 @@ void relaxBorderEdges(const DataFacade<mld::Algorithm> &facade,
|
|||||||
const auto node_weight = facade.GetNodeWeight(node_id);
|
const auto node_weight = facade.GetNodeWeight(node_id);
|
||||||
const auto node_duration = facade.GetNodeDuration(node_id);
|
const auto node_duration = facade.GetNodeDuration(node_id);
|
||||||
const auto node_distance = facade.GetNodeDistance(node_id);
|
const auto node_distance = facade.GetNodeDistance(node_id);
|
||||||
const auto turn_weight = node_weight + facade.GetWeightPenaltyForEdgeID(turn_id);
|
const auto turn_weight =
|
||||||
const auto turn_duration = node_duration + facade.GetDurationPenaltyForEdgeID(turn_id);
|
node_weight + alias_cast<EdgeWeight>(facade.GetWeightPenaltyForEdgeID(turn_id));
|
||||||
|
const auto turn_duration =
|
||||||
|
node_duration +
|
||||||
|
alias_cast<EdgeDuration>(facade.GetDurationPenaltyForEdgeID(turn_id));
|
||||||
|
|
||||||
BOOST_ASSERT_MSG(node_weight + turn_weight > 0, "edge weight is invalid");
|
BOOST_ASSERT_MSG(node_weight + turn_weight > EdgeWeight{0}, "edge weight is invalid");
|
||||||
const auto to_weight = weight + turn_weight;
|
const auto to_weight = weight + turn_weight;
|
||||||
const auto to_duration = duration + turn_duration;
|
const auto to_duration = duration + turn_duration;
|
||||||
const auto to_distance = distance + node_distance;
|
const auto to_distance = distance + node_distance;
|
||||||
@@ -259,17 +262,17 @@ oneToManySearch(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
target_nodes_index.insert(
|
target_nodes_index.insert(
|
||||||
{phantom_node.forward_segment_id.id,
|
{phantom_node.forward_segment_id.id,
|
||||||
std::make_tuple(index,
|
std::make_tuple(index,
|
||||||
-phantom_node.GetForwardWeightPlusOffset(),
|
EdgeWeight{0} - phantom_node.GetForwardWeightPlusOffset(),
|
||||||
-phantom_node.GetForwardDuration(),
|
EdgeDuration{0} - phantom_node.GetForwardDuration(),
|
||||||
-phantom_node.GetForwardDistance())});
|
EdgeDistance{0} - phantom_node.GetForwardDistance())});
|
||||||
|
|
||||||
if (phantom_node.IsValidReverseSource())
|
if (phantom_node.IsValidReverseSource())
|
||||||
target_nodes_index.insert(
|
target_nodes_index.insert(
|
||||||
{phantom_node.reverse_segment_id.id,
|
{phantom_node.reverse_segment_id.id,
|
||||||
std::make_tuple(index,
|
std::make_tuple(index,
|
||||||
-phantom_node.GetReverseWeightPlusOffset(),
|
EdgeWeight{0} - phantom_node.GetReverseWeightPlusOffset(),
|
||||||
-phantom_node.GetReverseDuration(),
|
EdgeDuration{0} - phantom_node.GetReverseDuration(),
|
||||||
-phantom_node.GetReverseDistance())});
|
EdgeDistance{0} - phantom_node.GetReverseDistance())});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -292,12 +295,12 @@ oneToManySearch(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
std::tie(index, target_weight, target_duration, target_distance) = it->second;
|
std::tie(index, target_weight, target_duration, target_distance) = it->second;
|
||||||
|
|
||||||
const auto path_weight = weight + target_weight;
|
const auto path_weight = weight + target_weight;
|
||||||
if (path_weight >= 0)
|
if (path_weight >= EdgeWeight{0})
|
||||||
{
|
{
|
||||||
const auto path_duration = duration + target_duration;
|
const auto path_duration = duration + target_duration;
|
||||||
const auto path_distance = distance + target_distance;
|
const auto path_distance = distance + target_distance;
|
||||||
|
|
||||||
EdgeDistance nulldistance = 0;
|
EdgeDistance nulldistance = {0};
|
||||||
auto ¤t_distance =
|
auto ¤t_distance =
|
||||||
distances_table.empty() ? nulldistance : distances_table[index];
|
distances_table.empty() ? nulldistance : distances_table[index];
|
||||||
|
|
||||||
@@ -350,17 +353,17 @@ oneToManySearch(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
if (phantom_node.IsValidForwardSource())
|
if (phantom_node.IsValidForwardSource())
|
||||||
{
|
{
|
||||||
insert_node(phantom_node.forward_segment_id.id,
|
insert_node(phantom_node.forward_segment_id.id,
|
||||||
-phantom_node.GetForwardWeightPlusOffset(),
|
EdgeWeight{0} - phantom_node.GetForwardWeightPlusOffset(),
|
||||||
-phantom_node.GetForwardDuration(),
|
EdgeDuration{0} - phantom_node.GetForwardDuration(),
|
||||||
-phantom_node.GetForwardDistance());
|
EdgeDistance{0} - phantom_node.GetForwardDistance());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (phantom_node.IsValidReverseSource())
|
if (phantom_node.IsValidReverseSource())
|
||||||
{
|
{
|
||||||
insert_node(phantom_node.reverse_segment_id.id,
|
insert_node(phantom_node.reverse_segment_id.id,
|
||||||
-phantom_node.GetReverseWeightPlusOffset(),
|
EdgeWeight{0} - phantom_node.GetReverseWeightPlusOffset(),
|
||||||
-phantom_node.GetReverseDuration(),
|
EdgeDuration{0} - phantom_node.GetReverseDuration(),
|
||||||
-phantom_node.GetReverseDistance());
|
EdgeDistance{0} - phantom_node.GetReverseDistance());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (DIRECTION == REVERSE_DIRECTION)
|
else if (DIRECTION == REVERSE_DIRECTION)
|
||||||
@@ -444,7 +447,7 @@ void forwardRoutingStep(const DataFacade<Algorithm> &facade,
|
|||||||
auto ¤t_weight = weights_table[location];
|
auto ¤t_weight = weights_table[location];
|
||||||
auto ¤t_duration = durations_table[location];
|
auto ¤t_duration = durations_table[location];
|
||||||
|
|
||||||
EdgeDistance nulldistance = 0;
|
EdgeDistance nulldistance = {0};
|
||||||
auto ¤t_distance = distances_table.empty() ? nulldistance : distances_table[location];
|
auto ¤t_distance = distances_table.empty() ? nulldistance : distances_table[location];
|
||||||
|
|
||||||
// Check if new weight is better
|
// Check if new weight is better
|
||||||
@@ -452,8 +455,9 @@ void forwardRoutingStep(const DataFacade<Algorithm> &facade,
|
|||||||
auto new_duration = heapNode.data.duration + target_duration;
|
auto new_duration = heapNode.data.duration + target_duration;
|
||||||
auto new_distance = heapNode.data.distance + target_distance;
|
auto new_distance = heapNode.data.distance + target_distance;
|
||||||
|
|
||||||
if (new_weight >= 0 && std::tie(new_weight, new_duration, new_distance) <
|
if (new_weight >= EdgeWeight{0} &&
|
||||||
std::tie(current_weight, current_duration, current_distance))
|
std::tie(new_weight, new_duration, new_distance) <
|
||||||
|
std::tie(current_weight, current_duration, current_distance))
|
||||||
{
|
{
|
||||||
current_weight = new_weight;
|
current_weight = new_weight;
|
||||||
current_duration = new_duration;
|
current_duration = new_duration;
|
||||||
|
|||||||
@@ -217,8 +217,8 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
const auto haversine_distance = util::coordinate_calculation::greatCircleDistance(
|
const auto haversine_distance = util::coordinate_calculation::greatCircleDistance(
|
||||||
prev_coordinate, current_coordinate);
|
prev_coordinate, current_coordinate);
|
||||||
// assumes minumum of 4 m/s
|
// assumes minumum of 4 m/s
|
||||||
const EdgeWeight weight_upper_bound =
|
const EdgeWeight weight_upper_bound = to_alias<EdgeWeight>(
|
||||||
((haversine_distance + max_distance_delta) / 4.) * facade.GetWeightMultiplier();
|
((haversine_distance + max_distance_delta) / 4.) * facade.GetWeightMultiplier());
|
||||||
|
|
||||||
// compute d_t for this timestamp and the next one
|
// compute d_t for this timestamp and the next one
|
||||||
for (const auto s : util::irange<std::size_t>(0UL, prev_viterbi.size()))
|
for (const auto s : util::irange<std::size_t>(0UL, prev_viterbi.size()))
|
||||||
|
|||||||
@@ -109,10 +109,10 @@ void search(SearchEngineData<Algorithm> & /*engine_working_data*/,
|
|||||||
weight = weight_upper_bound;
|
weight = weight_upper_bound;
|
||||||
|
|
||||||
// get offset to account for offsets on phantom nodes on compressed edges
|
// get offset to account for offsets on phantom nodes on compressed edges
|
||||||
const auto min_edge_offset = std::min(0, forward_heap.MinKey());
|
const auto min_edge_offset = std::min<EdgeWeight>({0}, forward_heap.MinKey());
|
||||||
BOOST_ASSERT(min_edge_offset <= 0);
|
BOOST_ASSERT(min_edge_offset <= EdgeWeight{0});
|
||||||
// we only every insert negative offsets for nodes in the forward heap
|
// we only every insert negative offsets for nodes in the forward heap
|
||||||
BOOST_ASSERT(reverse_heap.MinKey() >= 0);
|
BOOST_ASSERT(reverse_heap.MinKey() >= EdgeWeight{0});
|
||||||
|
|
||||||
// run two-Target Dijkstra routing step.
|
// run two-Target Dijkstra routing step.
|
||||||
while (0 < (forward_heap.Size() + reverse_heap.Size()))
|
while (0 < (forward_heap.Size() + reverse_heap.Size()))
|
||||||
|
|||||||
@@ -182,8 +182,8 @@ std::vector<TurnData> generateTurns(const datafacade &facade,
|
|||||||
all_turn_data.push_back(TurnData{coord_via,
|
all_turn_data.push_back(TurnData{coord_via,
|
||||||
angle_in,
|
angle_in,
|
||||||
turn_angle,
|
turn_angle,
|
||||||
turn_weight,
|
alias_cast<EdgeWeight>(turn_weight),
|
||||||
turn_duration,
|
alias_cast<EdgeDuration>(turn_duration),
|
||||||
turn_instruction});
|
turn_instruction});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,24 +74,26 @@ unsigned CompressedEdgeContainer::GetZippedPositionForReverseID(const EdgeID edg
|
|||||||
return map_iterator->second;
|
return map_iterator->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
SegmentWeight CompressedEdgeContainer::ClipWeight(const SegmentWeight weight)
|
SegmentWeight CompressedEdgeContainer::ClipWeight(const EdgeWeight weight)
|
||||||
{
|
{
|
||||||
if (weight >= INVALID_SEGMENT_WEIGHT)
|
SegmentWeight seg_weight = alias_cast<SegmentWeight>(weight);
|
||||||
|
if (seg_weight >= INVALID_SEGMENT_WEIGHT)
|
||||||
{
|
{
|
||||||
clipped_weights++;
|
clipped_weights++;
|
||||||
return MAX_SEGMENT_WEIGHT;
|
return MAX_SEGMENT_WEIGHT;
|
||||||
}
|
}
|
||||||
return weight;
|
return seg_weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
SegmentDuration CompressedEdgeContainer::ClipDuration(const SegmentDuration duration)
|
SegmentDuration CompressedEdgeContainer::ClipDuration(const EdgeDuration duration)
|
||||||
{
|
{
|
||||||
if (duration >= INVALID_SEGMENT_DURATION)
|
SegmentDuration seg_duration = alias_cast<SegmentDuration>(duration);
|
||||||
|
if (seg_duration >= INVALID_SEGMENT_DURATION)
|
||||||
{
|
{
|
||||||
clipped_weights++;
|
clipped_weights++;
|
||||||
return MAX_SEGMENT_DURATION;
|
return MAX_SEGMENT_DURATION;
|
||||||
}
|
}
|
||||||
return duration;
|
return seg_duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds info for a compressed edge to the container. edge_id_2
|
// Adds info for a compressed edge to the container. edge_id_2
|
||||||
@@ -119,8 +121,8 @@ void CompressedEdgeContainer::CompressEdge(const EdgeID edge_id_1,
|
|||||||
BOOST_ASSERT(SPECIAL_EDGEID != edge_id_2);
|
BOOST_ASSERT(SPECIAL_EDGEID != edge_id_2);
|
||||||
BOOST_ASSERT(SPECIAL_NODEID != via_node_id);
|
BOOST_ASSERT(SPECIAL_NODEID != via_node_id);
|
||||||
BOOST_ASSERT(SPECIAL_NODEID != target_node_id);
|
BOOST_ASSERT(SPECIAL_NODEID != target_node_id);
|
||||||
BOOST_ASSERT(INVALID_SEGMENT_WEIGHT != weight1);
|
BOOST_ASSERT(INVALID_EDGE_WEIGHT != weight1);
|
||||||
BOOST_ASSERT(INVALID_SEGMENT_WEIGHT != weight2);
|
BOOST_ASSERT(INVALID_EDGE_WEIGHT != weight2);
|
||||||
|
|
||||||
// append list of removed edge_id plus via node to surviving edge id:
|
// append list of removed edge_id plus via node to surviving edge id:
|
||||||
// <surv_1, .. , surv_n, via_node_id, rem_1, .. rem_n
|
// <surv_1, .. , surv_n, via_node_id, rem_1, .. rem_n
|
||||||
@@ -207,13 +209,14 @@ void CompressedEdgeContainer::CompressEdge(const EdgeID edge_id_1,
|
|||||||
|
|
||||||
void CompressedEdgeContainer::AddUncompressedEdge(const EdgeID edge_id,
|
void CompressedEdgeContainer::AddUncompressedEdge(const EdgeID edge_id,
|
||||||
const NodeID target_node_id,
|
const NodeID target_node_id,
|
||||||
const SegmentWeight weight,
|
const EdgeWeight weight,
|
||||||
const SegmentDuration duration)
|
const EdgeDuration duration)
|
||||||
{
|
{
|
||||||
// remove super-trivial geometries
|
// remove super-trivial geometries
|
||||||
BOOST_ASSERT(SPECIAL_EDGEID != edge_id);
|
BOOST_ASSERT(SPECIAL_EDGEID != edge_id);
|
||||||
BOOST_ASSERT(SPECIAL_NODEID != target_node_id);
|
BOOST_ASSERT(SPECIAL_NODEID != target_node_id);
|
||||||
BOOST_ASSERT(INVALID_EDGE_WEIGHT != weight);
|
BOOST_ASSERT(INVALID_EDGE_WEIGHT != weight);
|
||||||
|
BOOST_ASSERT(INVALID_EDGE_DURATION != duration);
|
||||||
|
|
||||||
// Add via node id. List is created if it does not exist
|
// Add via node id. List is created if it does not exist
|
||||||
if (!HasEntryForID(edge_id))
|
if (!HasEntryForID(edge_id))
|
||||||
@@ -336,12 +339,12 @@ void CompressedEdgeContainer::PrintStatistics() const
|
|||||||
if (clipped_weights > 0)
|
if (clipped_weights > 0)
|
||||||
{
|
{
|
||||||
util::Log(logWARNING) << "Clipped " << clipped_weights << " segment weights to "
|
util::Log(logWARNING) << "Clipped " << clipped_weights << " segment weights to "
|
||||||
<< (INVALID_SEGMENT_WEIGHT - 1);
|
<< MAX_SEGMENT_WEIGHT;
|
||||||
}
|
}
|
||||||
if (clipped_durations > 0)
|
if (clipped_durations > 0)
|
||||||
{
|
{
|
||||||
util::Log(logWARNING) << "Clipped " << clipped_durations << " segment durations to "
|
util::Log(logWARNING) << "Clipped " << clipped_durations << " segment durations to "
|
||||||
<< (INVALID_SEGMENT_DURATION - 1);
|
<< MAX_SEGMENT_DURATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
util::Log() << "Geometry successfully removed:"
|
util::Log() << "Geometry successfully removed:"
|
||||||
|
|||||||
@@ -34,20 +34,6 @@
|
|||||||
#include <tbb/parallel_for.h>
|
#include <tbb/parallel_for.h>
|
||||||
#include <tbb/parallel_pipeline.h>
|
#include <tbb/parallel_pipeline.h>
|
||||||
|
|
||||||
namespace std
|
|
||||||
{
|
|
||||||
template <> struct hash<std::pair<NodeID, NodeID>>
|
|
||||||
{
|
|
||||||
std::size_t operator()(const std::pair<NodeID, NodeID> &mk) const noexcept
|
|
||||||
{
|
|
||||||
std::size_t seed = 0;
|
|
||||||
boost::hash_combine(seed, mk.first);
|
|
||||||
boost::hash_combine(seed, mk.second);
|
|
||||||
return seed;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace std
|
|
||||||
|
|
||||||
namespace osrm
|
namespace osrm
|
||||||
{
|
{
|
||||||
namespace extractor
|
namespace extractor
|
||||||
@@ -59,7 +45,9 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
|
|||||||
EdgeBasedNodeDataContainer &node_data_container,
|
EdgeBasedNodeDataContainer &node_data_container,
|
||||||
const CompressedEdgeContainer &compressed_edge_container,
|
const CompressedEdgeContainer &compressed_edge_container,
|
||||||
const std::unordered_set<NodeID> &barrier_nodes,
|
const std::unordered_set<NodeID> &barrier_nodes,
|
||||||
const TrafficSignals &traffic_signals,
|
const TrafficFlowControlNodes &traffic_signals,
|
||||||
|
const TrafficFlowControlNodes &stop_signs,
|
||||||
|
const TrafficFlowControlNodes &give_way_signs,
|
||||||
const std::vector<util::Coordinate> &coordinates,
|
const std::vector<util::Coordinate> &coordinates,
|
||||||
const NameTable &name_table,
|
const NameTable &name_table,
|
||||||
const std::unordered_set<EdgeID> &segregated_edges,
|
const std::unordered_set<EdgeID> &segregated_edges,
|
||||||
@@ -67,7 +55,8 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
|
|||||||
: m_edge_based_node_container(node_data_container), m_connectivity_checksum(0),
|
: m_edge_based_node_container(node_data_container), m_connectivity_checksum(0),
|
||||||
m_number_of_edge_based_nodes(0), m_coordinates(coordinates),
|
m_number_of_edge_based_nodes(0), m_coordinates(coordinates),
|
||||||
m_node_based_graph(node_based_graph), m_barrier_nodes(barrier_nodes),
|
m_node_based_graph(node_based_graph), m_barrier_nodes(barrier_nodes),
|
||||||
m_traffic_signals(traffic_signals), m_compressed_edge_container(compressed_edge_container),
|
m_traffic_signals(traffic_signals), m_stop_signs(stop_signs),
|
||||||
|
m_give_way_signs(give_way_signs), m_compressed_edge_container(compressed_edge_container),
|
||||||
name_table(name_table), segregated_edges(segregated_edges),
|
name_table(name_table), segregated_edges(segregated_edges),
|
||||||
lane_description_map(lane_description_map)
|
lane_description_map(lane_description_map)
|
||||||
{
|
{
|
||||||
@@ -94,7 +83,7 @@ void EdgeBasedGraphFactory::GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &out
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EdgeBasedGraphFactory::GetEdgeBasedNodeDurations(
|
void EdgeBasedGraphFactory::GetEdgeBasedNodeDurations(
|
||||||
std::vector<EdgeWeight> &output_node_durations)
|
std::vector<EdgeDuration> &output_node_durations)
|
||||||
{
|
{
|
||||||
using std::swap; // Koenig swap
|
using std::swap; // Koenig swap
|
||||||
swap(m_edge_based_node_durations, output_node_durations);
|
swap(m_edge_based_node_durations, output_node_durations);
|
||||||
@@ -147,7 +136,8 @@ NBGToEBG EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const N
|
|||||||
// * in other cases node weights must be masked with 0x7fffffff to clear MSB
|
// * in other cases node weights must be masked with 0x7fffffff to clear MSB
|
||||||
if (nbe_to_ebn_mapping[edge_id_1] != SPECIAL_NODEID &&
|
if (nbe_to_ebn_mapping[edge_id_1] != SPECIAL_NODEID &&
|
||||||
nbe_to_ebn_mapping[edge_id_2] == SPECIAL_NODEID)
|
nbe_to_ebn_mapping[edge_id_2] == SPECIAL_NODEID)
|
||||||
m_edge_based_node_weights[nbe_to_ebn_mapping[edge_id_1]] |= 0x80000000;
|
m_edge_based_node_weights[nbe_to_ebn_mapping[edge_id_1]] |=
|
||||||
|
EdgeWeight{static_cast<EdgeWeight::value_type>(0x80000000)};
|
||||||
|
|
||||||
BOOST_ASSERT(m_compressed_edge_container.HasEntryForID(edge_id_1) ==
|
BOOST_ASSERT(m_compressed_edge_container.HasEntryForID(edge_id_1) ==
|
||||||
m_compressed_edge_container.HasEntryForID(edge_id_2));
|
m_compressed_edge_container.HasEntryForID(edge_id_2));
|
||||||
@@ -400,7 +390,7 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedNodes(const WayRestrictionMap &way_re
|
|||||||
segregated_edges.count(eid) > 0;
|
segregated_edges.count(eid) > 0;
|
||||||
|
|
||||||
const auto ebn_weight = m_edge_based_node_weights[nbe_to_ebn_mapping[eid]];
|
const auto ebn_weight = m_edge_based_node_weights[nbe_to_ebn_mapping[eid]];
|
||||||
BOOST_ASSERT((ebn_weight & 0x7fffffff) == edge_data.weight);
|
BOOST_ASSERT((ebn_weight & EdgeWeight{0x7fffffff}) == edge_data.weight);
|
||||||
m_edge_based_node_weights.push_back(ebn_weight);
|
m_edge_based_node_weights.push_back(ebn_weight);
|
||||||
m_edge_based_node_durations.push_back(
|
m_edge_based_node_durations.push_back(
|
||||||
m_edge_based_node_durations[nbe_to_ebn_mapping[eid]]);
|
m_edge_based_node_durations[nbe_to_ebn_mapping[eid]]);
|
||||||
@@ -642,7 +632,10 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
|||||||
// In theory we shouldn't get a directed traffic light on a turn, as it indicates that
|
// In theory we shouldn't get a directed traffic light on a turn, as it indicates that
|
||||||
// the traffic signal direction was potentially ambiguously annotated on the junction
|
// the traffic signal direction was potentially ambiguously annotated on the junction
|
||||||
// node But we'll check anyway.
|
// node But we'll check anyway.
|
||||||
const auto is_traffic_light = m_traffic_signals.HasSignal(from_node, intersection_node);
|
const auto is_traffic_light = m_traffic_signals.Has(from_node, intersection_node);
|
||||||
|
const auto is_stop_sign = m_stop_signs.Has(from_node, intersection_node);
|
||||||
|
const auto is_give_way_sign = m_give_way_signs.Has(from_node, intersection_node);
|
||||||
|
|
||||||
const auto is_uturn =
|
const auto is_uturn =
|
||||||
guidance::getTurnDirection(turn_angle) == guidance::DirectionModifier::UTurn;
|
guidance::getTurnDirection(turn_angle) == guidance::DirectionModifier::UTurn;
|
||||||
|
|
||||||
@@ -652,6 +645,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
|||||||
road_legs_on_the_right.size() + road_legs_on_the_left.size() + 2 - is_uturn,
|
road_legs_on_the_right.size() + road_legs_on_the_left.size() + 2 - is_uturn,
|
||||||
is_uturn,
|
is_uturn,
|
||||||
is_traffic_light,
|
is_traffic_light,
|
||||||
|
is_stop_sign,
|
||||||
|
is_give_way_sign,
|
||||||
m_edge_based_node_container.GetAnnotation(edge_data1.annotation_data)
|
m_edge_based_node_container.GetAnnotation(edge_data1.annotation_data)
|
||||||
.is_left_hand_driving,
|
.is_left_hand_driving,
|
||||||
// source info
|
// source info
|
||||||
@@ -663,7 +658,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
|||||||
edge_data1.flags.highway_turn_classification,
|
edge_data1.flags.highway_turn_classification,
|
||||||
edge_data1.flags.access_turn_classification,
|
edge_data1.flags.access_turn_classification,
|
||||||
((double)intersection::findEdgeLength(edge_geometries, node_based_edge_from) /
|
((double)intersection::findEdgeLength(edge_geometries, node_based_edge_from) /
|
||||||
edge_data1.duration) *
|
from_alias<double>(edge_data1.duration)) *
|
||||||
36,
|
36,
|
||||||
edge_data1.flags.road_classification.GetPriority(),
|
edge_data1.flags.road_classification.GetPriority(),
|
||||||
// target info
|
// target info
|
||||||
@@ -675,7 +670,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
|||||||
edge_data2.flags.highway_turn_classification,
|
edge_data2.flags.highway_turn_classification,
|
||||||
edge_data2.flags.access_turn_classification,
|
edge_data2.flags.access_turn_classification,
|
||||||
((double)intersection::findEdgeLength(edge_geometries, node_based_edge_to) /
|
((double)intersection::findEdgeLength(edge_geometries, node_based_edge_to) /
|
||||||
edge_data2.duration) *
|
from_alias<double>(edge_data2.duration)) *
|
||||||
36,
|
36,
|
||||||
edge_data2.flags.road_classification.GetPriority(),
|
edge_data2.flags.road_classification.GetPriority(),
|
||||||
// connected roads
|
// connected roads
|
||||||
@@ -686,17 +681,18 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
|||||||
|
|
||||||
// turn penalties are limited to [-2^15, 2^15) which roughly translates to 54 minutes
|
// turn penalties are limited to [-2^15, 2^15) which roughly translates to 54 minutes
|
||||||
// and fits signed 16bit deci-seconds
|
// and fits signed 16bit deci-seconds
|
||||||
auto weight_penalty =
|
auto weight_penalty = TurnPenalty{boost::numeric_cast<TurnPenalty::value_type>(
|
||||||
boost::numeric_cast<TurnPenalty>(extracted_turn.weight * weight_multiplier);
|
extracted_turn.weight * weight_multiplier)};
|
||||||
auto duration_penalty = boost::numeric_cast<TurnPenalty>(extracted_turn.duration * 10.);
|
auto duration_penalty = TurnPenalty{
|
||||||
|
boost::numeric_cast<TurnPenalty::value_type>(extracted_turn.duration * 10.)};
|
||||||
|
|
||||||
BOOST_ASSERT(SPECIAL_NODEID != nbe_to_ebn_mapping[node_based_edge_from]);
|
BOOST_ASSERT(SPECIAL_NODEID != nbe_to_ebn_mapping[node_based_edge_from]);
|
||||||
BOOST_ASSERT(SPECIAL_NODEID != nbe_to_ebn_mapping[node_based_edge_to]);
|
BOOST_ASSERT(SPECIAL_NODEID != nbe_to_ebn_mapping[node_based_edge_to]);
|
||||||
|
|
||||||
// auto turn_id = m_edge_based_edge_list.size();
|
// auto turn_id = m_edge_based_edge_list.size();
|
||||||
auto weight = boost::numeric_cast<EdgeWeight>(edge_data1.weight + weight_penalty);
|
auto weight = edge_data1.weight + alias_cast<EdgeWeight>(weight_penalty);
|
||||||
auto duration = boost::numeric_cast<EdgeWeight>(edge_data1.duration + duration_penalty);
|
auto duration = edge_data1.duration + alias_cast<EdgeDuration>(duration_penalty);
|
||||||
auto distance = boost::numeric_cast<EdgeDistance>(edge_data1.distance);
|
auto distance = edge_data1.distance;
|
||||||
|
|
||||||
EdgeBasedEdge edge_based_edge = {edge_based_node_from,
|
EdgeBasedEdge edge_based_edge = {edge_based_node_from,
|
||||||
edge_based_node_to,
|
edge_based_node_to,
|
||||||
@@ -860,7 +856,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
|||||||
edge_data.flags.access_turn_classification,
|
edge_data.flags.access_turn_classification,
|
||||||
((double)intersection::findEdgeLength(edge_geometries,
|
((double)intersection::findEdgeLength(edge_geometries,
|
||||||
connected_edge.eid) /
|
connected_edge.eid) /
|
||||||
edge_data.duration) *
|
from_alias<double>(edge_data.duration)) *
|
||||||
36,
|
36,
|
||||||
edge_data.flags.road_classification.GetPriority(),
|
edge_data.flags.road_classification.GetPriority(),
|
||||||
is_incoming,
|
is_incoming,
|
||||||
@@ -1281,7 +1277,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
|||||||
std::vector<ConditionalTurnPenalty>
|
std::vector<ConditionalTurnPenalty>
|
||||||
EdgeBasedGraphFactory::IndexConditionals(std::vector<Conditional> &&conditionals) const
|
EdgeBasedGraphFactory::IndexConditionals(std::vector<Conditional> &&conditionals) const
|
||||||
{
|
{
|
||||||
boost::unordered_multimap<std::pair<NodeID, NodeID>, ConditionalTurnPenalty *> index;
|
std::unordered_multimap<std::pair<NodeID, NodeID>, ConditionalTurnPenalty *> index;
|
||||||
|
|
||||||
// build and index of all conditional restrictions
|
// build and index of all conditional restrictions
|
||||||
for (auto &conditional : conditionals)
|
for (auto &conditional : conditionals)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "extractor/name_table.hpp"
|
#include "extractor/name_table.hpp"
|
||||||
#include "extractor/restriction.hpp"
|
#include "extractor/restriction.hpp"
|
||||||
#include "extractor/serialization.hpp"
|
#include "extractor/serialization.hpp"
|
||||||
|
#include "extractor/traffic_flow_control_nodes.hpp"
|
||||||
#include "util/coordinate_calculation.hpp"
|
#include "util/coordinate_calculation.hpp"
|
||||||
#include "util/integer_range.hpp"
|
#include "util/integer_range.hpp"
|
||||||
|
|
||||||
@@ -412,12 +413,17 @@ void ExtractionContainers::PrepareData(ScriptingEnvironment &scripting_environme
|
|||||||
{
|
{
|
||||||
const auto restriction_ways = IdentifyRestrictionWays();
|
const auto restriction_ways = IdentifyRestrictionWays();
|
||||||
const auto maneuver_override_ways = IdentifyManeuverOverrideWays();
|
const auto maneuver_override_ways = IdentifyManeuverOverrideWays();
|
||||||
const auto traffic_signals = IdentifyTrafficSignals();
|
const auto traffic_signals = IdentifyTrafficFlowControlNodes(external_traffic_signals);
|
||||||
|
const auto stop_signs = IdentifyTrafficFlowControlNodes(external_stop_signs);
|
||||||
|
const auto give_ways = IdentifyTrafficFlowControlNodes(external_give_ways);
|
||||||
|
|
||||||
PrepareNodes();
|
PrepareNodes();
|
||||||
PrepareEdges(scripting_environment);
|
PrepareEdges(scripting_environment);
|
||||||
|
|
||||||
PrepareTrafficSignals(traffic_signals);
|
PrepareTrafficFlowControlNodes(traffic_signals, internal_traffic_signals);
|
||||||
|
PrepareTrafficFlowControlNodes(stop_signs, internal_stop_signs);
|
||||||
|
PrepareTrafficFlowControlNodes(give_ways, internal_give_way_signs);
|
||||||
|
|
||||||
PrepareManeuverOverrides(maneuver_override_ways);
|
PrepareManeuverOverrides(maneuver_override_ways);
|
||||||
PrepareRestrictions(restriction_ways);
|
PrepareRestrictions(restriction_ways);
|
||||||
WriteCharData(name_file_name);
|
WriteCharData(name_file_name);
|
||||||
@@ -712,9 +718,11 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
|
|||||||
scripting_environment.ProcessSegment(segment);
|
scripting_environment.ProcessSegment(segment);
|
||||||
|
|
||||||
auto &edge = edge_iterator->result;
|
auto &edge = edge_iterator->result;
|
||||||
edge.weight = std::max<EdgeWeight>(1, std::round(segment.weight * weight_multiplier));
|
edge.weight = std::max<EdgeWeight>(
|
||||||
edge.duration = std::max<EdgeWeight>(1, std::round(segment.duration * 10.));
|
{1}, to_alias<EdgeWeight>(std::round(segment.weight * weight_multiplier)));
|
||||||
edge.distance = static_cast<float>(accurate_distance);
|
edge.duration = std::max<EdgeDuration>(
|
||||||
|
{1}, to_alias<EdgeDuration>(std::round(segment.duration * 10.)));
|
||||||
|
edge.distance = to_alias<EdgeDistance>(accurate_distance);
|
||||||
|
|
||||||
// assign new node id
|
// assign new node id
|
||||||
const auto node_id = mapExternalToInternalNodeID(
|
const auto node_id = mapExternalToInternalNodeID(
|
||||||
@@ -779,10 +787,8 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
|
|||||||
NodeID source = all_edges_list[i].result.source;
|
NodeID source = all_edges_list[i].result.source;
|
||||||
NodeID target = all_edges_list[i].result.target;
|
NodeID target = all_edges_list[i].result.target;
|
||||||
|
|
||||||
auto min_forward = std::make_pair(std::numeric_limits<EdgeWeight>::max(),
|
auto min_forward = std::make_pair(MAXIMAL_EDGE_WEIGHT, MAXIMAL_EDGE_DURATION);
|
||||||
std::numeric_limits<EdgeWeight>::max());
|
auto min_backward = std::make_pair(MAXIMAL_EDGE_WEIGHT, MAXIMAL_EDGE_DURATION);
|
||||||
auto min_backward = std::make_pair(std::numeric_limits<EdgeWeight>::max(),
|
|
||||||
std::numeric_limits<EdgeWeight>::max());
|
|
||||||
std::size_t min_forward_idx = std::numeric_limits<std::size_t>::max();
|
std::size_t min_forward_idx = std::numeric_limits<std::size_t>::max();
|
||||||
std::size_t min_backward_idx = std::numeric_limits<std::size_t>::max();
|
std::size_t min_backward_idx = std::numeric_limits<std::size_t>::max();
|
||||||
|
|
||||||
@@ -935,23 +941,23 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyManeuverOverr
|
|||||||
return maneuver_override_ways;
|
return maneuver_override_ways;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtractionContainers::PrepareTrafficSignals(
|
void ExtractionContainers::PrepareTrafficFlowControlNodes(
|
||||||
const ExtractionContainers::ReferencedTrafficSignals &referenced_traffic_signals)
|
const ReferencedTrafficFlowControlNodes &referenced_traffic_control_nodes,
|
||||||
|
TrafficFlowControlNodes &internal_traffic_control_nodes)
|
||||||
{
|
{
|
||||||
const auto &bidirectional_signal_nodes = referenced_traffic_signals.first;
|
const auto &bidirectional_traffic_control_nodes = referenced_traffic_control_nodes.first;
|
||||||
const auto &unidirectional_signal_segments = referenced_traffic_signals.second;
|
const auto &unidirectional_node_segments = referenced_traffic_control_nodes.second;
|
||||||
|
|
||||||
util::UnbufferedLog log;
|
util::UnbufferedLog log;
|
||||||
log << "Preparing traffic light signals for " << bidirectional_signal_nodes.size()
|
log << "Preparing traffic control nodes for " << bidirectional_traffic_control_nodes.size()
|
||||||
<< " bidirectional, " << unidirectional_signal_segments.size()
|
<< " bidirectional, " << unidirectional_node_segments.size() << " unidirectional nodes ...";
|
||||||
<< " unidirectional nodes ...";
|
|
||||||
TIMER_START(prepare_traffic_signals);
|
TIMER_START(prepare_traffic_signals);
|
||||||
|
|
||||||
std::unordered_set<NodeID> bidirectional;
|
std::unordered_set<NodeID> bidirectional;
|
||||||
std::unordered_set<std::pair<NodeID, NodeID>, boost::hash<std::pair<NodeID, NodeID>>>
|
std::unordered_set<std::pair<NodeID, NodeID>, boost::hash<std::pair<NodeID, NodeID>>>
|
||||||
unidirectional;
|
unidirectional;
|
||||||
|
|
||||||
for (const auto &osm_node : bidirectional_signal_nodes)
|
for (const auto &osm_node : bidirectional_traffic_control_nodes)
|
||||||
{
|
{
|
||||||
const auto node_id = mapExternalToInternalNodeID(
|
const auto node_id = mapExternalToInternalNodeID(
|
||||||
used_node_id_list.begin(), used_node_id_list.end(), osm_node);
|
used_node_id_list.begin(), used_node_id_list.end(), osm_node);
|
||||||
@@ -960,7 +966,7 @@ void ExtractionContainers::PrepareTrafficSignals(
|
|||||||
bidirectional.insert(node_id);
|
bidirectional.insert(node_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const auto &to_from : unidirectional_signal_segments)
|
for (const auto &to_from : unidirectional_node_segments)
|
||||||
{
|
{
|
||||||
const auto to_node_id = mapExternalToInternalNodeID(
|
const auto to_node_id = mapExternalToInternalNodeID(
|
||||||
used_node_id_list.begin(), used_node_id_list.end(), to_from.first);
|
used_node_id_list.begin(), used_node_id_list.end(), to_from.first);
|
||||||
@@ -972,8 +978,8 @@ void ExtractionContainers::PrepareTrafficSignals(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal_traffic_signals.bidirectional_nodes = std::move(bidirectional);
|
internal_traffic_control_nodes.bidirectional_nodes = std::move(bidirectional);
|
||||||
internal_traffic_signals.unidirectional_segments = std::move(unidirectional);
|
internal_traffic_control_nodes.unidirectional_segments = std::move(unidirectional);
|
||||||
|
|
||||||
TIMER_STOP(prepare_traffic_signals);
|
TIMER_STOP(prepare_traffic_signals);
|
||||||
log << "ok, after " << TIMER_SEC(prepare_traffic_signals) << "s";
|
log << "ok, after " << TIMER_SEC(prepare_traffic_signals) << "s";
|
||||||
@@ -1159,37 +1165,39 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyRestrictionWa
|
|||||||
return restriction_ways;
|
return restriction_ways;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTrafficSignals()
|
ExtractionContainers::ReferencedTrafficFlowControlNodes
|
||||||
|
ExtractionContainers::IdentifyTrafficFlowControlNodes(
|
||||||
|
const std::vector<InputTrafficFlowControlNode> &external_nodes)
|
||||||
{
|
{
|
||||||
util::UnbufferedLog log;
|
util::UnbufferedLog log;
|
||||||
log << "Collecting traffic signal information on " << external_traffic_signals.size()
|
log << "Collecting traffic nodes information on " << external_nodes.size() << " nodes...";
|
||||||
<< " signals...";
|
TIMER_START(identify_traffic_flow_control_nodes);
|
||||||
TIMER_START(identify_traffic_signals);
|
|
||||||
|
|
||||||
// Temporary store for nodes containing a unidirectional signal.
|
// Temporary store for nodes containing a unidirectional signal.
|
||||||
std::unordered_map<OSMNodeID, TrafficLightClass::Direction> unidirectional_signals;
|
std::unordered_map<OSMNodeID, TrafficFlowControlNodeDirection> unidirectional_traffic_nodes;
|
||||||
|
|
||||||
// For each node that has a unidirectional traffic signal, we store the node(s)
|
// For each node that has a unidirectional traffic signal, we store the node(s)
|
||||||
// that lead up to the signal.
|
// that lead up to the signal.
|
||||||
std::unordered_multimap<OSMNodeID, OSMNodeID> signal_segments;
|
std::unordered_multimap<OSMNodeID, OSMNodeID> node_segments;
|
||||||
|
|
||||||
std::unordered_set<OSMNodeID> bidirectional_signals;
|
std::unordered_set<OSMNodeID> bidirectional_traffic_nodes;
|
||||||
|
|
||||||
const auto mark_signals = [&](auto const &traffic_signal) {
|
const auto mark_traffic_nodes = [&](auto const &traffic_control_node) {
|
||||||
if (traffic_signal.second == TrafficLightClass::DIRECTION_FORWARD ||
|
if (traffic_control_node.second == TrafficFlowControlNodeDirection::FORWARD ||
|
||||||
traffic_signal.second == TrafficLightClass::DIRECTION_REVERSE)
|
traffic_control_node.second == TrafficFlowControlNodeDirection::REVERSE)
|
||||||
{
|
{
|
||||||
unidirectional_signals.insert({traffic_signal.first, traffic_signal.second});
|
unidirectional_traffic_nodes.insert(
|
||||||
|
{traffic_control_node.first, traffic_control_node.second});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(traffic_signal.second == TrafficLightClass::DIRECTION_ALL);
|
BOOST_ASSERT(traffic_control_node.second == TrafficFlowControlNodeDirection::ALL);
|
||||||
bidirectional_signals.insert(traffic_signal.first);
|
bidirectional_traffic_nodes.insert(traffic_control_node.first);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
std::for_each(external_traffic_signals.begin(), external_traffic_signals.end(), mark_signals);
|
std::for_each(external_nodes.begin(), external_nodes.end(), mark_traffic_nodes);
|
||||||
|
|
||||||
// Extract all the segments that lead up to unidirectional traffic signals.
|
// Extract all the segments that lead up to unidirectional traffic flow control nodes.
|
||||||
const auto set_segments = [&](const size_t way_list_idx, auto const & /*unused*/) {
|
const auto set_segments = [&](const size_t way_list_idx, auto const & /*unused*/) {
|
||||||
const auto node_start_offset =
|
const auto node_start_offset =
|
||||||
used_node_id_list.begin() + way_node_id_offsets[way_list_idx];
|
used_node_id_list.begin() + way_node_id_offsets[way_list_idx];
|
||||||
@@ -1198,24 +1206,24 @@ ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTra
|
|||||||
|
|
||||||
for (auto node_it = node_start_offset; node_it < node_end_offset; node_it++)
|
for (auto node_it = node_start_offset; node_it < node_end_offset; node_it++)
|
||||||
{
|
{
|
||||||
const auto sig = unidirectional_signals.find(*node_it);
|
const auto sig = unidirectional_traffic_nodes.find(*node_it);
|
||||||
if (sig != unidirectional_signals.end())
|
if (sig != unidirectional_traffic_nodes.end())
|
||||||
{
|
{
|
||||||
if (sig->second == TrafficLightClass::DIRECTION_FORWARD)
|
if (sig->second == TrafficFlowControlNodeDirection::FORWARD)
|
||||||
{
|
{
|
||||||
if (node_it != node_start_offset)
|
if (node_it != node_start_offset)
|
||||||
{
|
{
|
||||||
// Previous node leads to signal
|
// Previous node leads to signal
|
||||||
signal_segments.insert({*node_it, *(node_it - 1)});
|
node_segments.insert({*node_it, *(node_it - 1)});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(sig->second == TrafficLightClass::DIRECTION_REVERSE);
|
BOOST_ASSERT(sig->second == TrafficFlowControlNodeDirection::REVERSE);
|
||||||
if (node_it + 1 != node_end_offset)
|
if (node_it + 1 != node_end_offset)
|
||||||
{
|
{
|
||||||
// Next node leads to signal
|
// Next node leads to signal
|
||||||
signal_segments.insert({*node_it, *(node_it + 1)});
|
node_segments.insert({*node_it, *(node_it + 1)});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1224,7 +1232,7 @@ ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTra
|
|||||||
util::for_each_indexed(ways_list.cbegin(), ways_list.cend(), set_segments);
|
util::for_each_indexed(ways_list.cbegin(), ways_list.cend(), set_segments);
|
||||||
|
|
||||||
util::for_each_pair(
|
util::for_each_pair(
|
||||||
signal_segments, [](const auto pair_a, const auto pair_b) {
|
node_segments, [](const auto pair_a, const auto pair_b) {
|
||||||
if (pair_a.first == pair_b.first)
|
if (pair_a.first == pair_b.first)
|
||||||
{
|
{
|
||||||
// If a node is appearing multiple times in this map, then it's ambiguous.
|
// If a node is appearing multiple times in this map, then it's ambiguous.
|
||||||
@@ -1240,10 +1248,10 @@ ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTra
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
TIMER_STOP(identify_traffic_signals);
|
TIMER_STOP(identify_traffic_flow_control_nodes);
|
||||||
log << "ok, after " << TIMER_SEC(identify_traffic_signals) << "s";
|
log << "ok, after " << TIMER_SEC(identify_traffic_flow_control_nodes) << "s";
|
||||||
|
|
||||||
return {std::move(bidirectional_signals), std::move(signal_segments)};
|
return {std::move(bidirectional_traffic_nodes), std::move(node_segments)};
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtractionContainers::PrepareRestrictions(const ReferencedWays &restriction_ways)
|
void ExtractionContainers::PrepareRestrictions(const ReferencedWays &restriction_ways)
|
||||||
|
|||||||
@@ -226,6 +226,8 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
|
|||||||
parsed_osm_data.turn_restrictions,
|
parsed_osm_data.turn_restrictions,
|
||||||
parsed_osm_data.unresolved_maneuver_overrides,
|
parsed_osm_data.unresolved_maneuver_overrides,
|
||||||
parsed_osm_data.traffic_signals,
|
parsed_osm_data.traffic_signals,
|
||||||
|
parsed_osm_data.stop_signs,
|
||||||
|
parsed_osm_data.give_way_signs,
|
||||||
std::move(parsed_osm_data.barriers),
|
std::move(parsed_osm_data.barriers),
|
||||||
std::move(parsed_osm_data.osm_coordinates),
|
std::move(parsed_osm_data.osm_coordinates),
|
||||||
std::move(parsed_osm_data.osm_node_ids),
|
std::move(parsed_osm_data.osm_node_ids),
|
||||||
@@ -283,6 +285,8 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
|
|||||||
node_based_graph_factory.GetCompressedEdges(),
|
node_based_graph_factory.GetCompressedEdges(),
|
||||||
barrier_nodes,
|
barrier_nodes,
|
||||||
parsed_osm_data.traffic_signals,
|
parsed_osm_data.traffic_signals,
|
||||||
|
parsed_osm_data.stop_signs,
|
||||||
|
parsed_osm_data.give_way_signs,
|
||||||
restriction_graph,
|
restriction_graph,
|
||||||
segregated_edges,
|
segregated_edges,
|
||||||
name_table,
|
name_table,
|
||||||
@@ -649,6 +653,8 @@ Extractor::ParsedOSMData Extractor::ParseOSMData(ScriptingEnvironment &scripting
|
|||||||
std::move(extraction_containers.turn_restrictions),
|
std::move(extraction_containers.turn_restrictions),
|
||||||
std::move(extraction_containers.internal_maneuver_overrides),
|
std::move(extraction_containers.internal_maneuver_overrides),
|
||||||
std::move(extraction_containers.internal_traffic_signals),
|
std::move(extraction_containers.internal_traffic_signals),
|
||||||
|
std::move(extraction_containers.internal_stop_signs),
|
||||||
|
std::move(extraction_containers.internal_give_way_signs),
|
||||||
std::move(extraction_containers.used_barrier_nodes),
|
std::move(extraction_containers.used_barrier_nodes),
|
||||||
std::move(osm_coordinates),
|
std::move(osm_coordinates),
|
||||||
std::move(osm_node_ids),
|
std::move(osm_node_ids),
|
||||||
@@ -668,7 +674,7 @@ void Extractor::FindComponents(unsigned number_of_edge_based_nodes,
|
|||||||
|
|
||||||
for (const auto &edge : input_edge_list)
|
for (const auto &edge : input_edge_list)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT_MSG(static_cast<unsigned int>(std::max(edge.data.weight, 1)) > 0,
|
BOOST_ASSERT_MSG((std::max(edge.data.weight, EdgeWeight{1})) > EdgeWeight{0},
|
||||||
"edge distance < 1");
|
"edge distance < 1");
|
||||||
BOOST_ASSERT(edge.source < number_of_edge_based_nodes);
|
BOOST_ASSERT(edge.source < number_of_edge_based_nodes);
|
||||||
BOOST_ASSERT(edge.target < number_of_edge_based_nodes);
|
BOOST_ASSERT(edge.target < number_of_edge_based_nodes);
|
||||||
@@ -724,7 +730,9 @@ EdgeID Extractor::BuildEdgeExpandedGraph(
|
|||||||
const std::vector<util::Coordinate> &coordinates,
|
const std::vector<util::Coordinate> &coordinates,
|
||||||
const CompressedEdgeContainer &compressed_edge_container,
|
const CompressedEdgeContainer &compressed_edge_container,
|
||||||
const std::unordered_set<NodeID> &barrier_nodes,
|
const std::unordered_set<NodeID> &barrier_nodes,
|
||||||
const TrafficSignals &traffic_signals,
|
const TrafficFlowControlNodes &traffic_signals,
|
||||||
|
const TrafficFlowControlNodes &stop_signs,
|
||||||
|
const TrafficFlowControlNodes &give_way_signs,
|
||||||
const RestrictionGraph &restriction_graph,
|
const RestrictionGraph &restriction_graph,
|
||||||
const std::unordered_set<EdgeID> &segregated_edges,
|
const std::unordered_set<EdgeID> &segregated_edges,
|
||||||
const NameTable &name_table,
|
const NameTable &name_table,
|
||||||
@@ -746,6 +754,8 @@ EdgeID Extractor::BuildEdgeExpandedGraph(
|
|||||||
compressed_edge_container,
|
compressed_edge_container,
|
||||||
barrier_nodes,
|
barrier_nodes,
|
||||||
traffic_signals,
|
traffic_signals,
|
||||||
|
stop_signs,
|
||||||
|
give_way_signs,
|
||||||
coordinates,
|
coordinates,
|
||||||
name_table,
|
name_table,
|
||||||
segregated_edges,
|
segregated_edges,
|
||||||
|
|||||||
@@ -78,10 +78,23 @@ void ExtractorCallbacks::ProcessNode(const osmium::Node &input_node,
|
|||||||
{
|
{
|
||||||
external_memory.barrier_nodes.push_back(id);
|
external_memory.barrier_nodes.push_back(id);
|
||||||
}
|
}
|
||||||
if (result_node.traffic_lights != TrafficLightClass::NONE)
|
if (result_node.traffic_lights != TrafficFlowControlNodeDirection::NONE)
|
||||||
{
|
{
|
||||||
external_memory.external_traffic_signals.push_back({id, result_node.traffic_lights});
|
external_memory.external_traffic_signals.push_back({id, result_node.traffic_lights});
|
||||||
}
|
}
|
||||||
|
// TODO: we ignore `ALL` for both stop signs and give way signs, because we cannot understand
|
||||||
|
// direction of the way they should be applied yet see:
|
||||||
|
// https://wiki.openstreetmap.org/wiki/Tag:highway%3Dstop#Direction
|
||||||
|
if (result_node.give_way != TrafficFlowControlNodeDirection::NONE &&
|
||||||
|
result_node.give_way != TrafficFlowControlNodeDirection::ALL)
|
||||||
|
{
|
||||||
|
external_memory.external_give_ways.push_back({id, result_node.give_way});
|
||||||
|
}
|
||||||
|
if (result_node.stop_sign != TrafficFlowControlNodeDirection::NONE &&
|
||||||
|
result_node.stop_sign != TrafficFlowControlNodeDirection::ALL)
|
||||||
|
{
|
||||||
|
external_memory.external_stop_signs.push_back({id, result_node.stop_sign});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtractorCallbacks::ProcessRestriction(const InputTurnRestriction &restriction)
|
void ExtractorCallbacks::ProcessRestriction(const InputTurnRestriction &restriction)
|
||||||
@@ -425,10 +438,10 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
|||||||
NodeBasedEdgeWithOSM edge = {
|
NodeBasedEdgeWithOSM edge = {
|
||||||
OSMNodeID{static_cast<std::uint64_t>(first_node.ref())},
|
OSMNodeID{static_cast<std::uint64_t>(first_node.ref())},
|
||||||
OSMNodeID{static_cast<std::uint64_t>(last_node.ref())},
|
OSMNodeID{static_cast<std::uint64_t>(last_node.ref())},
|
||||||
0, // weight
|
{0}, // weight
|
||||||
0, // duration
|
{0}, // duration
|
||||||
0, // distance
|
{0}, // distance
|
||||||
{}, // geometry id
|
{}, // geometry id
|
||||||
static_cast<AnnotationID>(annotation_data_id),
|
static_cast<AnnotationID>(annotation_data_id),
|
||||||
{true,
|
{true,
|
||||||
in_backward_direction && !split_edge,
|
in_backward_direction && !split_edge,
|
||||||
@@ -459,10 +472,10 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
|||||||
NodeBasedEdgeWithOSM edge = {
|
NodeBasedEdgeWithOSM edge = {
|
||||||
OSMNodeID{static_cast<std::uint64_t>(first_node.ref())},
|
OSMNodeID{static_cast<std::uint64_t>(first_node.ref())},
|
||||||
OSMNodeID{static_cast<std::uint64_t>(last_node.ref())},
|
OSMNodeID{static_cast<std::uint64_t>(last_node.ref())},
|
||||||
0, // weight
|
{0}, // weight
|
||||||
0, // duration
|
{0}, // duration
|
||||||
0, // distance
|
{0}, // distance
|
||||||
{}, // geometry id
|
{}, // geometry id
|
||||||
static_cast<AnnotationID>(annotation_data_id),
|
static_cast<AnnotationID>(annotation_data_id),
|
||||||
{false,
|
{false,
|
||||||
true,
|
true,
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ namespace extractor
|
|||||||
static constexpr int SECOND_TO_DECISECOND = 10;
|
static constexpr int SECOND_TO_DECISECOND = 10;
|
||||||
|
|
||||||
void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||||
const TrafficSignals &traffic_signals,
|
const TrafficFlowControlNodes &traffic_signals,
|
||||||
|
const TrafficFlowControlNodes &stop_signs,
|
||||||
|
const TrafficFlowControlNodes &give_way_signs,
|
||||||
ScriptingEnvironment &scripting_environment,
|
ScriptingEnvironment &scripting_environment,
|
||||||
std::vector<TurnRestriction> &turn_restrictions,
|
std::vector<TurnRestriction> &turn_restrictions,
|
||||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
||||||
@@ -208,15 +210,22 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
|||||||
graph.GetEdgeData(reverse_e2).annotation_data = selectAnnotation(
|
graph.GetEdgeData(reverse_e2).annotation_data = selectAnnotation(
|
||||||
rev_edge_data2.annotation_data, rev_edge_data1.annotation_data);
|
rev_edge_data2.annotation_data, rev_edge_data1.annotation_data);
|
||||||
|
|
||||||
// Add node penalty when compress edge crosses a traffic signal
|
// Add node penalty when compress edge crosses a traffic signal/stop sign/give way
|
||||||
const bool has_forward_signal = traffic_signals.HasSignal(node_u, node_v);
|
const bool has_forward_signal = traffic_signals.Has(node_u, node_v);
|
||||||
const bool has_reverse_signal = traffic_signals.HasSignal(node_w, node_v);
|
const bool has_reverse_signal = traffic_signals.Has(node_w, node_v);
|
||||||
|
|
||||||
|
const bool has_forward_stop_sign = stop_signs.Has(node_u, node_v);
|
||||||
|
const bool has_reverse_stop_sign = stop_signs.Has(node_w, node_v);
|
||||||
|
|
||||||
|
const bool has_forward_give_way_sign = give_way_signs.Has(node_u, node_v);
|
||||||
|
const bool has_reverse_give_way_sign = give_way_signs.Has(node_w, node_v);
|
||||||
|
|
||||||
EdgeDuration forward_node_duration_penalty = MAXIMAL_EDGE_DURATION;
|
EdgeDuration forward_node_duration_penalty = MAXIMAL_EDGE_DURATION;
|
||||||
EdgeWeight forward_node_weight_penalty = INVALID_EDGE_WEIGHT;
|
EdgeWeight forward_node_weight_penalty = INVALID_EDGE_WEIGHT;
|
||||||
EdgeDuration reverse_node_duration_penalty = MAXIMAL_EDGE_DURATION;
|
EdgeDuration reverse_node_duration_penalty = MAXIMAL_EDGE_DURATION;
|
||||||
EdgeWeight reverse_node_weight_penalty = INVALID_EDGE_WEIGHT;
|
EdgeWeight reverse_node_weight_penalty = INVALID_EDGE_WEIGHT;
|
||||||
if (has_forward_signal || has_reverse_signal)
|
if (has_forward_signal || has_reverse_signal || has_forward_stop_sign ||
|
||||||
|
has_reverse_stop_sign || has_forward_give_way_sign || has_reverse_give_way_sign)
|
||||||
{
|
{
|
||||||
// we cannot handle this as node penalty, if it depends on turn direction
|
// we cannot handle this as node penalty, if it depends on turn direction
|
||||||
if (fwd_edge_data1.flags.restricted != fwd_edge_data2.flags.restricted)
|
if (fwd_edge_data1.flags.restricted != fwd_edge_data2.flags.restricted)
|
||||||
@@ -228,7 +237,10 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
|||||||
ExtractionTurn extraction_turn(0,
|
ExtractionTurn extraction_turn(0,
|
||||||
2,
|
2,
|
||||||
false,
|
false,
|
||||||
true,
|
has_forward_signal || has_reverse_signal,
|
||||||
|
has_forward_stop_sign || has_reverse_stop_sign,
|
||||||
|
has_forward_give_way_sign ||
|
||||||
|
has_reverse_give_way_sign,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
TRAVEL_MODE_DRIVING,
|
TRAVEL_MODE_DRIVING,
|
||||||
@@ -252,21 +264,25 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
|||||||
roads_on_the_left);
|
roads_on_the_left);
|
||||||
scripting_environment.ProcessTurn(extraction_turn);
|
scripting_environment.ProcessTurn(extraction_turn);
|
||||||
|
|
||||||
auto update_direction_penalty =
|
auto update_direction_penalty = [&extraction_turn, weight_multiplier](
|
||||||
[&extraction_turn, weight_multiplier](bool signal,
|
bool has_traffic_control_node,
|
||||||
EdgeDuration &duration_penalty,
|
EdgeDuration &duration_penalty,
|
||||||
EdgeWeight &weight_penalty) {
|
EdgeWeight &weight_penalty) {
|
||||||
if (signal)
|
if (has_traffic_control_node)
|
||||||
{
|
{
|
||||||
duration_penalty = extraction_turn.duration * SECOND_TO_DECISECOND;
|
duration_penalty = to_alias<EdgeDuration>(extraction_turn.duration *
|
||||||
weight_penalty = extraction_turn.weight * weight_multiplier;
|
SECOND_TO_DECISECOND);
|
||||||
}
|
weight_penalty =
|
||||||
};
|
to_alias<EdgeWeight>(extraction_turn.weight * weight_multiplier);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
update_direction_penalty(has_forward_signal,
|
update_direction_penalty(has_forward_signal || has_forward_stop_sign ||
|
||||||
|
has_forward_give_way_sign,
|
||||||
forward_node_duration_penalty,
|
forward_node_duration_penalty,
|
||||||
forward_node_weight_penalty);
|
forward_node_weight_penalty);
|
||||||
update_direction_penalty(has_reverse_signal,
|
update_direction_penalty(has_reverse_signal || has_reverse_stop_sign ||
|
||||||
|
has_reverse_give_way_sign,
|
||||||
reverse_node_duration_penalty,
|
reverse_node_duration_penalty,
|
||||||
reverse_node_weight_penalty);
|
reverse_node_weight_penalty);
|
||||||
}
|
}
|
||||||
@@ -276,16 +292,14 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
|||||||
const auto forward_weight2 = fwd_edge_data2.weight;
|
const auto forward_weight2 = fwd_edge_data2.weight;
|
||||||
const auto forward_duration1 = fwd_edge_data1.duration;
|
const auto forward_duration1 = fwd_edge_data1.duration;
|
||||||
const auto forward_duration2 = fwd_edge_data2.duration;
|
const auto forward_duration2 = fwd_edge_data2.duration;
|
||||||
const auto forward_distance2 = fwd_edge_data2.distance;
|
|
||||||
|
|
||||||
BOOST_ASSERT(0 != forward_weight1);
|
BOOST_ASSERT(EdgeWeight{0} != forward_weight1);
|
||||||
BOOST_ASSERT(0 != forward_weight2);
|
BOOST_ASSERT(EdgeWeight{0} != forward_weight2);
|
||||||
|
|
||||||
const auto reverse_weight1 = rev_edge_data1.weight;
|
const auto reverse_weight1 = rev_edge_data1.weight;
|
||||||
const auto reverse_weight2 = rev_edge_data2.weight;
|
const auto reverse_weight2 = rev_edge_data2.weight;
|
||||||
const auto reverse_duration1 = rev_edge_data1.duration;
|
const auto reverse_duration1 = rev_edge_data1.duration;
|
||||||
const auto reverse_duration2 = rev_edge_data2.duration;
|
const auto reverse_duration2 = rev_edge_data2.duration;
|
||||||
const auto reverse_distance2 = rev_edge_data2.distance;
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
// Because distances are symmetrical, we only need one
|
// Because distances are symmetrical, we only need one
|
||||||
@@ -293,42 +307,39 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
|||||||
// their mirrors.
|
// their mirrors.
|
||||||
const auto reverse_distance1 = rev_edge_data1.distance;
|
const auto reverse_distance1 = rev_edge_data1.distance;
|
||||||
const auto forward_distance1 = fwd_edge_data1.distance;
|
const auto forward_distance1 = fwd_edge_data1.distance;
|
||||||
|
const auto forward_distance2 = fwd_edge_data2.distance;
|
||||||
|
const auto reverse_distance2 = rev_edge_data2.distance;
|
||||||
BOOST_ASSERT(forward_distance1 == reverse_distance2);
|
BOOST_ASSERT(forward_distance1 == reverse_distance2);
|
||||||
BOOST_ASSERT(forward_distance2 == reverse_distance1);
|
BOOST_ASSERT(forward_distance2 == reverse_distance1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BOOST_ASSERT(0 != reverse_weight1);
|
BOOST_ASSERT(EdgeWeight{0} != reverse_weight1);
|
||||||
BOOST_ASSERT(0 != reverse_weight2);
|
BOOST_ASSERT(EdgeWeight{0} != reverse_weight2);
|
||||||
|
|
||||||
auto apply_e2_to_e1 = [&graph](EdgeID edge,
|
auto apply_e2_to_e1 = [&graph](EdgeID edge1,
|
||||||
EdgeWeight weight,
|
EdgeID edge2,
|
||||||
EdgeDuration duration,
|
EdgeWeight &weight_penalty,
|
||||||
EdgeDistance distance,
|
EdgeDuration &duration_penalty) {
|
||||||
EdgeDuration &duration_penalty,
|
auto &edge1_data = graph.GetEdgeData(edge1);
|
||||||
EdgeWeight &weight_penalty) {
|
const auto &edge2_data = graph.GetEdgeData(edge2);
|
||||||
auto &edge_data = graph.GetEdgeData(edge);
|
edge1_data.weight += edge2_data.weight;
|
||||||
edge_data.weight += weight;
|
edge1_data.duration += edge2_data.duration;
|
||||||
edge_data.duration += duration;
|
edge1_data.distance += edge2_data.distance;
|
||||||
edge_data.distance += distance;
|
|
||||||
if (weight_penalty != INVALID_EDGE_WEIGHT &&
|
if (weight_penalty != INVALID_EDGE_WEIGHT &&
|
||||||
duration_penalty != MAXIMAL_EDGE_DURATION)
|
duration_penalty != MAXIMAL_EDGE_DURATION)
|
||||||
{
|
{
|
||||||
edge_data.weight += weight_penalty;
|
edge1_data.weight += weight_penalty;
|
||||||
edge_data.duration += duration_penalty;
|
edge1_data.duration += duration_penalty;
|
||||||
// Note: no penalties for distances
|
// Note: no penalties for distances
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
apply_e2_to_e1(forward_e1,
|
apply_e2_to_e1(forward_e1,
|
||||||
forward_weight2,
|
forward_e2,
|
||||||
forward_duration2,
|
|
||||||
forward_distance2,
|
|
||||||
forward_node_weight_penalty,
|
forward_node_weight_penalty,
|
||||||
forward_node_duration_penalty);
|
forward_node_duration_penalty);
|
||||||
apply_e2_to_e1(reverse_e1,
|
apply_e2_to_e1(reverse_e1,
|
||||||
reverse_weight2,
|
reverse_e2,
|
||||||
reverse_duration2,
|
|
||||||
reverse_distance2,
|
|
||||||
reverse_node_weight_penalty,
|
reverse_node_weight_penalty,
|
||||||
reverse_node_duration_penalty);
|
reverse_node_duration_penalty);
|
||||||
|
|
||||||
@@ -351,8 +362,8 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
|||||||
if (weight_penalty == INVALID_EDGE_WEIGHT &&
|
if (weight_penalty == INVALID_EDGE_WEIGHT &&
|
||||||
other_weight_penalty != INVALID_EDGE_WEIGHT)
|
other_weight_penalty != INVALID_EDGE_WEIGHT)
|
||||||
{
|
{
|
||||||
weight_penalty = 0;
|
weight_penalty = {0};
|
||||||
duration_penalty = 0;
|
duration_penalty = {0};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
set_dummy_penalty(forward_node_weight_penalty,
|
set_dummy_penalty(forward_node_weight_penalty,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "extractor/node_based_graph_factory.hpp"
|
#include "extractor/node_based_graph_factory.hpp"
|
||||||
#include "extractor/files.hpp"
|
#include "extractor/files.hpp"
|
||||||
#include "extractor/graph_compressor.hpp"
|
#include "extractor/graph_compressor.hpp"
|
||||||
|
#include "extractor/traffic_flow_control_nodes.hpp"
|
||||||
#include "storage/io.hpp"
|
#include "storage/io.hpp"
|
||||||
|
|
||||||
#include "util/log.hpp"
|
#include "util/log.hpp"
|
||||||
@@ -19,7 +20,9 @@ NodeBasedGraphFactory::NodeBasedGraphFactory(
|
|||||||
ScriptingEnvironment &scripting_environment,
|
ScriptingEnvironment &scripting_environment,
|
||||||
std::vector<TurnRestriction> &turn_restrictions,
|
std::vector<TurnRestriction> &turn_restrictions,
|
||||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
||||||
const TrafficSignals &traffic_signals,
|
const TrafficFlowControlNodes &traffic_signals,
|
||||||
|
const TrafficFlowControlNodes &stop_signs,
|
||||||
|
const TrafficFlowControlNodes &give_way_signs,
|
||||||
std::unordered_set<NodeID> &&barriers,
|
std::unordered_set<NodeID> &&barriers,
|
||||||
std::vector<util::Coordinate> &&coordinates,
|
std::vector<util::Coordinate> &&coordinates,
|
||||||
extractor::PackedOSMIDs &&osm_node_ids,
|
extractor::PackedOSMIDs &&osm_node_ids,
|
||||||
@@ -29,7 +32,12 @@ NodeBasedGraphFactory::NodeBasedGraphFactory(
|
|||||||
coordinates(std::move(coordinates)), osm_node_ids(std::move(osm_node_ids))
|
coordinates(std::move(coordinates)), osm_node_ids(std::move(osm_node_ids))
|
||||||
{
|
{
|
||||||
BuildCompressedOutputGraph(edge_list);
|
BuildCompressedOutputGraph(edge_list);
|
||||||
Compress(scripting_environment, turn_restrictions, maneuver_overrides, traffic_signals);
|
Compress(scripting_environment,
|
||||||
|
turn_restrictions,
|
||||||
|
maneuver_overrides,
|
||||||
|
traffic_signals,
|
||||||
|
stop_signs,
|
||||||
|
give_way_signs);
|
||||||
CompressGeometry();
|
CompressGeometry();
|
||||||
CompressAnnotationData();
|
CompressAnnotationData();
|
||||||
}
|
}
|
||||||
@@ -74,11 +82,15 @@ void NodeBasedGraphFactory::BuildCompressedOutputGraph(const std::vector<NodeBas
|
|||||||
void NodeBasedGraphFactory::Compress(ScriptingEnvironment &scripting_environment,
|
void NodeBasedGraphFactory::Compress(ScriptingEnvironment &scripting_environment,
|
||||||
std::vector<TurnRestriction> &turn_restrictions,
|
std::vector<TurnRestriction> &turn_restrictions,
|
||||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
||||||
const TrafficSignals &traffic_signals)
|
const TrafficFlowControlNodes &traffic_signals,
|
||||||
|
const TrafficFlowControlNodes &stop_signs,
|
||||||
|
const TrafficFlowControlNodes &give_way_signs)
|
||||||
{
|
{
|
||||||
GraphCompressor graph_compressor;
|
GraphCompressor graph_compressor;
|
||||||
graph_compressor.Compress(barriers,
|
graph_compressor.Compress(barriers,
|
||||||
traffic_signals,
|
traffic_signals,
|
||||||
|
stop_signs,
|
||||||
|
give_way_signs,
|
||||||
scripting_environment,
|
scripting_environment,
|
||||||
turn_restrictions,
|
turn_restrictions,
|
||||||
maneuver_overrides,
|
maneuver_overrides,
|
||||||
|
|||||||
@@ -284,17 +284,26 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
|||||||
[&context, &get_location_tag](const osmium::Node &node, const char *key) {
|
[&context, &get_location_tag](const osmium::Node &node, const char *key) {
|
||||||
return get_location_tag(context, node.location(), key);
|
return get_location_tag(context, node.location(), key);
|
||||||
});
|
});
|
||||||
|
// just for backward compatibility
|
||||||
|
// TODO: remove in v6
|
||||||
context.state.new_enum("traffic_lights",
|
context.state.new_enum("traffic_lights",
|
||||||
"none",
|
"none",
|
||||||
extractor::TrafficLightClass::NONE,
|
extractor::TrafficFlowControlNodeDirection::NONE,
|
||||||
"direction_all",
|
"direction_all",
|
||||||
extractor::TrafficLightClass::DIRECTION_ALL,
|
extractor::TrafficFlowControlNodeDirection::ALL,
|
||||||
"direction_forward",
|
"direction_forward",
|
||||||
extractor::TrafficLightClass::DIRECTION_FORWARD,
|
extractor::TrafficFlowControlNodeDirection::FORWARD,
|
||||||
"direction_reverse",
|
"direction_reverse",
|
||||||
extractor::TrafficLightClass::DIRECTION_REVERSE);
|
extractor::TrafficFlowControlNodeDirection::REVERSE);
|
||||||
|
context.state.new_enum("traffic_flow_control_direction",
|
||||||
|
"none",
|
||||||
|
extractor::TrafficFlowControlNodeDirection::NONE,
|
||||||
|
"direction_all",
|
||||||
|
extractor::TrafficFlowControlNodeDirection::ALL,
|
||||||
|
"direction_forward",
|
||||||
|
extractor::TrafficFlowControlNodeDirection::FORWARD,
|
||||||
|
"direction_reverse",
|
||||||
|
extractor::TrafficFlowControlNodeDirection::REVERSE);
|
||||||
context.state.new_usertype<ExtractionNode>(
|
context.state.new_usertype<ExtractionNode>(
|
||||||
"ResultNode",
|
"ResultNode",
|
||||||
"traffic_lights",
|
"traffic_lights",
|
||||||
@@ -306,18 +315,30 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
|||||||
// state to the node is converted to the class enum
|
// state to the node is converted to the class enum
|
||||||
// TODO: Make a breaking API change and remove this option.
|
// TODO: Make a breaking API change and remove this option.
|
||||||
bool val = obj.as<bool>();
|
bool val = obj.as<bool>();
|
||||||
node.traffic_lights = (val) ? TrafficLightClass::DIRECTION_ALL
|
node.traffic_lights = (val) ? TrafficFlowControlNodeDirection::ALL
|
||||||
: TrafficLightClass::NONE;
|
: TrafficFlowControlNodeDirection::NONE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_ASSERT(obj.is<TrafficLightClass::Direction>());
|
BOOST_ASSERT(obj.is<TrafficFlowControlNodeDirection>());
|
||||||
{
|
{
|
||||||
TrafficLightClass::Direction val =
|
TrafficFlowControlNodeDirection val =
|
||||||
obj.as<TrafficLightClass::Direction>();
|
obj.as<TrafficFlowControlNodeDirection>();
|
||||||
node.traffic_lights = val;
|
node.traffic_lights = val;
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
"stop_sign",
|
||||||
|
sol::property([](const ExtractionNode &node) { return node.stop_sign; },
|
||||||
|
[](ExtractionNode &node, const sol::object &obj) {
|
||||||
|
BOOST_ASSERT(obj.is<TrafficFlowControlNodeDirection>());
|
||||||
|
node.stop_sign = obj.as<TrafficFlowControlNodeDirection>();
|
||||||
|
}),
|
||||||
|
"give_way",
|
||||||
|
sol::property([](const ExtractionNode &node) { return node.give_way; },
|
||||||
|
[](ExtractionNode &node, const sol::object &obj) {
|
||||||
|
BOOST_ASSERT(obj.is<TrafficFlowControlNodeDirection>());
|
||||||
|
node.give_way = obj.as<TrafficFlowControlNodeDirection>();
|
||||||
|
}),
|
||||||
"barrier",
|
"barrier",
|
||||||
&ExtractionNode::barrier);
|
&ExtractionNode::barrier);
|
||||||
|
|
||||||
@@ -549,7 +570,7 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
|||||||
"precision",
|
"precision",
|
||||||
COORDINATE_PRECISION,
|
COORDINATE_PRECISION,
|
||||||
"max_turn_weight",
|
"max_turn_weight",
|
||||||
std::numeric_limits<TurnPenalty>::max());
|
std::numeric_limits<TurnPenalty::value_type>::max());
|
||||||
|
|
||||||
// call initialize function
|
// call initialize function
|
||||||
sol::function setup_function = function_table.value()["setup"];
|
sol::function setup_function = function_table.value()["setup"];
|
||||||
@@ -763,9 +784,12 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
|||||||
&ExtractionTurn::is_u_turn,
|
&ExtractionTurn::is_u_turn,
|
||||||
"has_traffic_light",
|
"has_traffic_light",
|
||||||
&ExtractionTurn::has_traffic_light,
|
&ExtractionTurn::has_traffic_light,
|
||||||
|
"has_stop_sign",
|
||||||
|
&ExtractionTurn::has_stop_sign,
|
||||||
|
"has_give_way_sign",
|
||||||
|
&ExtractionTurn::has_give_way_sign,
|
||||||
"is_left_hand_driving",
|
"is_left_hand_driving",
|
||||||
&ExtractionTurn::is_left_hand_driving,
|
&ExtractionTurn::is_left_hand_driving,
|
||||||
|
|
||||||
"source_restricted",
|
"source_restricted",
|
||||||
&ExtractionTurn::source_restricted,
|
&ExtractionTurn::source_restricted,
|
||||||
"source_mode",
|
"source_mode",
|
||||||
@@ -1130,10 +1154,15 @@ void Sol2ScriptingEnvironment::ProcessTurn(ExtractionTurn &turn)
|
|||||||
// Turn weight falls back to the duration value in deciseconds
|
// Turn weight falls back to the duration value in deciseconds
|
||||||
// or uses the extracted unit-less weight value
|
// or uses the extracted unit-less weight value
|
||||||
if (context.properties.fallback_to_duration)
|
if (context.properties.fallback_to_duration)
|
||||||
|
{
|
||||||
turn.weight = turn.duration;
|
turn.weight = turn.duration;
|
||||||
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
|
{
|
||||||
// cap turn weight to max turn weight, which depend on weight precision
|
// cap turn weight to max turn weight, which depend on weight precision
|
||||||
turn.weight = std::min(turn.weight, context.properties.GetMaxTurnWeight());
|
turn.weight = std::min(turn.weight, context.properties.GetMaxTurnWeight());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|||||||
+32
-77
@@ -1,10 +1,12 @@
|
|||||||
#include "server/connection.hpp"
|
#include "server/connection.hpp"
|
||||||
#include "server/request_handler.hpp"
|
#include "server/request_handler.hpp"
|
||||||
|
#include "server/request_parser.hpp"
|
||||||
|
|
||||||
#include <boost/algorithm/string/predicate.hpp>
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <boost/iostreams/filter/gzip.hpp>
|
#include <boost/iostreams/filter/gzip.hpp>
|
||||||
#include <boost/iostreams/filtering_stream.hpp>
|
#include <boost/iostreams/filtering_stream.hpp>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace osrm
|
namespace osrm
|
||||||
@@ -12,40 +14,14 @@ namespace osrm
|
|||||||
namespace server
|
namespace server
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
const size_t CHUNK_SIZE = 8192;
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
Connection::Connection(boost::asio::io_context &io_context, RequestHandler &handler)
|
Connection::Connection(boost::asio::io_context &io_context, RequestHandler &handler)
|
||||||
: strand(boost::asio::make_strand(io_context)), TCP_socket(strand), timer(strand),
|
: strand(boost::asio::make_strand(io_context)), TCP_socket(strand), timer(strand),
|
||||||
request_handler(handler), http_request_parser(std::make_optional<RequestParser>())
|
request_handler(handler)
|
||||||
{
|
{
|
||||||
http_request_parser->header_limit(std::numeric_limits<std::uint32_t>::max());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::asio::ip::tcp::socket &Connection::socket() { return TCP_socket; }
|
boost::asio::ip::tcp::socket &Connection::socket() { return TCP_socket; }
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
http::compression_type select_compression(const boost::beast::http::fields &fields)
|
|
||||||
{
|
|
||||||
const auto header_value = fields[boost::beast::http::field::accept_encoding];
|
|
||||||
/* giving gzip precedence over deflate */
|
|
||||||
if (boost::icontains(header_value, "gzip"))
|
|
||||||
{
|
|
||||||
return http::gzip_rfc1952;
|
|
||||||
}
|
|
||||||
if (boost::icontains(header_value, "deflate"))
|
|
||||||
{
|
|
||||||
return http::deflate_rfc1951;
|
|
||||||
}
|
|
||||||
return http::no_compression;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
/// Start the first asynchronous operation for the connection.
|
/// Start the first asynchronous operation for the connection.
|
||||||
void Connection::start()
|
void Connection::start()
|
||||||
{
|
{
|
||||||
@@ -65,8 +41,7 @@ void Connection::start()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Connection::handle_read(const boost::system::error_code &error,
|
void Connection::handle_read(const boost::system::error_code &error, std::size_t bytes_transferred)
|
||||||
std::size_t /*bytes_transferred*/)
|
|
||||||
{
|
{
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
@@ -85,48 +60,20 @@ void Connection::handle_read(const boost::system::error_code &error,
|
|||||||
timer.expires_from_now(boost::posix_time::seconds(0));
|
timer.expires_from_now(boost::posix_time::seconds(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::beast::error_code ec;
|
|
||||||
http_request_parser->put(boost::asio::buffer(incoming_data_buffer), ec);
|
|
||||||
// no error detected, let's parse the request
|
// no error detected, let's parse the request
|
||||||
http::compression_type compression_type(http::no_compression);
|
http::compression_type compression_type(http::no_compression);
|
||||||
|
RequestParser::RequestStatus result;
|
||||||
|
std::tie(result, compression_type) =
|
||||||
|
request_parser.parse(current_request,
|
||||||
|
incoming_data_buffer.data(),
|
||||||
|
incoming_data_buffer.data() + bytes_transferred);
|
||||||
|
|
||||||
if (ec)
|
// the request has been parsed
|
||||||
|
if (result == RequestParser::RequestStatus::valid)
|
||||||
{
|
{
|
||||||
if (ec == boost::beast::http::error::need_more)
|
|
||||||
{
|
|
||||||
const auto current_size = incoming_data_buffer.size();
|
|
||||||
incoming_data_buffer.resize(incoming_data_buffer.size() + CHUNK_SIZE, 0);
|
|
||||||
// we don't have a result yet, so continue reading
|
|
||||||
TCP_socket.async_read_some(
|
|
||||||
boost::asio::buffer(incoming_data_buffer.data() + current_size, CHUNK_SIZE),
|
|
||||||
boost::bind(&Connection::handle_read,
|
|
||||||
this->shared_from_this(),
|
|
||||||
boost::asio::placeholders::error,
|
|
||||||
boost::asio::placeholders::bytes_transferred));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// request is not parseable
|
|
||||||
current_reply = http::reply::stock_reply(http::reply::bad_request);
|
|
||||||
|
|
||||||
boost::asio::async_write(TCP_socket,
|
|
||||||
current_reply.to_buffers(),
|
|
||||||
boost::bind(&Connection::handle_write,
|
|
||||||
this->shared_from_this(),
|
|
||||||
boost::asio::placeholders::error));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// the request has been parsed
|
|
||||||
const auto &message = http_request_parser->get();
|
|
||||||
compression_type = select_compression(message);
|
|
||||||
|
|
||||||
fill_request(message, current_request);
|
|
||||||
|
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
current_request.endpoint = TCP_socket.remote_endpoint(ec).address();
|
current_request.endpoint = TCP_socket.remote_endpoint(ec).address();
|
||||||
|
|
||||||
if (ec)
|
if (ec)
|
||||||
{
|
{
|
||||||
util::Log(logDEBUG) << "Socket remote endpoint error: " << ec.message();
|
util::Log(logDEBUG) << "Socket remote endpoint error: " << ec.message();
|
||||||
@@ -180,6 +127,25 @@ void Connection::handle_read(const boost::system::error_code &error,
|
|||||||
this->shared_from_this(),
|
this->shared_from_this(),
|
||||||
boost::asio::placeholders::error));
|
boost::asio::placeholders::error));
|
||||||
}
|
}
|
||||||
|
else if (result == RequestParser::RequestStatus::invalid)
|
||||||
|
{ // request is not parseable
|
||||||
|
current_reply = http::reply::stock_reply(http::reply::bad_request);
|
||||||
|
|
||||||
|
boost::asio::async_write(TCP_socket,
|
||||||
|
current_reply.to_buffers(),
|
||||||
|
boost::bind(&Connection::handle_write,
|
||||||
|
this->shared_from_this(),
|
||||||
|
boost::asio::placeholders::error));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we don't have a result yet, so continue reading
|
||||||
|
TCP_socket.async_read_some(boost::asio::buffer(incoming_data_buffer),
|
||||||
|
boost::bind(&Connection::handle_read,
|
||||||
|
this->shared_from_this(),
|
||||||
|
boost::asio::placeholders::error,
|
||||||
|
boost::asio::placeholders::bytes_transferred));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle completion of a write operation.
|
/// Handle completion of a write operation.
|
||||||
@@ -192,9 +158,8 @@ void Connection::handle_write(const boost::system::error_code &error)
|
|||||||
--processed_requests;
|
--processed_requests;
|
||||||
current_request = http::request();
|
current_request = http::request();
|
||||||
current_reply = http::reply();
|
current_reply = http::reply();
|
||||||
http_request_parser.emplace();
|
request_parser = RequestParser();
|
||||||
http_request_parser->header_limit(std::numeric_limits<std::uint32_t>::max());
|
incoming_data_buffer = boost::array<char, 8192>();
|
||||||
incoming_data_buffer.resize(CHUNK_SIZE, 0);
|
|
||||||
output_buffer.clear();
|
output_buffer.clear();
|
||||||
this->start();
|
this->start();
|
||||||
}
|
}
|
||||||
@@ -255,15 +220,5 @@ std::vector<char> Connection::compress_buffers(const std::vector<char> &uncompre
|
|||||||
|
|
||||||
return compressed_data;
|
return compressed_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Connection::fill_request(const RequestParser::value_type &http_message,
|
|
||||||
http::request ¤t_request)
|
|
||||||
{
|
|
||||||
current_request.uri = http_message.target().to_string();
|
|
||||||
current_request.agent = http_message[boost::beast::http::field::user_agent].to_string();
|
|
||||||
current_request.referrer = http_message[boost::beast::http::field::referer].to_string();
|
|
||||||
current_request.connection = http_message[boost::beast::http::field::connection].to_string();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace server
|
} // namespace server
|
||||||
} // namespace osrm
|
} // namespace osrm
|
||||||
|
|||||||
@@ -0,0 +1,302 @@
|
|||||||
|
#include "server/request_parser.hpp"
|
||||||
|
|
||||||
|
#include "server/http/compression_type.hpp"
|
||||||
|
#include "server/http/header.hpp"
|
||||||
|
#include "server/http/request.hpp"
|
||||||
|
|
||||||
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace osrm
|
||||||
|
{
|
||||||
|
namespace server
|
||||||
|
{
|
||||||
|
|
||||||
|
RequestParser::RequestParser()
|
||||||
|
: state(internal_state::method_start), current_header({"", ""}),
|
||||||
|
selected_compression(http::no_compression)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::tuple<RequestParser::RequestStatus, http::compression_type>
|
||||||
|
RequestParser::parse(http::request ¤t_request, char *begin, char *end)
|
||||||
|
{
|
||||||
|
while (begin != end)
|
||||||
|
{
|
||||||
|
RequestStatus result = consume(current_request, *begin++);
|
||||||
|
if (result != RequestStatus::indeterminate)
|
||||||
|
{
|
||||||
|
return std::make_tuple(result, selected_compression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RequestStatus result = RequestStatus::indeterminate;
|
||||||
|
|
||||||
|
return std::make_tuple(result, selected_compression);
|
||||||
|
}
|
||||||
|
|
||||||
|
RequestParser::RequestStatus RequestParser::consume(http::request ¤t_request,
|
||||||
|
const char input)
|
||||||
|
{
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case internal_state::method_start:
|
||||||
|
if (!is_char(input) || is_CTL(input) || is_special(input))
|
||||||
|
{
|
||||||
|
return RequestStatus::invalid;
|
||||||
|
}
|
||||||
|
state = internal_state::method;
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
case internal_state::method:
|
||||||
|
if (input == ' ')
|
||||||
|
{
|
||||||
|
state = internal_state::uri;
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
}
|
||||||
|
if (!is_char(input) || is_CTL(input) || is_special(input))
|
||||||
|
{
|
||||||
|
return RequestStatus::invalid;
|
||||||
|
}
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
case internal_state::uri_start:
|
||||||
|
if (is_CTL(input))
|
||||||
|
{
|
||||||
|
return RequestStatus::invalid;
|
||||||
|
}
|
||||||
|
state = internal_state::uri;
|
||||||
|
current_request.uri.push_back(input);
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
case internal_state::uri:
|
||||||
|
if (input == ' ')
|
||||||
|
{
|
||||||
|
state = internal_state::http_version_h;
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
}
|
||||||
|
if (is_CTL(input))
|
||||||
|
{
|
||||||
|
return RequestStatus::invalid;
|
||||||
|
}
|
||||||
|
current_request.uri.push_back(input);
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
case internal_state::http_version_h:
|
||||||
|
if (input == 'H')
|
||||||
|
{
|
||||||
|
state = internal_state::http_version_t_1;
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
}
|
||||||
|
return RequestStatus::invalid;
|
||||||
|
case internal_state::http_version_t_1:
|
||||||
|
if (input == 'T')
|
||||||
|
{
|
||||||
|
state = internal_state::http_version_t_2;
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
}
|
||||||
|
return RequestStatus::invalid;
|
||||||
|
case internal_state::http_version_t_2:
|
||||||
|
if (input == 'T')
|
||||||
|
{
|
||||||
|
state = internal_state::http_version_p;
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
}
|
||||||
|
return RequestStatus::invalid;
|
||||||
|
case internal_state::http_version_p:
|
||||||
|
if (input == 'P')
|
||||||
|
{
|
||||||
|
state = internal_state::http_version_slash;
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
}
|
||||||
|
return RequestStatus::invalid;
|
||||||
|
case internal_state::http_version_slash:
|
||||||
|
if (input == '/')
|
||||||
|
{
|
||||||
|
state = internal_state::http_version_major_start;
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
}
|
||||||
|
return RequestStatus::invalid;
|
||||||
|
case internal_state::http_version_major_start:
|
||||||
|
if (is_digit(input))
|
||||||
|
{
|
||||||
|
state = internal_state::http_version_major;
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
}
|
||||||
|
return RequestStatus::invalid;
|
||||||
|
case internal_state::http_version_major:
|
||||||
|
if (input == '.')
|
||||||
|
{
|
||||||
|
state = internal_state::http_version_minor_start;
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
}
|
||||||
|
if (is_digit(input))
|
||||||
|
{
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
}
|
||||||
|
return RequestStatus::invalid;
|
||||||
|
case internal_state::http_version_minor_start:
|
||||||
|
if (is_digit(input))
|
||||||
|
{
|
||||||
|
state = internal_state::http_version_minor;
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
}
|
||||||
|
return RequestStatus::invalid;
|
||||||
|
case internal_state::http_version_minor:
|
||||||
|
if (input == '\r')
|
||||||
|
{
|
||||||
|
state = internal_state::expecting_newline_1;
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
}
|
||||||
|
if (is_digit(input))
|
||||||
|
{
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
}
|
||||||
|
return RequestStatus::invalid;
|
||||||
|
case internal_state::expecting_newline_1:
|
||||||
|
if (input == '\n')
|
||||||
|
{
|
||||||
|
state = internal_state::header_line_start;
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
}
|
||||||
|
return RequestStatus::invalid;
|
||||||
|
case internal_state::header_line_start:
|
||||||
|
if (boost::iequals(current_header.name, "Accept-Encoding"))
|
||||||
|
{
|
||||||
|
/* giving gzip precedence over deflate */
|
||||||
|
if (boost::icontains(current_header.value, "deflate"))
|
||||||
|
{
|
||||||
|
selected_compression = http::deflate_rfc1951;
|
||||||
|
}
|
||||||
|
if (boost::icontains(current_header.value, "gzip"))
|
||||||
|
{
|
||||||
|
selected_compression = http::gzip_rfc1952;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (boost::iequals(current_header.name, "Referer"))
|
||||||
|
{
|
||||||
|
current_request.referrer = current_header.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (boost::iequals(current_header.name, "User-Agent"))
|
||||||
|
{
|
||||||
|
current_request.agent = current_header.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (boost::iequals(current_header.name, "Connection"))
|
||||||
|
{
|
||||||
|
current_request.connection = current_header.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input == '\r')
|
||||||
|
{
|
||||||
|
state = internal_state::expecting_newline_3;
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
}
|
||||||
|
if (!is_char(input) || is_CTL(input) || is_special(input))
|
||||||
|
{
|
||||||
|
return RequestStatus::invalid;
|
||||||
|
}
|
||||||
|
state = internal_state::header_name;
|
||||||
|
current_header.clear();
|
||||||
|
current_header.name.push_back(input);
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
case internal_state::header_lws:
|
||||||
|
if (input == '\r')
|
||||||
|
{
|
||||||
|
state = internal_state::expecting_newline_2;
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
}
|
||||||
|
if (input == ' ' || input == '\t')
|
||||||
|
{
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
}
|
||||||
|
if (is_CTL(input))
|
||||||
|
{
|
||||||
|
return RequestStatus::invalid;
|
||||||
|
}
|
||||||
|
state = internal_state::header_value;
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
case internal_state::header_name:
|
||||||
|
if (input == ':')
|
||||||
|
{
|
||||||
|
state = internal_state::header_value;
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
}
|
||||||
|
if (!is_char(input) || is_CTL(input) || is_special(input))
|
||||||
|
{
|
||||||
|
return RequestStatus::invalid;
|
||||||
|
}
|
||||||
|
current_header.name.push_back(input);
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
case internal_state::header_value:
|
||||||
|
if (input == ' ')
|
||||||
|
{
|
||||||
|
state = internal_state::header_value;
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
}
|
||||||
|
if (input == '\r')
|
||||||
|
{
|
||||||
|
state = internal_state::expecting_newline_2;
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
}
|
||||||
|
if (is_CTL(input))
|
||||||
|
{
|
||||||
|
return RequestStatus::invalid;
|
||||||
|
}
|
||||||
|
current_header.value.push_back(input);
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
case internal_state::expecting_newline_2:
|
||||||
|
if (input == '\n')
|
||||||
|
{
|
||||||
|
state = internal_state::header_line_start;
|
||||||
|
return RequestStatus::indeterminate;
|
||||||
|
}
|
||||||
|
return RequestStatus::invalid;
|
||||||
|
default: // expecting_newline_3
|
||||||
|
return input == '\n' ? RequestStatus::valid : RequestStatus::invalid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RequestParser::is_char(const int character) const
|
||||||
|
{
|
||||||
|
return character >= 0 && character <= 127;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RequestParser::is_CTL(const int character) const
|
||||||
|
{
|
||||||
|
return (character >= 0 && character <= 31) || (character == 127);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RequestParser::is_special(const int character) const
|
||||||
|
{
|
||||||
|
switch (character)
|
||||||
|
{
|
||||||
|
case '(':
|
||||||
|
case ')':
|
||||||
|
case '<':
|
||||||
|
case '>':
|
||||||
|
case '@':
|
||||||
|
case ',':
|
||||||
|
case ';':
|
||||||
|
case ':':
|
||||||
|
case '\\':
|
||||||
|
case '"':
|
||||||
|
case '/':
|
||||||
|
case '[':
|
||||||
|
case ']':
|
||||||
|
case '?':
|
||||||
|
case '=':
|
||||||
|
case '{':
|
||||||
|
case '}':
|
||||||
|
case ' ':
|
||||||
|
case '\t':
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RequestParser::is_digit(const int character) const
|
||||||
|
{
|
||||||
|
return character >= '0' && character <= '9';
|
||||||
|
}
|
||||||
|
} // namespace server
|
||||||
|
} // namespace osrm
|
||||||
+63
-46
@@ -84,7 +84,7 @@ inline SegmentDuration convertToDuration(double speed_in_kmh, double distance_in
|
|||||||
const auto speed_in_ms = speed_in_kmh / 3.6;
|
const auto speed_in_ms = speed_in_kmh / 3.6;
|
||||||
const auto duration = distance_in_meters / speed_in_ms;
|
const auto duration = distance_in_meters / speed_in_ms;
|
||||||
auto segment_duration = std::max<SegmentDuration>(
|
auto segment_duration = std::max<SegmentDuration>(
|
||||||
1, boost::numeric_cast<SegmentDuration>(std::round(duration * 10.)));
|
{1}, {boost::numeric_cast<SegmentDuration::value_type>(std::round(duration * 10.))});
|
||||||
if (segment_duration >= INVALID_SEGMENT_DURATION)
|
if (segment_duration >= INVALID_SEGMENT_DURATION)
|
||||||
{
|
{
|
||||||
util::Log(logWARNING) << "Clamping segment duration " << segment_duration << " to "
|
util::Log(logWARNING) << "Clamping segment duration " << segment_duration << " to "
|
||||||
@@ -114,7 +114,8 @@ void checkWeightsConsistency(
|
|||||||
{
|
{
|
||||||
auto range = segment_data.GetForwardWeights(geometry_id.id);
|
auto range = segment_data.GetForwardWeights(geometry_id.id);
|
||||||
// NOLINTNEXTLINE(bugprone-fold-init-type)
|
// NOLINTNEXTLINE(bugprone-fold-init-type)
|
||||||
EdgeWeight weight = std::accumulate(range.begin(), range.end(), EdgeWeight{0});
|
EdgeWeight weight = alias_cast<EdgeWeight>(
|
||||||
|
std::accumulate(range.begin(), range.end(), SegmentWeight{0}));
|
||||||
if (weight > edge.data.weight)
|
if (weight > edge.data.weight)
|
||||||
{
|
{
|
||||||
util::Log(logWARNING) << geometry_id.id << " vs " << edge.data.turn_id << ":"
|
util::Log(logWARNING) << geometry_id.id << " vs " << edge.data.turn_id << ":"
|
||||||
@@ -125,7 +126,8 @@ void checkWeightsConsistency(
|
|||||||
{
|
{
|
||||||
auto range = segment_data.GetReverseWeights(geometry_id.id);
|
auto range = segment_data.GetReverseWeights(geometry_id.id);
|
||||||
// NOLINTNEXTLINE(bugprone-fold-init-type)
|
// NOLINTNEXTLINE(bugprone-fold-init-type)
|
||||||
EdgeWeight weight = std::accumulate(range.begin(), range.end(), EdgeWeight{0});
|
EdgeWeight weight = alias_cast<EdgeWeight>(
|
||||||
|
std::accumulate(range.begin(), range.end(), SegmentWeight{0}));
|
||||||
if (weight > edge.data.weight)
|
if (weight > edge.data.weight)
|
||||||
{
|
{
|
||||||
util::Log(logWARNING) << geometry_id.id << " vs " << edge.data.turn_id << ":"
|
util::Log(logWARNING) << geometry_id.id << " vs " << edge.data.turn_id << ":"
|
||||||
@@ -185,8 +187,10 @@ updateSegmentData(const UpdaterConfig &config,
|
|||||||
|
|
||||||
const auto weight_multiplier = profile_properties.GetWeightMultiplier();
|
const auto weight_multiplier = profile_properties.GetWeightMultiplier();
|
||||||
const auto weight = distance_in_meters / rate;
|
const auto weight = distance_in_meters / rate;
|
||||||
auto segment_weight = std::max<SegmentWeight>(
|
auto segment_weight =
|
||||||
1, boost::numeric_cast<SegmentWeight>(std::round(weight * weight_multiplier)));
|
std::max<SegmentWeight>({1},
|
||||||
|
{boost::numeric_cast<SegmentWeight::value_type>(
|
||||||
|
std::round(weight * weight_multiplier))});
|
||||||
if (segment_weight >= INVALID_SEGMENT_WEIGHT)
|
if (segment_weight >= INVALID_SEGMENT_WEIGHT)
|
||||||
{
|
{
|
||||||
util::Log(logWARNING) << "Clamping segment weight " << segment_weight << " to "
|
util::Log(logWARNING) << "Clamping segment weight " << segment_weight << " to "
|
||||||
@@ -356,18 +360,21 @@ updateSegmentData(const UpdaterConfig &config,
|
|||||||
if (new_fwd_datasources_range[segment_offset] == LUA_SOURCE)
|
if (new_fwd_datasources_range[segment_offset] == LUA_SOURCE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (old_fwd_durations_range[segment_offset] >=
|
SegmentDuration old_fwd_duration = old_fwd_durations_range[segment_offset];
|
||||||
(new_fwd_durations_range[segment_offset] * config.log_edge_updates_factor))
|
SegmentDuration new_fwd_duration = new_fwd_durations_range[segment_offset];
|
||||||
|
|
||||||
|
if (old_fwd_duration >=
|
||||||
|
to_alias<SegmentDuration>(from_alias<double>(new_fwd_duration) *
|
||||||
|
config.log_edge_updates_factor))
|
||||||
{
|
{
|
||||||
auto from = osm_node_ids[nodes_range[segment_offset]];
|
auto from = osm_node_ids[nodes_range[segment_offset]];
|
||||||
auto to = osm_node_ids[nodes_range[segment_offset + 1]];
|
auto to = osm_node_ids[nodes_range[segment_offset + 1]];
|
||||||
util::Log(logWARNING)
|
util::Log(logWARNING) << "[weight updates] Edge weight update from "
|
||||||
<< "[weight updates] Edge weight update from "
|
<< from_alias<double>(old_fwd_duration) / 10. << "s to "
|
||||||
<< old_fwd_durations_range[segment_offset] / 10. << "s to "
|
<< from_alias<double>(new_fwd_duration) / 10.
|
||||||
<< new_fwd_durations_range[segment_offset] / 10. << "s Segment: " << from
|
<< "s Segment: " << from << "," << to << " based on "
|
||||||
<< "," << to << " based on "
|
<< config.segment_speed_lookup_paths
|
||||||
<< config.segment_speed_lookup_paths
|
[new_fwd_datasources_range[segment_offset] - 1];
|
||||||
[new_fwd_datasources_range[segment_offset] - 1];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,18 +384,21 @@ updateSegmentData(const UpdaterConfig &config,
|
|||||||
if (new_rev_datasources_range[segment_offset] == LUA_SOURCE)
|
if (new_rev_datasources_range[segment_offset] == LUA_SOURCE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (old_rev_durations_range[segment_offset] >=
|
SegmentDuration old_rev_duration = old_rev_durations_range[segment_offset];
|
||||||
(new_rev_durations_range[segment_offset] * config.log_edge_updates_factor))
|
SegmentDuration new_rev_duration = new_rev_durations_range[segment_offset];
|
||||||
|
|
||||||
|
if (old_rev_duration >=
|
||||||
|
to_alias<SegmentDuration>(from_alias<double>(new_rev_duration) *
|
||||||
|
config.log_edge_updates_factor))
|
||||||
{
|
{
|
||||||
auto from = osm_node_ids[nodes_range[segment_offset + 1]];
|
auto from = osm_node_ids[nodes_range[segment_offset + 1]];
|
||||||
auto to = osm_node_ids[nodes_range[segment_offset]];
|
auto to = osm_node_ids[nodes_range[segment_offset]];
|
||||||
util::Log(logWARNING)
|
util::Log(logWARNING) << "[weight updates] Edge weight update from "
|
||||||
<< "[weight updates] Edge weight update from "
|
<< from_alias<double>(old_rev_duration) / 10. << "s to "
|
||||||
<< old_rev_durations_range[segment_offset] / 10. << "s to "
|
<< from_alias<double>(new_rev_duration) / 10.
|
||||||
<< new_rev_durations_range[segment_offset] / 10. << "s Segment: " << from
|
<< "s Segment: " << from << "," << to << " based on "
|
||||||
<< "," << to << " based on "
|
<< config.segment_speed_lookup_paths
|
||||||
<< config.segment_speed_lookup_paths
|
[new_rev_datasources_range[segment_offset] - 1];
|
||||||
[new_rev_datasources_range[segment_offset] - 1];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -455,18 +465,20 @@ updateTurnPenalties(const UpdaterConfig &config,
|
|||||||
|
|
||||||
if (auto value = turn_penalty_lookup(osm_turn))
|
if (auto value = turn_penalty_lookup(osm_turn))
|
||||||
{
|
{
|
||||||
turn_duration_penalty =
|
turn_duration_penalty = {
|
||||||
boost::numeric_cast<TurnPenalty>(std::round(value->duration * 10.));
|
boost::numeric_cast<TurnPenalty::value_type>(std::round(value->duration * 10.))};
|
||||||
turn_weight_penalty = boost::numeric_cast<TurnPenalty>(std::round(
|
turn_weight_penalty = {boost::numeric_cast<TurnPenalty::value_type>(
|
||||||
std::isfinite(value->weight) ? value->weight * weight_multiplier
|
std::round(std::isfinite(value->weight)
|
||||||
: turn_duration_penalty * weight_multiplier / 10.));
|
? value->weight * weight_multiplier
|
||||||
|
: from_alias<TurnPenalty::value_type>(turn_duration_penalty) *
|
||||||
|
weight_multiplier / 10.))};
|
||||||
|
|
||||||
turn_duration_penalties[edge_index] = turn_duration_penalty;
|
turn_duration_penalties[edge_index] = turn_duration_penalty;
|
||||||
turn_weight_penalties[edge_index] = turn_weight_penalty;
|
turn_weight_penalties[edge_index] = turn_weight_penalty;
|
||||||
updated_turns.push_back(edge_index);
|
updated_turns.push_back(edge_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (turn_weight_penalty < 0)
|
if (turn_weight_penalty < TurnPenalty{0})
|
||||||
{
|
{
|
||||||
util::Log(logWARNING) << "Negative turn penalty at " << osm_turn.from << ", "
|
util::Log(logWARNING) << "Negative turn penalty at " << osm_turn.from << ", "
|
||||||
<< osm_turn.via << ", " << osm_turn.to << ": turn penalty "
|
<< osm_turn.via << ", " << osm_turn.to << ": turn penalty "
|
||||||
@@ -674,42 +686,44 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
|
|||||||
return std::tie(lhs.id, lhs.forward) < std::tie(rhs.id, rhs.forward);
|
return std::tie(lhs.id, lhs.forward) < std::tie(rhs.id, rhs.forward);
|
||||||
});
|
});
|
||||||
|
|
||||||
using WeightAndDuration = std::tuple<EdgeWeight, EdgeWeight>;
|
using WeightAndDuration = std::tuple<EdgeWeight, EdgeDuration>;
|
||||||
const auto compute_new_weight_and_duration =
|
const auto compute_new_weight_and_duration =
|
||||||
[&](const GeometryID geometry_id) -> WeightAndDuration {
|
[&](const GeometryID geometry_id) -> WeightAndDuration {
|
||||||
EdgeWeight new_weight = 0;
|
EdgeWeight new_weight = {0};
|
||||||
EdgeWeight new_duration = 0;
|
EdgeDuration new_duration = {0};
|
||||||
if (geometry_id.forward)
|
if (geometry_id.forward)
|
||||||
{
|
{
|
||||||
const auto weights = segment_data.GetForwardWeights(geometry_id.id);
|
const auto weights = segment_data.GetForwardWeights(geometry_id.id);
|
||||||
for (const auto weight : weights)
|
for (const SegmentWeight weight : weights)
|
||||||
{
|
{
|
||||||
if (weight == INVALID_SEGMENT_WEIGHT)
|
if (weight == INVALID_SEGMENT_WEIGHT)
|
||||||
{
|
{
|
||||||
new_weight = INVALID_EDGE_WEIGHT;
|
new_weight = INVALID_EDGE_WEIGHT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
new_weight += weight;
|
new_weight += alias_cast<EdgeWeight>(weight);
|
||||||
}
|
}
|
||||||
const auto durations = segment_data.GetForwardDurations(geometry_id.id);
|
const auto durations = segment_data.GetForwardDurations(geometry_id.id);
|
||||||
// NOLINTNEXTLINE(bugprone-fold-init-type)
|
// NOLINTNEXTLINE(bugprone-fold-init-type)
|
||||||
new_duration = std::accumulate(durations.begin(), durations.end(), EdgeWeight{0});
|
new_duration = alias_cast<EdgeDuration>(
|
||||||
|
std::accumulate(durations.begin(), durations.end(), SegmentDuration{0}));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const auto weights = segment_data.GetReverseWeights(geometry_id.id);
|
const auto weights = segment_data.GetReverseWeights(geometry_id.id);
|
||||||
for (const auto weight : weights)
|
for (const SegmentWeight weight : weights)
|
||||||
{
|
{
|
||||||
if (weight == INVALID_SEGMENT_WEIGHT)
|
if (weight == INVALID_SEGMENT_WEIGHT)
|
||||||
{
|
{
|
||||||
new_weight = INVALID_EDGE_WEIGHT;
|
new_weight = INVALID_EDGE_WEIGHT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
new_weight += weight;
|
new_weight += alias_cast<EdgeWeight>(SegmentWeight(weight));
|
||||||
}
|
}
|
||||||
const auto durations = segment_data.GetReverseDurations(geometry_id.id);
|
const auto durations = segment_data.GetReverseDurations(geometry_id.id);
|
||||||
// NOLINTNEXTLINE(bugprone-fold-init-type)
|
// NOLINTNEXTLINE(bugprone-fold-init-type)
|
||||||
new_duration = std::accumulate(durations.begin(), durations.end(), EdgeWeight{0});
|
new_duration = alias_cast<EdgeDuration>(
|
||||||
|
std::accumulate(durations.begin(), durations.end(), SegmentDuration{0}));
|
||||||
}
|
}
|
||||||
return std::make_tuple(new_weight, new_duration);
|
return std::make_tuple(new_weight, new_duration);
|
||||||
};
|
};
|
||||||
@@ -740,7 +754,7 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
|
|||||||
// Find a segment with zero speed and simultaneously compute the new edge
|
// Find a segment with zero speed and simultaneously compute the new edge
|
||||||
// weight
|
// weight
|
||||||
EdgeWeight new_weight;
|
EdgeWeight new_weight;
|
||||||
EdgeWeight new_duration;
|
EdgeDuration new_duration;
|
||||||
std::tie(new_weight, new_duration) =
|
std::tie(new_weight, new_duration) =
|
||||||
accumulated_segment_data[updated_iter - updated_segments.begin()];
|
accumulated_segment_data[updated_iter - updated_segments.begin()];
|
||||||
|
|
||||||
@@ -749,7 +763,9 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
|
|||||||
// but we should always assign the same value here.
|
// but we should always assign the same value here.
|
||||||
BOOST_ASSERT(edge.source < node_weights.size());
|
BOOST_ASSERT(edge.source < node_weights.size());
|
||||||
node_weights[edge.source] =
|
node_weights[edge.source] =
|
||||||
node_weights[edge.source] & 0x80000000 ? new_weight | 0x80000000 : new_weight;
|
from_alias<EdgeWeight::value_type>(node_weights[edge.source]) & 0x80000000
|
||||||
|
? new_weight | EdgeWeight{static_cast<EdgeWeight::value_type>(0x80000000)}
|
||||||
|
: new_weight;
|
||||||
node_durations[edge.source] = new_duration;
|
node_durations[edge.source] = new_duration;
|
||||||
|
|
||||||
// We found a zero-speed edge, so we'll skip this whole edge-based-edge
|
// We found a zero-speed edge, so we'll skip this whole edge-based-edge
|
||||||
@@ -765,15 +781,15 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
|
|||||||
auto turn_weight_penalty = turn_weight_penalties[edge.data.turn_id];
|
auto turn_weight_penalty = turn_weight_penalties[edge.data.turn_id];
|
||||||
auto turn_duration_penalty = turn_duration_penalties[edge.data.turn_id];
|
auto turn_duration_penalty = turn_duration_penalties[edge.data.turn_id];
|
||||||
const auto num_nodes = segment_data.GetForwardGeometry(geometry_id.id).size();
|
const auto num_nodes = segment_data.GetForwardGeometry(geometry_id.id).size();
|
||||||
const auto weight_min_value = static_cast<EdgeWeight>(num_nodes);
|
const auto weight_min_value = to_alias<EdgeWeight>(num_nodes);
|
||||||
if (turn_weight_penalty + new_weight < weight_min_value)
|
if (alias_cast<EdgeWeight>(turn_weight_penalty) + new_weight < weight_min_value)
|
||||||
{
|
{
|
||||||
if (turn_weight_penalty < 0)
|
if (turn_weight_penalty < TurnPenalty{0})
|
||||||
{
|
{
|
||||||
util::Log(logWARNING)
|
util::Log(logWARNING)
|
||||||
<< "turn penalty " << turn_weight_penalty
|
<< "turn penalty " << turn_weight_penalty
|
||||||
<< " is too negative: clamping turn weight to " << weight_min_value;
|
<< " is too negative: clamping turn weight to " << weight_min_value;
|
||||||
turn_weight_penalty = weight_min_value - new_weight;
|
turn_weight_penalty = alias_cast<TurnPenalty>(weight_min_value - new_weight);
|
||||||
turn_weight_penalties[edge.data.turn_id] = turn_weight_penalty;
|
turn_weight_penalties[edge.data.turn_id] = turn_weight_penalty;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -783,8 +799,9 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update edge weight
|
// Update edge weight
|
||||||
edge.data.weight = new_weight + turn_weight_penalty;
|
edge.data.weight = new_weight + alias_cast<EdgeWeight>(turn_weight_penalty);
|
||||||
edge.data.duration = new_duration + turn_duration_penalty;
|
edge.data.duration = from_alias<EdgeDuration::value_type>(
|
||||||
|
new_duration + alias_cast<EdgeDuration>(turn_duration_penalty));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -125,6 +125,8 @@
|
|||||||
{"key": "side_road", "value": "rotary", "description": "gets speed penalty"},
|
{"key": "side_road", "value": "rotary", "description": "gets speed penalty"},
|
||||||
{"key": "route", "object_types": ["way"]},
|
{"key": "route", "object_types": ["way"]},
|
||||||
{"key": "highway", "value": "traffic_signals", "object_types": ["node"]},
|
{"key": "highway", "value": "traffic_signals", "object_types": ["node"]},
|
||||||
|
{"key": "highway", "value": "stop", "object_types": ["node"]},
|
||||||
|
{"key": "highway", "value": "give_way", "object_types": ["node"]},
|
||||||
{"key": "highway", "value": "crossing", "object_types": ["node"]},
|
{"key": "highway", "value": "crossing", "object_types": ["node"]},
|
||||||
{"key": "access", "value": "yes"},
|
{"key": "access", "value": "yes"},
|
||||||
{"key": "access", "value": "motorcar"},
|
{"key": "access", "value": "motorcar"},
|
||||||
|
|||||||
+10
-4
@@ -286,9 +286,9 @@ test('route: routes Monaco with several (duration, distance, nodes) annotations
|
|||||||
assert.ok(first.routes[0].legs.every(l => { return l.annotation.distance;}), 'every leg has annotations for distance');
|
assert.ok(first.routes[0].legs.every(l => { return l.annotation.distance;}), 'every leg has annotations for distance');
|
||||||
assert.ok(first.routes[0].legs.every(l => { return l.annotation.duration;}), 'every leg has annotations for durations');
|
assert.ok(first.routes[0].legs.every(l => { return l.annotation.duration;}), 'every leg has annotations for durations');
|
||||||
assert.ok(first.routes[0].legs.every(l => { return l.annotation.nodes;}), 'every leg has annotations for nodes');
|
assert.ok(first.routes[0].legs.every(l => { return l.annotation.nodes;}), 'every leg has annotations for nodes');
|
||||||
assert.notOk(first.routes[0].legs.every(l => { return l.annotation.weight; }), 'has no annotations for weight')
|
assert.notOk(first.routes[0].legs.every(l => { return l.annotation.weight; }), 'has no annotations for weight');
|
||||||
assert.notOk(first.routes[0].legs.every(l => { return l.annotation.datasources; }), 'has no annotations for datasources')
|
assert.notOk(first.routes[0].legs.every(l => { return l.annotation.datasources; }), 'has no annotations for datasources');
|
||||||
assert.notOk(first.routes[0].legs.every(l => { return l.annotation.speed; }), 'has no annotations for speed')
|
assert.notOk(first.routes[0].legs.every(l => { return l.annotation.speed; }), 'has no annotations for speed');
|
||||||
|
|
||||||
options.overview = 'full';
|
options.overview = 'full';
|
||||||
osrm.route(options, function(err, full) {
|
osrm.route(options, function(err, full) {
|
||||||
@@ -303,7 +303,7 @@ test('route: routes Monaco with several (duration, distance, nodes) annotations
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('route: routes Monaco with options', function(assert) {
|
test('route: routes Monaco with options', function(assert) {
|
||||||
assert.plan(11);
|
assert.plan(17);
|
||||||
var osrm = new OSRM(monaco_path);
|
var osrm = new OSRM(monaco_path);
|
||||||
var options = {
|
var options = {
|
||||||
coordinates: two_test_coordinates,
|
coordinates: two_test_coordinates,
|
||||||
@@ -322,6 +322,12 @@ test('route: routes Monaco with options', function(assert) {
|
|||||||
assert.ok(first.routes[0].legs[0]);
|
assert.ok(first.routes[0].legs[0]);
|
||||||
assert.ok(first.routes[0].legs.every(l => { return l.steps.length > 0; }), 'every leg has steps');
|
assert.ok(first.routes[0].legs.every(l => { return l.steps.length > 0; }), 'every leg has steps');
|
||||||
assert.ok(first.routes[0].legs.every(l => { return l.annotation;}), 'every leg has annotations');
|
assert.ok(first.routes[0].legs.every(l => { return l.annotation;}), 'every leg has annotations');
|
||||||
|
assert.ok(first.routes[0].legs.every(l => { return l.annotation.distance;}), 'every leg has annotations for distance');
|
||||||
|
assert.ok(first.routes[0].legs.every(l => { return l.annotation.duration;}), 'every leg has annotations for durations');
|
||||||
|
assert.ok(first.routes[0].legs.every(l => { return l.annotation.nodes;}), 'every leg has annotations for nodes');
|
||||||
|
assert.ok(first.routes[0].legs.every(l => { return l.annotation.weight; }), 'every leg has annotations for weight');
|
||||||
|
assert.ok(first.routes[0].legs.every(l => { return l.annotation.datasources; }), 'every leg has annotations for datasources');
|
||||||
|
assert.ok(first.routes[0].legs.every(l => { return l.annotation.speed; }), 'every leg has annotations for speed');
|
||||||
|
|
||||||
options.overview = 'full';
|
options.overview = 'full';
|
||||||
osrm.route(options, function(err, full) {
|
osrm.route(options, function(err, full) {
|
||||||
|
|||||||
@@ -80,6 +80,30 @@ test('table: returns buffer', function(assert) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('table: throws on invalid snapping values', function (assert) {
|
||||||
|
assert.plan(1);
|
||||||
|
var osrm = new OSRM(data_path);
|
||||||
|
var options = {
|
||||||
|
coordinates: [three_test_coordinates[0], three_test_coordinates[1]],
|
||||||
|
snapping: 'zing'
|
||||||
|
};
|
||||||
|
assert.throws(function () { osrm.table(options, function (err, response) { }); },
|
||||||
|
/'snapping' param must be one of \[default, any\]/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('table: snapping parameter passed through OK', function (assert) {
|
||||||
|
assert.plan(2);
|
||||||
|
var osrm = new OSRM(data_path);
|
||||||
|
var options = {
|
||||||
|
coordinates: [three_test_coordinates[0], three_test_coordinates[1]],
|
||||||
|
snapping: 'any'
|
||||||
|
};
|
||||||
|
osrm.table(options, function(err, table) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.ok(table['durations'], 'distances table result should exist');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
var tables = ['distances', 'durations'];
|
var tables = ['distances', 'durations'];
|
||||||
|
|
||||||
tables.forEach(function(annotation) {
|
tables.forEach(function(annotation) {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user