Compare commits

...

38 Commits

Author SHA1 Message Date
Michael Krasnyk
28a5fe06bb
Bump version to 5.14.3 2018-01-02 18:18:21 +01:00
Michael Krasnyk
4c817de697
Use default maxspeed value for ua:urban 2018-01-02 18:18:20 +01:00
Michael Krasnyk
5133f39d76
Change default urban speed in Ukraine to 50kmh
From 1/1/2018 60kmh speed limit changed to 50kmh
http://zakon3.rada.gov.ua/laws/show/883-2017-%D0%BF
2018-01-02 15:55:44 +01:00
Darafei Praliaskouski
a29dcfa951
Belarus speed limits (#4764)
* Belarus speed limits

https://en.wikipedia.org/wiki/Speed_limits_in_Belarus

* taginfo.json update

* Update CHANGELOG.md
2018-01-02 15:55:40 +01:00
Michael Krasnyk
e546ddd777
Use consistent EBG node weights in duplicated via nodes 2018-01-02 15:55:34 +01:00
Michael Krasnyk
c21c9c9106
Update CHANGELOG entry 2017-12-26 16:23:05 +01:00
Michael Krasnyk
511f3cff33
Don't use to_string conversion in requiresNameAnnounced 2017-12-26 16:21:46 +01:00
Michael Krasnyk
d5ffbc6a9a
Remove check unnamed check in sliproad handler 2017-12-26 16:21:39 +01:00
Michael Krasnyk
60551d209d
Test for sliproads to roads with empty names 2017-12-26 16:21:34 +01:00
Patrick Niklaus
57be7beb5d
Add test case for sliproads converted from forks 2017-12-26 16:21:29 +01:00
Patrick Niklaus
a8d0c115da Restore original intend of roundabout test
When doing the new Lua version refactor we changed the expectation to
use `continue uturn` instead of making a whole circle in the roundabout
as the original test case. This was only the shortest path since there
was no roundabout penalty.
2017-12-26 13:31:28 +00:00
Patrick Niklaus
d9fcf1ecf7 Make sure we only count turns as UTurns for the turn_function 2017-12-26 13:30:53 +00:00
karenzshea
1967701385 Update Changelog for 5.14.2 2017-12-18 12:05:00 +01:00
Patrick Niklaus
a2cdc063d4 Remove superflous sentinel in DynamicGraph, fixes #4738 2017-12-18 12:01:15 +01:00
Patrick Niklaus
6e06daff15 Remove code for checking the .core file, since we do not create it anymore 2017-12-18 12:00:48 +01:00
karenzshea
2b6bdaf727 add assert for untested sliproad cases, removed redundant empty_nameid checks 2017-12-18 11:54:16 +01:00
karenzshea
2347c0ada7 check for empty on string_ref, rather than string itself 2017-12-18 11:54:09 +01:00
karenzshea
65034612ff check for empty name_id before getting data 2017-12-18 11:53:37 +01:00
karenzshea
bd427e966d access way names through RouteStep in post processing 2017-12-18 11:53:22 +01:00
karenzshea
b777fb1052 check empty name string in roundabout handler 2017-12-18 11:53:10 +01:00
karenzshea
11d491e00f check empty name string in turn collapsing 2017-12-18 11:53:00 +01:00
karenzshea
aa51e8dadd check empty name string in turn handler 2017-12-18 11:52:50 +01:00
karenzshea
83ca62aa09 check empty name string in sliproad handler 2017-12-18 11:52:41 +01:00
karenzshea
a26695c04a check empty name string in motorway handler 2017-12-18 11:52:32 +01:00
karenzshea
4787fe30b7 check empty string name in mergable road detector 2017-12-18 11:52:24 +01:00
karenzshea
fdef3fdfd7 check empty name string in findBasicTurnType 2017-12-18 11:52:12 +01:00
Daniel J. Hofmann
f148810a1c Adds cucumber test for continue not taking ref into account when name is empty 2017-12-18 11:52:00 +01:00
karenzshea
9d5a4be2d9 5.14.2 2017-12-18 11:39:44 +01:00
Michael Krasnyk
5484118d77
Bump version to 5.14.1 2017-11-29 13:28:30 +01:00
Michael Krasnyk
2116cc68ca
Don't use removed alternative paths in filterPackedPathsByCellSharing 2017-11-29 13:21:54 +01:00
Daniel Patterson
531b281b73
Use the correct driving_side property on the arrive step. (#4708)
Use the correct driving_side property on the arrive step.
2017-11-27 13:17:03 -08:00
Daniel J. Hofmann
7137459fb0
Makes MLD default algorithm in example to avoid confusion, see #4702 2017-11-27 12:37:13 -08:00
brian lewis
f57fd4ffc3
Refer to Lua scripting language by its correct name 2017-11-27 12:37:04 -08:00
brian lewis
275f71a7d7
Fix typos in profiles documentation 2017-11-27 12:36:58 -08:00
Daniel Patterson
2c7d1ed48c
Add Macau and Hong Kong to the left-side driving polygon file. 2017-11-27 12:36:48 -08:00
Daniel Patterson
d67cd34edd
Enable building release candidate branch 2017-11-22 12:54:12 -08:00
Daniel Patterson
c8c3a49fb5
Set changelog to 5.14 2017-11-22 12:36:01 -08:00
Daniel Patterson
3ae313d35d
Make 5.14.0-rc.1 2017-11-22 12:35:30 -08:00
32 changed files with 589 additions and 244 deletions

View File

@ -15,6 +15,7 @@ branches:
- master
# enable building tags
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/
- 5.14
cache:
yarn: true
@ -422,7 +423,7 @@ install:
script:
- if [[ $TARGET_ARCH == armhf ]] ; then echo "Skip tests for $TARGET_ARCH" && exit 0 ; fi
- make -C test/data benchmark
- ./example/build/osrm-example test/data/ch/monaco.osrm
- ./example/build/osrm-example test/data/mld/monaco.osrm
# All tests assume to be run from the build directory
- pushd ${OSRM_BUILD_DIR}
- ./unit_tests/library-tests

View File

@ -1,4 +1,30 @@
# UNRELEASED
# 5.14.3
- Changes from 5.14.2:
- Bugfixes:
- FIXED #4754: U-Turn penalties are applied to straight turns.
- FIXED #4756: Removed too restrictive road name check in the sliproad handler
- FIXED #4731: Use correct weights for edge-based graph duplicated via nodes.
- Profile:
- CHANGED: added Belarus speed limits
- CHANGED: set default urban speed in Ukraine to 50kmh
# 5.14.2
- Changes from 5.14.1:
- Bugfixes:
- FIXED #4727: Erroring when a old .core file is present.
- FIXED #4642: Update checks for EMPTY_NAMEID to check for empty name strings
- FIXED #4738: Fix potential segmentation fault
- Node.js Bindings:
- ADDED: Exposed new `max_radiuses_map_matching` option from `EngingConfig` options
- Tools:
- ADDED: New osrm-routed `max_radiuses_map_matching` command line flag to optionally set a maximum radius for map matching
# 5.14.1
- Changes from 5.14.0
- Bugfixes:
- FIXED: don't use removed alternative candidates in `filterPackedPathsByCellSharing`
# 5.14.0
- Changes from 5.13
- API:
- ADDED: new RouteStep property `driving_side` that has either "left" or "right" for that step

View File

@ -62,7 +62,7 @@ endif()
project(OSRM C CXX)
set(OSRM_VERSION_MAJOR 5)
set(OSRM_VERSION_MINOR 14)
set(OSRM_VERSION_PATCH 0)
set(OSRM_VERSION_PATCH 3)
set(OSRM_VERSION "${OSRM_VERSION_MAJOR}.${OSRM_VERSION_MINOR}.${OSRM_VERSION_PATCH}")
add_definitions(-DOSRM_PROJECT_DIR="${CMAKE_CURRENT_SOURCE_DIR}")

View File

@ -1,6 +1,6 @@
# Everyone
Please take some time to review our [code of conduct](CODE_OF_CONDUCT.md) to help guide your interactions with others on this project.
Please take some time to review our [code of conduct](CODE-OF-CONDUCT.md) to help guide your interactions with others on this project.
# User

View File

@ -36,7 +36,9 @@
},
{
"type": "Feature",
"properties": { "driving_side" : "left" },
"properties": {
"driving_side": "left"
},
"geometry": {
"type": "Polygon",
"coordinates": [
@ -399,7 +401,9 @@
},
{
"type": "Feature",
"properties": { "driving_side" : "left" },
"properties": {
"driving_side": "left"
},
"geometry": {
"type": "Polygon",
"coordinates": [
@ -506,7 +510,9 @@
},
{
"type": "Feature",
"properties": { "driving_side" : "left" },
"properties": {
"driving_side": "left"
},
"geometry": {
"type": "Polygon",
"coordinates": [
@ -589,7 +595,9 @@
},
{
"type": "Feature",
"properties": { "driving_side" : "left" },
"properties": {
"driving_side": "left"
},
"geometry": {
"type": "Polygon",
"coordinates": [
@ -1277,7 +1285,9 @@
},
{
"type": "Feature",
"properties": { "driving_side" : "left" },
"properties": {
"driving_side": "left"
},
"geometry": {
"type": "Polygon",
"coordinates": [
@ -1308,7 +1318,9 @@
},
{
"type": "Feature",
"properties": { "driving_side" : "left" },
"properties": {
"driving_side": "left"
},
"geometry": {
"type": "Polygon",
"coordinates": [
@ -1339,7 +1351,9 @@
},
{
"type": "Feature",
"properties": { "driving_side" : "left" },
"properties": {
"driving_side": "left"
},
"geometry": {
"type": "Polygon",
"coordinates": [
@ -1370,7 +1384,9 @@
},
{
"type": "Feature",
"properties": { "driving_side" : "left" },
"properties": {
"driving_side": "left"
},
"geometry": {
"type": "Polygon",
"coordinates": [
@ -1529,7 +1545,9 @@
},
{
"type": "Feature",
"properties": { "driving_side" : "left" },
"properties": {
"driving_side": "left"
},
"geometry": {
"type": "Polygon",
"coordinates": [
@ -1560,7 +1578,9 @@
},
{
"type": "Feature",
"properties": { "driving_side" : "left" },
"properties": {
"driving_side": "left"
},
"geometry": {
"type": "Polygon",
"coordinates": [
@ -1591,7 +1611,9 @@
},
{
"type": "Feature",
"properties": { "driving_side" : "left" },
"properties": {
"driving_side": "left"
},
"geometry": {
"type": "Polygon",
"coordinates": [
@ -1622,7 +1644,9 @@
},
{
"type": "Feature",
"properties": { "driving_side" : "left" },
"properties": {
"driving_side": "left"
},
"geometry": {
"type": "Polygon",
"coordinates": [
@ -1653,7 +1677,9 @@
},
{
"type": "Feature",
"properties": { "driving_side" : "left" },
"properties": {
"driving_side": "left"
},
"geometry": {
"type": "Polygon",
"coordinates": [
@ -1684,7 +1710,9 @@
},
{
"type": "Feature",
"properties": { "driving_side" : "left" },
"properties": {
"driving_side": "left"
},
"geometry": {
"type": "Polygon",
"coordinates": [
@ -1715,7 +1743,9 @@
},
{
"type": "Feature",
"properties": { "driving_side" : "left" },
"properties": {
"driving_side": "left"
},
"geometry": {
"type": "Polygon",
"coordinates": [
@ -1743,6 +1773,212 @@
]
]
}
},
{
"type": "Feature",
"properties": {
"driving_side": "left"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
113.53256464004518,
22.17096258989228
],
[
113.53754281997682,
22.16047023983672
],
[
113.54106187820436,
22.154587822430837
],
[
113.54878664016725,
22.14703570986906
],
[
113.54990243911743,
22.141947742446394
],
[
113.54792833328247,
22.118731558535227
],
[
113.54852914810182,
22.11006426296891
],
[
113.56088876724245,
22.105531611874294
],
[
113.5914444923401,
22.117300298747207
],
[
113.60217332839966,
22.136303063467075
],
[
113.58766794204713,
22.183520585503548
],
[
113.57015848159791,
22.189083895743767
],
[
113.56621026992799,
22.189163370008256
],
[
113.56406450271608,
22.190514425625366
],
[
113.56380701065065,
22.19941517306984
],
[
113.56191873550418,
22.2050573189853
],
[
113.56088876724245,
22.21260631441281
],
[
113.55256319046022,
22.217294433458783
],
[
113.54850769042969,
22.21683754739093
],
[
113.5441303253174,
22.217056058304685
],
[
113.54318618774415,
22.216479983343337
],
[
113.5415554046631,
22.213242000752253
],
[
113.54114770889284,
22.213003618712484
],
[
113.53824019432068,
22.213659168347313
],
[
113.53728532791139,
22.21367903343993
],
[
113.53571891784668,
22.213559842841935
],
[
113.53435635566713,
22.213182405280275
],
[
113.53312253952026,
22.212367931293002
],
[
113.53496789932252,
22.20616982803302
],
[
113.53222131729127,
22.19401121511328
],
[
113.52681398391725,
22.184792218694355
],
[
113.53256464004518,
22.17096258989228
]
]
]
}
},
{
"type": "Feature",
"properties": {
"driving_side": "left"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
114.1398811340332,
22.298308554808454
],
[
114.1146469116211,
22.295926164040363
],
[
114.10280227661133,
22.2808367460213
],
[
114.1505241394043,
22.226342457476385
],
[
114.20768737792969,
22.188199741518677
],
[
114.26794052124023,
22.199325771045544
],
[
114.26673889160155,
22.257008033931445
],
[
114.24699783325194,
22.278295210101668
],
[
114.22657012939453,
22.29354373265189
],
[
114.20408248901367,
22.29973796977008
],
[
114.184513092041,
22.290843594643704
],
[
114.16563034057617,
22.28925525380013
],
[
114.1398811340332,
22.298308554808454
]
]
]
}
}
]
}

View File

@ -6,7 +6,7 @@ OSRM supports "profiles". Profiles representing routing behavior for different t
## Available profiles
Out-of-the-box OSRM comes with profiles for car, bicycle and foot. You can easily modify these or create new ones if you like.
Profiles have a 'lua' extension, and are places in 'profiles' directory.
Profiles have a 'lua' extension, and are placed in 'profiles' directory.
When running OSRM preprocessing commands you specify the profile with the --profile (or the shorthand -p) option, for example:
@ -17,8 +17,8 @@ It's important to understand that profiles are used when preprocessing the OSM d
This means that after modifying a profile **you will need to extract, contract and reload the data again** and to see changes in the routing results. See [Processing Flow](https://github.com/Project-OSRM/osrm-backend/wiki/Processing-Flow) for more.
## Profiles are written in LUA
Profiles are not just configuration files. They are scripts written in the [LUA scripting language](http://www.lua.org). The reason for this is that OpenStreetMap data is complex, and it's not possible to simply define tag mappings. LUA scripting offers a powerful way to handle all the possible tag combinations found in OpenStreetMap nodes and ways.
## Profiles are written in Lua
Profiles are not just configuration files. They are scripts written in the [Lua scripting language](http://www.lua.org). The reason for this is that OpenStreetMap data is complex, and it's not possible to simply define tag mappings. Lua scripting offers a powerful way to handle all the possible tag combinations found in OpenStreetMap nodes and ways.
## Basic structure of profiles
A profile will process every node and way in the OSM input data to determine what ways are routable in which direction, at what speed, etc.
@ -35,40 +35,40 @@ A profile can also define various local functions it needs.
Looking at [car.lua](../profiles/car.lua) as an example, at the top of the file the api version is defined and then required library files are included.
Then follows the `setup` functions, which is called once when the profile is loaded. It returns a big hash table of configurations, specifying things like what speed to use for different way types. The configurations are used later in the various processing functions. Many adjustments can be done just be modifying this configuration table.
Then follows the `setup` function, which is called once when the profile is loaded. It returns a big hash table of configurations, specifying things like what speed to use for different way types. The configurations are used later in the various processing functions. Many adjustments can be done just by modifying this configuration table.
The setup function is also where you can do other setup, like loading elevation data source if you want to consider that when processing ways.
The setup function is also where you can do other setup, like loading an elevation data source if you want to consider that when processing ways.
Then comes the `process_node` and `process_way` functions, which are called for each OSM node and way when extracting OpenStreetMap data with `osrm-extract`.
Then come the `process_node` and `process_way` functions, which are called for each OSM node and way when extracting OpenStreetMap data with `osrm-extract`.
The `process_turn` function processes every possible turn in the network, and sets a penalty depending on the angle and turn of the movement.
Profiles can also define a `process_segment` function to handle differences in speed along an OSM way, for example to handle elevation. As you can see, this is not currently used in the car profile.
At the end of the file, a table if returned with references to the setup and processing functions the profile has defined.
At the end of the file, a table is returned with references to the setup and processing functions the profile has defined.
## Understanding speed, weight and rate
When computing a route from A to B there can be different measure of what is the best route. That's why there's a need for different profiles.
When computing a route from A to B there can be different measures of what is the best route. That's why there's a need for different profiles.
Because speeds very on different types of roads, the shortest and the fastest route are typically different. But there are many other possible preferences. For example a user might prefer a bicycle route that follow parks or other green areas, even though both duration and distance are a bit longer.
Because speeds vary on different types of roads, the shortest and the fastest route are typically different. But there are many other possible preferences. For example a user might prefer a bicycle route that follow parks or other green areas, even though both duration and distance are a bit longer.
To handle this, OSRM doesn't simply choose the ways with the highest speed. Instead it uses the concept of `weight` and `rate`. The rate is an abstract measure that you can assign to ways as you like to make some ways preferable to others. Routing will prefer ways with high rate.
To handle this, OSRM doesn't simply choose the ways with the highest speed. Instead it uses the concepts of `weight` and `rate`. The rate is an abstract measure that you can assign to ways as you like to make some ways preferable to others. Routing will prefer ways with high rate.
The weight of a way normally computed as length / rate. The weight can be thought of as the resistance or cost when passing the way. Routing will prefer ways with low weight.
The weight of a way is normally computed as length / rate. The weight can be thought of as the resistance or cost when passing the way. Routing will prefer ways with low weight.
You can also set the weight of a way to a fixed value, In this case it's not calculated based on the length or rate, and the rate is ignored.
You can also set the weight of a way to a fixed value. In this case it's not calculated based on the length or rate, and the rate is ignored.
You should set the speed to you best estimate of the actual speed that will be used on a particular way. This will result in the best estimated travel times.
You should set the speed to your best estimate of the actual speed that will be used on a particular way. This will result in the best estimated travel times.
If you want to prefer certain ways due to other factors than the speed, adjust the rate accordingly. If you adjust the speed, the time time estimation will be skewed.
If you want to prefer certain ways due to other factors than the speed, adjust the rate accordingly. If you adjust the speed, the time estimation will be skewed.
If you set the same rate on all ways, the result will be shortest path routing.
If you set rate = speed on all ways, the result will be fastest path routing.
If you want to prioritize certain street, increase the rate on these.
If you want to prioritize certain streets, increase the rate on these.
## Elements
### api_version
A profile should set api_version at the top of your profile. This is done to ensure that older profiles are still supported when the api changes. If api_version is not defined, 0 will be assumed. The current api version is 2.
A profile should set `api_version` at the top of your profile. This is done to ensure that older profiles are still supported when the api changes. If `api_version` is not defined, 0 will be assumed. The current api version is 2.
### Library files
The folder [profiles/lib/](../profiles/lib/) contains LUA library files for handling many common processing tasks.
@ -81,15 +81,15 @@ set.lua | Defines the Set helper for handling sets of values
sequence.lua | Defines the Sequence helper for handling sequences of values
access.lua | Function for finding relevant access tags
destination.lua | Function for finding relevant destination tags
destination.lua | Function for determining maximum speed
maxspeed.lua | Function for determining maximum speed
guidance.lua | Function for processing guidance attributes
They all return a table of functions when you use `require` to load them. You can either store this table and reference it's functions later, of if you need only a single you can store that directly.
They all return a table of functions when you use `require` to load them. You can either store this table and reference its functions later, or if you need only a single function you can store that directly.
### setup()
The `setup` function is called once when the profile is loaded and must return a table of configurations. It's also where you can do other global setup, like loading data sources that are used during processing.
Note that processing of data is parallelized and several unconnected LUA interpreters will be running at the same time. The `setup` function will be called once for each. Each LUA iinterpreter will have it's own set of globals.
Note that processing of data is parallelized and several unconnected LUA interpreters will be running at the same time. The `setup` function will be called once for each. Each LUA iinterpreter will have its own set of globals.
The following global properties can be set under `properties` in the hash you return in the `setup` function:
@ -109,8 +109,7 @@ The following additional global properties can be set in the hash you return in
Attribute | Type | Notes
-------------------------------------|------------------|----------------------------------------------------------------------------
excludable | Sequence of Sets | Determines which class-combinations are supported by the `exclude` option at query time.
| | E.g. `Sequence{Set{"ferry", "motorway"}, Set{"motorway"}}` will allow you to exclude ferries and motorways, or only motorways.
excludable | Sequence of Sets | Determines which class-combinations are supported by the `exclude` option at query time. E.g. `Sequence{Set{"ferry", "motorway"}, Set{"motorway"}}` will allow you to exclude ferries and motorways, or only motorways.
classes | Sequence | Determines the allowed classes that can be referenced using `{forward,backward}_classes` on the way in the `process_way` function.
restrictions | Sequence | Determines which turn restrictions will be used for this profile.
suffix_list | Set | List of name suffixes needed for determining if "Highway 101 NW" the same road as "Highway 101 ES".
@ -147,26 +146,26 @@ Importantly it will set `result.forward_mode` and `result.backward_mode` to indi
It will also set a number of other attributes on `result`.
Using the power of the scripting language you wouldn't typically see something as simple as a `result.forward_speed = 20` line within the `process_way` function. Instead `process_way` will examine the tag set on the way, process this information in various ways, calling other local functions and referencing the configuration in `profile`, etc, before arriving at the result.
Using the power of the scripting language you wouldn't typically see something as simple as a `result.forward_speed = 20` line within the `process_way` function. Instead `process_way` will examine the tag set on the way, process this information in various ways, calling other local functions and referencing the configuration in `profile`, etc., before arriving at the result.
The following attributes can be set on the result in `process_way`:
Attribute | Type | Notes
----------------------------------------|----------|--------------------------------------------------------------------------
forward_speed | Float | Speed on this way in km/h. Mandatory.
backward_speed | Float | " "
backward_speed | Float | ""
forward_rate | Float | Routing weight, expressed as meters/*weight* (e.g. for a fastest-route weighting, you would want this to be meters/second, so set it to forward_speed/3.6)
backward_rate | Float | " "
backward_rate | Float | ""
forward_mode | Enum | Mode of travel (e.g. `car`, `ferry`). Mandatory. Defined in `include/extractor/travel_mode.hpp`.
backward_mode | Enum | " "
backward_mode | Enum | ""
forward_classes | Table | Mark this way as being of a specific class, e.g. `result.classes["toll"] = true`. This will be exposed in the API as `classes` on each `RouteStep`.
backward_classes | Table | " "
backward_classes | Table | ""
duration | Float | Alternative setter for duration of the whole way in both directions
weight | Float | Alternative setter for weight of the whole way in both directions
turn_lanes_forward | String | Directions for individual lanes (normalized OSM `turn:lanes` value)
turn_lanes_backward | String | " "
turn_lanes_backward | String | ""
forward_restricted | Boolean | Is this a restricted access road? (e.g. private, or deliveries only; used to enable high turn penalty, so that way is only chosen for start/end of route)
backward_restricted | Boolean | " "
backward_restricted | Boolean | ""
is_startpoint | Boolean | Can a journey start on this way? (e.g. ferry; if `false`, prevents snapping the start point to this way)
roundabout | Boolean | Is this part of a roundabout?
circular | Boolean | Is this part of a non-roundabout circular junction?
@ -188,18 +187,18 @@ The `process_segment` function is called for every segment of OSM ways. A segmen
On OpenStreetMap way cannot have different tags on different parts of a way. Instead you would split the way into several smaller ways. However many ways are long. For example, many ways pass hills without any change in tags.
Processing each segment of an OSM way makes it possible to have different speeds on different parts of a way based on external data like data about elevation, pollution, noise or scenic value and adjust weight and duration of the segment.
Processing each segment of an OSM way makes it possible to have different speeds on different parts of a way based on external data like data about elevation, pollution, noise or scenic value and adjust weight and duration of the segment accordingly.
In the `process_segment` you don't have access to OSM tags. Instead you use the geographical location of the start and end point of the way to lookup other data source, like elevation data. See [rasterbot.lua](../profiles/rasterbot.lua) for an example.
In the `process_segment` function you don't have access to OSM tags. Instead you use the geographical location of the start and end point of the way to look up information from another data source, like elevation data. See [rasterbot.lua](../profiles/rasterbot.lua) for an example.
The following attributes can be read and set on the result in `process_segment`:
Attribute | Read/write? | Type | Notes
-------------------|-------------|---------|----------------------------------------
source.lon | Read | Float | Co-ordinates of segment start
source.lat | Read | Float | " "
source.lat | Read | Float | ""
target.lon | Read | Float | Co-ordinates of segment end
target.lat | Read | Float | " "
target.lat | Read | Float | ""
target.distance | Read | Float | Length of segment
weight | Read/write | Float | Routing weight for this segment
duration | Read/write | Float | Duration for this segment
@ -231,7 +230,7 @@ The priority-category influences the decision which road is considered the obvio
Forks can be emitted between roads of similar priority category only. Obvious choices follow a major priority road, if the priority difference is large.
### Using raster data
OSRM has build-in support for loading an interpolating raster data in ASCII format. This can be used e.g. for factoring in elevation when computing routes.
OSRM has built-in support for loading an interpolating raster data in ASCII format. This can be used e.g. for factoring in elevation when computing routes.
Use `raster:load()` in your `setup` function to load data and store the source in your configuration hash:
@ -284,8 +283,8 @@ See [rasterbot.lua](../profiles/rasterbot.lua) and [rasterbotinterp.lua](../prof
### Helper functions
There are a few helper functions defined in the global scope that profiles can use:
durationIsValid
parseDuration
trimLaneString
applyAccessTokens
canonicalizeStringList
- `durationIsValid`
- `parseDuration`
- `trimLaneString`
- `applyAccessTokens`
- `canonicalizeStringList`

View File

@ -30,9 +30,17 @@ int main(int argc, const char *argv[])
// Configure based on a .osrm base path, and no datasets in shared mem from osrm-datastore
EngineConfig config;
config.storage_config = {argv[1]};
config.use_shared_memory = false;
// We support two routing speed up techniques:
// - Contraction Hierarchies (CH): requires extract+contract pre-processing
// - Multi-Level Dijkstra (MLD): requires extract+partition+customize pre-processing
//
// config.algorithm = EngineConfig::Algorithm::CH;
config.algorithm = EngineConfig::Algorithm::MLD;
// Routing machine with several services (such as Route, Table, Nearest, Trip, Match)
const OSRM osrm{config};

View File

@ -116,3 +116,28 @@ Feature: Testbot - side bias
| from | to | route | driving_side | time |
| d | a | bd,ab,ab | right,right,right | 27s +-1 |
| d | c | bd,bc,bc | right,right,right | 24s +-1 |
Scenario: changing sides
Given the profile "car"
# Note - the boundary in null-island.geojson is at lon = 2.0,
# and we use the "last node of the way" as the heuristic to detect
# whether the way is in our out of the driving_side polygon
And the node locations
| node | lat | lon |
| a | 0 | 0.5 |
| b | 0 | 1.5 |
| c | 0 | 2.5 |
| d | 0 | 3.5 |
And the ways
| nodes |
| ab |
| bc |
| cd |
And the extract extra arguments "--location-dependent-data test/data/regions/null-island.geojson"
When I route I should get
| from | to | route | driving_side |
| d | a | cd,bc,ab,ab | right,right,left,left |
| a | d | ab,bc,cd,cd | left,right,right,right |

View File

@ -992,7 +992,6 @@ Feature: Slipways and Dedicated Turn Lanes
| dbef | primary | dbef | |
| ae | primary_link | ae | yes |
When I route I should get
| waypoints | route | turns | locations |
| s,f | sabc,dbef,dbef | depart,turn right,arrive | s,a,f |
@ -1019,7 +1018,6 @@ Feature: Slipways and Dedicated Turn Lanes
| dbcf | primary | dbcf | |
| ac | primary_link | ae | yes |
When I route I should get
| waypoints | route | turns | locations |
| s,f | sab,dbcf,dbcf | depart,turn right,arrive | s,a,f |
@ -1047,7 +1045,55 @@ Feature: Slipways and Dedicated Turn Lanes
| ae | primary_link | sab | yes |
| cg | primary | cg | |
When I route I should get
| waypoints | route | turns | locations |
| s,f | sab,dbcef,dbcef | depart,turn right,arrive | s,a,f |
@sliproads
Scenario: Sliproad converted from a fork
Given the node map
"""
d
.
b
s . a '.
`c
.
f
"""
And the ways
| nodes | highway | name | ref | oneway |
| sa | tertiary | | D 60A | yes |
| ab | tertiary | ab | D 60A | yes |
| ac | tertiary | | D 60A | yes |
| dbcf | tertiary | dbcf | D 543 | yes |
When I route I should get
| waypoints | route | turns | locations |
| s,f | ,dbcf,dbcf | depart,turn right,arrive | s,a,f |
@sliproads
Scenario: Sliproad to a road with a reference only
Given the node map
"""
s . a . b . d
` .
' .
..
c
.
f
"""
And the ways
| nodes | highway | name | ref | oneway |
| sabd | primary | road | | |
| bcf | primary | | K108 | |
| ac | primary_link | | | yes |
When I route I should get
| waypoints | route | turns | locations |
| s,f | road,, | depart,turn right,arrive | s,a,f |

View File

@ -745,12 +745,15 @@ Feature: Basic Roundabout
Scenario: Drive through roundabout
Given a grid size of 5 meters
Given the node map
"""
a
b e d f
c
g h
. a .
. .
b e --- d ---- f
. .
.c.
g h
"""
And the ways
@ -760,12 +763,12 @@ Feature: Basic Roundabout
| gch | | yes |
When I route I should get
| waypoints | bearings | route | turns |
| e,f | 90 90 | edf,edf | depart,arrive |
| e,h | 90 135 | edf,gch,gch,gch | depart,roundabout-exit-2,exit roundabout straight,arrive |
| g,f | 45 90 | gch,edf,edf,edf | depart,roundabout-exit-2,exit roundabout right,arrive |
| g,h | 45 135 | gch,gch,gch | depart,exit roundabout right,arrive |
| e,e | 90 270 | edf,edf,edf | depart,continue uturn,arrive |
| waypoints | bearings | route | turns |
| e,f | 90 90 | edf,edf | depart,arrive |
| e,h | 90 130 | edf,gch,gch,gch | depart,roundabout-exit-2,exit roundabout straight,arrive |
| g,f | 50 90 | gch,edf,edf,edf | depart,roundabout-exit-2,exit roundabout slight right,arrive |
| g,h | 50 130 | gch,gch,gch | depart,exit roundabout right,arrive |
| e,e | 90 270 | edf,edf,edf,edf | depart,roundabout-exit-3,exit roundabout sharp left,arrive |
Scenario: CCW and CW roundabouts with overlaps
Given the node map

View File

@ -1372,3 +1372,64 @@ Feature: Simple Turns
| waypoints | route | turns |
| a,d | ab,bcd,bcd | depart,fork slight right,arrive |
| a,g | ab,befg,befg | depart,fork slight left,arrive |
# https://www.openstreetmap.org/#map=18/52.25130/10.42545
Scenario: Turn for roads with no name, ref changes
Given the node map
"""
d
.
.
e c . . f
.
.
b
.
.
a
"""
And the ways
| nodes | highway | ref | name |
| abc | tertiary | K 57 | |
| cd | tertiary | K 56 | |
| cf | tertiary | K 56 | |
| ce | residential | | Heinrichshöhe |
When I route I should get
| waypoints | route | turns |
| a,f | ,, | depart,turn right,arrive |
# https://www.openstreetmap.org/#map=18/52.24071/10.29066
Scenario: Turn for roads with no name, ref changes
Given the node map
"""
x
.
.
d
. .
. .
. .
e. . t . c . p. .f
. .
. .
. .
b
.
.
a
"""
And the ways
| nodes | highway | ref | name | oneway |
| abp | tertiary | K 23 | | yes |
| pdx | tertiary | K 23 | | yes |
| xdt | tertiary | K 23 | | yes |
| tba | tertiary | K 23 | | yes |
| etcpf | primary | B 1 | | no |
When I route I should get
| waypoints | route | turns |
| e,x | ,,, | depart,turn sharp left,turn right,arrive |
| f,a | ,, | depart,turn left,arrive |

View File

@ -108,7 +108,7 @@ struct ContractedEdgeContainer
edges.insert(edges.end(), new_edges.begin(), new_end);
auto edges_size = edges.size();
auto new_edges_size = std::distance(new_edges.begin(), new_end);
BOOST_ASSERT(edges_size >= new_edges_size);
BOOST_ASSERT(static_cast<int>(edges_size) >= new_edges_size);
flags.resize(edges_size);
std::fill(flags.begin() + edges_size - new_edges_size, flags.end(), flag);

View File

@ -312,7 +312,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
leg_geometry.locations.size() - 1,
leg_geometry.locations.size(),
{intersection},
facade.IsLeftHandDriving(source_node_id)});
facade.IsLeftHandDriving(target_node_id)});
BOOST_ASSERT(steps.front().intersections.size() == 1);
BOOST_ASSERT(steps.front().intersections.front().bearings.size() == 1);

View File

@ -77,7 +77,11 @@ struct TurnInstruction
TurnType::Enum type : 5;
DirectionModifier::Enum direction_modifier : 3;
// the lane tupel that is used for the turn
bool IsUTurn() const
{
return type != TurnType::NoTurn && direction_modifier == DirectionModifier::UTurn;
}
static TurnInstruction INVALID() { return {TurnType::Invalid, DirectionModifier::UTurn}; }

View File

@ -48,14 +48,6 @@ const constexpr char *block_id_to_name[] = {"NAME_CHAR_DATA",
"HSGR_CHECKSUM",
"TIMESTAMP",
"FILE_INDEX_PATH",
"CH_CORE_MARKER_0",
"CH_CORE_MARKER_1",
"CH_CORE_MARKER_2",
"CH_CORE_MARKER_3",
"CH_CORE_MARKER_4",
"CH_CORE_MARKER_5",
"CH_CORE_MARKER_6",
"CH_CORE_MARKER_7",
"DATASOURCES_NAMES",
"PROPERTIES",
"BEARING_CLASSID",
@ -132,14 +124,6 @@ struct DataLayout
HSGR_CHECKSUM,
TIMESTAMP,
FILE_INDEX_PATH,
CH_CORE_MARKER_0,
CH_CORE_MARKER_1,
CH_CORE_MARKER_2,
CH_CORE_MARKER_3,
CH_CORE_MARKER_4,
CH_CORE_MARKER_5,
CH_CORE_MARKER_6,
CH_CORE_MARKER_7,
DATASOURCES_NAMES,
PROPERTIES,
BEARING_CLASSID,
@ -200,15 +184,7 @@ struct DataLayout
inline uint64_t GetBlockEntries(BlockID bid) const { return num_entries[bid]; }
inline uint64_t GetBlockSize(BlockID bid) const
{
// special bit encoding
if (bid >= CH_CORE_MARKER_0 && bid <= CH_CORE_MARKER_7)
{
return (num_entries[bid] / 32 + 1) * entry_size[bid];
}
return num_entries[bid] * entry_size[bid];
}
inline uint64_t GetBlockSize(BlockID bid) const { return num_entries[bid] * entry_size[bid]; }
inline uint64_t GetSizeOfLayout() const
{

View File

@ -64,7 +64,6 @@ struct StorageConfig final : IOConfig
{".osrm.hsgr",
".osrm.nbg_nodes",
".osrm.ebg_nodes",
".osrm.core",
".osrm.cells",
".osrm.cell_metrics",
".osrm.mldgr",

View File

@ -115,7 +115,7 @@ template <typename EdgeDataT> class DynamicGraph
number_of_nodes = nodes;
number_of_edges = static_cast<EdgeIterator>(graph.size());
node_array.resize(number_of_nodes + 1);
node_array.resize(number_of_nodes);
EdgeIterator edge = 0;
EdgeIterator position = 0;
for (const auto node : irange(0u, number_of_nodes))
@ -129,7 +129,6 @@ template <typename EdgeDataT> class DynamicGraph
node_array[node].edges = edge - last_edge;
position += node_array[node].edges;
}
node_array.back().first_edge = position;
edge_list.reserve(static_cast<std::size_t>(edge_list.size() * 1.1));
edge_list.resize(position);
edge = 0;
@ -144,6 +143,8 @@ template <typename EdgeDataT> class DynamicGraph
++edge;
}
}
BOOST_ASSERT(node_array.size() == number_of_nodes);
}
// Copy&move for the same data
@ -191,6 +192,8 @@ template <typename EdgeDataT> class DynamicGraph
// Removes all edges to and from nodes for which filter(node_id) returns false
template <typename Pred> auto Filter(Pred filter) const &
{
BOOST_ASSERT(node_array.size() == number_of_nodes);
DynamicGraph other;
other.number_of_nodes = number_of_nodes;
@ -202,6 +205,8 @@ template <typename EdgeDataT> class DynamicGraph
std::transform(
node_array.begin(), node_array.end(), other.node_array.begin(), [&](const Node &node) {
const EdgeIterator first_edge = other.edge_list.size();
BOOST_ASSERT(node_id < number_of_nodes);
if (filter(node_id++))
{
std::copy_if(edge_list.begin() + node.first_edge,
@ -416,7 +421,7 @@ template <typename EdgeDataT> class DynamicGraph
void Renumber(const std::vector<NodeID> &old_to_new_node)
{
// permutate everything but the sentinel
util::inplacePermutation(node_array.begin(), std::prev(node_array.end()), old_to_new_node);
util::inplacePermutation(node_array.begin(), node_array.end(), old_to_new_node);
// Build up edge permutation
auto new_edge_index = 0;

View File

@ -26,7 +26,8 @@ namespace guidance
// Name Change Logic
// Used both during Extraction as well as during Post-Processing
inline std::string longest_common_substring(const std::string &lhs, const std::string &rhs)
inline util::StringView longest_common_substring(const util::StringView &lhs,
const util::StringView &rhs)
{
if (lhs.empty() || rhs.empty())
return "";
@ -60,15 +61,15 @@ inline std::string longest_common_substring(const std::string &lhs, const std::s
// TODO US-ASCII support only, no UTF-8 support
// While UTF-8 might work in some cases, we do not guarantee full functionality
inline auto decompose(const std::string &lhs, const std::string &rhs)
template <typename StringView> inline auto decompose(const StringView &lhs, const StringView &rhs)
{
auto const lcs = longest_common_substring(lhs, rhs);
// trim spaces, transform to lower
const auto trim = [](auto str) {
const auto trim = [](StringView view) {
// we compare suffixes based on this value, it might break UTF chars, but as long as we are
// consistent in handling, we do not create bad results
boost::to_lower(str);
std::string str = boost::to_lower_copy(view.to_string());
auto front = str.find_first_not_of(" ");
if (front == std::string::npos)
@ -80,8 +81,7 @@ inline auto decompose(const std::string &lhs, const std::string &rhs)
if (lcs.empty())
{
std::string empty = "";
return std::make_tuple(trim(lhs), trim(rhs), empty, empty);
return std::make_tuple(trim(lhs), trim(rhs), std::string(), std::string());
}
// find the common substring in both
@ -92,32 +92,27 @@ inline auto decompose(const std::string &lhs, const std::string &rhs)
BOOST_ASSERT(rhs_pos + lcs.size() <= rhs.size());
// prefixes
std::string lhs_prefix = (lhs_pos > 0) ? lhs.substr(0, lhs_pos) : "";
std::string rhs_prefix = (rhs_pos > 0) ? rhs.substr(0, rhs_pos) : "";
auto lhs_prefix = (lhs_pos > 0) ? lhs.substr(0, lhs_pos) : StringView();
auto rhs_prefix = (rhs_pos > 0) ? rhs.substr(0, rhs_pos) : StringView();
// suffices
std::string lhs_suffix = lhs.substr(lhs_pos + lcs.size());
std::string rhs_suffix = rhs.substr(rhs_pos + lcs.size());
auto lhs_suffix = lhs.substr(lhs_pos + lcs.size());
auto rhs_suffix = rhs.substr(rhs_pos + lcs.size());
lhs_prefix = trim(std::move(lhs_prefix));
lhs_suffix = trim(std::move(lhs_suffix));
rhs_prefix = trim(std::move(rhs_prefix));
rhs_suffix = trim(std::move(rhs_suffix));
return std::make_tuple(lhs_prefix, lhs_suffix, rhs_prefix, rhs_suffix);
return std::make_tuple(trim(lhs_prefix), trim(lhs_suffix), trim(rhs_prefix), trim(rhs_suffix));
}
// Note: there is an overload without suffix checking below.
// (that's the reason we template the suffix table here)
template <typename SuffixTable>
inline bool requiresNameAnnounced(const std::string &from_name,
const std::string &from_ref,
const std::string &from_pronunciation,
const std::string &from_exits,
const std::string &to_name,
const std::string &to_ref,
const std::string &to_pronunciation,
const std::string &to_exits,
template <typename StringView, typename SuffixTable>
inline bool requiresNameAnnounced(const StringView &from_name,
const StringView &from_ref,
const StringView &from_pronunciation,
const StringView &from_exits,
const StringView &to_name,
const StringView &to_ref,
const StringView &to_pronunciation,
const StringView &to_exits,
const SuffixTable &suffix_table)
{
// first is empty and the second is not
@ -134,7 +129,7 @@ inline bool requiresNameAnnounced(const std::string &from_name,
boost::starts_with(from_name, to_name) || boost::starts_with(to_name, from_name);
const auto checkForPrefixOrSuffixChange =
[](const std::string &first, const std::string &second, const SuffixTable &suffix_table) {
[](const StringView &first, const StringView &second, const SuffixTable &suffix_table) {
std::string first_prefix, first_suffix, second_prefix, second_suffix;
std::tie(first_prefix, first_suffix, second_prefix, second_suffix) =
decompose(first, second);
@ -203,17 +198,17 @@ inline bool requiresNameAnnounced(const std::string &from_name,
struct NopSuffixTable final
{
NopSuffixTable() {}
bool isSuffix(const std::string &) const { return false; }
bool isSuffix(const StringView &) const { return false; }
} static const table;
return requiresNameAnnounced(from_name,
from_ref,
from_pronunciation,
from_exits,
to_name,
to_ref,
to_pronunciation,
to_exits,
return requiresNameAnnounced(util::StringView(from_name),
util::StringView(from_ref),
util::StringView(from_pronunciation),
util::StringView(from_exits),
util::StringView(to_name),
util::StringView(to_ref),
util::StringView(to_pronunciation),
util::StringView(to_exits),
table);
}
@ -225,37 +220,17 @@ inline bool requiresNameAnnounced(const NameID from_name_id,
if (from_name_id == to_name_id)
return false;
else
return requiresNameAnnounced(name_table.GetNameForID(from_name_id).to_string(),
name_table.GetRefForID(from_name_id).to_string(),
name_table.GetPronunciationForID(from_name_id).to_string(),
name_table.GetExitsForID(from_name_id).to_string(),
return requiresNameAnnounced(name_table.GetNameForID(from_name_id),
name_table.GetRefForID(from_name_id),
name_table.GetPronunciationForID(from_name_id),
name_table.GetExitsForID(from_name_id),
//
name_table.GetNameForID(to_name_id).to_string(),
name_table.GetRefForID(to_name_id).to_string(),
name_table.GetPronunciationForID(to_name_id).to_string(),
name_table.GetExitsForID(to_name_id).to_string(),
name_table.GetNameForID(to_name_id),
name_table.GetRefForID(to_name_id),
name_table.GetPronunciationForID(to_name_id),
name_table.GetExitsForID(to_name_id),
//
suffix_table);
// FIXME: converts StringViews to strings since the name change heuristics mutates in place
}
inline bool requiresNameAnnounced(const NameID from_name_id,
const NameID to_name_id,
const util::NameTable &name_table)
{
if (from_name_id == to_name_id)
return false;
else
return requiresNameAnnounced(name_table.GetNameForID(from_name_id).to_string(),
name_table.GetRefForID(from_name_id).to_string(),
name_table.GetPronunciationForID(from_name_id).to_string(),
name_table.GetExitsForID(from_name_id).to_string(),
//
name_table.GetNameForID(to_name_id).to_string(),
name_table.GetRefForID(to_name_id).to_string(),
name_table.GetExitsForID(to_name_id).to_string(),
name_table.GetPronunciationForID(to_name_id).to_string());
// FIXME: converts StringViews to strings since the name change heuristics mutates in place
}
} // namespace guidance

View File

@ -1,6 +1,6 @@
{
"name": "osrm",
"version": "5.14.0-latest.1",
"version": "5.14.3",
"private": false,
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.",
"dependencies": {

View File

@ -253,6 +253,8 @@ function setup()
["at:rural"] = 100,
["at:trunk"] = 100,
["be:motorway"] = 120,
["by:urban"] = 60,
["by:motorway"] = 110,
["ch:rural"] = 80,
["ch:trunk"] = 100,
["ch:motorway"] = 120,
@ -276,7 +278,6 @@ function setup()
["ru:living_street"] = 20,
["ru:urban"] = 60,
["ru:motorway"] = 110,
["ua:urban"] = 60,
["uk:nsl_single"] = (60*1609)/1000,
["uk:nsl_dual"] = (70*1609)/1000,
["uk:motorway"] = (70*1609)/1000,

View File

@ -384,7 +384,7 @@ void RenumberData(std::vector<RemainingNodeData> &remaining_nodes,
// we need to make a copy here because we are going to modify it
auto to_orig = new_to_old_node_id;
auto new_node_id = 0;
auto new_node_id = 0u;
// All remaining nodes get the low IDs
for (auto &remaining : remaining_nodes)

View File

@ -41,15 +41,14 @@ bool noIntermediaryIntersections(const RouteStep &step)
}
// Link roads, as far as we are concerned, are short unnamed segments between to named segments.
bool isLinkroad(const RouteStep &pre_link_step,
bool isLinkRoad(const RouteStep &pre_link_step,
const RouteStep &link_step,
const RouteStep &post_link_step)
{
const constexpr double MAX_LINK_ROAD_LENGTH = 2 * MAX_COLLAPSE_DISTANCE;
const auto is_short = link_step.distance <= MAX_LINK_ROAD_LENGTH;
const auto unnamed = link_step.name_id == EMPTY_NAMEID;
const auto between_named =
(pre_link_step.name_id != EMPTY_NAMEID) && (post_link_step.name_id != EMPTY_NAMEID);
const auto unnamed = link_step.name.empty();
const auto between_named = !pre_link_step.name.empty() && !post_link_step.name.empty();
return is_short && unnamed && between_named && noIntermediaryIntersections(link_step);
}
@ -196,7 +195,7 @@ bool isUTurn(const RouteStepIterator step_prior_to_intersection,
const auto only_allowed_turn = (numberOfAllowedTurns(*step_leaving_intersection) == 1) &&
noIntermediaryIntersections(*step_entering_intersection);
return collapsable || isLinkroad(*step_prior_to_intersection,
return collapsable || isLinkRoad(*step_prior_to_intersection,
*step_entering_intersection,
*step_leaving_intersection) ||
only_allowed_turn;

View File

@ -784,9 +784,8 @@ InternalManyRoutesResult alternativePathSearch(SearchEngineData<Algorithm> &sear
begin(weighted_packed_paths) + 1,
alternative_paths_last);
alternative_paths_last = filterPackedPathsByCellSharing(begin(weighted_packed_paths), //
end(weighted_packed_paths), //
partition); //
alternative_paths_last = filterPackedPathsByCellSharing(
begin(weighted_packed_paths), alternative_paths_last, partition);
BOOST_ASSERT(weighted_packed_paths.size() >= 1);

View File

@ -375,7 +375,9 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedNodes(const WayRestrictionMap &way_re
m_edge_based_node_container.nodes[edge_based_node_id].segregated =
segregated_edges.count(eid) > 0;
m_edge_based_node_weights.push_back(m_edge_based_node_weights[eid]);
const auto ebn_weight = m_edge_based_node_weights[nbe_to_ebn_mapping[eid]];
BOOST_ASSERT(ebn_weight == INVALID_EDGE_WEIGHT || ebn_weight == edge_data.weight);
m_edge_based_node_weights.push_back(ebn_weight);
edge_based_node_id++;
progress.PrintStatus(progress_counter++);
@ -580,7 +582,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
ExtractionTurn extracted_turn(
turn.angle,
m_node_based_graph.GetOutDegree(node_at_center_of_intersection),
turn.instruction.direction_modifier == guidance::DirectionModifier::UTurn,
turn.instruction.IsUTurn(),
is_traffic_light,
edge_data1.flags.restricted,
edge_data2.flags.restricted,

View File

@ -71,17 +71,19 @@ TurnType::Enum IntersectionHandler::findBasicTurnType(const EdgeID via_edge,
if (!on_ramp && onto_ramp)
return TurnType::OnRamp;
const auto &in_name =
const auto &in_name_id =
node_data_container.GetAnnotation(node_based_graph.GetEdgeData(via_edge).annotation_data)
.name_id;
const auto &out_name =
const auto &out_name_id =
node_data_container.GetAnnotation(node_based_graph.GetEdgeData(road.eid).annotation_data)
.name_id;
const auto &in_name_empty = name_table.GetNameForID(in_name_id).empty();
const auto &out_name_empty = name_table.GetNameForID(out_name_id).empty();
const auto same_name = !util::guidance::requiresNameAnnounced(
in_name, out_name, name_table, street_name_suffix_table);
in_name_id, out_name_id, name_table, street_name_suffix_table);
if (in_name != EMPTY_NAMEID && out_name != EMPTY_NAMEID && same_name)
if (!in_name_empty && !out_name_empty && same_name)
{
return TurnType::Continue;
}
@ -488,8 +490,8 @@ bool IntersectionHandler::isSameName(const EdgeID source_edge_id, const EdgeID t
const auto &target_edge_data = node_data_container.GetAnnotation(
node_based_graph.GetEdgeData(target_edge_id).annotation_data);
return source_edge_data.name_id != EMPTY_NAMEID && //
target_edge_data.name_id != EMPTY_NAMEID && //
return !name_table.GetNameForID(source_edge_data.name_id).empty() && //
!name_table.GetNameForID(target_edge_data.name_id).empty() && //
!util::guidance::requiresNameAnnounced(source_edge_data.name_id,
target_edge_data.name_id,
name_table,

View File

@ -23,6 +23,8 @@ namespace guidance
namespace
{
// check a connected road for equality of a name
// returns 'true' if no equality because this is used as a filter elsewhere, i.e. filter if fn
// returns 'true'
inline auto makeCheckRoadForName(const NameID name_id,
const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
@ -32,15 +34,18 @@ inline auto makeCheckRoadForName(const NameID name_id,
return [name_id, &node_based_graph, &node_data_container, &name_table, &suffix_table](
const MergableRoadDetector::MergableRoadData &road) {
// since we filter here, we don't want any other name than the one we are looking for
const auto road_name =
const auto road_name_id =
node_data_container
.GetAnnotation(node_based_graph.GetEdgeData(road.eid).annotation_data)
.name_id;
if (name_id == EMPTY_NAMEID || road_name == EMPTY_NAMEID)
const auto road_name_empty = name_table.GetNameForID(road_name_id).empty();
const auto in_name_empty = name_table.GetNameForID(name_id).empty();
if (in_name_empty || road_name_empty)
return true;
const auto requires_announcement =
util::guidance::requiresNameAnnounced(name_id, road_name, name_table, suffix_table) ||
util::guidance::requiresNameAnnounced(road_name, name_id, name_table, suffix_table);
util::guidance::requiresNameAnnounced(
name_id, road_name_id, name_table, suffix_table) ||
util::guidance::requiresNameAnnounced(road_name_id, name_id, name_table, suffix_table);
return requires_announcement;
};
@ -465,16 +470,18 @@ bool MergableRoadDetector::IsTrafficIsland(const NodeID intersection_node,
.name_id;
const auto has_required_name = [this, required_name_id](const auto edge_id) {
const auto road_name =
const auto road_name_id =
node_data_container
.GetAnnotation(node_based_graph.GetEdgeData(edge_id).annotation_data)
.name_id;
if (required_name_id == EMPTY_NAMEID || road_name == EMPTY_NAMEID)
const auto &road_name_empty = name_table.GetNameForID(road_name_id).empty();
const auto &required_name_empty = name_table.GetNameForID(required_name_id).empty();
if (required_name_empty && road_name_empty)
return false;
return !util::guidance::requiresNameAnnounced(
required_name_id, road_name, name_table, street_name_suffix_table) ||
required_name_id, road_name_id, name_table, street_name_suffix_table) ||
!util::guidance::requiresNameAnnounced(
road_name, required_name_id, name_table, street_name_suffix_table);
road_name_id, required_name_id, name_table, street_name_suffix_table);
};
/* the beautiful way would be:

View File

@ -379,11 +379,15 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
//
// 7 1
// 0
const auto &first_intersection_name_empty =
name_table.GetNameForID(first_intersection_data.name_id).empty();
const auto &second_intersection_name_empty =
name_table.GetNameForID(second_intersection_data.name_id).empty();
if (intersection[1].entry_allowed)
{
if (isMotorwayClass(intersection[1].eid, node_based_graph) &&
second_intersection_data.name_id != EMPTY_NAMEID &&
first_intersection_data.name_id != EMPTY_NAMEID && first_second_same_name)
!second_intersection_name_empty && !first_intersection_name_empty &&
first_second_same_name)
{
// circular order indicates a merge to the left (0-3 onto 4
if (angularDeviation(intersection[1].angle, STRAIGHT_ANGLE) <
@ -407,8 +411,8 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
{
BOOST_ASSERT(intersection[2].entry_allowed);
if (isMotorwayClass(intersection[2].eid, node_based_graph) &&
second_intersection_data.name_id != EMPTY_NAMEID &&
first_intersection_data.name_id != EMPTY_NAMEID && first_second_same_name)
!second_intersection_name_empty && !first_intersection_name_empty &&
first_second_same_name)
{
// circular order (5-0) onto 4
if (angularDeviation(intersection[2].angle, STRAIGHT_ANGLE) <

View File

@ -295,7 +295,8 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
return SPECIAL_EDGEID;
}
if (EMPTY_NAMEID != edge_data.name_id)
const auto &edge_name_empty = name_table.GetNameForID(edge_data.name_id).empty();
if (!edge_name_empty)
{
const auto announce = [&](unsigned id) {
@ -306,7 +307,6 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
if (std::all_of(begin(roundabout_name_ids), end(roundabout_name_ids), announce))
roundabout_name_ids.insert(edge_data.name_id);
}
continue_edge = edge_id;
}
else if (!edge.flags.roundabout && !edge.flags.circular)

View File

@ -1,5 +1,6 @@
#include "extractor/guidance/sliproad_handler.hpp"
#include "extractor/guidance/constants.hpp"
#include "util/assert.hpp"
#include "util/bearing.hpp"
#include "util/coordinate_calculation.hpp"
#include "util/guidance/name_announcements.hpp"
@ -474,10 +475,7 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter
// Name mismatch: check roads at `c` and `d` for same name
const auto name_mismatch = [&](const NameID road_name_id) {
const auto unnamed = road_name_id == EMPTY_NAMEID;
return unnamed ||
util::guidance::requiresNameAnnounced(road_name_id, //
return util::guidance::requiresNameAnnounced(road_name_id, //
candidate_data.name_id, //
name_table, //
street_name_suffix_table); //
@ -499,11 +497,15 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter
node_data_container
.GetAnnotation(node_based_graph.GetEdgeData(main_road.eid).annotation_data)
.name_id;
const auto main_road_name_empty = name_table.GetNameForID(main_road_name_id).empty();
const auto &sliproad_annotation =
node_data_container.GetAnnotation(sliproad_edge_data.annotation_data);
const auto sliproad_name_empty =
name_table.GetNameForID(sliproad_annotation.name_id).empty();
const auto candidate_road_name_empty =
name_table.GetNameForID(candidate_data.name_id).empty();
if (!sliproad_edge_data.flags.road_classification.IsLinkClass() &&
sliproad_annotation.name_id != EMPTY_NAMEID && main_road_name_id != EMPTY_NAMEID &&
candidate_data.name_id != EMPTY_NAMEID &&
!sliproad_name_empty && !main_road_name_empty && !candidate_road_name_empty &&
util::guidance::requiresNameAnnounced(main_road_name_id,
sliproad_annotation.name_id,
name_table,
@ -575,7 +577,7 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter
intersection[*obvious].instruction.direction_modifier =
getTurnDirection(intersection[*obvious].angle);
}
else if (main_annotation.name_id != EMPTY_NAMEID)
else if (!name_table.GetNameForID(main_annotation.name_id).empty())
{
intersection[*obvious].instruction.type = TurnType::NewName;
intersection[*obvious].instruction.direction_modifier =

View File

@ -199,7 +199,8 @@ bool TurnHandler::isObviousOfTwo(const EdgeID via_edge,
const bool turn_is_perfectly_straight =
angularDeviation(road.angle, STRAIGHT_ANGLE) < std::numeric_limits<double>::epsilon();
if (via_data.name_id != EMPTY_NAMEID)
const auto &via_name_empty = name_table.GetNameForID(via_data.name_id).empty();
if (!via_name_empty)
{
const auto same_name = !util::guidance::requiresNameAnnounced(
via_data.name_id, road_data.name_id, name_table, street_name_suffix_table);

View File

@ -331,43 +331,6 @@ void Storage::PopulateLayout(DataLayout &layout)
layout.SetBlockSize<char>(DataLayout::TIMESTAMP, timestamp_size);
}
// load core marker size
if (boost::filesystem::exists(config.GetPath(".osrm.core")))
{
io::FileReader core_marker_file(config.GetPath(".osrm.core"),
io::FileReader::VerifyFingerprint);
const auto num_metrics = core_marker_file.ReadElementCount64();
if (num_metrics > NUM_METRICS)
{
throw util::exception("Only " + std::to_string(NUM_METRICS) +
" metrics are supported at the same time.");
}
const auto number_of_core_markers = core_marker_file.ReadElementCount64();
for (const auto index : util::irange<std::size_t>(0, num_metrics))
{
layout.SetBlockSize<unsigned>(
static_cast<DataLayout::BlockID>(DataLayout::CH_CORE_MARKER_0 + index),
number_of_core_markers);
}
for (const auto index : util::irange<std::size_t>(num_metrics, NUM_METRICS))
{
layout.SetBlockSize<unsigned>(
static_cast<DataLayout::BlockID>(DataLayout::CH_CORE_MARKER_0 + index), 0);
}
}
else
{
layout.SetBlockSize<unsigned>(DataLayout::CH_CORE_MARKER_0, 0);
layout.SetBlockSize<unsigned>(DataLayout::CH_CORE_MARKER_1, 0);
layout.SetBlockSize<unsigned>(DataLayout::CH_CORE_MARKER_2, 0);
layout.SetBlockSize<unsigned>(DataLayout::CH_CORE_MARKER_3, 0);
layout.SetBlockSize<unsigned>(DataLayout::CH_CORE_MARKER_4, 0);
layout.SetBlockSize<unsigned>(DataLayout::CH_CORE_MARKER_5, 0);
layout.SetBlockSize<unsigned>(DataLayout::CH_CORE_MARKER_6, 0);
layout.SetBlockSize<unsigned>(DataLayout::CH_CORE_MARKER_7, 0);
}
// load turn weight penalties
{
io::FileReader turn_weight_penalties_file(config.GetPath(".osrm.turn_weight_penalties"),

View File

@ -147,6 +147,8 @@
{"key": "maxspeed", "value": "AT:rural"},
{"key": "maxspeed", "value": "AT:trunk"},
{"key": "maxspeed", "value": "BE:motorway"},
{"key": "maxspeed", "value": "BY:urban"},
{"key": "maxspeed", "value": "BY:motorway"},
{"key": "maxspeed", "value": "CH:rural"},
{"key": "maxspeed", "value": "CH:trunk"},
{"key": "maxspeed", "value": "CH:motorway"},
@ -170,7 +172,6 @@
{"key": "maxspeed", "value": "RU:living_street"},
{"key": "maxspeed", "value": "RU:urban"},
{"key": "maxspeed", "value": "RU:motorway"},
{"key": "maxspeed", "value": "UA:urban"},
{"key": "maxspeed", "value": "UK:nsl_single"},
{"key": "maxspeed", "value": "UK:nsl_dual"},
{"key": "maxspeed", "value": "UK:motorway"},