Compare commits

..

34 Commits

Author SHA1 Message Date
Siarhei Fedartsou 04ee126297 Take stop signs into account during routing 2022-10-31 22:24:22 +01:00
Siarhei Fedartsou 3f7a629db8 Take stop signs into account during routing 2022-10-31 22:22:40 +01:00
Siarhei Fedartsou 750826215f Take stop signs into account during routing 2022-10-31 22:00:24 +01:00
Siarhei Fedartsou ee008e75e5 Take stop signs into account during routing 2022-10-31 21:58:36 +01:00
Siarhei Fedartsou 3080be59ed Take stop signs into account during routing 2022-10-31 21:58:18 +01:00
Siarhei Fedartsou a7142ee737 Take stop signs into account during routing 2022-10-31 21:47:48 +01:00
Siarhei Fedartsou eb72ca4941 Merge branch 'master' into sf-stop-sign 2022-10-31 21:47:36 +01:00
Siarhei Fedartsou b887e72d0b Take stop signs into account during routing 2022-10-31 21:45:20 +01:00
Siarhei Fedartsou be1b86657c Take stop signs into account during routing 2022-10-31 21:36:08 +01:00
Siarhei Fedartsou 62298cf409 Take stop signs into account during routing 2022-10-31 17:30:15 +01:00
Siarhei Fedartsou afe34456b9 Delete CloudFormation templates (#6435)
There is no need in them - it seems they were needed to manage some Mapbox S3 bucket which we have no access to anyway.
2022-10-31 13:22:13 +01:00
Dennis Luxen 2f75d6f22b Merge pull request #6429 from Project-OSRM/less_boost_unordered
Replace boost::unordered_{map/set} with std, also remove code duplication
2022-10-30 22:17:48 +01:00
Siarhei Fedartsou c28a6832d7 Take stop signs into account during routing 2022-10-30 11:59:33 +01:00
Dennis Luxen 061f0a1f14 Fix includes 2022-10-30 11:43:28 +01:00
Dennis Luxen 60e283312c Fix typo historgram -> histogram (#6427) 2022-10-30 08:34:00 +01:00
Dennis Luxen f97e18d285 Fix formatting 2022-10-29 23:01:38 +02:00
Dennis Luxen 7b73b977ff Replace boost::unordered_{map/set} with std, also remove code duplication 2022-10-29 22:57:14 +02:00
Siarhei Fedartsou 97883178fa Take stop signs into account during routing 2022-10-28 23:03:51 +02:00
Siarhei Fedartsou 350862d177 Take stop signs into account during routing 2022-10-28 22:59:46 +02:00
Siarhei Fedartsou 4432756de1 Take stop signs into account during routing 2022-10-28 22:30:50 +02:00
Siarhei Fedartsou 3558ec9db4 Take stop signs into account during routing 2022-10-28 22:16:00 +02:00
Siarhei Fedartsou 36f3a5eec8 Take stop signs into account during routing 2022-10-28 22:04:02 +02:00
Michael Bell 5d468f2897 Make edge metrics strongly typed (#6421)
This change takes the existing typedefs for weight, duration and
distance, and makes them proper types, using the existing Alias
functionality.

Primarily this is to prevent bugs where the metrics are switched,
but it also adds additional documentation. For example, it now
makes it clear (despite the naming of variables) that most of the
trip algorithm is running on the duration metric.

I've not made any changes to the casts performed between metrics
and numeric types, they now just more explicit.
2022-10-28 15:16:12 +01:00
Siarhei Fedartsou 72ea34f3b7 Take stop signs into account during routing 2022-10-28 09:47:43 +02:00
Siarhei Fedartsou 7f635f2ed6 Take stop signs into account during routing 2022-10-27 21:39:21 +02:00
Siarhei Fedartsou 8a4af59838 wip 2022-10-27 21:13:57 +02:00
Siarhei Fedartsou 16685d0de9 Add link to Discord server (#6422) 2022-10-26 11:22:28 +02:00
Siarhei Fedartsou 82897791d1 Update actions/cache to v3 (#6420) 2022-10-24 00:52:15 +02:00
Michael Bell 9ad432c5b2 Fix adding traffic signal penalties during compression (#6419)
Weight and duration penalties are flipped in the lambda function
that applies penalties from traffic signals.

Duration is in deciseconds, whilst weight is multipled by
10^weight_precision, with weight_precision being 1 by default.

Therefore, for default routability profile, the penalties end up
being the same, hence why no tests picked this up.

If distance weight is used however, it will incorrectly apply an
additional penalty to the weight, and not add the traffic signal
delay to the duration in the routing graph.

To confuse things further, in some API responses the values are
correct because they use geometry data instead, but it's still
possible that a sub-optimal route was selected.

However, given the distance weight is in meters, and the additional
penalty per traffic light would be 20, it's unlikely this would
have changed the routing results.

In any case, we correct the function to apply the arguments correctly.
2022-10-23 14:59:12 +01:00
Siarhei Fedartsou c1d2c15995 Handle snapping parameter for all plugins in NodeJs bindings, but not for Route only (#6417) 2022-10-22 16:49:35 +02:00
Siarhei Fedartsou fb1bb7a15b Fix annotations=true handling in NodeJS bindings & libosrm (#6415) 2022-10-19 08:35:18 +02:00
Siarhei Fedartsou d65e8c7d1e Fix bindings compilation on latest Node (#6416) 2022-10-18 21:59:39 +02:00
Michael Bell 5e5f1f4add 5.27.1 release (#6409)
* Bookkeeping for 5.27.1 release

* Reset for next release
2022-10-14 23:04:41 +01:00
Siarhei Fedartsou 9d160a9b5d Revert back to using custom HTTP parser instead of Boost.Beast (#6407) 2022-10-14 14:37:33 +02:00
115 changed files with 2497 additions and 1740 deletions
File diff suppressed because it is too large Load Diff
+14
View File
@@ -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
View File
@@ -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}")
+3 -3
View File
@@ -1,8 +1,7 @@
## Open Source Routing Machine ## Open Source Routing Machine
| Linux / macOS / Windows | Code Coverage |
| ----------------------- | ------------- | [![osrm-backend CI](https://github.com/Project-OSRM/osrm-backend/actions/workflows/osrm-backend.yml/badge.svg)](https://github.com/Project-OSRM/osrm-backend/actions/workflows/osrm-backend.yml) [![Codecov](https://codecov.io/gh/Project-OSRM/osrm-backend/branch/master/graph/badge.svg)](https://codecov.io/gh/Project-OSRM/osrm-backend) [![Discord](https://img.shields.io/discord/1034487840219860992)](https://discord.gg/es9CdcCXcb)
| [![osrm-backend CI](https://github.com/Project-OSRM/osrm-backend/actions/workflows/osrm-backend.yml/badge.svg)](https://github.com/Project-OSRM/osrm-backend/actions/workflows/osrm-backend.yml) | [![Codecov](https://codecov.io/gh/Project-OSRM/osrm-backend/branch/master/graph/badge.svg)](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`
-75
View File
@@ -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"
]
}
}
}
}
-59
View File
@@ -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 |
+77
View File
@@ -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 |
+44 -9
View File
@@ -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
""" """
+1 -1
View 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
View File
@@ -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})
+28
View File
@@ -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;
}
+3 -3
View File
@@ -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;
+4 -4
View File
@@ -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;
+3 -4
View File
@@ -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(
+1 -1
View File
@@ -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]; }
+2 -2
View File
@@ -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(
+14 -11
View File
@@ -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));
} }
+1 -1
View File
@@ -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;
+43 -34
View File
@@ -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
+13 -8
View File
@@ -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)});
} }
+10 -10
View File
@@ -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);
+18 -17
View File
@@ -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),
+4 -4
View File
@@ -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)
+14 -14
View File
@@ -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;
}; };
+5 -5
View File
@@ -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)
{ {
+14 -13
View File
@@ -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");
+13 -12
View File
@@ -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};
+5 -5
View File
@@ -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;
+21 -8
View File
@@ -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;
+10 -4
View File
@@ -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
+6 -1
View File
@@ -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
+7 -3
View File
@@ -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 -2
View File
@@ -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)
{ {
} }
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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>
+1 -1
View File
@@ -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
+5 -3
View File
@@ -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.
@@ -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
-25
View File
@@ -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_
+4 -4
View File
@@ -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
+5 -6
View File
@@ -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
+37 -30
View File
@@ -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 -8
View File
@@ -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;
+75
View File
@@ -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 &current_request, char *begin, char *end);
private:
RequestStatus consume(http::request &current_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
+35
View File
@@ -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)
{ {
+2 -2
View File
@@ -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");
+6 -6
View File
@@ -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());
+34 -2
View File
@@ -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
View File
@@ -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;
+5 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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)))
+9
View File
@@ -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
+10
View File
@@ -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
+2 -2
View File
@@ -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
+2 -1
View File
@@ -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
+3 -3
View File
@@ -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 +=
+2 -1
View File
@@ -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
View File
@@ -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);
+14 -9
View File
@@ -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
View File
@@ -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
View File
@@ -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 &current_weight = weights_table[row_index * number_of_targets + column_index]; auto &current_weight = weights_table[row_index * number_of_targets + column_index];
EdgeDistance nulldistance = 0; EdgeDistance nulldistance = {0};
auto &current_duration = durations_table[row_index * number_of_targets + column_index]; auto &current_duration = durations_table[row_index * number_of_targets + column_index];
auto &current_distance = auto &current_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 &current_distance = auto &current_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 &current_weight = weights_table[location]; auto &current_weight = weights_table[location];
auto &current_duration = durations_table[location]; auto &current_duration = durations_table[location];
EdgeDistance nulldistance = 0; EdgeDistance nulldistance = {0};
auto &current_distance = distances_table.empty() ? nulldistance : distances_table[location]; auto &current_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()))
+2 -2
View File
@@ -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});
} }
} }
+15 -12
View File
@@ -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:"
+26 -30
View File
@@ -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)
+53 -45
View File
@@ -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)
+12 -2
View File
@@ -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,
+22 -9
View File
@@ -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,
+55 -44
View File
@@ -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,
+15 -3
View File
@@ -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,
+42 -13
View File
@@ -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
View File
@@ -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 &current_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
+302
View File
@@ -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 &current_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 &current_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
View File
@@ -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));
} }
}; };
+2
View File
@@ -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
View File
@@ -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) {
+24
View File
@@ -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