Compare commits

..

5 Commits

Author SHA1 Message Date
Michael Bell 4a5d9c92c0 Bump Conan version 2022-10-10 12:47:14 +01:00
Michael Bell a901f64ffd Final 5.27 release tag 2022-10-10 12:24:40 +01:00
Michael Bell 4f8197eae0 Update Docker commands to new registry 2022-10-10 12:22:58 +01:00
Michael Bell 723e49474d Prep rc.1 2022-10-06 22:09:04 +01:00
Michael Bell 288fa59fec Bookkeeping for 5.27.0 release. 2022-10-06 22:09:04 +01:00
117 changed files with 1141 additions and 2124 deletions
+6 -6
View File
@@ -79,7 +79,7 @@ jobs:
with:
node-version: 12
- name: Enable Node.js cache
uses: actions/cache@v3
uses: actions/cache@v2
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
@@ -104,7 +104,7 @@ jobs:
- name: Check out the repo
uses: actions/checkout@v3
- name: Enable osm.pbf cache
uses: actions/cache@v3
uses: actions/cache@v2
with:
path: berlin-latest.osm.pbf
key: v1-berlin-osm-pbf
@@ -526,28 +526,28 @@ jobs:
with:
node-version: ${{ matrix.node }}
- name: Enable Node.js cache
uses: actions/cache@v3
uses: actions/cache@v2
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Enable compiler cache
uses: actions/cache@v3
uses: actions/cache@v2
with:
path: ~/.ccache
key: ccache-${{ matrix.name }}-${{ github.sha }}
restore-keys: |
ccache-${{ matrix.name }}-
- name: Enable Conan cache
uses: actions/cache@v3
uses: actions/cache@v2
with:
path: ~/.conan
key: v6-conan-${{ matrix.name }}-${{ github.sha }}
restore-keys: |
v6-conan-${{ matrix.name }}-
- name: Enable test cache
uses: actions/cache@v3
uses: actions/cache@v2
with:
path: ${{github.workspace}}/test/cache
key: v3-test-${{ matrix.name }}-${{ github.sha }}
-21
View File
@@ -1,24 +1,3 @@
# 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
- 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)
- Routing:
- CHANGED: Add support for surface=metal,grass_paver,woodchips in bicyle profile. [#6395](https://github.com/Project-OSRM/osrm-backend/pull/6395)
# 5.27.0
- Changes from 5.26.0
- API:
+3 -3
View File
@@ -1,7 +1,8 @@
## Open Source Routing Machine
[![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)
| 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) |
High performance routing engine written in C++14 designed to run on OpenStreetMap data.
@@ -32,7 +33,6 @@ Related [Project-OSRM](https://github.com/Project-OSRM) repositories:
## Contact
- Discord: [https://discord.gg/es9CdcCXcb](join)
- IRC: `irc.oftc.net`, channel: `#osrm` ([Webchat](https://webchat.oftc.net))
- Mailinglist: `https://lists.openstreetmap.org/listinfo/osrm-talk`
+75
View File
@@ -0,0 +1,75 @@
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "user for publishing to s3://mapbox-node-binary/osrm",
"Resources": {
"User": {
"Type": "AWS::IAM::User",
"Properties": {
"Policies": [
{
"PolicyName": "list",
"PolicyDocument": {
"Statement": [
{
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::mapbox-node-binary",
"Condition": {
"StringLike": {
"s3:prefix": [
"osrm/*"
]
}
}
}
]
}
},
{
"PolicyName": "publish",
"PolicyDocument": {
"Statement": [
{
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:GetObjectAcl",
"s3:PutObject",
"s3:PutObjectAcl"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::mapbox-node-binary/osrm/*"
}
]
}
}
]
}
},
"AccessKey": {
"Type": "AWS::IAM::AccessKey",
"Properties": {
"UserName": {
"Ref": "User"
}
}
}
},
"Outputs": {
"AccessKeyId": {
"Value": {
"Ref": "AccessKey"
}
},
"SecretAccessKey": {
"Value": {
"Fn::GetAtt": [
"AccessKey",
"SecretAccessKey"
]
}
}
}
}
+59
View File
@@ -0,0 +1,59 @@
var cf = require('@mapbox/cloudfriend');
var package_json = require('../package.json')
module.exports = {
AWSTemplateFormatVersion: '2010-09-09',
Description: 'user for publishing to s3://mapbox-node-binary/' + package_json.name,
Resources: {
User: {
Type: 'AWS::IAM::User',
Properties: {
Policies: [
{
PolicyName: 'list',
PolicyDocument: {
Statement: [
{
Action: ['s3:ListBucket'],
Effect: 'Allow',
Resource: 'arn:aws:s3:::mapbox-node-binary',
Condition : {
StringLike : {
"s3:prefix": [ package_json.name + "/*"]
}
}
}
]
}
},
{
PolicyName: 'publish',
PolicyDocument: {
Statement: [
{
Action: ['s3:DeleteObject', 's3:GetObject', 's3:GetObjectAcl', 's3:PutObject', 's3:PutObjectAcl'],
Effect: 'Allow',
Resource: 'arn:aws:s3:::mapbox-node-binary/' + package_json.name + '/*'
}
]
}
}
]
}
},
AccessKey: {
Type: 'AWS::IAM::AccessKey',
Properties: {
UserName: cf.ref('User')
}
}
},
Outputs: {
AccessKeyId: {
Value: cf.ref('AccessKey')
},
SecretAccessKey: {
Value: cf.getAtt('AccessKey', 'SecretAccessKey')
}
}
};
-3
View File
@@ -15,7 +15,6 @@ Feature: Bike - Surfaces
| cycleway | cobblestone:flattened | 72 s |
| cycleway | paving_stones | 72 s |
| cycleway | wood | 72 s |
| cycleway | metal | 72 s |
| cycleway | compacted | 72 s |
| cycleway | fine_gravel | 72 s |
| cycleway | ground | 72 s |
@@ -23,13 +22,11 @@ Feature: Bike - Surfaces
| cycleway | cobblestone | 102.9 s |
| cycleway | gravel | 120 s |
| cycleway | pebblestone | 120 s |
| cycleway | grass_paver | 120 s |
| cycleway | dirt | 90 s |
| cycleway | earth | 120 s |
| cycleway | grass | 120 s |
| cycleway | mud | 240 s |
| cycleway | sand | 240 s |
| cycleway | woodchips | 240 s |
| cycleway | sett | 80 s |
Scenario: Bicycle - Good surfaces on small paths
@@ -1,77 +0,0 @@
@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 |
-30
View File
@@ -115,36 +115,6 @@ Feature: Car - Turn restrictions
| c | a | cj,aj,aj |
| c | b | cj,bj,bj |
@no_turning
Scenario: Car - No u-turn
# https://www.openstreetmap.org/edit?node=54878482#map=19/34.05242/-117.19067
Given the node map
"""
c
3
a 1 x 2 b
4
d
"""
And the ways
| nodes |
| ax |
| xb |
| cx |
| xd |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | ax | ax | x | no_u_turn |
| restriction | bx | bx | x | no_u_turn |
| restriction | cx | cx | x | no_u_turn |
| restriction | dx | dx | x | no_u_turn |
When I route I should get
| waypoints | route | turns |
| a,x,a | ax,xb,xb,xb,ax,ax | depart,new name straight,continue uturn,arrive,depart,arrive |
@no_turning
Scenario: Car - Handle any no_* relation
Given the node map
-77
View File
@@ -1,77 +0,0 @@
@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 |
+9 -44
View File
@@ -66,50 +66,15 @@ Feature: Car - Handle traffic lights
| k | traffic_signals | backward |
When I route I should get
| from | to | time | weight | # |
| 1 | 2 | 11.1s | 11.1 | no turn with no traffic light |
| 2 | 1 | 11.1s | 11.1 | no turn with no traffic light |
| 3 | 4 | 13.1s | 13.1 | no turn with traffic light |
| 4 | 3 | 13.1s | 13.1 | no turn with traffic light |
| 5 | 6 | 13.1s | 13.1 | no turn with traffic light |
| 6 | 5 | 11.1s | 11.1 | no turn with no traffic light |
| 7 | 8 | 11.1s | 11.1 | no turn with no 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 |
| from | to | time | # |
| 1 | 2 | 11.1s | no turn with no traffic light |
| 2 | 1 | 11.1s | no turn with no traffic light |
| 3 | 4 | 13.1s | no turn with traffic light |
| 4 | 3 | 13.1s | no turn with traffic light |
| 5 | 6 | 13.1s | no turn with traffic light |
| 6 | 5 | 11.1s | no turn with no traffic light |
| 7 | 8 | 11.1s | no turn with no traffic light |
| 8 | 7 | 13.1s | no turn with traffic light |
Scenario: Car - Encounters a traffic light
@@ -1,6 +1,7 @@
@routing @testbot @turn_function
Feature: Turn Function Information
Background:
Given the profile file
"""
+4 -4
View File
@@ -4,7 +4,7 @@ module.exports = function () {
this.When(/^I request \/(.*)$/, (path, callback) => {
this.reprocessAndLoadData((e) => {
if (e) return callback(e);
this.requestUrl(path, (err, res, body) => {
this.requestPath(path, {}, (err, res, body) => {
this.response = res;
callback(err, res, body);
});
@@ -23,13 +23,13 @@ module.exports = function () {
this.ShouldBeWellFormed();
});
this.Then(/^status code should be (.+)$/, (code, callback) => {
this.Then(/^status code should be (\d+)$/, (code, callback) => {
try {
this.json = JSON.parse(this.response.body);
} catch(e) {
return callback(e);
}
assert.equal(this.json.code, code);
assert.equal(this.json.status, parseInt(code));
callback();
});
@@ -55,4 +55,4 @@ module.exports = function () {
assert.equal(this.processError.process, binary);
assert.equal(parseInt(this.processError.code), parseInt(code));
});
};
};
File diff suppressed because one or more lines are too long
+1 -2
View File
@@ -38,8 +38,7 @@ if (ENABLE_FUZZING)
"table_parameters"
"tile_parameters"
"trip_parameters"
"url_parser"
"request_parser")
"url_parser")
foreach (target ${ServerTargets})
add_fuzz_target(${target})
-28
View File
@@ -1,28 +0,0 @@
#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
{
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)
{
}
ContractorEdgeData(EdgeWeight weight,
EdgeDuration duration,
EdgeWeight duration,
EdgeDistance distance,
unsigned original_edges,
unsigned id,
@@ -30,7 +30,7 @@ struct ContractorEdgeData
{
}
EdgeWeight weight;
EdgeDuration duration;
EdgeWeight duration;
EdgeDistance distance;
unsigned id;
unsigned originalEdges : 29;
@@ -29,20 +29,18 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
#ifndef NDEBUG
const unsigned int constexpr DAY_IN_DECI_SECONDS = 24 * 60 * 60 * 10;
if (from_alias<unsigned int>(std::max(input_edge.data.weight, EdgeWeight{1})) >
DAY_IN_DECI_SECONDS)
if (static_cast<unsigned int>(std::max(input_edge.data.weight, 1)) > DAY_IN_DECI_SECONDS)
{
util::Log(logWARNING) << "Edge weight large -> "
<< from_alias<unsigned int>(
std::max(input_edge.data.weight, EdgeWeight{1}))
<< static_cast<unsigned int>(std::max(input_edge.data.weight, 1))
<< " : " << static_cast<unsigned int>(input_edge.source) << " -> "
<< static_cast<unsigned int>(input_edge.target);
}
#endif
edges.emplace_back(input_edge.source,
input_edge.target,
std::max(input_edge.data.weight, {1}),
to_alias<EdgeDuration>(input_edge.data.duration),
std::max(input_edge.data.weight, 1),
input_edge.data.duration,
input_edge.data.distance,
1,
input_edge.data.turn_id,
@@ -52,8 +50,8 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
edges.emplace_back(input_edge.target,
input_edge.source,
std::max(input_edge.data.weight, {1}),
to_alias<EdgeDuration>(input_edge.data.duration),
std::max(input_edge.data.weight, 1),
input_edge.data.duration,
input_edge.data.distance,
1,
input_edge.data.turn_id,
@@ -111,7 +109,7 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
// merge edges (s,t) and (t,s) into bidirectional edge
if (forward_edge.data.weight == reverse_edge.data.weight)
{
if (forward_edge.data.weight != INVALID_EDGE_WEIGHT)
if ((int)forward_edge.data.weight != INVALID_EDGE_WEIGHT)
{
forward_edge.data.backward = true;
edges[edge++] = forward_edge;
@@ -119,11 +117,11 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
}
else
{ // insert seperate edges
if (forward_edge.data.weight != INVALID_EDGE_WEIGHT)
if (((int)forward_edge.data.weight) != INVALID_EDGE_WEIGHT)
{
edges[edge++] = forward_edge;
}
if (reverse_edge.data.weight != INVALID_EDGE_WEIGHT)
if ((int)reverse_edge.data.weight != INVALID_EDGE_WEIGHT)
{
edges[edge++] = reverse_edge;
}
@@ -159,7 +157,7 @@ template <class Edge, typename GraphT> inline std::vector<Edge> toEdges(GraphT g
new_edge.target = target;
BOOST_ASSERT_MSG(SPECIAL_NODEID != new_edge.target, "Target id invalid");
new_edge.data.weight = data.weight;
new_edge.data.duration = from_alias<EdgeDuration::value_type>(data.duration);
new_edge.data.duration = data.duration;
new_edge.data.distance = data.distance;
new_edge.data.shortcut = data.shortcut;
new_edge.data.turn_id = data.id;
+4 -4
View File
@@ -17,15 +17,15 @@ struct QueryEdge
struct EdgeData
{
explicit EdgeData()
: turn_id(0), shortcut(false), weight{0}, duration(0), forward(false),
backward(false), distance{0}
: turn_id(0), shortcut(false), weight(0), duration(0), forward(false), backward(false),
distance(0)
{
}
EdgeData(const NodeID turn_id,
const bool shortcut,
const EdgeWeight weight,
const EdgeDuration duration,
const EdgeWeight duration,
const EdgeDistance distance,
const bool forward,
const bool backward)
@@ -50,7 +50,7 @@ struct QueryEdge
NodeID turn_id : 31;
bool shortcut : 1;
EdgeWeight weight;
EdgeDuration::value_type duration : 30;
EdgeWeight duration : 30;
std::uint32_t forward : 1;
std::uint32_t backward : 1;
EdgeDistance distance;
+4 -3
View File
@@ -61,7 +61,7 @@ class CellCustomizer
}
}
heap.Clear();
heap.Insert(source, {0}, {false, {0}, {0}});
heap.Insert(source, 0, {false, 0, 0});
// explore search space
while (!heap.Empty() && !destinations_set.empty())
@@ -216,11 +216,12 @@ class CellCustomizer
partition.GetCell(level - 1, to)))
{
const EdgeWeight to_weight = weight + data.weight;
const EdgeDuration to_duration = duration + to_alias<EdgeDuration>(data.duration);
const EdgeDuration to_duration = duration + data.duration;
const EdgeDistance to_distance = distance + data.distance;
if (!heap.WasInserted(to))
{
heap.Insert(to, to_weight, {false, to_duration, to_distance});
heap.Insert(
to, to_weight, {false, duration + data.duration, distance + data.distance});
}
else if (std::tie(to_weight, to_duration, to_distance) <
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]; }
EdgeDuration GetNodeDuration(NodeID node) const { return node_durations[node]; }
EdgeWeight GetNodeDuration(NodeID node) const { return node_durations[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
flatbuffers::Offset<flatbuffers::Vector<float>> speed;
if (requested_annotations & RouteParameters::AnnotationsType::Speed)
if (parameters.annotations_type & RouteParameters::AnnotationsType::Speed)
{
double prev_speed = 0;
speed =
@@ -778,7 +778,7 @@ class RouteAPI : public BaseAPI
util::json::Object annotation;
// AnnotationsType uses bit flags, & operator checks if a property is set
if (requested_annotations & RouteParameters::AnnotationsType::Speed)
if (parameters.annotations_type & RouteParameters::AnnotationsType::Speed)
{
double prev_speed = 0;
annotation.values["speed"] = GetAnnotations(
+11 -14
View File
@@ -133,8 +133,7 @@ class TableAPI final : public BaseAPI
}
bool have_speed_cells =
parameters.fallback_speed != from_alias<double>(INVALID_FALLBACK_SPEED) &&
parameters.fallback_speed > 0;
parameters.fallback_speed != INVALID_FALLBACK_SPEED && parameters.fallback_speed > 0;
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> speed_cells;
if (have_speed_cells)
{
@@ -224,8 +223,7 @@ class TableAPI final : public BaseAPI
MakeDistanceTable(tables.second, number_of_sources, number_of_destinations);
}
if (parameters.fallback_speed != from_alias<double>(INVALID_FALLBACK_SPEED) &&
parameters.fallback_speed > 0)
if (parameters.fallback_speed != INVALID_FALLBACK_SPEED && parameters.fallback_speed > 0)
{
response.values["fallback_speed_cells"] = MakeEstimatesTable(fallback_speed_cells);
}
@@ -274,17 +272,17 @@ class TableAPI final : public BaseAPI
virtual flatbuffers::Offset<flatbuffers::Vector<float>>
MakeDurationTable(flatbuffers::FlatBufferBuilder &builder,
const std::vector<EdgeDuration> &values) const
const std::vector<EdgeWeight> &values) const
{
std::vector<float> distance_table;
distance_table.resize(values.size());
std::transform(
values.begin(), values.end(), distance_table.begin(), [](const EdgeDuration duration) {
values.begin(), values.end(), distance_table.begin(), [](const EdgeWeight duration) {
if (duration == MAXIMAL_EDGE_DURATION)
{
return 0.;
}
return from_alias<double>(duration) / 10.;
return duration / 10.;
});
return builder.CreateVector(distance_table);
}
@@ -301,7 +299,7 @@ class TableAPI final : public BaseAPI
{
return 0.;
}
return std::round(from_alias<double>(distance) * 10) / 10.;
return std::round(distance * 10) / 10.;
});
return builder.CreateVector(duration_table);
}
@@ -349,7 +347,7 @@ class TableAPI final : public BaseAPI
return json_waypoints;
}
virtual util::json::Array MakeDurationTable(const std::vector<EdgeDuration> &values,
virtual util::json::Array MakeDurationTable(const std::vector<EdgeWeight> &values,
std::size_t number_of_rows,
std::size_t number_of_columns) const
{
@@ -363,14 +361,13 @@ class TableAPI final : public BaseAPI
std::transform(row_begin_iterator,
row_end_iterator,
json_row.values.begin(),
[](const EdgeDuration duration) {
[](const EdgeWeight duration) {
if (duration == MAXIMAL_EDGE_DURATION)
{
return util::json::Value(util::json::Null());
}
// division by 10 because the duration is in deciseconds (10s)
return util::json::Value(
util::json::Number(from_alias<double>(duration) / 10.));
return util::json::Value(util::json::Number(duration / 10.));
});
json_table.values.push_back(std::move(json_row));
}
@@ -397,8 +394,8 @@ class TableAPI final : public BaseAPI
return util::json::Value(util::json::Null());
}
// round to single decimal place
return util::json::Value(util::json::Number(
std::round(from_alias<double>(distance) * 10) / 10.));
return util::json::Value(
util::json::Number(std::round(distance * 10) / 10.));
});
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> destinations;
double fallback_speed = from_alias<double>(INVALID_FALLBACK_SPEED);
double fallback_speed = INVALID_FALLBACK_SPEED;
enum class FallbackCoordinateType
{
@@ -83,7 +83,7 @@ template <> class AlgorithmDataFacade<MLD>
virtual EdgeWeight GetNodeWeight(const NodeID edge_based_node_id) const = 0;
virtual EdgeDuration
virtual EdgeWeight
GetNodeDuration(const NodeID edge_based_node_id) const = 0; // TODO: to be removed
virtual EdgeDistance GetNodeDistance(const NodeID edge_based_node_id) const = 0;
+34 -43
View File
@@ -320,84 +320,75 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
const auto forward_weight_offset =
// NOLINTNEXTLINE(bugprone-fold-init-type)
alias_cast<EdgeWeight>(
std::accumulate(forward_weights.begin(),
forward_weights.begin() + data.fwd_segment_position,
SegmentWeight{0}));
std::accumulate(forward_weights.begin(),
forward_weights.begin() + data.fwd_segment_position,
EdgeWeight{0});
const auto forward_duration_offset =
// NOLINTNEXTLINE(bugprone-fold-init-type)
alias_cast<EdgeDuration>(
std::accumulate(forward_durations.begin(),
forward_durations.begin() + data.fwd_segment_position,
SegmentDuration{0}));
std::accumulate(forward_durations.begin(),
forward_durations.begin() + data.fwd_segment_position,
EdgeDuration{0});
EdgeDistance forward_distance_offset = {0};
EdgeDistance forward_distance_offset = 0;
// Sum up the distance from the start to the fwd_segment_position
for (auto current = forward_geometry.begin();
current < forward_geometry.begin() + data.fwd_segment_position;
++current)
{
forward_distance_offset +=
to_alias<EdgeDistance>(util::coordinate_calculation::greatCircleDistance(
datafacade.GetCoordinateOfNode(*current),
datafacade.GetCoordinateOfNode(*std::next(current))));
forward_distance_offset += util::coordinate_calculation::greatCircleDistance(
datafacade.GetCoordinateOfNode(*current),
datafacade.GetCoordinateOfNode(*std::next(current)));
}
BOOST_ASSERT(data.fwd_segment_position <
std::distance(forward_durations.begin(), forward_durations.end()));
EdgeWeight forward_weight =
alias_cast<EdgeWeight>(forward_weights[data.fwd_segment_position]);
EdgeDuration forward_duration =
alias_cast<EdgeDuration>(forward_durations[data.fwd_segment_position]);
EdgeDistance forward_distance =
to_alias<EdgeDistance>(util::coordinate_calculation::greatCircleDistance(
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position)),
point_on_segment));
EdgeWeight forward_weight = forward_weights[data.fwd_segment_position];
EdgeDuration forward_duration = forward_durations[data.fwd_segment_position];
EdgeDistance forward_distance = util::coordinate_calculation::greatCircleDistance(
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position)),
point_on_segment);
const auto reverse_weight_offset = alias_cast<EdgeWeight>(
const auto reverse_weight_offset =
std::accumulate(reverse_weights.begin(),
reverse_weights.end() - data.fwd_segment_position - 1,
SegmentWeight{0}));
EdgeWeight{0});
const auto reverse_duration_offset = alias_cast<EdgeDuration>(
const auto reverse_duration_offset =
std::accumulate(reverse_durations.begin(),
reverse_durations.end() - data.fwd_segment_position - 1,
SegmentDuration{0}));
EdgeDuration{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
for (auto current = forward_geometry.begin() + data.fwd_segment_position + 1;
current != std::prev(forward_geometry.end());
++current)
{
reverse_distance_offset +=
to_alias<EdgeDistance>(util::coordinate_calculation::greatCircleDistance(
datafacade.GetCoordinateOfNode(*current),
datafacade.GetCoordinateOfNode(*std::next(current))));
reverse_distance_offset += util::coordinate_calculation::greatCircleDistance(
datafacade.GetCoordinateOfNode(*current),
datafacade.GetCoordinateOfNode(*std::next(current)));
}
EdgeWeight reverse_weight = alias_cast<EdgeWeight>(
reverse_weights[reverse_weights.size() - data.fwd_segment_position - 1]);
EdgeDuration reverse_duration = alias_cast<EdgeDuration>(
reverse_durations[reverse_durations.size() - data.fwd_segment_position - 1]);
EdgeDistance reverse_distance =
to_alias<EdgeDistance>(util::coordinate_calculation::greatCircleDistance(
point_on_segment,
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position + 1))));
EdgeWeight reverse_weight =
reverse_weights[reverse_weights.size() - data.fwd_segment_position - 1];
EdgeDuration reverse_duration =
reverse_durations[reverse_durations.size() - data.fwd_segment_position - 1];
EdgeDistance reverse_distance = util::coordinate_calculation::greatCircleDistance(
point_on_segment,
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position + 1)));
ratio = std::min(1.0, std::max(0.0, ratio));
if (data.forward_segment_id.id != SPECIAL_SEGMENTID)
{
forward_weight = to_alias<EdgeWeight>(from_alias<double>(forward_weight) * ratio);
forward_duration = to_alias<EdgeDuration>(from_alias<double>(forward_duration) * ratio);
forward_weight = static_cast<EdgeWeight>(forward_weight * ratio);
forward_duration = static_cast<EdgeDuration>(forward_duration * ratio);
}
if (data.reverse_segment_id.id != SPECIAL_SEGMENTID)
{
reverse_weight -= to_alias<EdgeWeight>(from_alias<double>(reverse_weight) * ratio);
reverse_duration -=
to_alias<EdgeDuration>(from_alias<double>(reverse_duration) * ratio);
reverse_weight -= static_cast<EdgeWeight>(reverse_weight * ratio);
reverse_duration -= static_cast<EdgeDuration>(reverse_duration * ratio);
}
// check phantom node segments validity
+8 -13
View File
@@ -95,9 +95,8 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
// the duration_of_turn/weight_of_turn value, which is 0 for
// non-preceeding-turn segments, but contains the turn value
// for segments before a turn.
from_alias<double>(path_point.duration_until_turn - path_point.duration_of_turn) /
10.,
from_alias<double>(path_point.weight_until_turn - path_point.weight_of_turn) /
(path_point.duration_until_turn - path_point.duration_of_turn) / 10.,
(path_point.weight_until_turn - path_point.weight_of_turn) /
facade.GetWeightMultiplier(),
path_point.datasource_id});
geometry.locations.push_back(coordinate);
@@ -122,15 +121,14 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
if (geometry.annotations.empty())
{
auto duration =
std::abs(from_alias<EdgeDuration::value_type>(
std::abs(
(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.;
BOOST_ASSERT(duration >= 0);
auto weight =
std::abs(from_alias<EdgeWeight::value_type>(
(reversed_target ? target_node.reverse_weight : target_node.forward_weight) -
(reversed_source ? source_node.reverse_weight : source_node.forward_weight))) /
std::abs((reversed_target ? target_node.reverse_weight : target_node.forward_weight) -
(reversed_source ? source_node.reverse_weight : source_node.forward_weight)) /
facade.GetWeightMultiplier();
BOOST_ASSERT(weight >= 0);
@@ -144,11 +142,8 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
{
geometry.annotations.emplace_back(LegGeometry::Annotation{
current_distance,
from_alias<double>(reversed_target ? target_node.reverse_duration
: target_node.forward_duration) /
10.,
from_alias<double>(reversed_target ? target_node.reverse_weight
: target_node.forward_weight) /
(reversed_target ? target_node.reverse_duration : target_node.forward_duration) / 10.,
(reversed_target ? target_node.reverse_weight : target_node.forward_weight) /
facade.GetWeightMultiplier(),
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;
struct NamedSegment
{
EdgeDuration duration;
EdgeWeight duration;
std::uint32_t position;
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;
const auto target_node_id = target_traversed_in_reverse ? target_node.reverse_segment_id.id
: target_node.forward_segment_id.id;
if (target_duration > EdgeDuration{1})
if (target_duration > 1)
segments.push_back({target_duration, index++, facade.GetNameIndex(target_node_id)});
// this makes sure that the segment with the lowest position comes first
std::sort(
@@ -184,11 +184,11 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
auto duration = std::accumulate(
route_data.begin(), route_data.end(), 0, [](const double sum, const PathData &data) {
return sum + from_alias<double>(data.duration_until_turn);
return sum + data.duration_until_turn;
});
auto weight = std::accumulate(
route_data.begin(), route_data.end(), 0, [](const double sum, const PathData &data) {
return sum + from_alias<double>(data.weight_until_turn);
return sum + data.weight_until_turn;
});
// 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.
// On local segments, the target duration is already part of the duration, however.
duration = duration + from_alias<double>(target_duration);
weight = weight + from_alias<double>(target_weight);
duration = duration + target_duration;
weight = weight + target_weight;
if (route_data.empty())
{
weight -= from_alias<double>(target_traversed_in_reverse ? source_node.reverse_weight
: source_node.forward_weight);
duration -= from_alias<double>(target_traversed_in_reverse ? source_node.reverse_duration
: source_node.forward_duration);
weight -=
(target_traversed_in_reverse ? source_node.reverse_weight : source_node.forward_weight);
duration -= (target_traversed_in_reverse ? source_node.reverse_duration
: source_node.forward_duration);
// use rectified linear unit function to avoid negative duration values
// due to flooring errors in phantom snapping
duration = std::max(0, duration);
+17 -18
View File
@@ -52,7 +52,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
const constexpr char *NO_ROTARY_NAME = "";
const EdgeWeight source_weight =
source_traversed_in_reverse ? source_node.reverse_weight : source_node.forward_weight;
const EdgeDuration source_duration =
const EdgeWeight source_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
: 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);
auto source_classes = facade.GetClasses(facade.GetClassData(source_node_id));
const EdgeDuration target_duration =
const EdgeWeight target_duration =
target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration;
const EdgeWeight target_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.
// We need to skip the first segment because it is already covered by the
// initial start of a route
EdgeDuration segment_duration = {0};
EdgeWeight segment_weight = {0};
EdgeWeight segment_duration = 0;
EdgeWeight segment_weight = 0;
// some name changes are not announced in our processing. For these, we have to keep the
// first name on the segment
@@ -121,7 +121,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
: osrm::guidance::TurnInstruction::NO_TURN();
if (turn_instruction.type != osrm::guidance::TurnType::NoTurn)
{
BOOST_ASSERT(segment_weight >= EdgeWeight{0});
BOOST_ASSERT(segment_weight >= 0);
const auto name = facade.GetNameForID(step_name_id);
const auto ref = facade.GetRefForID(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(),
NO_ROTARY_NAME,
NO_ROTARY_NAME,
from_alias<double>(segment_duration) / 10.,
segment_duration / 10.,
distance,
from_alias<double>(segment_weight) / weight_multiplier,
segment_weight / weight_multiplier,
travel_mode,
maneuver,
leg_geometry.FrontIndex(segment_index),
@@ -228,16 +228,16 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
WaypointType::None,
0};
segment_index++;
segment_duration = {0};
segment_weight = {0};
segment_duration = 0;
segment_weight = 0;
}
}
const auto distance = leg_geometry.segment_distances[segment_index];
const EdgeDuration duration = segment_duration + target_duration;
const EdgeWeight duration = segment_duration + target_duration;
const EdgeWeight weight = segment_weight + target_weight;
// intersections contain the classes of exiting road
intersection.classes = facade.GetClasses(facade.GetClassData(target_node_id));
BOOST_ASSERT(duration >= EdgeDuration{0});
BOOST_ASSERT(duration >= 0);
steps.push_back(RouteStep{leg_data[leg_data.size() - 1].from_edge_based_node,
step_name_id,
is_segregated,
@@ -248,9 +248,9 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
facade.GetExitsForID(step_name_id).to_string(),
NO_ROTARY_NAME,
NO_ROTARY_NAME,
from_alias<double>(duration) / 10.,
duration / 10.,
distance,
from_alias<double>(weight) / weight_multiplier,
weight / weight_multiplier,
target_mode,
maneuver,
leg_geometry.FrontIndex(segment_index),
@@ -280,9 +280,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
// use rectified linear unit function to avoid negative duration values
// due to flooring errors in phantom snapping
BOOST_ASSERT(target_duration >= source_duration || weight == EdgeWeight{0});
const EdgeDuration duration =
std::max<EdgeDuration>({0}, target_duration - source_duration);
BOOST_ASSERT(target_duration >= source_duration || weight == 0);
const EdgeWeight duration = std::max(0, target_duration - source_duration);
steps.push_back(RouteStep{source_node_id,
source_name_id,
@@ -294,9 +293,9 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
facade.GetExitsForID(source_name_id).to_string(),
NO_ROTARY_NAME,
NO_ROTARY_NAME,
from_alias<double>(duration) / 10.,
duration / 10.,
leg_geometry.segment_distances[segment_index],
from_alias<double>(weight) / weight_multiplier,
weight / weight_multiplier,
source_mode,
maneuver,
leg_geometry.FrontIndex(segment_index),
+4 -4
View File
@@ -37,10 +37,10 @@ struct PathData
EdgeWeight weight_of_turn;
// duration that is traveled on the segment until the turn is reached,
// including a turn if the segment precedes one.
EdgeDuration duration_until_turn;
EdgeWeight duration_until_turn;
// If this segment immediately precedes a turn, then duration_of_turn
// will contain the duration of the turn. Otherwise it will be 0.
EdgeDuration duration_of_turn;
EdgeWeight duration_of_turn;
// Source of the speed value on this road segment
DatasourceID datasource_id;
// 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.
EdgeDuration duration() const
EdgeWeight duration() const
{
EdgeDuration ret{0};
EdgeWeight ret{0};
for (const auto &leg : unpacked_path_segments)
for (const auto &segment : leg)
+14 -14
View File
@@ -48,12 +48,12 @@ struct PhantomNode
PhantomNode()
: forward_segment_id{SPECIAL_SEGMENTID, false}, reverse_segment_id{SPECIAL_SEGMENTID,
false},
forward_weight(INVALID_EDGE_WEIGHT),
reverse_weight(INVALID_EDGE_WEIGHT), forward_weight_offset{0}, reverse_weight_offset{0},
forward_weight(INVALID_EDGE_WEIGHT), 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_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_offset{0}, reverse_duration_offset{0},
forward_duration_offset(0), reverse_duration_offset(0),
component({INVALID_COMPONENTID, 0}),
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)
@@ -73,13 +73,13 @@ struct PhantomNode
return reverse_weight_offset + reverse_weight;
}
EdgeDuration GetForwardDuration() const
EdgeWeight GetForwardDuration() const
{
BOOST_ASSERT(forward_segment_id.enabled);
return forward_duration + forward_duration_offset;
}
EdgeDuration GetReverseDuration() const
EdgeWeight GetReverseDuration() const
{
BOOST_ASSERT(reverse_segment_id.enabled);
return reverse_duration + reverse_duration_offset;
@@ -168,10 +168,10 @@ struct PhantomNode
EdgeDistance reverse_distance,
EdgeDistance forward_distance_offset,
EdgeDistance reverse_distance_offset,
EdgeDuration forward_duration,
EdgeDuration reverse_duration,
EdgeDuration forward_duration_offset,
EdgeDuration reverse_duration_offset,
EdgeWeight forward_duration,
EdgeWeight reverse_duration,
EdgeWeight forward_duration_offset,
EdgeWeight reverse_duration_offset,
bool is_valid_forward_source,
bool is_valid_forward_target,
bool is_valid_reverse_source,
@@ -206,10 +206,10 @@ struct PhantomNode
EdgeDistance reverse_distance;
EdgeDistance forward_distance_offset; // TODO: try to remove -> requires path unpacking changes
EdgeDistance reverse_distance_offset; // TODO: try to remove -> requires path unpacking changes
EdgeDuration forward_duration;
EdgeDuration reverse_duration;
EdgeDuration forward_duration_offset; // TODO: try to remove -> requires path unpacking changes
EdgeDuration reverse_duration_offset; // TODO: try to remove -> requires path unpacking changes
EdgeWeight forward_duration;
EdgeWeight reverse_duration;
EdgeWeight forward_duration_offset; // TODO: try to remove -> requires path unpacking changes
EdgeWeight reverse_duration_offset; // TODO: try to remove -> requires path unpacking changes
ComponentID component;
util::Coordinate location; // this is the coordinate of x
@@ -43,14 +43,14 @@ void insertSourceInForwardHeap(Heap &forward_heap, const PhantomNode &source)
if (source.IsValidForwardSource())
{
forward_heap.Insert(source.forward_segment_id.id,
EdgeWeight{0} - source.GetForwardWeightPlusOffset(),
-source.GetForwardWeightPlusOffset(),
source.forward_segment_id.id);
}
if (source.IsValidReverseSource())
{
forward_heap.Insert(source.reverse_segment_id.id,
EdgeWeight{0} - source.GetReverseWeightPlusOffset(),
-source.GetReverseWeightPlusOffset(),
source.reverse_segment_id.id);
}
}
@@ -127,18 +127,18 @@ void insertSourceInHeap(ManyToManyQueryHeap &heap, const PhantomNodeCandidates &
if (phantom_node.IsValidForwardSource())
{
heap.Insert(phantom_node.forward_segment_id.id,
EdgeWeight{0} - phantom_node.GetForwardWeightPlusOffset(),
-phantom_node.GetForwardWeightPlusOffset(),
{phantom_node.forward_segment_id.id,
EdgeDuration{0} - phantom_node.GetForwardDuration(),
EdgeDistance{0} - phantom_node.GetForwardDistance()});
-phantom_node.GetForwardDuration(),
-phantom_node.GetForwardDistance()});
}
if (phantom_node.IsValidReverseSource())
{
heap.Insert(phantom_node.reverse_segment_id.id,
EdgeWeight{0} - phantom_node.GetReverseWeightPlusOffset(),
-phantom_node.GetReverseWeightPlusOffset(),
{phantom_node.reverse_segment_id.id,
EdgeDuration{0} - phantom_node.GetReverseDuration(),
EdgeDistance{0} - phantom_node.GetReverseDistance()});
-phantom_node.GetReverseDuration(),
-phantom_node.GetReverseDistance()});
}
}
}
@@ -251,24 +251,25 @@ void annotatePath(const FacadeT &facade,
BOOST_ASSERT(start_index < end_index);
for (std::size_t segment_idx = start_index; segment_idx < end_index; ++segment_idx)
{
unpacked_path.push_back(PathData{node_id,
id_vector[segment_idx + 1],
alias_cast<EdgeWeight>(weight_vector[segment_idx]),
{0},
alias_cast<EdgeDuration>(duration_vector[segment_idx]),
{0},
datasource_vector[segment_idx],
boost::none});
unpacked_path.push_back(
PathData{node_id,
id_vector[segment_idx + 1],
static_cast<EdgeWeight>(weight_vector[segment_idx]),
0,
static_cast<EdgeDuration>(duration_vector[segment_idx]),
0,
datasource_vector[segment_idx],
boost::none});
}
BOOST_ASSERT(!unpacked_path.empty());
const auto turn_duration = facade.GetDurationPenaltyForEdgeID(turn_id);
const auto turn_weight = facade.GetWeightPenaltyForEdgeID(turn_id);
unpacked_path.back().duration_until_turn += alias_cast<EdgeDuration>(turn_duration);
unpacked_path.back().duration_of_turn = alias_cast<EdgeDuration>(turn_duration);
unpacked_path.back().weight_until_turn += alias_cast<EdgeWeight>(turn_weight);
unpacked_path.back().weight_of_turn = alias_cast<EdgeWeight>(turn_weight);
unpacked_path.back().duration_until_turn += turn_duration;
unpacked_path.back().duration_of_turn = turn_duration;
unpacked_path.back().weight_until_turn += turn_weight;
unpacked_path.back().weight_of_turn = turn_weight;
unpacked_path.back().turn_edge = turn_id;
}
@@ -310,10 +311,10 @@ void annotatePath(const FacadeT &facade,
unpacked_path.push_back(
PathData{target_node_id,
id_vector[start_index < end_index ? segment_idx + 1 : segment_idx - 1],
alias_cast<EdgeWeight>(weight_vector[segment_idx]),
{0},
alias_cast<EdgeDuration>(duration_vector[segment_idx]),
{0},
static_cast<EdgeWeight>(weight_vector[segment_idx]),
0,
static_cast<EdgeDuration>(duration_vector[segment_idx]),
0,
datasource_vector[segment_idx],
boost::none});
}
@@ -340,9 +341,9 @@ void annotatePath(const FacadeT &facade,
// node to the first turn would be the same as from end to end of a segment,
// which is obviously incorrect and not ideal...
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 =
std::max(unpacked_path.front().duration_until_turn - source_duration, {0});
std::max(unpacked_path.front().duration_until_turn - source_duration, 0);
}
}
@@ -409,7 +410,7 @@ template <typename FacadeT> EdgeDistance computeEdgeDistance(const FacadeT &faca
{
const auto geometry_index = facade.GetGeometryIndex(node_id);
EdgeDistance total_distance = {0};
EdgeDistance total_distance = 0.0;
auto geometry_range = facade.GetUncompressedForwardGeometry(geometry_index.id);
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 EdgeWeight edge_weight = data.weight;
BOOST_ASSERT_MSG(edge_weight > EdgeWeight{0}, "edge_weight invalid");
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
const auto toHeapNode = query_heap.GetHeapNodeIfWasInserted(to);
if (toHeapNode)
{
@@ -61,7 +61,7 @@ void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
const NodeID to = facade.GetTarget(edge);
const EdgeWeight edge_weight = data.weight;
BOOST_ASSERT_MSG(edge_weight > EdgeWeight{0}, "edge_weight invalid");
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
const EdgeWeight to_weight = heapNode.weight + edge_weight;
const auto toHeapNode = heap.GetHeapNodeIfWasInserted(to);
@@ -135,7 +135,7 @@ void routingStep(const DataFacade<Algorithm> &facade,
force_loop(force_loop_reverse_nodes, heapNode) ||
// in this case we are looking at a bi-directional way where the source
// and target phantom are on the same edge based node
new_weight < EdgeWeight{0})
new_weight < 0)
{
// check whether there is a loop present at the 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 loop_weight = new_weight + edge_weight;
if (loop_weight >= EdgeWeight{0} && loop_weight < upper_bound)
if (loop_weight >= 0 && loop_weight < upper_bound)
{
middle_node_id = heapNode.node;
upper_bound = loop_weight;
@@ -159,7 +159,7 @@ void routingStep(const DataFacade<Algorithm> &facade,
}
else
{
BOOST_ASSERT(new_weight >= EdgeWeight{0});
BOOST_ASSERT(new_weight >= 0);
middle_node_id = heapNode.node;
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
// for the nodes in the forward heap with the forward/reverse offset
BOOST_ASSERT(min_edge_offset <= EdgeWeight{0});
BOOST_ASSERT(min_edge_offset <= 0);
if (heapNode.weight + min_edge_offset > upper_bound)
{
forward_heap.DeleteAll();
@@ -185,6 +185,31 @@ void routingStep(const DataFacade<Algorithm> &facade,
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
* the shortcut
@@ -276,7 +301,7 @@ EdgeDistance calculateEBGNodeAnnotations(const DataFacade<Algorithm> &facade,
// Make sure we have at least something to unpack
if (packed_path_begin == packed_path_end ||
std::distance(packed_path_begin, packed_path_end) <= 1)
return {0};
return 0;
std::stack<std::tuple<NodeID, NodeID, bool>> recursion_stack;
std::stack<EdgeDistance> distance_stack;
@@ -358,7 +383,7 @@ EdgeDistance calculateEBGNodeAnnotations(const DataFacade<Algorithm> &facade,
}
}
EdgeDistance total_distance = {0};
EdgeDistance total_distance = 0;
while (!distance_stack.empty())
{
total_distance += distance_stack.top();
@@ -480,48 +505,8 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
const PhantomNode &source_phantom,
const PhantomNode &target_phantom,
EdgeWeight duration_upper_bound = INVALID_EDGE_WEIGHT);
int 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 routing_algorithms
} // namespace engine
@@ -363,8 +363,7 @@ void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
// TODO: BOOST_ASSERT(edge_data.weight == node_weight + turn_penalty);
const EdgeWeight to_weight =
heapNode.weight + node_weight + alias_cast<EdgeWeight>(turn_penalty);
const EdgeWeight to_weight = heapNode.weight + node_weight + turn_penalty;
const auto toHeapNode = forward_heap.GetHeapNodeIfWasInserted(to);
if (!toHeapNode)
@@ -411,7 +410,7 @@ void routingStep(const DataFacade<Algorithm> &facade,
// 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)
if (!force_loop(force_loop_forward_nodes, heapNode) &&
!force_loop(force_loop_reverse_nodes, heapNode) && (path_weight >= EdgeWeight{0}) &&
!force_loop(force_loop_reverse_nodes, heapNode) && (path_weight >= 0) &&
(path_weight < path_upper_bound))
{
middle_node = heapNode.node;
@@ -530,8 +529,8 @@ UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
// Here heaps can be reused, let's go deeper!
forward_heap.Clear();
reverse_heap.Clear();
forward_heap.Insert(source, {0}, {source});
reverse_heap.Insert(target, {0}, {target});
forward_heap.Insert(source, 0, {source});
reverse_heap.Insert(target, 0, {target});
// TODO: when structured bindings will be allowed change to
// auto [subpath_weight, subpath_source, subpath_target, subpath] = ...
@@ -292,7 +292,7 @@ shortestPathWithWaypointUTurns(SearchEngineData<Algorithm> &engine_working_data,
const std::vector<PhantomNodeCandidates> &waypoint_candidates)
{
EdgeWeight total_weight = {0};
EdgeWeight total_weight = 0;
std::vector<NodeID> total_packed_path;
std::vector<std::size_t> packed_leg_begin;
@@ -467,8 +467,8 @@ struct route_state
route_state(const PhantomNodeCandidates &init_candidates)
: current_leg(0), previous_leg_path_offset(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_forward.resize(init_candidates.size(), 0);
last.total_weight_to_reverse.resize(init_candidates.size(), 0);
// Initialize routability from source validity.
std::transform(
init_candidates.begin(),
@@ -23,7 +23,7 @@ struct TurnData final
const int in_angle;
const int turn_angle;
const EdgeWeight weight;
const EdgeDuration duration;
const EdgeWeight duration;
const guidance::TurnInstruction turn_instruction;
};
+5 -5
View File
@@ -29,9 +29,9 @@ struct HeapData
struct ManyToManyHeapData : HeapData
{
EdgeDuration duration;
EdgeWeight duration;
EdgeDistance distance;
ManyToManyHeapData(NodeID p, EdgeDuration duration, EdgeDistance distance)
ManyToManyHeapData(NodeID p, EdgeWeight duration, EdgeDistance distance)
: HeapData(p), duration(duration), distance(distance)
{
}
@@ -78,15 +78,15 @@ struct MultiLayerDijkstraHeapData
struct ManyToManyMultiLayerDijkstraHeapData : MultiLayerDijkstraHeapData
{
EdgeDuration duration;
EdgeWeight duration;
EdgeDistance distance;
ManyToManyMultiLayerDijkstraHeapData(NodeID p, EdgeDuration duration, EdgeDistance distance)
ManyToManyMultiLayerDijkstraHeapData(NodeID p, EdgeWeight duration, EdgeDistance distance)
: MultiLayerDijkstraHeapData(p), duration(duration), distance(distance)
{
}
ManyToManyMultiLayerDijkstraHeapData(NodeID p,
bool from,
EdgeDuration duration,
EdgeWeight duration,
EdgeDistance distance)
: MultiLayerDijkstraHeapData(p, from), duration(duration), distance(distance)
{
+13 -14
View File
@@ -23,12 +23,12 @@ namespace trip
{
// computes the distance of a given permutation
inline EdgeDuration ReturnDistance(const util::DistTableWrapper<EdgeDuration> &dist_table,
const std::vector<NodeID> &location_order,
const EdgeDuration min_route_dist,
const std::size_t number_of_locations)
inline EdgeWeight ReturnDistance(const util::DistTableWrapper<EdgeWeight> &dist_table,
const std::vector<NodeID> &location_order,
const EdgeWeight min_route_dist,
const std::size_t number_of_locations)
{
EdgeDuration route_dist = {0};
EdgeWeight route_dist = 0;
std::size_t current_index = 0;
while (current_index < location_order.size() && (route_dist < min_route_dist))
{
@@ -36,13 +36,12 @@ inline EdgeDuration ReturnDistance(const util::DistTableWrapper<EdgeDuration> &d
std::size_t next_index = (current_index + 1) % number_of_locations;
auto edge_weight = dist_table(location_order[current_index], location_order[next_index]);
// If the edge_weight is very large (INVALID_EDGE_DURATION) then the algorithm will not
// choose this edge in final minimal path. So instead of computing all the permutations
// after this large edge, discard this edge right here and don't consider the path after
// this edge.
if (edge_weight == INVALID_EDGE_DURATION)
// If the edge_weight is very large (INVALID_EDGE_WEIGHT) then the algorithm will not choose
// this edge in final minimal path. So instead of computing all the permutations after this
// large edge, discard this edge right here and don't consider the path after this edge.
if (edge_weight == INVALID_EDGE_WEIGHT)
{
return INVALID_EDGE_DURATION;
return INVALID_EDGE_WEIGHT;
}
else
{
@@ -51,7 +50,7 @@ inline EdgeDuration ReturnDistance(const util::DistTableWrapper<EdgeDuration> &d
// This boost assert should not be reached if TFSE table
BOOST_ASSERT_MSG(dist_table(location_order[current_index], location_order[next_index]) !=
INVALID_EDGE_DURATION,
INVALID_EDGE_WEIGHT,
"invalid route found");
++current_index;
}
@@ -61,14 +60,14 @@ inline EdgeDuration ReturnDistance(const util::DistTableWrapper<EdgeDuration> &d
// computes the route by computing all permutations and selecting the shortest
inline std::vector<NodeID> BruteForceTrip(const std::size_t number_of_locations,
const util::DistTableWrapper<EdgeDuration> &dist_table)
const util::DistTableWrapper<EdgeWeight> &dist_table)
{
// set initial order in which nodes are visited to 0, 1, 2, 3, ...
std::vector<NodeID> node_order(number_of_locations);
std::iota(std::begin(node_order), std::end(node_order), 0);
std::vector<NodeID> route = node_order;
EdgeDuration min_route_dist = INVALID_EDGE_DURATION;
EdgeWeight min_route_dist = INVALID_EDGE_WEIGHT;
// check length of all possible permutation of the component ids
BOOST_ASSERT_MSG(node_order.size() > 0, "no order permutation given");
+12 -13
View File
@@ -23,15 +23,15 @@ namespace trip
// 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
using NodeIDIter = std::vector<NodeID>::iterator;
inline std::pair<EdgeDuration, NodeIDIter>
inline std::pair<EdgeWeight, NodeIDIter>
GetShortestRoundTrip(const NodeID new_loc,
const util::DistTableWrapper<EdgeDuration> &dist_table,
const util::DistTableWrapper<EdgeWeight> &dist_table,
const std::size_t number_of_locations,
std::vector<NodeID> &route)
{
(void)number_of_locations; // unused
auto min_trip_distance = INVALID_EDGE_DURATION;
auto min_trip_distance = INVALID_EDGE_WEIGHT;
NodeIDIter next_insert_point_candidate;
// for all nodes in the current trip find the best insertion resulting in the shortest path
@@ -48,11 +48,10 @@ GetShortestRoundTrip(const NodeID new_loc,
const auto dist_from = dist_table(*from_node, new_loc);
const auto dist_to = dist_table(new_loc, *to_node);
// If the edge_weight is very large (INVALID_EDGE_DURATION) then the algorithm will not
// choose this edge in final minimal path. So instead of computing all the permutations
// after this large edge, discard this edge right here and don't consider the path after
// this edge.
if (dist_from == INVALID_EDGE_DURATION || dist_to == INVALID_EDGE_DURATION)
// If the edge_weight is very large (INVALID_EDGE_WEIGHT) then the algorithm will not choose
// this edge in final minimal path. So instead of computing all the permutations after this
// large edge, discard this edge right here and don't consider the path after this edge.
if (dist_from == INVALID_EDGE_WEIGHT || dist_to == INVALID_EDGE_WEIGHT)
continue;
const auto trip_dist = dist_from + dist_to - dist_table(*from_node, *to_node);
@@ -72,14 +71,14 @@ GetShortestRoundTrip(const NodeID new_loc,
next_insert_point_candidate = to_node;
}
}
BOOST_ASSERT_MSG(min_trip_distance != INVALID_EDGE_DURATION, "trip has invalid edge weight");
BOOST_ASSERT_MSG(min_trip_distance != INVALID_EDGE_WEIGHT, "trip has invalid edge weight");
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
inline std::vector<NodeID> FindRoute(const std::size_t &number_of_locations,
const util::DistTableWrapper<EdgeDuration> &dist_table,
const util::DistTableWrapper<EdgeWeight> &dist_table,
const NodeID &start1,
const NodeID &start2)
{
@@ -100,7 +99,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
for (std::size_t added_nodes = 2; added_nodes < number_of_locations; ++added_nodes)
{
auto farthest_distance = EdgeDuration{std::numeric_limits<EdgeDuration::value_type>::min()};
auto farthest_distance = std::numeric_limits<int>::min();
auto next_node = -1;
NodeIDIter next_insert_point;
@@ -113,7 +112,7 @@ inline std::vector<NodeID> FindRoute(const std::size_t &number_of_locations,
const auto insert_candidate =
GetShortestRoundTrip(id, dist_table, number_of_locations, route);
BOOST_ASSERT_MSG(insert_candidate.first != INVALID_EDGE_DURATION,
BOOST_ASSERT_MSG(insert_candidate.first != INVALID_EDGE_WEIGHT,
"shortest round trip is invalid");
// add the location to the current trip such that it results in the shortest total
@@ -138,7 +137,7 @@ inline std::vector<NodeID> FindRoute(const std::size_t &number_of_locations,
inline std::vector<NodeID>
FarthestInsertionTrip(const std::size_t number_of_locations,
const util::DistTableWrapper<EdgeDuration> &dist_table)
const util::DistTableWrapper<EdgeWeight> &dist_table)
{
//////////////////////////////////////////////////////////////////////////////////////////////////
// START FARTHEST INSERTION HERE
@@ -44,8 +44,8 @@ class CompressedEdgeContainer
void AddUncompressedEdge(const EdgeID edge_id,
const NodeID target_node,
const EdgeWeight weight,
const EdgeDuration duration);
const SegmentWeight weight,
const SegmentWeight duration);
void InitializeBothwayVector();
unsigned ZipEdges(const unsigned f_edge_pos, const unsigned r_edge_pos);
@@ -67,8 +67,8 @@ class CompressedEdgeContainer
std::unique_ptr<SegmentDataContainer> ToSegmentData();
private:
SegmentWeight ClipWeight(const EdgeWeight weight);
SegmentDuration ClipDuration(const EdgeDuration duration);
SegmentWeight ClipWeight(const SegmentWeight weight);
SegmentDuration ClipDuration(const SegmentDuration duration);
int free_list_maximum = 0;
std::atomic_size_t clipped_weights{0};
+5 -5
View File
@@ -16,14 +16,14 @@ struct EdgeBasedEdge
struct 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,
const EdgeWeight weight,
const EdgeDistance distance,
const EdgeDuration duration,
const EdgeWeight duration,
const bool forward,
const bool backward)
: 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)
EdgeWeight weight;
EdgeDistance distance;
EdgeDuration::value_type duration : 30;
EdgeWeight duration : 30;
std::uint32_t forward : 1;
std::uint32_t backward : 1;
@@ -47,7 +47,7 @@ struct EdgeBasedEdge
const NodeID target,
const NodeID edge_id,
const EdgeWeight weight,
const EdgeDuration duration,
const EdgeWeight duration,
const EdgeDistance distance,
const bool forward,
const bool backward);
@@ -72,7 +72,7 @@ inline EdgeBasedEdge::EdgeBasedEdge(const NodeID source,
const NodeID target,
const NodeID turn_id,
const EdgeWeight weight,
const EdgeDuration duration,
const EdgeWeight duration,
const EdgeDistance distance,
const bool forward,
const bool backward)
@@ -23,7 +23,7 @@
#include "util/typedefs.hpp"
#include "storage/io.hpp"
#include "traffic_flow_control_nodes.hpp"
#include "traffic_signals.hpp"
#include <algorithm>
#include <cstddef>
@@ -69,9 +69,7 @@ class EdgeBasedGraphFactory
EdgeBasedNodeDataContainer &node_data_container,
const CompressedEdgeContainer &compressed_edge_container,
const std::unordered_set<NodeID> &barrier_nodes,
const TrafficFlowControlNodes &traffic_signals,
const TrafficFlowControlNodes &stop_signs,
const TrafficFlowControlNodes &give_way_signs,
const TrafficSignals &traffic_signals,
const std::vector<util::Coordinate> &coordinates,
const NameTable &name_table,
const std::unordered_set<EdgeID> &segregated_edges,
@@ -93,7 +91,7 @@ class EdgeBasedGraphFactory
void GetEdgeBasedEdges(util::DeallocatingVector<EdgeBasedEdge> &edges);
void GetEdgeBasedNodeSegments(std::vector<EdgeBasedNodeSegment> &nodes);
void GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &output_node_weights);
void GetEdgeBasedNodeDurations(std::vector<EdgeDuration> &output_node_durations);
void GetEdgeBasedNodeDurations(std::vector<EdgeWeight> &output_node_durations);
void GetEdgeBasedNodeDistances(std::vector<EdgeDistance> &output_node_distances);
std::uint32_t GetConnectivityChecksum() const;
@@ -137,10 +135,7 @@ class EdgeBasedGraphFactory
const util::NodeBasedDynamicGraph &m_node_based_graph;
const std::unordered_set<NodeID> &m_barrier_nodes;
const TrafficFlowControlNodes &m_traffic_signals;
const TrafficFlowControlNodes &m_stop_signs;
const TrafficFlowControlNodes &m_give_way_signs;
const TrafficSignals &m_traffic_signals;
const CompressedEdgeContainer &m_compressed_edge_container;
const NameTable &name_table;
+8 -21
View File
@@ -8,7 +8,8 @@
#include "extractor/scripting_environment.hpp"
#include "storage/tar_fwd.hpp"
#include "traffic_flow_control_nodes.hpp"
#include "traffic_lights.hpp"
#include "traffic_signals.hpp"
#include <unordered_map>
#include <unordered_set>
@@ -26,29 +27,20 @@ namespace extractor
*/
class ExtractionContainers
{
public:
using InputTrafficFlowControlNode = std::pair<OSMNodeID, TrafficFlowControlNodeDirection>;
private:
using ReferencedWays = std::unordered_map<OSMWayID, NodesOfWay>;
using ReferencedTrafficFlowControlNodes =
using ReferencedTrafficSignals =
std::pair<std::unordered_set<OSMNodeID>, std::unordered_multimap<OSMNodeID, OSMNodeID>>;
// The relationship between way and nodes is lost during node preparation.
// 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.
ReferencedWays IdentifyRestrictionWays();
ReferencedWays IdentifyManeuverOverrideWays();
ReferencedTrafficFlowControlNodes IdentifyTrafficFlowControlNodes(
const std::vector<InputTrafficFlowControlNode> &external_traffic_control_nodes);
ReferencedTrafficSignals IdentifyTrafficSignals();
void PrepareNodes();
void PrepareManeuverOverrides(const ReferencedWays &maneuver_override_ways);
void PrepareRestrictions(const ReferencedWays &restriction_ways);
void PrepareTrafficFlowControlNodes(
const ReferencedTrafficFlowControlNodes &referenced_traffic_control_nodes,
TrafficFlowControlNodes &internal_traffic_control_nodes);
void PrepareTrafficSignals(const ReferencedTrafficSignals &referenced_traffic_signals);
void PrepareEdges(ScriptingEnvironment &scripting_environment);
void WriteCharData(const std::string &file_name);
@@ -62,6 +54,7 @@ class ExtractionContainers
using NameOffsets = std::vector<size_t>;
using WayIDVector = std::vector<OSMWayID>;
using WayNodeIDOffsets = std::vector<size_t>;
using InputTrafficSignal = std::pair<OSMNodeID, TrafficLightClass::Direction>;
std::vector<OSMNodeID> barrier_nodes;
NodeIDVector used_node_id_list;
@@ -76,14 +69,8 @@ class ExtractionContainers
unsigned max_internal_node_id;
std::vector<InputTrafficFlowControlNode> external_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<InputTrafficSignal> external_traffic_signals;
TrafficSignals internal_traffic_signals;
std::vector<NodeBasedEdge> used_edges;
+4 -10
View File
@@ -1,8 +1,7 @@
#ifndef EXTRACTION_NODE_HPP
#define EXTRACTION_NODE_HPP
#include "traffic_flow_control_nodes.hpp"
#include <cstdint>
#include "traffic_lights.hpp"
namespace osrm
{
@@ -11,19 +10,14 @@ namespace extractor
struct ExtractionNode
{
ExtractionNode() : traffic_lights(TrafficFlowControlNodeDirection::NONE), barrier(false) {}
ExtractionNode() : traffic_lights(TrafficLightClass::NONE), barrier(false) {}
void clear()
{
traffic_lights = TrafficFlowControlNodeDirection::NONE;
stop_sign = TrafficFlowControlNodeDirection::NONE;
give_way = TrafficFlowControlNodeDirection::NONE;
traffic_lights = TrafficLightClass::NONE;
barrier = false;
}
TrafficFlowControlNodeDirection traffic_lights;
TrafficLightClass::Direction traffic_lights;
bool barrier;
TrafficFlowControlNodeDirection stop_sign;
TrafficFlowControlNodeDirection give_way;
};
} // namespace extractor
} // namespace osrm
+1 -6
View File
@@ -51,8 +51,6 @@ struct ExtractionTurn
int number_of_roads,
bool is_u_turn,
bool has_traffic_light,
bool has_stop_sign,
bool has_give_way_sign,
bool is_left_hand_driving,
bool source_restricted,
TravelMode source_mode,
@@ -77,8 +75,7 @@ struct ExtractionTurn
const std::vector<ExtractionTurnLeg> &roads_on_the_right,
const std::vector<ExtractionTurnLeg> &roads_on_the_left)
: angle(180. - angle), number_of_roads(number_of_roads), is_u_turn(is_u_turn),
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),
has_traffic_light(has_traffic_light), is_left_hand_driving(is_left_hand_driving),
source_restricted(source_restricted), source_mode(source_mode),
source_is_motorway(source_is_motorway), source_is_link(source_is_link),
@@ -103,8 +100,6 @@ struct ExtractionTurn
const int number_of_roads;
const bool is_u_turn;
const bool has_traffic_light;
const bool has_stop_sign;
const bool has_give_way_sign;
const bool is_left_hand_driving;
// source info
+3 -7
View File
@@ -43,7 +43,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "util/guidance/turn_lanes.hpp"
#include "restriction_graph.hpp"
#include "traffic_flow_control_nodes.hpp"
#include "traffic_signals.hpp"
#include "util/typedefs.hpp"
namespace osrm
@@ -66,9 +66,7 @@ class Extractor
LaneDescriptionMap turn_lane_map;
std::vector<TurnRestriction> turn_restrictions;
std::vector<UnresolvedManeuverOverride> unresolved_maneuver_overrides;
TrafficFlowControlNodes traffic_signals;
TrafficFlowControlNodes stop_signs;
TrafficFlowControlNodes give_way_signs;
TrafficSignals traffic_signals;
std::unordered_set<NodeID> barriers;
std::vector<util::Coordinate> osm_coordinates;
extractor::PackedOSMIDs osm_node_ids;
@@ -88,9 +86,7 @@ class Extractor
const std::vector<util::Coordinate> &coordinates,
const CompressedEdgeContainer &compressed_edge_container,
const std::unordered_set<NodeID> &barrier_nodes,
const TrafficFlowControlNodes &traffic_signals,
const TrafficFlowControlNodes &stop_signs,
const TrafficFlowControlNodes &give_way_signs,
const TrafficSignals &traffic_signals,
const RestrictionGraph &restriction_graph,
const std::unordered_set<EdgeID> &segregated_edges,
const NameTable &name_table,
@@ -10,7 +10,6 @@
#include <string>
#include <unordered_map>
#include <unordered_set>
namespace osmium
{
+2 -4
View File
@@ -4,7 +4,7 @@
#include "extractor/scripting_environment.hpp"
#include "util/typedefs.hpp"
#include "traffic_flow_control_nodes.hpp"
#include "traffic_signals.hpp"
#include "util/node_based_graph.hpp"
#include <memory>
@@ -26,9 +26,7 @@ class GraphCompressor
public:
void Compress(const std::unordered_set<NodeID> &barrier_nodes,
const TrafficFlowControlNodes &traffic_signals,
const TrafficFlowControlNodes &stop_signs,
const TrafficFlowControlNodes &give_way_signs,
const TrafficSignals &traffic_signals,
ScriptingEnvironment &scripting_environment,
std::vector<TurnRestriction> &turn_restrictions,
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
@@ -63,7 +63,7 @@ struct InternalExtractorEdge
WeightData weight_data,
DurationData duration_data,
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)
{
}
+1 -1
View File
@@ -141,7 +141,7 @@ inline NodeBasedEdgeClassification::NodeBasedEdgeClassification()
}
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)
{
}
@@ -8,7 +8,7 @@
#include "extractor/packed_osm_ids.hpp"
#include "extractor/scripting_environment.hpp"
#include "traffic_flow_control_nodes.hpp"
#include "traffic_signals.hpp"
#include "util/coordinate.hpp"
#include "util/node_based_graph.hpp"
@@ -41,9 +41,7 @@ class NodeBasedGraphFactory
NodeBasedGraphFactory(ScriptingEnvironment &scripting_environment,
std::vector<TurnRestriction> &turn_restrictions,
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
const TrafficFlowControlNodes &traffic_signals,
const TrafficFlowControlNodes &stop_signs,
const TrafficFlowControlNodes &give_way_signs,
const TrafficSignals &traffic_signals,
std::unordered_set<NodeID> &&barriers,
std::vector<util::Coordinate> &&coordinates,
extractor::PackedOSMIDs &&osm_node_ids,
@@ -75,9 +73,7 @@ class NodeBasedGraphFactory
void Compress(ScriptingEnvironment &scripting_environment,
std::vector<TurnRestriction> &turn_restrictions,
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
const TrafficFlowControlNodes &traffic_signals,
const TrafficFlowControlNodes &stop_signs,
const TrafficFlowControlNodes &give_way_signs);
const TrafficSignals &traffic_signals);
// 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
+1 -1
View File
@@ -6,8 +6,8 @@
#include "util/typedefs.hpp"
#include <boost/range/adaptor/filtered.hpp>
#include <boost/unordered_map.hpp>
#include <unordered_map>
#include <utility>
#include <vector>
+1 -1
View File
@@ -114,7 +114,7 @@ struct ProfileProperties
double GetMaxTurnWeight() const
{
return from_alias<double>(MAXIMAL_TURN_PENALTY) / GetWeightMultiplier();
return std::numeric_limits<TurnPenalty>::max() / GetWeightMultiplier();
}
//! penalty to cross a traffic light in deci-seconds
+3 -5
View File
@@ -2,13 +2,11 @@
#define OSRM_EXTRACTOR_RESTRICTION_GRAPH_HPP_
#include <boost/assert.hpp>
#include <boost/unordered_map.hpp>
#include "util/node_based_graph.hpp"
#include "util/std_hash.hpp"
#include "util/typedefs.hpp"
#include <unordered_map>
namespace osrm
{
namespace extractor
@@ -114,10 +112,10 @@ struct RestrictionGraph
RestrictionRange GetRestrictions(RestrictionID id) const;
// A compressed node-based edge can only have one start node in the restriction graph.
std::unordered_map<EdgeKey, RestrictionID> start_edge_to_node{};
boost::unordered_map<EdgeKey, RestrictionID> start_edge_to_node{};
// 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).
std::unordered_multimap<EdgeKey, RestrictionID> via_edge_to_node{};
boost::unordered_multimap<EdgeKey, RestrictionID> via_edge_to_node{};
std::vector<RestrictionNode> nodes;
// TODO: Investigate reusing DynamicGraph. Currently it requires specific attributes
// (e.g. reversed, weight) that would not make sense for restrictions.
+25
View File
@@ -0,0 +1,25 @@
#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_
@@ -2,38 +2,26 @@
#define OSRM_EXTRACTOR_TRAFFIC_SIGNALS_HPP
#include "util/typedefs.hpp"
#include <boost/functional/hash.hpp>
#include <unordered_set>
#include <boost/unordered_set.hpp>
namespace osrm
{
namespace extractor
{
// 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
struct TrafficSignals
{
std::unordered_set<NodeID> bidirectional_nodes;
std::unordered_set<std::pair<NodeID, NodeID>, boost::hash<std::pair<NodeID, NodeID>>>
unidirectional_segments;
inline bool Has(NodeID from, NodeID to) const
inline bool HasSignal(NodeID from, NodeID to) const
{
return bidirectional_nodes.count(to) > 0 || unidirectional_segments.count({from, to}) > 0;
}
};
} // namespace extractor
} // namespace osrm
+4 -4
View File
@@ -3,7 +3,7 @@
#include "util/typedefs.hpp"
#include <unordered_map>
#include <boost/unordered_map.hpp>
#include <vector>
namespace osrm
@@ -43,9 +43,9 @@ class TurnPathCompressor
// via nodes are the same.
// 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.
std::unordered_multimap<NodeID, TurnPath *> starts;
std::unordered_multimap<NodeID, TurnPath *> vias;
std::unordered_multimap<NodeID, TurnPath *> ends;
boost::unordered_multimap<NodeID, TurnPath *> starts;
boost::unordered_multimap<NodeID, TurnPath *> vias;
boost::unordered_multimap<NodeID, TurnPath *> ends;
};
} // namespace extractor
+6 -5
View File
@@ -1,16 +1,17 @@
#ifndef 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_graph.hpp"
#include "util/integer_range.hpp"
#include "util/typedefs.hpp"
// to access the turn restrictions
#include <unordered_map>
#include <utility>
#include <vector>
namespace osrm
{
namespace extractor
+30 -37
View File
@@ -767,37 +767,6 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
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;
}
@@ -830,9 +799,6 @@ inline bool parseCommonParameters(const v8::Local<v8::Object> &obj, ParamType &p
if (annotations->IsBoolean())
{
params->annotations = Nan::To<bool>(annotations).FromJust();
params->annotations_type = params->annotations
? osrm::RouteParameters::AnnotationsType::All
: osrm::RouteParameters::AnnotationsType::None;
}
else if (annotations->IsArray())
{
@@ -879,9 +845,6 @@ inline bool parseCommonParameters(const v8::Local<v8::Object> &obj, ParamType &p
Nan::ThrowError("this 'annotations' param is not supported");
return false;
}
params->annotations =
params->annotations_type != osrm::RouteParameters::AnnotationsType::None;
}
}
else
@@ -1146,6 +1109,36 @@ 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);
if (!parsedSuccessfully)
{
@@ -41,8 +41,8 @@ splitBidirectionalEdges(const std::vector<extractor::EdgeBasedEdge> &edges)
directed.emplace_back(edge.source,
edge.target,
edge.data.turn_id,
std::max(edge.data.weight, {1}),
to_alias<EdgeDuration>(edge.data.duration),
std::max(edge.data.weight, 1),
edge.data.duration,
edge.data.distance,
edge.data.forward,
edge.data.backward);
@@ -50,8 +50,8 @@ splitBidirectionalEdges(const std::vector<extractor::EdgeBasedEdge> &edges)
directed.emplace_back(edge.target,
edge.source,
edge.data.turn_id,
std::max(edge.data.weight, {1}),
to_alias<EdgeDuration>(edge.data.duration),
std::max(edge.data.weight, 1),
edge.data.duration,
edge.data.distance,
edge.data.backward,
edge.data.forward);
+7 -3
View File
@@ -4,14 +4,15 @@
#include "server/http/compression_type.hpp"
#include "server/http/reply.hpp"
#include "server/http/request.hpp"
#include "server/request_parser.hpp"
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/config.hpp>
#include <boost/version.hpp>
#include <memory>
#include <optional>
#include <vector>
// workaround for incomplete std::shared_ptr compatibility in old boost versions
@@ -47,6 +48,7 @@ class Connection : public std::enable_shared_from_this<Connection>
void start();
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);
/// Handle completion of a write operation.
@@ -60,11 +62,13 @@ class Connection : public std::enable_shared_from_this<Connection>
std::vector<char> compress_buffers(const std::vector<char> &uncompressed_data,
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::ip::tcp::socket TCP_socket;
boost::asio::deadline_timer timer;
RequestHandler &request_handler;
RequestParser request_parser;
std::optional<RequestParser> http_request_parser;
boost::array<char, 8192> incoming_data_buffer;
http::request current_request;
http::reply current_reply;
-75
View File
@@ -1,75 +0,0 @@
#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,7 +28,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef OSRM_UTIL_ALIAS_HPP
#define OSRM_UTIL_ALIAS_HPP
#include <boost/numeric/conversion/cast.hpp>
#include <functional>
#include <iostream>
#include <type_traits>
@@ -126,40 +125,6 @@ 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>
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(); }
T operator()(NodeID from, NodeID to) const
EdgeWeight operator()(NodeID from, NodeID to) const
{
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");
@@ -46,7 +46,7 @@ template <typename T> class DistTableWrapper
return table_[index];
}
void SetValue(NodeID from, NodeID to, T value)
void SetValue(NodeID from, NodeID to, EdgeWeight value)
{
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");
+6 -6
View File
@@ -21,14 +21,14 @@ namespace util
struct NodeBasedEdgeData
{
NodeBasedEdgeData()
: weight(INVALID_EDGE_WEIGHT), duration(INVALID_EDGE_DURATION),
: weight(INVALID_EDGE_WEIGHT), duration(INVALID_EDGE_WEIGHT),
distance(INVALID_EDGE_DISTANCE), geometry_id({0, false}), reversed(false),
annotation_data(-1)
{
}
NodeBasedEdgeData(EdgeWeight weight,
EdgeDuration duration,
EdgeWeight duration,
EdgeDistance distance,
GeometryID geometry_id,
bool reversed,
@@ -40,7 +40,7 @@ struct NodeBasedEdgeData
}
EdgeWeight weight;
EdgeDuration duration;
EdgeWeight duration;
EdgeDistance distance;
GeometryID geometry_id;
bool reversed : 1;
@@ -88,9 +88,9 @@ NodeBasedDynamicGraphFromEdges(NodeID number_of_nodes,
output_edge.data.flags = input_edge.flags;
output_edge.data.annotation_data = input_edge.annotation_data;
BOOST_ASSERT(output_edge.data.weight > EdgeWeight{0});
BOOST_ASSERT(output_edge.data.duration > EdgeDuration{0});
BOOST_ASSERT(output_edge.data.distance >= EdgeDistance{0});
BOOST_ASSERT(output_edge.data.weight > 0);
BOOST_ASSERT(output_edge.data.duration > 0);
BOOST_ASSERT(output_edge.data.distance >= 0);
});
tbb::parallel_sort(edges_list.begin(), edges_list.end());
+2 -34
View File
@@ -83,45 +83,19 @@ inline T get_upper_half_value(WordT word,
}
template <typename WordT, typename T>
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)
inline WordT set_lower_value(WordT word, WordT mask, std::uint8_t offset, T value)
{
static_assert(std::is_unsigned<WordT>::value, "Only unsigned word types supported for now.");
return (word & ~mask) | ((static_cast<WordT>(value) << offset) & mask);
}
template <typename WordT, typename T>
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)
inline WordT set_upper_value(WordT word, WordT mask, std::uint8_t offset, T value)
{
static_assert(std::is_unsigned<WordT>::value, "Only unsigned word types supported for now.");
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)
{
#if defined(_MSC_VER)
@@ -313,12 +287,6 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
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)
{
return os << static_cast<T>(rhs);
+16 -50
View File
@@ -48,26 +48,7 @@ struct osm_way_id
struct duplicated_node
{
};
struct edge_weight
{
};
struct edge_duration
{
};
struct edge_distance
{
};
struct segment_weight
{
};
struct segment_duration
{
};
struct turn_penalty
{
};
} // namespace tag
using OSMNodeID = osrm::Alias<std::uint64_t, tag::osm_node_id>;
// clang-tidy fires `bugprone-throw-keyword-missing` here for unknown reason
// NOLINTNEXTLINE(bugprone-throw-keyword-missing)
@@ -96,13 +77,12 @@ using EdgeID = std::uint32_t;
using NameID = std::uint32_t;
using AnnotationID = std::uint32_t;
using PackedGeometryID = std::uint32_t;
using EdgeWeight = osrm::Alias<std::int32_t, tag::edge_weight>;
using EdgeDuration = osrm::Alias<std::int32_t, tag::edge_duration>;
using EdgeDistance = osrm::Alias<float, tag::edge_distance>;
using SegmentWeight = osrm::Alias<std::uint32_t, tag::segment_weight>;
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
using EdgeWeight = std::int32_t;
using EdgeDuration = std::int32_t;
using EdgeDistance = float;
using SegmentWeight = std::uint32_t;
using SegmentDuration = std::uint32_t;
using TurnPenalty = std::int16_t; // turn penalty in 100ms units
static const std::size_t INVALID_INDEX = std::numeric_limits<std::size_t>::max();
@@ -129,30 +109,16 @@ static const NameID EMPTY_NAMEID = 0;
static const unsigned INVALID_COMPONENTID = 0;
static const std::size_t SEGMENT_WEIGHT_BITS = 22;
static const std::size_t SEGMENT_DURATION_BITS = 22;
static const SegmentWeight INVALID_SEGMENT_WEIGHT = SegmentWeight{(1u << SEGMENT_WEIGHT_BITS) - 1};
static const SegmentDuration INVALID_SEGMENT_DURATION =
SegmentDuration{(1u << SEGMENT_DURATION_BITS) - 1};
static const SegmentWeight MAX_SEGMENT_WEIGHT = INVALID_SEGMENT_WEIGHT - SegmentWeight{1};
static const SegmentDuration MAX_SEGMENT_DURATION = INVALID_SEGMENT_DURATION - SegmentDuration{1};
static const EdgeWeight INVALID_EDGE_WEIGHT =
EdgeWeight{std::numeric_limits<EdgeWeight::value_type>::max()};
static const EdgeDuration INVALID_EDGE_DURATION =
EdgeDuration{std::numeric_limits<EdgeDuration::value_type>::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()};
static const SegmentWeight INVALID_SEGMENT_WEIGHT = (1u << SEGMENT_WEIGHT_BITS) - 1;
static const SegmentDuration INVALID_SEGMENT_DURATION = (1u << SEGMENT_DURATION_BITS) - 1;
static const SegmentWeight MAX_SEGMENT_WEIGHT = INVALID_SEGMENT_WEIGHT - 1;
static const SegmentDuration MAX_SEGMENT_DURATION = INVALID_SEGMENT_DURATION - 1;
static const EdgeWeight INVALID_EDGE_WEIGHT = std::numeric_limits<EdgeWeight>::max();
static const EdgeDuration MAXIMAL_EDGE_DURATION = std::numeric_limits<EdgeDuration>::max();
static const EdgeDistance MAXIMAL_EDGE_DISTANCE = std::numeric_limits<EdgeDistance>::max();
static const TurnPenalty INVALID_TURN_PENALTY = std::numeric_limits<TurnPenalty>::max();
static const EdgeDistance INVALID_EDGE_DISTANCE = std::numeric_limits<EdgeDistance>::max();
static const EdgeDistance INVALID_FALLBACK_SPEED = std::numeric_limits<EdgeDistance>::max();
using DatasourceID = std::uint8_t;
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@project-osrm/osrm",
"version": "5.28.0-unreleased",
"name": "osrm",
"version": "5.27.0-unreleased",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -10090,9 +10090,9 @@
"dev": true
},
"nan": {
"version": "2.17.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz",
"integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ=="
"version": "2.16.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz",
"integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA=="
},
"nanomatch": {
"version": "1.2.13",
+2 -2
View File
@@ -1,13 +1,13 @@
{
"name": "@project-osrm/osrm",
"version": "5.28.0-unreleased",
"version": "5.27.0",
"private": false,
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.",
"dependencies": {
"@mapbox/node-pre-gyp": "^1.0.9",
"cheap-ruler": "^3.0.2",
"mkdirp": "^0.5.6",
"nan": "^2.17.0",
"nan": "^2.16.0",
"node-cmake": "^2.5.1",
"rimraf": "^2.7.1"
},
-3
View File
@@ -178,7 +178,6 @@ function setup()
concrete = default_speed,
concrete_lanes = default_speed,
wood = 10,
metal = 10,
["cobblestone:flattened"] = 10,
paving_stones = 10,
compacted = 10,
@@ -187,14 +186,12 @@ function setup()
fine_gravel = 10,
gravel = 6,
pebblestone = 6,
grass_paver = 6,
ground = 10,
dirt = 8,
earth = 6,
grass = 6,
mud = 3,
sand = 3,
woodchips = 3,
sett = 9
},
+1 -16
View File
@@ -7,8 +7,6 @@ Sequence = require('lib/sequence')
Handlers = require("lib/way_handlers")
Relations = require("lib/relations")
TrafficSignal = require("lib/traffic_signal")
StopSign = require("lib/stop_sign")
GiveWay = require("lib/give_way")
find_access_tag = require("lib/access").find_access_tag
limit = require("lib/maxspeed").limit
Utils = require("lib/utils")
@@ -30,8 +28,6 @@ function setup()
use_turn_restrictions = true,
left_hand_driving = false,
traffic_light_penalty = 2,
stop_sign_penalty = 2,
give_way_sign_penalty = 1.5
},
default_mode = mode.driving,
@@ -366,12 +362,6 @@ function process_node(profile, node, result, relations)
-- check if node is a traffic light
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
function process_way(profile, way, result, relations)
@@ -481,14 +471,9 @@ function process_turn(profile, turn)
local turn_bias = turn.is_left_hand_driving and 1. / profile.turn_bias or profile.turn_bias
if turn.has_traffic_light then
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
turn.duration = profile.properties.traffic_light_penalty
end
if turn.number_of_roads > 2 or turn.source_mode ~= turn.target_mode or turn.is_u_turn 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)))
-9
View File
@@ -1,9 +0,0 @@
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
@@ -1,10 +0,0 @@
local StopSign = {}
TrafficFlowControlNode = require("lib/traffic_flow_control_node")
function StopSign.get_value(node)
return TrafficFlowControlNode.get_value(node, "stop")
end
return StopSign
@@ -1,21 +0,0 @@
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")
if direction then
if "forward" == direction then
return traffic_flow_control_direction.direction_forward
return traffic_lights.direction_forward
end
if "backward" == direction then
return traffic_flow_control_direction.direction_reverse
return traffic_lights.direction_reverse
end
end
-- return traffic_lights.direction_all
+1 -2
View File
@@ -78,8 +78,7 @@ int Contractor::Run()
// Convert node weights for oneway streets to INVALID_EDGE_WEIGHT
for (auto &weight : node_weights)
{
weight = (from_alias<EdgeWeight::value_type>(weight) & 0x80000000) ? INVALID_EDGE_WEIGHT
: weight;
weight = (weight & 0x80000000) ? INVALID_EDGE_WEIGHT : weight;
}
// Contracting the edge-expanded graph
+3 -3
View File
@@ -170,8 +170,8 @@ void ContractNode(ContractorThreadData *data,
}
heap.Clear();
heap.Insert(source, {0}, ContractorHeapData{});
EdgeWeight max_weight = {0};
heap.Insert(source, 0, ContractorHeapData{});
EdgeWeight max_weight = 0;
unsigned number_of_targets = 0;
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
// guarantees that source is not connected to another node that is
// contracted
node_weights[source] = path_weight + EdgeWeight{1};
node_weights[source] = path_weight + 1;
BOOST_ASSERT(stats != nullptr);
stats->edges_added_count += 2;
stats->original_edges_added_count +=
+1 -2
View File
@@ -133,8 +133,7 @@ int Customizer::Run(const CustomizationConfig &config)
auto graph = LoadAndUpdateEdgeExpandedGraph(
config, mlp, node_weights, node_durations, node_distances, connectivity_checksum);
BOOST_ASSERT(graph.GetNumberOfNodes() == node_weights.size());
std::for_each(
node_weights.begin(), node_weights.end(), [](auto &w) { w &= EdgeWeight{0x7fffffff}; });
std::for_each(node_weights.begin(), node_weights.end(), [](auto &w) { w &= 0x7fffffff; });
util::Log() << "Loaded edge based graph: " << graph.GetNumberOfEdges() << " edges, "
<< graph.GetNumberOfNodes() << " nodes";
+3 -3
View File
@@ -3,11 +3,11 @@
#include "engine/datafacade/datafacade_base.hpp"
#include <boost/assert.hpp>
#include <boost/unordered_set.hpp>
#include <algorithm>
#include <iterator>
#include <tuple>
#include <unordered_set>
namespace osrm
{
@@ -106,8 +106,8 @@ bool Hint::IsValid(const util::Coordinate new_input_coordinates,
// Check hints do not contain duplicate segment pairs
// We can't allow duplicates as search heaps do not support it.
std::unordered_set<NodeID> forward_segments;
std::unordered_set<NodeID> reverse_segments;
boost::unordered_set<NodeID> forward_segments;
boost::unordered_set<NodeID> reverse_segments;
for (const auto &seg_hint : segment_hints)
{
const auto forward_res = forward_segments.insert(seg_hint.phantom.forward_segment_id.id);
+9 -14
View File
@@ -90,8 +90,7 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
std::vector<api::TableAPI::TableCellRef> estimated_pairs;
// Scan table for null results - if any exist, replace with distance estimates
if (params.fallback_speed != from_alias<double>(INVALID_FALLBACK_SPEED) ||
params.scale_factor != 1)
if (params.fallback_speed != INVALID_FALLBACK_SPEED || params.scale_factor != 1)
{
for (std::size_t row = 0; row < num_sources; row++)
{
@@ -99,8 +98,7 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
{
const auto &table_index = row * num_destinations + column;
BOOST_ASSERT(table_index < result_tables_pair.first.size());
if (params.fallback_speed != from_alias<double>(INVALID_FALLBACK_SPEED) &&
params.fallback_speed > 0 &&
if (params.fallback_speed != INVALID_FALLBACK_SPEED && params.fallback_speed > 0 &&
result_tables_pair.first[table_index] == MAXIMAL_EDGE_DURATION)
{
const auto &source =
@@ -120,32 +118,29 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
candidatesSnappedLocation(destination));
result_tables_pair.first[table_index] =
to_alias<EdgeDuration>(distance_estimate / params.fallback_speed);
distance_estimate / (double)params.fallback_speed;
if (!result_tables_pair.second.empty())
{
result_tables_pair.second[table_index] =
to_alias<EdgeDistance>(distance_estimate);
result_tables_pair.second[table_index] = distance_estimate;
}
estimated_pairs.emplace_back(row, column);
}
if (params.scale_factor > 0 && params.scale_factor != 1 &&
result_tables_pair.first[table_index] != MAXIMAL_EDGE_DURATION &&
result_tables_pair.first[table_index] != EdgeDuration{0})
result_tables_pair.first[table_index] != 0)
{
EdgeDuration diff =
MAXIMAL_EDGE_DURATION / result_tables_pair.first[table_index];
if (params.scale_factor >= from_alias<double>(diff))
if (params.scale_factor >= diff)
{
result_tables_pair.first[table_index] =
MAXIMAL_EDGE_DURATION - EdgeDuration{1};
result_tables_pair.first[table_index] = MAXIMAL_EDGE_DURATION - 1;
}
else
{
result_tables_pair.first[table_index] = to_alias<EdgeDuration>(
std::lround(from_alias<double>(result_tables_pair.first[table_index]) *
params.scale_factor));
result_tables_pair.first[table_index] = std::lround(
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);
// If this is a valid forward edge, go ahead and add it to the tile
if (forward_duration != SegmentDuration{0} && edge.forward_segment_id.enabled)
if (forward_duration != 0 && edge.forward_segment_id.enabled)
{
// Calculate the speed for this line
std::uint32_t speed_kmh_idx = static_cast<std::uint32_t>(
round(length / from_alias<double>(forward_duration) * 10 * 3.6));
std::uint32_t speed_kmh_idx =
static_cast<std::uint32_t>(round(length / forward_duration * 10 * 3.6));
// Rate values are in meters per weight-unit - and similar to speeds, we
// present 1 decimal place of precision (these values are added as
// double/10) lower down
std::uint32_t forward_rate = static_cast<std::uint32_t>(
round(length / from_alias<double>(forward_weight) * 10.));
std::uint32_t forward_rate =
static_cast<std::uint32_t>(round(length / forward_weight * 10.));
auto tile_line = coordinatesToTileLine(a, b, tile_bbox);
if (!tile_line.empty())
@@ -519,8 +519,8 @@ void encodeVectorTile(const DataFacadeBase &facade,
fbuilder.set_is_small(component_id.is_tiny);
fbuilder.set_datasource(
facade.GetDatasourceName(forward_datasource_idx).to_string());
fbuilder.set_weight(from_alias<double>(forward_weight) / 10.0);
fbuilder.set_duration(from_alias<double>(forward_duration) / 10.0);
fbuilder.set_weight(forward_weight / 10.0);
fbuilder.set_duration(forward_duration / 10.0);
fbuilder.set_name(name);
fbuilder.set_rate(forward_rate / 10.0);
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`
// properties
if (reverse_duration != SegmentDuration{0} && edge.reverse_segment_id.enabled)
if (reverse_duration != 0 && edge.reverse_segment_id.enabled)
{
// Calculate the speed for this line
std::uint32_t speed_kmh_idx = static_cast<std::uint32_t>(
round(length / from_alias<double>(reverse_duration) * 10 * 3.6));
std::uint32_t speed_kmh_idx =
static_cast<std::uint32_t>(round(length / reverse_duration * 10 * 3.6));
// Rate values are in meters per weight-unit - and similar to speeds, we
// present 1 decimal place of precision (these values are added as
// double/10) lower down
std::uint32_t reverse_rate = static_cast<std::uint32_t>(
round(length / from_alias<double>(reverse_weight) * 10.));
std::uint32_t reverse_rate =
static_cast<std::uint32_t>(round(length / reverse_weight * 10.));
auto tile_line = coordinatesToTileLine(b, a, tile_bbox);
if (!tile_line.empty())
@@ -553,8 +553,8 @@ void encodeVectorTile(const DataFacadeBase &facade,
fbuilder.set_is_small(component_id.is_tiny);
fbuilder.set_datasource(
facade.GetDatasourceName(reverse_datasource_idx).to_string());
fbuilder.set_weight(from_alias<double>(reverse_weight) / 10.0);
fbuilder.set_duration(from_alias<double>(reverse_duration) / 10.0);
fbuilder.set_weight(reverse_weight / 10.0);
fbuilder.set_duration(reverse_duration / 10.0);
fbuilder.set_name(name);
fbuilder.set_rate(reverse_rate / 10.0);
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_turn_angle(turn_data.turn_angle);
fbuilder.set_cost(from_alias<double>(turn_data.duration) / 10.0);
fbuilder.set_weight(from_alias<double>(turn_data.weight) / 10.0);
fbuilder.set_cost(turn_data.duration / 10.0);
fbuilder.set_weight(turn_data.weight / 10.0);
fbuilder.set_turn(turn_data.turn_instruction);
fbuilder.commit();
+12 -12
View File
@@ -20,9 +20,9 @@ namespace engine
namespace plugins
{
bool IsStronglyConnectedComponent(const util::DistTableWrapper<EdgeDuration> &result_table)
bool IsStronglyConnectedComponent(const util::DistTableWrapper<EdgeWeight> &result_table)
{
return std::find(std::begin(result_table), std::end(result_table), INVALID_EDGE_DURATION) ==
return std::find(std::begin(result_table), std::end(result_table), INVALID_EDGE_WEIGHT) ==
std::end(result_table);
}
@@ -68,7 +68,7 @@ TripPlugin::ComputeRoute(const RoutingAlgorithmsInterface &algorithms,
void ManipulateTableForFSE(const std::size_t source_id,
const std::size_t destination_id,
util::DistTableWrapper<EdgeDuration> &result_table)
util::DistTableWrapper<EdgeWeight> &result_table)
{
// ****************** Change Table *************************
// 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)
continue;
result_table.SetValue(i, source_id, INVALID_EDGE_DURATION);
result_table.SetValue(i, source_id, INVALID_EDGE_WEIGHT);
}
// change parameters.destination row
@@ -104,22 +104,22 @@ void ManipulateTableForFSE(const std::size_t source_id,
{
if (i == destination_id)
continue;
result_table.SetValue(destination_id, i, INVALID_EDGE_DURATION);
result_table.SetValue(destination_id, i, INVALID_EDGE_WEIGHT);
}
// set destination->source to zero so roundtrip treats source and
// 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
// to find another path to get to destination
result_table.SetValue(source_id, destination_id, INVALID_EDGE_DURATION);
result_table.SetValue(source_id, destination_id, INVALID_EDGE_WEIGHT);
//********* End of changes to table *************************************
}
void ManipulateTableForNonRoundtripFS(const std::size_t source_id,
util::DistTableWrapper<EdgeDuration> &result_table)
util::DistTableWrapper<EdgeWeight> &result_table)
{
// 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'
@@ -127,12 +127,12 @@ void ManipulateTableForNonRoundtripFS(const std::size_t source_id,
// source.
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,
util::DistTableWrapper<EdgeDuration> &result_table)
util::DistTableWrapper<EdgeWeight> &result_table)
{
// 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.
@@ -140,7 +140,7 @@ void ManipulateTableForNonRoundtripFE(const std::size_t destination_id,
// from the destination to any source.
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);
// compute the duration table of all phantom nodes
auto result_duration_table = util::DistTableWrapper<EdgeDuration>(
auto result_duration_table = util::DistTableWrapper<EdgeWeight>(
algorithms.ManyToManySearch(snapped_phantoms, {}, {}, /*requestDistance*/ false).first,
number_of_locations);
@@ -44,7 +44,7 @@ struct RankedCandidateNode
bool operator<(const RankedCandidateNode &other) const
{
return (EdgeWeight{2} * weight + sharing) < (EdgeWeight{2} * other.weight + other.sharing);
return (2 * weight + sharing) < (2 * other.weight + other.sharing);
}
};
@@ -66,8 +66,8 @@ void alternativeRoutingStep(const DataFacade<Algorithm> &facade,
// toHeapNode is the same
const auto heapNode = forward_heap.DeleteMinGetHeapNode();
const auto scaled_weight = to_alias<EdgeWeight>(
from_alias<double>(heapNode.weight + min_edge_offset) / (1. + VIAPATH_EPSILON));
const auto scaled_weight =
static_cast<EdgeWeight>((heapNode.weight + min_edge_offset) / (1. + VIAPATH_EPSILON));
if ((INVALID_EDGE_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;
if (new_weight < *upper_bound_to_shortest_path_weight)
{
if (new_weight >= EdgeWeight{0})
if (new_weight >= 0)
{
*middle_node = heapNode.node;
*upper_bound_to_shortest_path_weight = new_weight;
@@ -92,8 +92,7 @@ void alternativeRoutingStep(const DataFacade<Algorithm> &facade,
else
{
// check whether there is a loop present at the node
const auto loop_weight =
std::get<0>(getLoopMetric<EdgeWeight>(facade, heapNode.node));
const auto loop_weight = std::get<0>(getLoopWeight<false>(facade, heapNode.node));
const EdgeWeight new_weight_with_loop = new_weight + loop_weight;
if (loop_weight != INVALID_EDGE_WEIGHT &&
new_weight_with_loop <= *upper_bound_to_shortest_path_weight)
@@ -113,7 +112,7 @@ void alternativeRoutingStep(const DataFacade<Algorithm> &facade,
const NodeID to = facade.GetTarget(edge);
const EdgeWeight edge_weight = data.weight;
BOOST_ASSERT(edge_weight > EdgeWeight{0});
BOOST_ASSERT(edge_weight > 0);
const EdgeWeight to_weight = heapNode.weight + edge_weight;
const auto toHeapNode = forward_heap.GetHeapNodeIfWasInserted(to);
@@ -181,7 +180,7 @@ void computeWeightAndSharingOfViaPath(SearchEngineData<Algorithm> &engine_workin
NodeID s_v_middle = SPECIAL_NODEID;
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
while (!new_reverse_heap.Empty())
{
@@ -197,7 +196,7 @@ void computeWeightAndSharingOfViaPath(SearchEngineData<Algorithm> &engine_workin
// compute path <v,..,t> by reusing backward search from node t
NodeID v_t_middle = SPECIAL_NODEID;
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())
{
routingStep<FORWARD_DIRECTION>(facade,
@@ -343,7 +342,7 @@ bool viaNodeCandidatePassesTTest(SearchEngineData<Algorithm> &engine_working_dat
*s_v_middle = SPECIAL_NODEID;
EdgeWeight upper_bound_s_v_path_weight = INVALID_EDGE_WEIGHT;
// 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)
{
routingStep<REVERSE_DIRECTION>(facade,
@@ -364,7 +363,7 @@ bool viaNodeCandidatePassesTTest(SearchEngineData<Algorithm> &engine_working_dat
// compute path <v,..,t> by reusing backward search from t
*v_t_middle = SPECIAL_NODEID;
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)
{
routingStep<FORWARD_DIRECTION>(facade,
@@ -401,9 +400,8 @@ bool viaNodeCandidatePassesTTest(SearchEngineData<Algorithm> &engine_working_dat
{
return false;
}
const EdgeWeight T_threshold =
to_alias<EdgeWeight>(VIAPATH_ALPHA * from_alias<double>(weight_of_shortest_path));
EdgeWeight unpacked_until_weight = {0};
const EdgeWeight T_threshold = static_cast<EdgeWeight>(VIAPATH_ALPHA * weight_of_shortest_path);
EdgeWeight unpacked_until_weight = 0;
std::stack<SearchSpaceEdge> unpack_stack;
// Traverse path s-->v
@@ -465,7 +463,7 @@ bool viaNodeCandidatePassesTTest(SearchEngineData<Algorithm> &engine_working_dat
}
EdgeWeight t_test_path_weight = unpacked_until_weight;
unpacked_until_weight = {0};
unpacked_until_weight = 0;
// Traverse path s-->v
BOOST_ASSERT(!packed_v_t_path.empty());
for (unsigned i = 0, packed_path_length = static_cast<unsigned>(packed_v_t_path.size() - 1);
@@ -534,8 +532,8 @@ bool viaNodeCandidatePassesTTest(SearchEngineData<Algorithm> &engine_working_dat
EdgeWeight upper_bound = INVALID_EDGE_WEIGHT;
NodeID middle = SPECIAL_NODEID;
forward_heap3.Insert(s_P, {0}, s_P);
reverse_heap3.Insert(t_P, {0}, t_P);
forward_heap3.Insert(s_P, 0, s_P);
reverse_heap3.Insert(t_P, 0, t_P);
// exploration from s and t until deletemin/(1+epsilon) > _lengt_oO_sShortest_path
while ((forward_heap3.Size() + reverse_heap3.Size()) > 0)
{
@@ -582,11 +580,10 @@ InternalManyRoutesResult alternativePathSearch(SearchEngineData<Algorithm> &engi
insertNodesInHeaps(forward_heap1, reverse_heap1, endpoint_candidates);
// get offset to account for offsets on phantom nodes on compressed edges
EdgeWeight min_edge_offset =
forward_heap1.Empty() ? EdgeWeight{0} : std::min<EdgeWeight>({0}, forward_heap1.MinKey());
BOOST_ASSERT(min_edge_offset <= EdgeWeight{0});
EdgeWeight min_edge_offset = forward_heap1.Empty() ? 0 : std::min(0, forward_heap1.MinKey());
BOOST_ASSERT(min_edge_offset <= 0);
// we only every insert negative offsets for nodes in the forward heap
BOOST_ASSERT(reverse_heap1.Empty() || reverse_heap1.MinKey() >= EdgeWeight{0});
BOOST_ASSERT(reverse_heap1.Empty() || reverse_heap1.MinKey() >= 0);
// search from s and t till new_min/(1+epsilon) > weight_of_shortest_path
while (0 < (forward_heap1.Size() + reverse_heap1.Size()))
@@ -704,27 +701,22 @@ InternalManyRoutesResult alternativePathSearch(SearchEngineData<Algorithm> &engi
if (node == middle_node)
continue;
const auto fwd_iterator = approximated_forward_sharing.find(node);
const EdgeWeight fwd_sharing = (fwd_iterator != approximated_forward_sharing.end())
? fwd_iterator->second
: EdgeWeight{0};
const EdgeWeight fwd_sharing =
(fwd_iterator != approximated_forward_sharing.end()) ? fwd_iterator->second : 0;
const auto rev_iterator = approximated_reverse_sharing.find(node);
const EdgeWeight rev_sharing = (rev_iterator != approximated_reverse_sharing.end())
? rev_iterator->second
: EdgeWeight{0};
const EdgeWeight rev_sharing =
(rev_iterator != approximated_reverse_sharing.end()) ? rev_iterator->second : 0;
const EdgeWeight approximated_sharing = fwd_sharing + rev_sharing;
const EdgeWeight approximated_weight =
forward_heap1.GetKey(node) + reverse_heap1.GetKey(node);
const bool weight_passes =
(from_alias<double>(approximated_weight) <
from_alias<double>(upper_bound_to_shortest_path_weight) * (1 + VIAPATH_EPSILON));
(approximated_weight < upper_bound_to_shortest_path_weight * (1 + VIAPATH_EPSILON));
const bool sharing_passes =
(from_alias<double>(approximated_sharing) <=
from_alias<double>(upper_bound_to_shortest_path_weight) * VIAPATH_GAMMA);
(approximated_sharing <= upper_bound_to_shortest_path_weight * VIAPATH_GAMMA);
const bool stretch_passes =
from_alias<double>(approximated_weight - approximated_sharing) <
((1. + VIAPATH_EPSILON) *
from_alias<double>(upper_bound_to_shortest_path_weight - approximated_sharing));
(approximated_weight - approximated_sharing) <
((1. + VIAPATH_EPSILON) * (upper_bound_to_shortest_path_weight - approximated_sharing));
if (weight_passes && sharing_passes && stretch_passes)
{
@@ -745,7 +737,7 @@ InternalManyRoutesResult alternativePathSearch(SearchEngineData<Algorithm> &engi
// prioritizing via nodes for deep inspection
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,
facade,
node,
@@ -753,11 +745,10 @@ InternalManyRoutesResult alternativePathSearch(SearchEngineData<Algorithm> &engi
&sharing_of_via_path,
packed_shortest_path,
min_edge_offset);
const EdgeWeight maximum_allowed_sharing = to_alias<EdgeWeight>(
from_alias<double>(upper_bound_to_shortest_path_weight) * VIAPATH_GAMMA);
const EdgeWeight maximum_allowed_sharing =
static_cast<EdgeWeight>(upper_bound_to_shortest_path_weight * VIAPATH_GAMMA);
if (sharing_of_via_path <= maximum_allowed_sharing &&
from_alias<double>(weight_of_via_path) <=
from_alias<double>(upper_bound_to_shortest_path_weight) * (1 + VIAPATH_EPSILON))
weight_of_via_path <= upper_bound_to_shortest_path_weight * (1 + VIAPATH_EPSILON))
{
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:
// - Shortest path 10 minutes, alternative 13 minutes => Factor of 0.30 ok
// - Shortest path 10 hours, alternative 13 hours => Factor of 0.30 unreasonable
double getLongerByFactorBasedOnDuration(const EdgeDuration duration)
double getLongerByFactorBasedOnDuration(const EdgeWeight duration)
{
BOOST_ASSERT(duration != INVALID_EDGE_DURATION);
BOOST_ASSERT(duration != INVALID_EDGE_WEIGHT);
// 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.
@@ -118,20 +118,19 @@ double getLongerByFactorBasedOnDuration(const EdgeDuration duration)
const constexpr auto c = 2.45437877e+09;
const constexpr auto d = -2.07944571e+03;
if (duration < EdgeDuration{5 * 60})
if (duration < EdgeWeight(5 * 60))
{
return 1.0;
}
else if (duration > EdgeDuration{10 * 60 * 60})
else if (duration > EdgeWeight(10 * 60 * 60))
{
return 0.20;
}
// Bigger than 10 minutes but smaller than 10 hours
BOOST_ASSERT(duration >= EdgeDuration{5 * 60} && duration <= EdgeDuration{10 * 60 * 60});
BOOST_ASSERT(duration >= 5 * 60 && duration <= 10 * 60 * 60);
return a + b / (from_alias<double>(duration) - d) +
c / std::pow(from_alias<double>(duration) - d, 3);
return a + b / (duration - d) + c / std::pow(duration - d, 3);
}
Parameters parametersFromRequest(const PhantomEndpointCandidates &endpoint_candidates)
@@ -224,11 +223,10 @@ RandIt filterViaCandidatesByStretch(RandIt first,
// 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
// either generate more candidates than we have to or not enough. But is okay.
const auto stretch_weight_limit =
(1. + parameters.kAtMostLongerBy) * from_alias<double>(weight);
const auto stretch_weight_limit = (1. + parameters.kAtMostLongerBy) * weight;
const auto over_weight_limit = [=](const auto via) {
return from_alias<double>(via.weight) > stretch_weight_limit;
return via.weight > stretch_weight_limit;
};
return std::remove_if(first, last, over_weight_limit);
@@ -446,8 +444,7 @@ RandIt filterPackedPathsByLocalOptimality(const WeightedViaNodePackedPath &path,
const auto detour_length = forward_heap.GetKey(via) - forward_heap.GetKey(a) +
reverse_heap.GetKey(via) - reverse_heap.GetKey(b);
return from_alias<double>(plateaux_length) <
parameters.kAtLeastOptimalAroundViaBy * from_alias<double>(detour_length);
return plateaux_length < parameters.kAtLeastOptimalAroundViaBy * detour_length;
};
return std::remove_if(first, last, is_not_locally_optimal);
@@ -485,8 +482,8 @@ RandIt filterUnpackedPathsBySharing(RandIt first,
return false;
}
EdgeDuration total_duration = {0};
const auto add_if_seen = [&](const EdgeDuration duration, const NodeID node) {
EdgeWeight total_duration = 0;
const auto add_if_seen = [&](const EdgeWeight duration, const NodeID node) {
auto node_duration = facade.GetNodeDuration(node);
total_duration += node_duration;
if (nodes.count(node) > 0)
@@ -499,7 +496,7 @@ RandIt filterUnpackedPathsBySharing(RandIt first,
const auto shared_duration = std::accumulate(
begin(unpacked.nodes), end(unpacked.nodes), EdgeDuration{0}, add_if_seen);
unpacked.sharing = from_alias<double>(shared_duration) / from_alias<double>(total_duration);
unpacked.sharing = shared_duration / static_cast<double>(total_duration);
BOOST_ASSERT(unpacked.sharing >= 0.);
BOOST_ASSERT(unpacked.sharing <= 1.);
@@ -534,11 +531,10 @@ RandIt filterAnnotatedRoutesByStretch(RandIt first,
BOOST_ASSERT(shortest_route.is_valid());
const auto shortest_route_duration = shortest_route.duration();
const auto stretch_duration_limit =
(1. + parameters.kAtMostLongerBy) * from_alias<double>(shortest_route_duration);
const auto stretch_duration_limit = (1. + parameters.kAtMostLongerBy) * shortest_route_duration;
const auto over_duration_limit = [=](const auto &route) {
return from_alias<double>(route.duration()) > stretch_duration_limit;
return route.duration() > stretch_duration_limit;
};
return std::remove_if(first, last, over_duration_limit);
@@ -614,8 +610,8 @@ void unpackPackedPaths(InputIt first,
// Here heaps can be reused, let's go deeper!
forward_heap.Clear();
reverse_heap.Clear();
forward_heap.Insert(source, {0}, {source});
reverse_heap.Insert(target, {0}, {target});
forward_heap.Insert(source, 0, {source});
reverse_heap.Insert(target, 0, {target});
BOOST_ASSERT(!facade.ExcludeNode(source));
BOOST_ASSERT(!facade.ExcludeNode(target));
@@ -698,8 +694,7 @@ makeCandidateVias(SearchEngineData<Algorithm> &search_engine_data,
while (forward_heap.Size() + reverse_heap.Size() > 0)
{
if (shortest_path_weight != INVALID_EDGE_WEIGHT)
overlap_weight = to_alias<EdgeWeight>(from_alias<double>(shortest_path_weight) *
parameters.kSearchSpaceOverlapFactor);
overlap_weight = shortest_path_weight * parameters.kSearchSpaceOverlapFactor;
// 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;
@@ -825,10 +820,8 @@ InternalManyRoutesResult alternativePathSearch(SearchEngineData<Algorithm> &sear
NodeID shortest_path_via = shortest_path_via_it->node;
EdgeWeight shortest_path_weight = shortest_path_via_it->weight;
const double duration_estimation =
from_alias<double>(shortest_path_weight) / facade.GetWeightMultiplier();
parameters.kAtMostLongerBy =
getLongerByFactorBasedOnDuration(to_alias<EdgeDuration>(duration_estimation));
const double duration_estimation = shortest_path_weight / facade.GetWeightMultiplier();
parameters.kAtMostLongerBy = getLongerByFactorBasedOnDuration(duration_estimation);
// Filters via candidate nodes with heuristics
@@ -24,16 +24,16 @@ inline bool addLoopWeight(const DataFacade<ch::Algorithm> &facade,
EdgeDuration &duration,
EdgeDistance &distance)
{ // Special case for CH when contractor creates a loop edge node->node
BOOST_ASSERT(weight < EdgeWeight{0});
BOOST_ASSERT(weight < 0);
const auto loop_weight = ch::getLoopMetric<EdgeWeight>(facade, node);
const auto loop_weight = ch::getLoopWeight<false>(facade, node);
if (std::get<0>(loop_weight) != INVALID_EDGE_WEIGHT)
{
const auto new_weight_with_loop = weight + std::get<0>(loop_weight);
if (new_weight_with_loop >= EdgeWeight{0})
if (new_weight_with_loop >= 0)
{
weight = new_weight_with_loop;
auto result = ch::getLoopMetric<EdgeDuration>(facade, node);
auto result = ch::getLoopWeight<true>(facade, node);
duration += std::get<0>(result);
distance += std::get<1>(result);
return true;
@@ -67,9 +67,9 @@ void relaxOutgoingEdges(
const auto edge_duration = data.duration;
const auto edge_distance = data.distance;
BOOST_ASSERT_MSG(edge_weight > EdgeWeight{0}, "edge_weight invalid");
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
const auto to_weight = heapNode.weight + edge_weight;
const auto to_duration = heapNode.data.duration + to_alias<EdgeDuration>(edge_duration);
const auto to_duration = heapNode.data.duration + edge_duration;
const auto to_distance = heapNode.data.distance + edge_distance;
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];
EdgeDistance nulldistance = {0};
EdgeDistance nulldistance = 0;
auto &current_duration = durations_table[row_index * number_of_targets + column_index];
auto &current_distance =
@@ -132,7 +132,7 @@ void forwardRoutingStep(const DataFacade<Algorithm> &facade,
auto new_duration = heapNode.data.duration + target_duration;
auto new_distance = heapNode.data.distance + target_distance;
if (new_weight < EdgeWeight{0})
if (new_weight < 0)
{
if (addLoopWeight(facade, heapNode.node, new_weight, new_duration, new_distance))
{
@@ -62,13 +62,10 @@ void relaxBorderEdges(const DataFacade<mld::Algorithm> &facade,
const auto node_weight = facade.GetNodeWeight(node_id);
const auto node_duration = facade.GetNodeDuration(node_id);
const auto node_distance = facade.GetNodeDistance(node_id);
const auto turn_weight =
node_weight + alias_cast<EdgeWeight>(facade.GetWeightPenaltyForEdgeID(turn_id));
const auto turn_duration =
node_duration +
alias_cast<EdgeDuration>(facade.GetDurationPenaltyForEdgeID(turn_id));
const auto turn_weight = node_weight + facade.GetWeightPenaltyForEdgeID(turn_id);
const auto turn_duration = node_duration + facade.GetDurationPenaltyForEdgeID(turn_id);
BOOST_ASSERT_MSG(node_weight + turn_weight > EdgeWeight{0}, "edge weight is invalid");
BOOST_ASSERT_MSG(node_weight + turn_weight > 0, "edge weight is invalid");
const auto to_weight = weight + turn_weight;
const auto to_duration = duration + turn_duration;
const auto to_distance = distance + node_distance;
@@ -262,17 +259,17 @@ oneToManySearch(SearchEngineData<Algorithm> &engine_working_data,
target_nodes_index.insert(
{phantom_node.forward_segment_id.id,
std::make_tuple(index,
EdgeWeight{0} - phantom_node.GetForwardWeightPlusOffset(),
EdgeDuration{0} - phantom_node.GetForwardDuration(),
EdgeDistance{0} - phantom_node.GetForwardDistance())});
-phantom_node.GetForwardWeightPlusOffset(),
-phantom_node.GetForwardDuration(),
-phantom_node.GetForwardDistance())});
if (phantom_node.IsValidReverseSource())
target_nodes_index.insert(
{phantom_node.reverse_segment_id.id,
std::make_tuple(index,
EdgeWeight{0} - phantom_node.GetReverseWeightPlusOffset(),
EdgeDuration{0} - phantom_node.GetReverseDuration(),
EdgeDistance{0} - phantom_node.GetReverseDistance())});
-phantom_node.GetReverseWeightPlusOffset(),
-phantom_node.GetReverseDuration(),
-phantom_node.GetReverseDistance())});
}
}
}
@@ -295,12 +292,12 @@ oneToManySearch(SearchEngineData<Algorithm> &engine_working_data,
std::tie(index, target_weight, target_duration, target_distance) = it->second;
const auto path_weight = weight + target_weight;
if (path_weight >= EdgeWeight{0})
if (path_weight >= 0)
{
const auto path_duration = duration + target_duration;
const auto path_distance = distance + target_distance;
EdgeDistance nulldistance = {0};
EdgeDistance nulldistance = 0;
auto &current_distance =
distances_table.empty() ? nulldistance : distances_table[index];
@@ -353,17 +350,17 @@ oneToManySearch(SearchEngineData<Algorithm> &engine_working_data,
if (phantom_node.IsValidForwardSource())
{
insert_node(phantom_node.forward_segment_id.id,
EdgeWeight{0} - phantom_node.GetForwardWeightPlusOffset(),
EdgeDuration{0} - phantom_node.GetForwardDuration(),
EdgeDistance{0} - phantom_node.GetForwardDistance());
-phantom_node.GetForwardWeightPlusOffset(),
-phantom_node.GetForwardDuration(),
-phantom_node.GetForwardDistance());
}
if (phantom_node.IsValidReverseSource())
{
insert_node(phantom_node.reverse_segment_id.id,
EdgeWeight{0} - phantom_node.GetReverseWeightPlusOffset(),
EdgeDuration{0} - phantom_node.GetReverseDuration(),
EdgeDistance{0} - phantom_node.GetReverseDistance());
-phantom_node.GetReverseWeightPlusOffset(),
-phantom_node.GetReverseDuration(),
-phantom_node.GetReverseDistance());
}
}
else if (DIRECTION == REVERSE_DIRECTION)
@@ -447,7 +444,7 @@ void forwardRoutingStep(const DataFacade<Algorithm> &facade,
auto &current_weight = weights_table[location];
auto &current_duration = durations_table[location];
EdgeDistance nulldistance = {0};
EdgeDistance nulldistance = 0;
auto &current_distance = distances_table.empty() ? nulldistance : distances_table[location];
// Check if new weight is better
@@ -455,9 +452,8 @@ void forwardRoutingStep(const DataFacade<Algorithm> &facade,
auto new_duration = heapNode.data.duration + target_duration;
auto new_distance = heapNode.data.distance + target_distance;
if (new_weight >= EdgeWeight{0} &&
std::tie(new_weight, new_duration, new_distance) <
std::tie(current_weight, current_duration, current_distance))
if (new_weight >= 0 && std::tie(new_weight, new_duration, new_distance) <
std::tie(current_weight, current_duration, current_distance))
{
current_weight = new_weight;
current_duration = new_duration;
@@ -217,8 +217,8 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
const auto haversine_distance = util::coordinate_calculation::greatCircleDistance(
prev_coordinate, current_coordinate);
// assumes minumum of 4 m/s
const EdgeWeight weight_upper_bound = to_alias<EdgeWeight>(
((haversine_distance + max_distance_delta) / 4.) * facade.GetWeightMultiplier());
const EdgeWeight weight_upper_bound =
((haversine_distance + max_distance_delta) / 4.) * facade.GetWeightMultiplier();
// compute d_t for this timestamp and the next one
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;
// get offset to account for offsets on phantom nodes on compressed edges
const auto min_edge_offset = std::min<EdgeWeight>({0}, forward_heap.MinKey());
BOOST_ASSERT(min_edge_offset <= EdgeWeight{0});
const auto min_edge_offset = std::min(0, forward_heap.MinKey());
BOOST_ASSERT(min_edge_offset <= 0);
// we only every insert negative offsets for nodes in the forward heap
BOOST_ASSERT(reverse_heap.MinKey() >= EdgeWeight{0});
BOOST_ASSERT(reverse_heap.MinKey() >= 0);
// run two-Target Dijkstra routing step.
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,
angle_in,
turn_angle,
alias_cast<EdgeWeight>(turn_weight),
alias_cast<EdgeDuration>(turn_duration),
turn_weight,
turn_duration,
turn_instruction});
}
}
+12 -15
View File
@@ -74,26 +74,24 @@ unsigned CompressedEdgeContainer::GetZippedPositionForReverseID(const EdgeID edg
return map_iterator->second;
}
SegmentWeight CompressedEdgeContainer::ClipWeight(const EdgeWeight weight)
SegmentWeight CompressedEdgeContainer::ClipWeight(const SegmentWeight weight)
{
SegmentWeight seg_weight = alias_cast<SegmentWeight>(weight);
if (seg_weight >= INVALID_SEGMENT_WEIGHT)
if (weight >= INVALID_SEGMENT_WEIGHT)
{
clipped_weights++;
return MAX_SEGMENT_WEIGHT;
}
return seg_weight;
return weight;
}
SegmentDuration CompressedEdgeContainer::ClipDuration(const EdgeDuration duration)
SegmentDuration CompressedEdgeContainer::ClipDuration(const SegmentDuration duration)
{
SegmentDuration seg_duration = alias_cast<SegmentDuration>(duration);
if (seg_duration >= INVALID_SEGMENT_DURATION)
if (duration >= INVALID_SEGMENT_DURATION)
{
clipped_weights++;
return MAX_SEGMENT_DURATION;
}
return seg_duration;
return duration;
}
// Adds info for a compressed edge to the container. edge_id_2
@@ -121,8 +119,8 @@ void CompressedEdgeContainer::CompressEdge(const EdgeID edge_id_1,
BOOST_ASSERT(SPECIAL_EDGEID != edge_id_2);
BOOST_ASSERT(SPECIAL_NODEID != via_node_id);
BOOST_ASSERT(SPECIAL_NODEID != target_node_id);
BOOST_ASSERT(INVALID_EDGE_WEIGHT != weight1);
BOOST_ASSERT(INVALID_EDGE_WEIGHT != weight2);
BOOST_ASSERT(INVALID_SEGMENT_WEIGHT != weight1);
BOOST_ASSERT(INVALID_SEGMENT_WEIGHT != weight2);
// append list of removed edge_id plus via node to surviving edge id:
// <surv_1, .. , surv_n, via_node_id, rem_1, .. rem_n
@@ -209,14 +207,13 @@ void CompressedEdgeContainer::CompressEdge(const EdgeID edge_id_1,
void CompressedEdgeContainer::AddUncompressedEdge(const EdgeID edge_id,
const NodeID target_node_id,
const EdgeWeight weight,
const EdgeDuration duration)
const SegmentWeight weight,
const SegmentDuration duration)
{
// remove super-trivial geometries
BOOST_ASSERT(SPECIAL_EDGEID != edge_id);
BOOST_ASSERT(SPECIAL_NODEID != target_node_id);
BOOST_ASSERT(INVALID_EDGE_WEIGHT != weight);
BOOST_ASSERT(INVALID_EDGE_DURATION != duration);
// Add via node id. List is created if it does not exist
if (!HasEntryForID(edge_id))
@@ -339,12 +336,12 @@ void CompressedEdgeContainer::PrintStatistics() const
if (clipped_weights > 0)
{
util::Log(logWARNING) << "Clipped " << clipped_weights << " segment weights to "
<< MAX_SEGMENT_WEIGHT;
<< (INVALID_SEGMENT_WEIGHT - 1);
}
if (clipped_durations > 0)
{
util::Log(logWARNING) << "Clipped " << clipped_durations << " segment durations to "
<< MAX_SEGMENT_DURATION;
<< (INVALID_SEGMENT_DURATION - 1);
}
util::Log() << "Geometry successfully removed:"
+30 -26
View File
@@ -34,6 +34,20 @@
#include <tbb/parallel_for.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 extractor
@@ -45,9 +59,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
EdgeBasedNodeDataContainer &node_data_container,
const CompressedEdgeContainer &compressed_edge_container,
const std::unordered_set<NodeID> &barrier_nodes,
const TrafficFlowControlNodes &traffic_signals,
const TrafficFlowControlNodes &stop_signs,
const TrafficFlowControlNodes &give_way_signs,
const TrafficSignals &traffic_signals,
const std::vector<util::Coordinate> &coordinates,
const NameTable &name_table,
const std::unordered_set<EdgeID> &segregated_edges,
@@ -55,8 +67,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
: m_edge_based_node_container(node_data_container), m_connectivity_checksum(0),
m_number_of_edge_based_nodes(0), m_coordinates(coordinates),
m_node_based_graph(node_based_graph), m_barrier_nodes(barrier_nodes),
m_traffic_signals(traffic_signals), m_stop_signs(stop_signs),
m_give_way_signs(give_way_signs), m_compressed_edge_container(compressed_edge_container),
m_traffic_signals(traffic_signals), m_compressed_edge_container(compressed_edge_container),
name_table(name_table), segregated_edges(segregated_edges),
lane_description_map(lane_description_map)
{
@@ -83,7 +94,7 @@ void EdgeBasedGraphFactory::GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &out
}
void EdgeBasedGraphFactory::GetEdgeBasedNodeDurations(
std::vector<EdgeDuration> &output_node_durations)
std::vector<EdgeWeight> &output_node_durations)
{
using std::swap; // Koenig swap
swap(m_edge_based_node_durations, output_node_durations);
@@ -136,8 +147,7 @@ NBGToEBG EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const N
// * in other cases node weights must be masked with 0x7fffffff to clear MSB
if (nbe_to_ebn_mapping[edge_id_1] != SPECIAL_NODEID &&
nbe_to_ebn_mapping[edge_id_2] == SPECIAL_NODEID)
m_edge_based_node_weights[nbe_to_ebn_mapping[edge_id_1]] |=
EdgeWeight{static_cast<EdgeWeight::value_type>(0x80000000)};
m_edge_based_node_weights[nbe_to_ebn_mapping[edge_id_1]] |= 0x80000000;
BOOST_ASSERT(m_compressed_edge_container.HasEntryForID(edge_id_1) ==
m_compressed_edge_container.HasEntryForID(edge_id_2));
@@ -390,7 +400,7 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedNodes(const WayRestrictionMap &way_re
segregated_edges.count(eid) > 0;
const auto ebn_weight = m_edge_based_node_weights[nbe_to_ebn_mapping[eid]];
BOOST_ASSERT((ebn_weight & EdgeWeight{0x7fffffff}) == edge_data.weight);
BOOST_ASSERT((ebn_weight & 0x7fffffff) == edge_data.weight);
m_edge_based_node_weights.push_back(ebn_weight);
m_edge_based_node_durations.push_back(
m_edge_based_node_durations[nbe_to_ebn_mapping[eid]]);
@@ -632,10 +642,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
// 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
// node But we'll check anyway.
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_traffic_light = m_traffic_signals.HasSignal(from_node, intersection_node);
const auto is_uturn =
guidance::getTurnDirection(turn_angle) == guidance::DirectionModifier::UTurn;
@@ -645,8 +652,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
road_legs_on_the_right.size() + road_legs_on_the_left.size() + 2 - is_uturn,
is_uturn,
is_traffic_light,
is_stop_sign,
is_give_way_sign,
m_edge_based_node_container.GetAnnotation(edge_data1.annotation_data)
.is_left_hand_driving,
// source info
@@ -658,7 +663,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
edge_data1.flags.highway_turn_classification,
edge_data1.flags.access_turn_classification,
((double)intersection::findEdgeLength(edge_geometries, node_based_edge_from) /
from_alias<double>(edge_data1.duration)) *
edge_data1.duration) *
36,
edge_data1.flags.road_classification.GetPriority(),
// target info
@@ -670,7 +675,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
edge_data2.flags.highway_turn_classification,
edge_data2.flags.access_turn_classification,
((double)intersection::findEdgeLength(edge_geometries, node_based_edge_to) /
from_alias<double>(edge_data2.duration)) *
edge_data2.duration) *
36,
edge_data2.flags.road_classification.GetPriority(),
// connected roads
@@ -681,18 +686,17 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
// turn penalties are limited to [-2^15, 2^15) which roughly translates to 54 minutes
// and fits signed 16bit deci-seconds
auto weight_penalty = TurnPenalty{boost::numeric_cast<TurnPenalty::value_type>(
extracted_turn.weight * weight_multiplier)};
auto duration_penalty = TurnPenalty{
boost::numeric_cast<TurnPenalty::value_type>(extracted_turn.duration * 10.)};
auto weight_penalty =
boost::numeric_cast<TurnPenalty>(extracted_turn.weight * weight_multiplier);
auto duration_penalty = boost::numeric_cast<TurnPenalty>(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_to]);
// auto turn_id = m_edge_based_edge_list.size();
auto weight = edge_data1.weight + alias_cast<EdgeWeight>(weight_penalty);
auto duration = edge_data1.duration + alias_cast<EdgeDuration>(duration_penalty);
auto distance = edge_data1.distance;
auto weight = boost::numeric_cast<EdgeWeight>(edge_data1.weight + weight_penalty);
auto duration = boost::numeric_cast<EdgeWeight>(edge_data1.duration + duration_penalty);
auto distance = boost::numeric_cast<EdgeDistance>(edge_data1.distance);
EdgeBasedEdge edge_based_edge = {edge_based_node_from,
edge_based_node_to,
@@ -856,7 +860,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
edge_data.flags.access_turn_classification,
((double)intersection::findEdgeLength(edge_geometries,
connected_edge.eid) /
from_alias<double>(edge_data.duration)) *
edge_data.duration) *
36,
edge_data.flags.road_classification.GetPriority(),
is_incoming,
@@ -1277,7 +1281,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
std::vector<ConditionalTurnPenalty>
EdgeBasedGraphFactory::IndexConditionals(std::vector<Conditional> &&conditionals) const
{
std::unordered_multimap<std::pair<NodeID, NodeID>, ConditionalTurnPenalty *> index;
boost::unordered_multimap<std::pair<NodeID, NodeID>, ConditionalTurnPenalty *> index;
// build and index of all conditional restrictions
for (auto &conditional : conditionals)
+45 -53
View File
@@ -5,7 +5,6 @@
#include "extractor/name_table.hpp"
#include "extractor/restriction.hpp"
#include "extractor/serialization.hpp"
#include "extractor/traffic_flow_control_nodes.hpp"
#include "util/coordinate_calculation.hpp"
#include "util/integer_range.hpp"
@@ -413,17 +412,12 @@ void ExtractionContainers::PrepareData(ScriptingEnvironment &scripting_environme
{
const auto restriction_ways = IdentifyRestrictionWays();
const auto maneuver_override_ways = IdentifyManeuverOverrideWays();
const auto traffic_signals = IdentifyTrafficFlowControlNodes(external_traffic_signals);
const auto stop_signs = IdentifyTrafficFlowControlNodes(external_stop_signs);
const auto give_ways = IdentifyTrafficFlowControlNodes(external_give_ways);
const auto traffic_signals = IdentifyTrafficSignals();
PrepareNodes();
PrepareEdges(scripting_environment);
PrepareTrafficFlowControlNodes(traffic_signals, internal_traffic_signals);
PrepareTrafficFlowControlNodes(stop_signs, internal_stop_signs);
PrepareTrafficFlowControlNodes(give_ways, internal_give_way_signs);
PrepareTrafficSignals(traffic_signals);
PrepareManeuverOverrides(maneuver_override_ways);
PrepareRestrictions(restriction_ways);
WriteCharData(name_file_name);
@@ -718,11 +712,9 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
scripting_environment.ProcessSegment(segment);
auto &edge = edge_iterator->result;
edge.weight = std::max<EdgeWeight>(
{1}, to_alias<EdgeWeight>(std::round(segment.weight * weight_multiplier)));
edge.duration = std::max<EdgeDuration>(
{1}, to_alias<EdgeDuration>(std::round(segment.duration * 10.)));
edge.distance = to_alias<EdgeDistance>(accurate_distance);
edge.weight = std::max<EdgeWeight>(1, std::round(segment.weight * weight_multiplier));
edge.duration = std::max<EdgeWeight>(1, std::round(segment.duration * 10.));
edge.distance = static_cast<float>(accurate_distance);
// assign new node id
const auto node_id = mapExternalToInternalNodeID(
@@ -787,8 +779,10 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
NodeID source = all_edges_list[i].result.source;
NodeID target = all_edges_list[i].result.target;
auto min_forward = std::make_pair(MAXIMAL_EDGE_WEIGHT, MAXIMAL_EDGE_DURATION);
auto min_backward = std::make_pair(MAXIMAL_EDGE_WEIGHT, MAXIMAL_EDGE_DURATION);
auto min_forward = std::make_pair(std::numeric_limits<EdgeWeight>::max(),
std::numeric_limits<EdgeWeight>::max());
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_backward_idx = std::numeric_limits<std::size_t>::max();
@@ -941,23 +935,23 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyManeuverOverr
return maneuver_override_ways;
}
void ExtractionContainers::PrepareTrafficFlowControlNodes(
const ReferencedTrafficFlowControlNodes &referenced_traffic_control_nodes,
TrafficFlowControlNodes &internal_traffic_control_nodes)
void ExtractionContainers::PrepareTrafficSignals(
const ExtractionContainers::ReferencedTrafficSignals &referenced_traffic_signals)
{
const auto &bidirectional_traffic_control_nodes = referenced_traffic_control_nodes.first;
const auto &unidirectional_node_segments = referenced_traffic_control_nodes.second;
const auto &bidirectional_signal_nodes = referenced_traffic_signals.first;
const auto &unidirectional_signal_segments = referenced_traffic_signals.second;
util::UnbufferedLog log;
log << "Preparing traffic control nodes for " << bidirectional_traffic_control_nodes.size()
<< " bidirectional, " << unidirectional_node_segments.size() << " unidirectional nodes ...";
log << "Preparing traffic light signals for " << bidirectional_signal_nodes.size()
<< " bidirectional, " << unidirectional_signal_segments.size()
<< " unidirectional nodes ...";
TIMER_START(prepare_traffic_signals);
std::unordered_set<NodeID> bidirectional;
std::unordered_set<std::pair<NodeID, NodeID>, boost::hash<std::pair<NodeID, NodeID>>>
unidirectional;
for (const auto &osm_node : bidirectional_traffic_control_nodes)
for (const auto &osm_node : bidirectional_signal_nodes)
{
const auto node_id = mapExternalToInternalNodeID(
used_node_id_list.begin(), used_node_id_list.end(), osm_node);
@@ -966,7 +960,7 @@ void ExtractionContainers::PrepareTrafficFlowControlNodes(
bidirectional.insert(node_id);
}
}
for (const auto &to_from : unidirectional_node_segments)
for (const auto &to_from : unidirectional_signal_segments)
{
const auto to_node_id = mapExternalToInternalNodeID(
used_node_id_list.begin(), used_node_id_list.end(), to_from.first);
@@ -978,8 +972,8 @@ void ExtractionContainers::PrepareTrafficFlowControlNodes(
}
}
internal_traffic_control_nodes.bidirectional_nodes = std::move(bidirectional);
internal_traffic_control_nodes.unidirectional_segments = std::move(unidirectional);
internal_traffic_signals.bidirectional_nodes = std::move(bidirectional);
internal_traffic_signals.unidirectional_segments = std::move(unidirectional);
TIMER_STOP(prepare_traffic_signals);
log << "ok, after " << TIMER_SEC(prepare_traffic_signals) << "s";
@@ -1165,39 +1159,37 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyRestrictionWa
return restriction_ways;
}
ExtractionContainers::ReferencedTrafficFlowControlNodes
ExtractionContainers::IdentifyTrafficFlowControlNodes(
const std::vector<InputTrafficFlowControlNode> &external_nodes)
ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTrafficSignals()
{
util::UnbufferedLog log;
log << "Collecting traffic nodes information on " << external_nodes.size() << " nodes...";
TIMER_START(identify_traffic_flow_control_nodes);
log << "Collecting traffic signal information on " << external_traffic_signals.size()
<< " signals...";
TIMER_START(identify_traffic_signals);
// Temporary store for nodes containing a unidirectional signal.
std::unordered_map<OSMNodeID, TrafficFlowControlNodeDirection> unidirectional_traffic_nodes;
std::unordered_map<OSMNodeID, TrafficLightClass::Direction> unidirectional_signals;
// For each node that has a unidirectional traffic signal, we store the node(s)
// that lead up to the signal.
std::unordered_multimap<OSMNodeID, OSMNodeID> node_segments;
std::unordered_multimap<OSMNodeID, OSMNodeID> signal_segments;
std::unordered_set<OSMNodeID> bidirectional_traffic_nodes;
std::unordered_set<OSMNodeID> bidirectional_signals;
const auto mark_traffic_nodes = [&](auto const &traffic_control_node) {
if (traffic_control_node.second == TrafficFlowControlNodeDirection::FORWARD ||
traffic_control_node.second == TrafficFlowControlNodeDirection::REVERSE)
const auto mark_signals = [&](auto const &traffic_signal) {
if (traffic_signal.second == TrafficLightClass::DIRECTION_FORWARD ||
traffic_signal.second == TrafficLightClass::DIRECTION_REVERSE)
{
unidirectional_traffic_nodes.insert(
{traffic_control_node.first, traffic_control_node.second});
unidirectional_signals.insert({traffic_signal.first, traffic_signal.second});
}
else
{
BOOST_ASSERT(traffic_control_node.second == TrafficFlowControlNodeDirection::ALL);
bidirectional_traffic_nodes.insert(traffic_control_node.first);
BOOST_ASSERT(traffic_signal.second == TrafficLightClass::DIRECTION_ALL);
bidirectional_signals.insert(traffic_signal.first);
}
};
std::for_each(external_nodes.begin(), external_nodes.end(), mark_traffic_nodes);
std::for_each(external_traffic_signals.begin(), external_traffic_signals.end(), mark_signals);
// Extract all the segments that lead up to unidirectional traffic flow control nodes.
// Extract all the segments that lead up to unidirectional traffic signals.
const auto set_segments = [&](const size_t way_list_idx, auto const & /*unused*/) {
const auto node_start_offset =
used_node_id_list.begin() + way_node_id_offsets[way_list_idx];
@@ -1206,24 +1198,24 @@ ExtractionContainers::IdentifyTrafficFlowControlNodes(
for (auto node_it = node_start_offset; node_it < node_end_offset; node_it++)
{
const auto sig = unidirectional_traffic_nodes.find(*node_it);
if (sig != unidirectional_traffic_nodes.end())
const auto sig = unidirectional_signals.find(*node_it);
if (sig != unidirectional_signals.end())
{
if (sig->second == TrafficFlowControlNodeDirection::FORWARD)
if (sig->second == TrafficLightClass::DIRECTION_FORWARD)
{
if (node_it != node_start_offset)
{
// Previous node leads to signal
node_segments.insert({*node_it, *(node_it - 1)});
signal_segments.insert({*node_it, *(node_it - 1)});
}
}
else
{
BOOST_ASSERT(sig->second == TrafficFlowControlNodeDirection::REVERSE);
BOOST_ASSERT(sig->second == TrafficLightClass::DIRECTION_REVERSE);
if (node_it + 1 != node_end_offset)
{
// Next node leads to signal
node_segments.insert({*node_it, *(node_it + 1)});
signal_segments.insert({*node_it, *(node_it + 1)});
}
}
}
@@ -1232,7 +1224,7 @@ ExtractionContainers::IdentifyTrafficFlowControlNodes(
util::for_each_indexed(ways_list.cbegin(), ways_list.cend(), set_segments);
util::for_each_pair(
node_segments, [](const auto pair_a, const auto pair_b) {
signal_segments, [](const auto pair_a, const auto pair_b) {
if (pair_a.first == pair_b.first)
{
// If a node is appearing multiple times in this map, then it's ambiguous.
@@ -1248,10 +1240,10 @@ ExtractionContainers::IdentifyTrafficFlowControlNodes(
}
});
TIMER_STOP(identify_traffic_flow_control_nodes);
log << "ok, after " << TIMER_SEC(identify_traffic_flow_control_nodes) << "s";
TIMER_STOP(identify_traffic_signals);
log << "ok, after " << TIMER_SEC(identify_traffic_signals) << "s";
return {std::move(bidirectional_traffic_nodes), std::move(node_segments)};
return {std::move(bidirectional_signals), std::move(signal_segments)};
}
void ExtractionContainers::PrepareRestrictions(const ReferencedWays &restriction_ways)
+2 -12
View File
@@ -226,8 +226,6 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
parsed_osm_data.turn_restrictions,
parsed_osm_data.unresolved_maneuver_overrides,
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.osm_coordinates),
std::move(parsed_osm_data.osm_node_ids),
@@ -285,8 +283,6 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
node_based_graph_factory.GetCompressedEdges(),
barrier_nodes,
parsed_osm_data.traffic_signals,
parsed_osm_data.stop_signs,
parsed_osm_data.give_way_signs,
restriction_graph,
segregated_edges,
name_table,
@@ -653,8 +649,6 @@ Extractor::ParsedOSMData Extractor::ParseOSMData(ScriptingEnvironment &scripting
std::move(extraction_containers.turn_restrictions),
std::move(extraction_containers.internal_maneuver_overrides),
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(osm_coordinates),
std::move(osm_node_ids),
@@ -674,7 +668,7 @@ void Extractor::FindComponents(unsigned number_of_edge_based_nodes,
for (const auto &edge : input_edge_list)
{
BOOST_ASSERT_MSG((std::max(edge.data.weight, EdgeWeight{1})) > EdgeWeight{0},
BOOST_ASSERT_MSG(static_cast<unsigned int>(std::max(edge.data.weight, 1)) > 0,
"edge distance < 1");
BOOST_ASSERT(edge.source < number_of_edge_based_nodes);
BOOST_ASSERT(edge.target < number_of_edge_based_nodes);
@@ -730,9 +724,7 @@ EdgeID Extractor::BuildEdgeExpandedGraph(
const std::vector<util::Coordinate> &coordinates,
const CompressedEdgeContainer &compressed_edge_container,
const std::unordered_set<NodeID> &barrier_nodes,
const TrafficFlowControlNodes &traffic_signals,
const TrafficFlowControlNodes &stop_signs,
const TrafficFlowControlNodes &give_way_signs,
const TrafficSignals &traffic_signals,
const RestrictionGraph &restriction_graph,
const std::unordered_set<EdgeID> &segregated_edges,
const NameTable &name_table,
@@ -754,8 +746,6 @@ EdgeID Extractor::BuildEdgeExpandedGraph(
compressed_edge_container,
barrier_nodes,
traffic_signals,
stop_signs,
give_way_signs,
coordinates,
name_table,
segregated_edges,
+9 -22
View File
@@ -78,23 +78,10 @@ void ExtractorCallbacks::ProcessNode(const osmium::Node &input_node,
{
external_memory.barrier_nodes.push_back(id);
}
if (result_node.traffic_lights != TrafficFlowControlNodeDirection::NONE)
if (result_node.traffic_lights != TrafficLightClass::NONE)
{
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)
@@ -438,10 +425,10 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
NodeBasedEdgeWithOSM edge = {
OSMNodeID{static_cast<std::uint64_t>(first_node.ref())},
OSMNodeID{static_cast<std::uint64_t>(last_node.ref())},
{0}, // weight
{0}, // duration
{0}, // distance
{}, // geometry id
0, // weight
0, // duration
0, // distance
{}, // geometry id
static_cast<AnnotationID>(annotation_data_id),
{true,
in_backward_direction && !split_edge,
@@ -472,10 +459,10 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
NodeBasedEdgeWithOSM edge = {
OSMNodeID{static_cast<std::uint64_t>(first_node.ref())},
OSMNodeID{static_cast<std::uint64_t>(last_node.ref())},
{0}, // weight
{0}, // duration
{0}, // distance
{}, // geometry id
0, // weight
0, // duration
0, // distance
{}, // geometry id
static_cast<AnnotationID>(annotation_data_id),
{false,
true,
+44 -55
View File
@@ -22,9 +22,7 @@ namespace extractor
static constexpr int SECOND_TO_DECISECOND = 10;
void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
const TrafficFlowControlNodes &traffic_signals,
const TrafficFlowControlNodes &stop_signs,
const TrafficFlowControlNodes &give_way_signs,
const TrafficSignals &traffic_signals,
ScriptingEnvironment &scripting_environment,
std::vector<TurnRestriction> &turn_restrictions,
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
@@ -210,22 +208,15 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
graph.GetEdgeData(reverse_e2).annotation_data = selectAnnotation(
rev_edge_data2.annotation_data, rev_edge_data1.annotation_data);
// Add node penalty when compress edge crosses a traffic signal/stop sign/give way
const bool has_forward_signal = traffic_signals.Has(node_u, 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);
// Add node penalty when compress edge crosses a traffic signal
const bool has_forward_signal = traffic_signals.HasSignal(node_u, node_v);
const bool has_reverse_signal = traffic_signals.HasSignal(node_w, node_v);
EdgeDuration forward_node_duration_penalty = MAXIMAL_EDGE_DURATION;
EdgeWeight forward_node_weight_penalty = INVALID_EDGE_WEIGHT;
EdgeDuration reverse_node_duration_penalty = MAXIMAL_EDGE_DURATION;
EdgeWeight reverse_node_weight_penalty = INVALID_EDGE_WEIGHT;
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)
if (has_forward_signal || has_reverse_signal)
{
// we cannot handle this as node penalty, if it depends on turn direction
if (fwd_edge_data1.flags.restricted != fwd_edge_data2.flags.restricted)
@@ -237,10 +228,7 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
ExtractionTurn extraction_turn(0,
2,
false,
has_forward_signal || has_reverse_signal,
has_forward_stop_sign || has_reverse_stop_sign,
has_forward_give_way_sign ||
has_reverse_give_way_sign,
true,
false,
false,
TRAVEL_MODE_DRIVING,
@@ -264,25 +252,21 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
roads_on_the_left);
scripting_environment.ProcessTurn(extraction_turn);
auto update_direction_penalty = [&extraction_turn, weight_multiplier](
bool has_traffic_control_node,
EdgeDuration &duration_penalty,
EdgeWeight &weight_penalty) {
if (has_traffic_control_node)
{
duration_penalty = to_alias<EdgeDuration>(extraction_turn.duration *
SECOND_TO_DECISECOND);
weight_penalty =
to_alias<EdgeWeight>(extraction_turn.weight * weight_multiplier);
}
};
auto update_direction_penalty =
[&extraction_turn, weight_multiplier](bool signal,
EdgeDuration &duration_penalty,
EdgeWeight &weight_penalty) {
if (signal)
{
duration_penalty = extraction_turn.duration * SECOND_TO_DECISECOND;
weight_penalty = extraction_turn.weight * weight_multiplier;
}
};
update_direction_penalty(has_forward_signal || has_forward_stop_sign ||
has_forward_give_way_sign,
update_direction_penalty(has_forward_signal,
forward_node_duration_penalty,
forward_node_weight_penalty);
update_direction_penalty(has_reverse_signal || has_reverse_stop_sign ||
has_reverse_give_way_sign,
update_direction_penalty(has_reverse_signal,
reverse_node_duration_penalty,
reverse_node_weight_penalty);
}
@@ -292,14 +276,16 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
const auto forward_weight2 = fwd_edge_data2.weight;
const auto forward_duration1 = fwd_edge_data1.duration;
const auto forward_duration2 = fwd_edge_data2.duration;
const auto forward_distance2 = fwd_edge_data2.distance;
BOOST_ASSERT(EdgeWeight{0} != forward_weight1);
BOOST_ASSERT(EdgeWeight{0} != forward_weight2);
BOOST_ASSERT(0 != forward_weight1);
BOOST_ASSERT(0 != forward_weight2);
const auto reverse_weight1 = rev_edge_data1.weight;
const auto reverse_weight2 = rev_edge_data2.weight;
const auto reverse_duration1 = rev_edge_data1.duration;
const auto reverse_duration2 = rev_edge_data2.duration;
const auto reverse_distance2 = rev_edge_data2.distance;
#ifndef NDEBUG
// Because distances are symmetrical, we only need one
@@ -307,39 +293,42 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
// their mirrors.
const auto reverse_distance1 = rev_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_distance2 == reverse_distance1);
#endif
BOOST_ASSERT(EdgeWeight{0} != reverse_weight1);
BOOST_ASSERT(EdgeWeight{0} != reverse_weight2);
BOOST_ASSERT(0 != reverse_weight1);
BOOST_ASSERT(0 != reverse_weight2);
auto apply_e2_to_e1 = [&graph](EdgeID edge1,
EdgeID edge2,
EdgeWeight &weight_penalty,
EdgeDuration &duration_penalty) {
auto &edge1_data = graph.GetEdgeData(edge1);
const auto &edge2_data = graph.GetEdgeData(edge2);
edge1_data.weight += edge2_data.weight;
edge1_data.duration += edge2_data.duration;
edge1_data.distance += edge2_data.distance;
auto apply_e2_to_e1 = [&graph](EdgeID edge,
EdgeWeight weight,
EdgeDuration duration,
EdgeDistance distance,
EdgeDuration &duration_penalty,
EdgeWeight &weight_penalty) {
auto &edge_data = graph.GetEdgeData(edge);
edge_data.weight += weight;
edge_data.duration += duration;
edge_data.distance += distance;
if (weight_penalty != INVALID_EDGE_WEIGHT &&
duration_penalty != MAXIMAL_EDGE_DURATION)
{
edge1_data.weight += weight_penalty;
edge1_data.duration += duration_penalty;
edge_data.weight += weight_penalty;
edge_data.duration += duration_penalty;
// Note: no penalties for distances
}
};
apply_e2_to_e1(forward_e1,
forward_e2,
forward_weight2,
forward_duration2,
forward_distance2,
forward_node_weight_penalty,
forward_node_duration_penalty);
apply_e2_to_e1(reverse_e1,
reverse_e2,
reverse_weight2,
reverse_duration2,
reverse_distance2,
reverse_node_weight_penalty,
reverse_node_duration_penalty);
@@ -362,8 +351,8 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
if (weight_penalty == INVALID_EDGE_WEIGHT &&
other_weight_penalty != INVALID_EDGE_WEIGHT)
{
weight_penalty = {0};
duration_penalty = {0};
weight_penalty = 0;
duration_penalty = 0;
}
};
set_dummy_penalty(forward_node_weight_penalty,
+3 -15
View File
@@ -1,7 +1,6 @@
#include "extractor/node_based_graph_factory.hpp"
#include "extractor/files.hpp"
#include "extractor/graph_compressor.hpp"
#include "extractor/traffic_flow_control_nodes.hpp"
#include "storage/io.hpp"
#include "util/log.hpp"
@@ -20,9 +19,7 @@ NodeBasedGraphFactory::NodeBasedGraphFactory(
ScriptingEnvironment &scripting_environment,
std::vector<TurnRestriction> &turn_restrictions,
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
const TrafficFlowControlNodes &traffic_signals,
const TrafficFlowControlNodes &stop_signs,
const TrafficFlowControlNodes &give_way_signs,
const TrafficSignals &traffic_signals,
std::unordered_set<NodeID> &&barriers,
std::vector<util::Coordinate> &&coordinates,
extractor::PackedOSMIDs &&osm_node_ids,
@@ -32,12 +29,7 @@ NodeBasedGraphFactory::NodeBasedGraphFactory(
coordinates(std::move(coordinates)), osm_node_ids(std::move(osm_node_ids))
{
BuildCompressedOutputGraph(edge_list);
Compress(scripting_environment,
turn_restrictions,
maneuver_overrides,
traffic_signals,
stop_signs,
give_way_signs);
Compress(scripting_environment, turn_restrictions, maneuver_overrides, traffic_signals);
CompressGeometry();
CompressAnnotationData();
}
@@ -82,15 +74,11 @@ void NodeBasedGraphFactory::BuildCompressedOutputGraph(const std::vector<NodeBas
void NodeBasedGraphFactory::Compress(ScriptingEnvironment &scripting_environment,
std::vector<TurnRestriction> &turn_restrictions,
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
const TrafficFlowControlNodes &traffic_signals,
const TrafficFlowControlNodes &stop_signs,
const TrafficFlowControlNodes &give_way_signs)
const TrafficSignals &traffic_signals)
{
GraphCompressor graph_compressor;
graph_compressor.Compress(barriers,
traffic_signals,
stop_signs,
give_way_signs,
scripting_environment,
turn_restrictions,
maneuver_overrides,
+13 -42
View File
@@ -284,26 +284,17 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
[&context, &get_location_tag](const osmium::Node &node, const char *key) {
return get_location_tag(context, node.location(), key);
});
// just for backward compatibility
// TODO: remove in v6
context.state.new_enum("traffic_lights",
"none",
extractor::TrafficFlowControlNodeDirection::NONE,
extractor::TrafficLightClass::NONE,
"direction_all",
extractor::TrafficFlowControlNodeDirection::ALL,
extractor::TrafficLightClass::DIRECTION_ALL,
"direction_forward",
extractor::TrafficFlowControlNodeDirection::FORWARD,
extractor::TrafficLightClass::DIRECTION_FORWARD,
"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);
extractor::TrafficLightClass::DIRECTION_REVERSE);
context.state.new_usertype<ExtractionNode>(
"ResultNode",
"traffic_lights",
@@ -315,30 +306,18 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
// state to the node is converted to the class enum
// TODO: Make a breaking API change and remove this option.
bool val = obj.as<bool>();
node.traffic_lights = (val) ? TrafficFlowControlNodeDirection::ALL
: TrafficFlowControlNodeDirection::NONE;
node.traffic_lights = (val) ? TrafficLightClass::DIRECTION_ALL
: TrafficLightClass::NONE;
return;
}
BOOST_ASSERT(obj.is<TrafficFlowControlNodeDirection>());
BOOST_ASSERT(obj.is<TrafficLightClass::Direction>());
{
TrafficFlowControlNodeDirection val =
obj.as<TrafficFlowControlNodeDirection>();
TrafficLightClass::Direction val =
obj.as<TrafficLightClass::Direction>();
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",
&ExtractionNode::barrier);
@@ -570,7 +549,7 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
"precision",
COORDINATE_PRECISION,
"max_turn_weight",
std::numeric_limits<TurnPenalty::value_type>::max());
std::numeric_limits<TurnPenalty>::max());
// call initialize function
sol::function setup_function = function_table.value()["setup"];
@@ -784,12 +763,9 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
&ExtractionTurn::is_u_turn,
"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",
&ExtractionTurn::is_left_hand_driving,
"source_restricted",
&ExtractionTurn::source_restricted,
"source_mode",
@@ -1154,15 +1130,10 @@ void Sol2ScriptingEnvironment::ProcessTurn(ExtractionTurn &turn)
// Turn weight falls back to the duration value in deciseconds
// or uses the extracted unit-less weight value
if (context.properties.fallback_to_duration)
{
turn.weight = turn.duration;
}
else
{
// cap turn weight to max turn weight, which depend on weight precision
turn.weight = std::min(turn.weight, context.properties.GetMaxTurnWeight());
}
}
break;
+64 -30
View File
@@ -1,12 +1,10 @@
#include "server/connection.hpp"
#include "server/request_handler.hpp"
#include "server/request_parser.hpp"
#include <boost/algorithm/string/predicate.hpp>
#include <boost/bind.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <vector>
namespace osrm
@@ -16,12 +14,32 @@ namespace server
Connection::Connection(boost::asio::io_context &io_context, RequestHandler &handler)
: strand(boost::asio::make_strand(io_context)), TCP_socket(strand), timer(strand),
request_handler(handler)
request_handler(handler), http_request_parser(std::make_optional<RequestParser>())
{
}
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.
void Connection::start()
{
@@ -60,20 +78,45 @@ void Connection::handle_read(const boost::system::error_code &error, std::size_t
timer.expires_from_now(boost::posix_time::seconds(0));
}
boost::beast::error_code ec;
http_request_parser->put(boost::asio::buffer(incoming_data_buffer, bytes_transferred), ec);
// no error detected, let's parse the request
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);
// the request has been parsed
if (result == RequestParser::RequestStatus::valid)
if (ec)
{
if (ec == boost::beast::http::error::need_more)
{
// 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));
}
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;
current_request.endpoint = TCP_socket.remote_endpoint(ec).address();
if (ec)
{
util::Log(logDEBUG) << "Socket remote endpoint error: " << ec.message();
@@ -127,25 +170,6 @@ void Connection::handle_read(const boost::system::error_code &error, std::size_t
this->shared_from_this(),
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.
@@ -158,7 +182,7 @@ void Connection::handle_write(const boost::system::error_code &error)
--processed_requests;
current_request = http::request();
current_reply = http::reply();
request_parser = RequestParser();
http_request_parser.emplace();
incoming_data_buffer = boost::array<char, 8192>();
output_buffer.clear();
this->start();
@@ -220,5 +244,15 @@ std::vector<char> Connection::compress_buffers(const std::vector<char> &uncompre
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 osrm
-302
View File
@@ -1,302 +0,0 @@
#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
+46 -63
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 duration = distance_in_meters / speed_in_ms;
auto segment_duration = std::max<SegmentDuration>(
{1}, {boost::numeric_cast<SegmentDuration::value_type>(std::round(duration * 10.))});
1, boost::numeric_cast<SegmentDuration>(std::round(duration * 10.)));
if (segment_duration >= INVALID_SEGMENT_DURATION)
{
util::Log(logWARNING) << "Clamping segment duration " << segment_duration << " to "
@@ -114,8 +114,7 @@ void checkWeightsConsistency(
{
auto range = segment_data.GetForwardWeights(geometry_id.id);
// NOLINTNEXTLINE(bugprone-fold-init-type)
EdgeWeight weight = alias_cast<EdgeWeight>(
std::accumulate(range.begin(), range.end(), SegmentWeight{0}));
EdgeWeight weight = std::accumulate(range.begin(), range.end(), EdgeWeight{0});
if (weight > edge.data.weight)
{
util::Log(logWARNING) << geometry_id.id << " vs " << edge.data.turn_id << ":"
@@ -126,8 +125,7 @@ void checkWeightsConsistency(
{
auto range = segment_data.GetReverseWeights(geometry_id.id);
// NOLINTNEXTLINE(bugprone-fold-init-type)
EdgeWeight weight = alias_cast<EdgeWeight>(
std::accumulate(range.begin(), range.end(), SegmentWeight{0}));
EdgeWeight weight = std::accumulate(range.begin(), range.end(), EdgeWeight{0});
if (weight > edge.data.weight)
{
util::Log(logWARNING) << geometry_id.id << " vs " << edge.data.turn_id << ":"
@@ -187,10 +185,8 @@ updateSegmentData(const UpdaterConfig &config,
const auto weight_multiplier = profile_properties.GetWeightMultiplier();
const auto weight = distance_in_meters / rate;
auto segment_weight =
std::max<SegmentWeight>({1},
{boost::numeric_cast<SegmentWeight::value_type>(
std::round(weight * weight_multiplier))});
auto segment_weight = std::max<SegmentWeight>(
1, boost::numeric_cast<SegmentWeight>(std::round(weight * weight_multiplier)));
if (segment_weight >= INVALID_SEGMENT_WEIGHT)
{
util::Log(logWARNING) << "Clamping segment weight " << segment_weight << " to "
@@ -360,21 +356,18 @@ updateSegmentData(const UpdaterConfig &config,
if (new_fwd_datasources_range[segment_offset] == LUA_SOURCE)
continue;
SegmentDuration old_fwd_duration = old_fwd_durations_range[segment_offset];
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))
if (old_fwd_durations_range[segment_offset] >=
(new_fwd_durations_range[segment_offset] * config.log_edge_updates_factor))
{
auto from = osm_node_ids[nodes_range[segment_offset]];
auto to = osm_node_ids[nodes_range[segment_offset + 1]];
util::Log(logWARNING) << "[weight updates] Edge weight update from "
<< from_alias<double>(old_fwd_duration) / 10. << "s to "
<< from_alias<double>(new_fwd_duration) / 10.
<< "s Segment: " << from << "," << to << " based on "
<< config.segment_speed_lookup_paths
[new_fwd_datasources_range[segment_offset] - 1];
util::Log(logWARNING)
<< "[weight updates] Edge weight update from "
<< old_fwd_durations_range[segment_offset] / 10. << "s to "
<< new_fwd_durations_range[segment_offset] / 10. << "s Segment: " << from
<< "," << to << " based on "
<< config.segment_speed_lookup_paths
[new_fwd_datasources_range[segment_offset] - 1];
}
}
@@ -384,21 +377,18 @@ updateSegmentData(const UpdaterConfig &config,
if (new_rev_datasources_range[segment_offset] == LUA_SOURCE)
continue;
SegmentDuration old_rev_duration = old_rev_durations_range[segment_offset];
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))
if (old_rev_durations_range[segment_offset] >=
(new_rev_durations_range[segment_offset] * config.log_edge_updates_factor))
{
auto from = osm_node_ids[nodes_range[segment_offset + 1]];
auto to = osm_node_ids[nodes_range[segment_offset]];
util::Log(logWARNING) << "[weight updates] Edge weight update from "
<< from_alias<double>(old_rev_duration) / 10. << "s to "
<< from_alias<double>(new_rev_duration) / 10.
<< "s Segment: " << from << "," << to << " based on "
<< config.segment_speed_lookup_paths
[new_rev_datasources_range[segment_offset] - 1];
util::Log(logWARNING)
<< "[weight updates] Edge weight update from "
<< old_rev_durations_range[segment_offset] / 10. << "s to "
<< new_rev_durations_range[segment_offset] / 10. << "s Segment: " << from
<< "," << to << " based on "
<< config.segment_speed_lookup_paths
[new_rev_datasources_range[segment_offset] - 1];
}
}
}
@@ -465,20 +455,18 @@ updateTurnPenalties(const UpdaterConfig &config,
if (auto value = turn_penalty_lookup(osm_turn))
{
turn_duration_penalty = {
boost::numeric_cast<TurnPenalty::value_type>(std::round(value->duration * 10.))};
turn_weight_penalty = {boost::numeric_cast<TurnPenalty::value_type>(
std::round(std::isfinite(value->weight)
? value->weight * weight_multiplier
: from_alias<TurnPenalty::value_type>(turn_duration_penalty) *
weight_multiplier / 10.))};
turn_duration_penalty =
boost::numeric_cast<TurnPenalty>(std::round(value->duration * 10.));
turn_weight_penalty = boost::numeric_cast<TurnPenalty>(std::round(
std::isfinite(value->weight) ? value->weight * weight_multiplier
: turn_duration_penalty * weight_multiplier / 10.));
turn_duration_penalties[edge_index] = turn_duration_penalty;
turn_weight_penalties[edge_index] = turn_weight_penalty;
updated_turns.push_back(edge_index);
}
if (turn_weight_penalty < TurnPenalty{0})
if (turn_weight_penalty < 0)
{
util::Log(logWARNING) << "Negative turn penalty at " << osm_turn.from << ", "
<< osm_turn.via << ", " << osm_turn.to << ": turn penalty "
@@ -686,44 +674,42 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
return std::tie(lhs.id, lhs.forward) < std::tie(rhs.id, rhs.forward);
});
using WeightAndDuration = std::tuple<EdgeWeight, EdgeDuration>;
using WeightAndDuration = std::tuple<EdgeWeight, EdgeWeight>;
const auto compute_new_weight_and_duration =
[&](const GeometryID geometry_id) -> WeightAndDuration {
EdgeWeight new_weight = {0};
EdgeDuration new_duration = {0};
EdgeWeight new_weight = 0;
EdgeWeight new_duration = 0;
if (geometry_id.forward)
{
const auto weights = segment_data.GetForwardWeights(geometry_id.id);
for (const SegmentWeight weight : weights)
for (const auto weight : weights)
{
if (weight == INVALID_SEGMENT_WEIGHT)
{
new_weight = INVALID_EDGE_WEIGHT;
break;
}
new_weight += alias_cast<EdgeWeight>(weight);
new_weight += weight;
}
const auto durations = segment_data.GetForwardDurations(geometry_id.id);
// NOLINTNEXTLINE(bugprone-fold-init-type)
new_duration = alias_cast<EdgeDuration>(
std::accumulate(durations.begin(), durations.end(), SegmentDuration{0}));
new_duration = std::accumulate(durations.begin(), durations.end(), EdgeWeight{0});
}
else
{
const auto weights = segment_data.GetReverseWeights(geometry_id.id);
for (const SegmentWeight weight : weights)
for (const auto weight : weights)
{
if (weight == INVALID_SEGMENT_WEIGHT)
{
new_weight = INVALID_EDGE_WEIGHT;
break;
}
new_weight += alias_cast<EdgeWeight>(SegmentWeight(weight));
new_weight += weight;
}
const auto durations = segment_data.GetReverseDurations(geometry_id.id);
// NOLINTNEXTLINE(bugprone-fold-init-type)
new_duration = alias_cast<EdgeDuration>(
std::accumulate(durations.begin(), durations.end(), SegmentDuration{0}));
new_duration = std::accumulate(durations.begin(), durations.end(), EdgeWeight{0});
}
return std::make_tuple(new_weight, new_duration);
};
@@ -754,7 +740,7 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
// Find a segment with zero speed and simultaneously compute the new edge
// weight
EdgeWeight new_weight;
EdgeDuration new_duration;
EdgeWeight new_duration;
std::tie(new_weight, new_duration) =
accumulated_segment_data[updated_iter - updated_segments.begin()];
@@ -763,9 +749,7 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
// but we should always assign the same value here.
BOOST_ASSERT(edge.source < node_weights.size());
node_weights[edge.source] =
from_alias<EdgeWeight::value_type>(node_weights[edge.source]) & 0x80000000
? new_weight | EdgeWeight{static_cast<EdgeWeight::value_type>(0x80000000)}
: new_weight;
node_weights[edge.source] & 0x80000000 ? new_weight | 0x80000000 : new_weight;
node_durations[edge.source] = new_duration;
// We found a zero-speed edge, so we'll skip this whole edge-based-edge
@@ -781,15 +765,15 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
auto turn_weight_penalty = turn_weight_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 weight_min_value = to_alias<EdgeWeight>(num_nodes);
if (alias_cast<EdgeWeight>(turn_weight_penalty) + new_weight < weight_min_value)
const auto weight_min_value = static_cast<EdgeWeight>(num_nodes);
if (turn_weight_penalty + new_weight < weight_min_value)
{
if (turn_weight_penalty < TurnPenalty{0})
if (turn_weight_penalty < 0)
{
util::Log(logWARNING)
<< "turn penalty " << turn_weight_penalty
<< " is too negative: clamping turn weight to " << weight_min_value;
turn_weight_penalty = alias_cast<TurnPenalty>(weight_min_value - new_weight);
turn_weight_penalty = weight_min_value - new_weight;
turn_weight_penalties[edge.data.turn_id] = turn_weight_penalty;
}
else
@@ -799,9 +783,8 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
}
// Update edge weight
edge.data.weight = new_weight + alias_cast<EdgeWeight>(turn_weight_penalty);
edge.data.duration = from_alias<EdgeDuration::value_type>(
new_duration + alias_cast<EdgeDuration>(turn_duration_penalty));
edge.data.weight = new_weight + turn_weight_penalty;
edge.data.duration = new_duration + turn_duration_penalty;
}
};

Some files were not shown because too many files have changed in this diff Show More