Compare commits

..

82 Commits

Author SHA1 Message Date
Daniel Patterson eeff4be544 Enable builds on 5.10 release branch. 2017-08-03 13:05:54 -07:00
Daniel Patterson 7fdc544229 Set version to 5.10 2017-08-03 12:57:09 -07:00
Moritz Kobitzsch 52691af7ba Add regression test for interaction between via-way and via-node 2017-08-03 12:52:04 -07:00
Moritz Kobitzsch 19c57771a1 move babel to dev dependencies, update releasing docs to reflect scripts in package.json 2017-08-03 12:52:00 -07:00
Daniel J. Hofmann 77141d1088 Updates our node osrm docs and re-runs docs generation, resolves #4043 2017-08-03 12:51:54 -07:00
Daniel J. Hofmann 57955cd0d6 Adds babel transformation needed for node osrm docs 2017-08-03 12:51:48 -07:00
Michael Krasnyk 2e91874104 Fix gcc5 internal compilation error 2017-08-03 12:51:40 -07:00
Moritz Kobitzsch 84ce97a31e Bump version to v5.10.0-rc.2 2017-08-01 12:30:31 +02:00
Moritz Kobitzsch 7e0c9f7340 remove accidental addition of debug code 2017-08-01 12:29:56 +02:00
Moritz Kobitzsch 917a36eaee fix pedantic warnings 2017-08-01 12:27:29 +02:00
Moritz Kobitzsch 7620d419c6 fix serialisation of conditional turn restrictions 2017-08-01 12:27:29 +02:00
Moritz Kobitzsch 50c90b29d2 parse conditional turn restriction with via way 2017-08-01 12:27:29 +02:00
Daniel Patterson 0e77cf53f6 Update CHANGELOG with bugfix notes. 2017-07-31 08:33:19 -07:00
Moritz Kobitzsch 9dfbae69cc [skip-ci] Bump version to v5.10.0-rc.1 2017-07-31 16:18:56 +02:00
Michael Krasnyk c1ad4f6b45 Fix a single weekday grammar callback 2017-07-31 14:56:08 +02:00
Moritz Kobitzsch 8135f08958 restructure for review remarks 2017-07-31 09:36:25 +02:00
Moritz Kobitzsch 645b1ffd75 add testcases to highlight limitation of via-way handling 2017-07-31 09:36:25 +02:00
Moritz Kobitzsch 8d0202d240 Add data structure to allow identification of via-way turns during creation of edge-based-graph
initial version of handling via-way turn restrictions (this is dirty)

 - requires update of data structures
 - requires clean-up
 - requires optimisation
2017-07-31 09:36:25 +02:00
Moritz Kobitzsch b1809d1667 pre-filter turn restrictions for validity 2017-07-31 09:36:25 +02:00
Moritz Kobitzsch 2e9a7d9c1a refactor restriction parsing / extraction to actual types
Makes turn restrictions into dedicated structures and diferentiates between them via a variant.
Ensures that we do not accidentally mess up ID types within our application.
In addition this improves the restriction performance by only parsing all edges
once at the cost of (at the time of writing) 22MB in terms of main memory usage.
2017-07-31 09:36:25 +02:00
Moritz Kobitzsch 1f7aa6f812 adding tests to highlight via-way-restriciton development 2017-07-31 09:36:25 +02:00
Patrick Niklaus 032a189440 Merge pull request #4352 from Project-OSRM/fix_reverse_datasources
Save both forward and reverse datasources.
2017-07-28 07:53:17 +00:00
Daniel Patterson be5fc50136 Save both forward and reverse datasources. 2017-07-27 14:45:28 -07:00
Moritz Kobitzsch 0affec8f17 handle throughabouts -- do not announce going through 2017-07-26 10:37:20 +02:00
Daniel Patterson 8c9ae4d3b4 Update CHANGELOG. 2017-07-25 15:14:45 -06:00
Daniel Patterson dac6bb27aa Don't include turn costs when calculation weight/duration/speed annotations. 2017-07-25 15:14:45 -06:00
Daniel J. Hofmann 6c0ab24100 Updates npm and yarn lockfiles 2017-07-24 13:15:15 +02:00
Michael Krasnyk 95c7832c3e Don't use STXXL library by default 2017-07-24 13:05:22 +02:00
Daniel J. Hofmann c2e8d6160f Documents system-wide limit constructor parameters in node bindings, resolves #4317 2017-07-24 13:02:56 +02:00
Emil Tin f609905267 fix profile debugging related to way classes 2017-07-24 13:01:32 +02:00
Daniel J. Hofmann f7c8bac3fd Handles distinction of no-route vs invalid-route in mld alternatives
The viaroute plugin always expects a route to be there potentially
with invalid edge weight to represent no-route-found. By switching
to the many-route-result for the mld alternatives algorithm we might
return an empty many-route-result invalidating the post-condition.
2017-07-22 12:50:54 +02:00
Patrick Niklaus 58811d8f5c Merge pull request #4320 from Project-OSRM/oak-franklin-scenario
Adds lane anticipation Oak St -> Franklin St -> Fell St scenario
2017-07-22 08:08:56 +00:00
Daniel J. Hofmann 54960f9b5d Adds lane anticipation Oak St -> Franklin St -> Fell St scenario 2017-07-21 19:04:55 +02:00
Patrick Niklaus cd45ddda13 Merge pull request #4304 from Project-OSRM/third_party/update_dependencies
Update third party dependencies
2017-07-21 00:00:44 +00:00
Patrick Niklaus 04acd2141b Use sol 2.17.5 instead 2017-07-20 22:01:54 +00:00
Michael Krasnyk 336ec4741c Update TBB mason version to 2017_U7 2017-07-20 13:49:18 +00:00
Pepijn Schoen 8da40419ee Maintain storage_config exposed API 2017-07-20 12:01:05 +02:00
Pepijn Schoen 0b5c7a97a7 Addressed comments 2017-07-20 12:01:05 +02:00
Pepijn Schoen d9e8caf369 Use GetPath with file names over accessing member variables 2017-07-20 12:01:05 +02:00
Pepijn Schoen e208485c17 expose mandatory / optional / output files in io_config; config files to use new io_config constructor 2017-07-20 12:01:05 +02:00
Pepijn Schoen 5a6dee80ac Fix rebase problems 2017-07-20 12:01:05 +02:00
Pepijn Schoen 67fae1d1f0 rename osrm_input_path to osrm_path, clang-format 2017-07-20 12:01:05 +02:00
Pepijn Schoen 1b31099f73 superclass extractor_config with io_config 2017-07-20 12:01:05 +02:00
Pepijn Schoen 897518a297 superclass customizer_config with io_config 2017-07-20 12:01:05 +02:00
Pepijn Schoen a9b6686725 superclass partition_config with io_config 2017-07-20 12:01:05 +02:00
Pepijn Schoen 2c7cb5baba superclass contractor_config with io_config 2017-07-20 12:01:05 +02:00
Pepijn Schoen 29160eec9c superclass updater_config with io_config 2017-07-20 12:01:05 +02:00
Pepijn Schoen fe00a8a0ca superclass storage_config with io_config 2017-07-20 12:01:05 +02:00
Patrick Niklaus 64574c779f [skip ci] Backport 5.9 changelog 2017-07-19 17:02:29 +00:00
Daniel J. Hofmann 64e4b7eaa0 Introduces a construction whitelist in profiles 2017-07-19 16:24:45 +00:00
Daniel J. Hofmann 48824c4c8a Normalizes spaces in profiles 2017-07-19 16:24:45 +00:00
Daniel J. Hofmann ababeb3a69 Makes construction=minor ways routable again, see #4258 2017-07-19 16:24:45 +00:00
Mateusz Loskot cfa2a63323 Set OSRM_BUILD_DIR based on CMake build dir
For typical local workflow, CMake can auto-configure most
of the environment, for convenience.
2017-07-19 12:57:04 +00:00
Patrick Niklaus 9418f5613a Update sol2 to v2.17.5 2017-07-18 21:11:03 +00:00
Patrick Niklaus 22a3e06e1c Merge commit 'b91c2f0299722e64a6945808d64c3397c35811d0' into third_party/update_dependencies 2017-07-18 21:08:32 +00:00
Patrick Niklaus b91c2f0299 Squashed 'third_party/libosmium/' changes from c1f34c455..9fd2348c6
9fd2348c6 Release v2.11.3
ed708286e Fix namespace.
835df8a7f Fix multipolygon assembler.
0979ab529 Fix areas assembler algorithm.
801f84c62 Bugfix: Invalid use of iterators.
f85653820 Read OPL file correctly even if trailing newline in file missing.
a31571c0f Release v2.11.2
a3903b368 Use minimum size of 64 bytes for buffers.
b86bafefe Release v2.11.1
32ebf736c Updated change log.
632ea5198 Bugfix: Call get_creator_function() in main thread.
ddc79eee7 Add test for not correctly handled unsupported_file_format_error.
86197a14f Bugfix: Terminate called on full buffer.
4340be8ad Fix the Filter::count() method.

git-subtree-dir: third_party/libosmium
git-subtree-split: 9fd2348c6956b6e1b930b50850e99eb31207ed50
2017-07-18 21:08:32 +00:00
Patrick Niklaus 07416c7a46 Bump versions to latest releases 2017-07-18 21:08:05 +00:00
Patrick Niklaus 440dccb81b Move classes to intersection object and don't emit notifications 2017-07-18 16:48:22 +00:00
Emil Tin e413b25cd9 profiles api v2 2017-07-18 10:09:22 +00:00
Daniel J. Hofmann 5ece65cade Trigger lane anticipation based on distance, see discussion in #4260 2017-07-18 11:23:46 +02:00
Moritz Kobitzsch c0c9ec1c7b changelog, consistent deprecated documentation 2017-07-18 11:23:46 +02:00
Moritz Kobitzsch f2f00b99e0 remove usage of use-lane completely 2017-07-18 11:23:46 +02:00
Moritz Kobitzsch 7b755d6f8b deprecate use-lane -- the information can be found in the intersections array 2017-07-18 11:23:46 +02:00
Daniel J. Hofmann 7d63301039 Only enables -fopenmp in case the user wants stxxl 2017-07-17 19:19:10 +02:00
Patrick Niklaus 49f0b1eb59 Add abstraction to change the data facade at compile time 2017-07-17 11:40:55 +00:00
Michael Krasnyk b2ed46efb5 Check activation index of EntryClass and warn if activation failed 2017-07-13 22:14:41 +00:00
Daniel J. Hofmann 58b61c68a3 Exposes EngineConfig system-wide limits in Node.js bindings, resolves #4226 2017-07-13 21:48:48 +00:00
Moritz Kobitzsch 30b8225812 only consider allowed entries when continuing on motorways 2017-07-13 08:59:01 +00:00
Moritz Kobitzsch 54530a14e9 add test indicating missdetection of continuing on motorways 2017-07-13 08:59:01 +00:00
Daniel Patterson ee8ffcf57b Include osrm-customize when doing 'make install' 2017-07-12 22:11:42 +00:00
Daniel J. Hofmann 5e9397fcca Canonicalizes all OSM string list handling in the profiles 2017-07-12 22:09:01 +00:00
Patrick Niklaus 8508834e50 Bump version to 5.10 2017-07-11 08:25:57 +00:00
Michael Krasnyk 924a8a7e38 Remove STXXL from OSM parsing and enable in CMake by default 2017-07-11 08:23:26 +00:00
Michael Krasnyk 960e9178ba Updated ChangeLog 2017-07-11 08:23:26 +00:00
Michael Krasnyk a3257ff651 Added STXXL configuration 2017-07-11 08:23:26 +00:00
Michael Krasnyk 960f9ba29a Don't use stxxl vector in contractor 2017-07-11 08:23:26 +00:00
Michael Krasnyk 3940cc1641 Switch from stxxl::vector to std::vector in extractor 2017-07-11 08:23:26 +00:00
Michael Krasnyk a498ba6537 Removed external_to_internal_node_id_map container 2017-07-11 08:23:26 +00:00
Daniel J. Hofmann 5b5a907023 Makes tile size checks strict, resolves #4177 2017-07-10 12:19:53 +02:00
Daniel J. Hofmann c1cb3ebff7 Fixes Node.js bindings always enabling alternatives when using boolean overload 2017-07-10 10:44:15 +02:00
Daniel J. Hofmann 6a555a477b Discards construction and proposed ways, resolves #4230 2017-07-10 10:34:20 +02:00
Daniel J. Hofmann 175d27691d Fixes line endings, related to #4235 2017-07-10 07:26:17 +00:00
169 changed files with 11189 additions and 5007 deletions
+1
View File
@@ -1,4 +1,5 @@
{
"plugins": ["transform-class-properties"],
"presets": [
"stage-0",
"es2015",
+1 -1
View File
@@ -17,9 +17,9 @@ notifications:
branches:
only:
- master
- "5.10"
# enable building tags
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/
- "5.9"
cache:
yarn: true
+26 -4
View File
@@ -1,12 +1,34 @@
# 5.10.0
- Changes from 5.9:
- Profiles:
- New version 2 profile API which cleans up a number of things and makes it easier to for profiles to include each other. Profiles using the old version 0 and 1 APIs are still supported.
- New required `setup()` function that must return a configuration hash. Storing configuration in globals is deprecated.
- Passes the config hash returned in `setup()` as an argument to `process_node/way/segment/turn`.
- Properties are now set in `.properties` in the config hash returend by setup().
- initialize raster sources in `setup()` instead of in a separate callback.
- Renames the `sources` helper to `raster`.
- Renames `way_functions` to `process_way` (same for node, segment and turn).
- Removes `get_restrictions()`. Instead set `.restrictions` in the config hash in `setup()`.
- Removes `get_name_suffix_list()`. Instead set `.suffix_list` in the config hash in `setup()`.
- Renames `Handlers` to `WayHandlers`.
- Pass functions instead of strings to `WayHandlers.run()`, so it's possible to mix in your own functions.
- Reorders arguments to `WayHandlers` functions to match `process_way()`.
- Profiles must return a hash of profile functions. This makes it easier for profiles to include each other.
- Guidance: add support for throughabouts
- Bugfixes
- Properly save/retrieve datasource annotations for road segments ([#4346](https://github.com/Project-OSRM/osrm-backend/issues/4346)
- Fix conditional restriction grammer parsing so it works for single-day-of-week restrictions ([#4357](https://github.com/Project-OSRM/osrm-backend/pull/4357))
- Algorithm)
- BREAKING: the file format requires re-processing due to the changes on via-ways
- Added support for via-way restrictions
# 5.9.2
- API:
- `annotations=durations,weights,speeds` values no longer include turn penalty values ([#4330](https://github.com/Project-OSRM/osrm-backend/issues/4330))
# 5.9.1
- Changes from 5.9.0:
- #4322: Deprecated `UseLane`. Use the intersections array if you require lanes between steps
- #4321: Fixes a potential crash in the MLD alternative code path when not even a shortest path can be found
- #4324: STXXL is not required by default
- Infrastructure
- STXXL is not required by default
# 5.9.0
- Changes from 5.8:
+10 -5
View File
@@ -14,6 +14,11 @@ if(BUILD_AS_SUBPROJECT)
message(STATUS "Building libosrm as subproject.")
endif()
# set OSRM_BUILD_DIR location (might be used in various scripts)
if (NOT WIN32 AND NOT DEFINED ENV{OSRM_BUILD_DIR})
set(ENV{OSRM_BUILD_DIR} ${CMAKE_CURRENT_BINARY_DIR})
endif()
option(ENABLE_MASON "Use mason for dependencies" OFF)
option(ENABLE_CCACHE "Speed up incremental rebuilds via ccache" ON)
option(BUILD_TOOLS "Build OSRM tools" OFF)
@@ -36,7 +41,7 @@ if(ENABLE_MASON)
set(MASON_EXPAT_VERSION "2.2.0")
set(MASON_LUA_VERSION "5.2.4")
set(MASON_BZIP2_VERSION "1.0.6")
set(MASON_TBB_VERSION "2017_20161128")
set(MASON_TBB_VERSION "2017_U7")
set(MASON_LIBSHP_VERSION "1.3.0")
message(STATUS "Enabling mason")
@@ -55,8 +60,8 @@ if (POLICY CMP0048)
endif()
project(OSRM C CXX)
set(OSRM_VERSION_MAJOR 5)
set(OSRM_VERSION_MINOR 9)
set(OSRM_VERSION_PATCH 2)
set(OSRM_VERSION_MINOR 10)
set(OSRM_VERSION_PATCH 0)
set(OSRM_VERSION "${OSRM_VERSION_MAJOR}.${OSRM_VERSION_MINOR}.${OSRM_VERSION_PATCH}")
add_definitions(-DOSRM_PROJECT_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
@@ -733,10 +738,10 @@ file(GLOB LibraryGlob include/osrm/*.hpp)
file(GLOB ParametersGlob include/engine/api/*_parameters.hpp)
set(EngineHeader include/engine/status.hpp include/engine/engine_config.hpp include/engine/hint.hpp include/engine/bearing.hpp include/engine/approach.hpp include/engine/phantom_node.hpp)
set(UtilHeader include/util/coordinate.hpp include/util/json_container.hpp include/util/typedefs.hpp include/util/alias.hpp include/util/exception.hpp)
set(ExtractorHeader include/extractor/extractor.hpp include/extractor/extractor_config.hpp include/extractor/travel_mode.hpp)
set(ExtractorHeader include/extractor/extractor.hpp include/storage/io_config.hpp include/extractor/extractor_config.hpp include/extractor/travel_mode.hpp)
set(PartitionerHeader include/partition/partitioner.hpp include/partition/partition_config.hpp)
set(ContractorHeader include/contractor/contractor.hpp include/contractor/contractor_config.hpp)
set(StorageHeader include/storage/storage.hpp include/storage/storage_config.hpp)
set(StorageHeader include/storage/storage.hpp include/storage/io_config.hpp include/storage/storage_config.hpp)
install(FILES ${EngineHeader} DESTINATION include/osrm/engine)
install(FILES ${UtilHeader} DESTINATION include/osrm/util)
install(FILES ${StorageHeader} DESTINATION include/osrm/storage)
+30 -29
View File
@@ -27,11 +27,11 @@ var osrm = new OSRM('network.osrm');
This requires you to run `osrm-datastore` prior to creating an `OSRM` object.
- `options.path` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** The path to the `.osrm` files. This is mutually exclusive with setting {options.shared_memory} to true.
- `options.max_locations_trip` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. locations supported in trip query (default: unlimited).
- `options.max_locations_viaroute` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. locations supported in viaroute query 9default: unlimited).
- `options.max_locations_viaroute` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. locations supported in viaroute query (default: unlimited).
- `options.max_locations_distance_table` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. locations supported in distance table query (default: unlimited).
- `options.max_locations_map_matching` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. locations supported in map matching query (default: unlimited).
- `options.max_locations_map_matching` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. locations supported in map-matching query (default: unlimited).
- `options.max_results_nearest` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. results supported in nearest query (default: unlimited).
- `options.max_alternatives` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. number of alternative routes supported (default: 3).
- `options.max_alternatives` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max.number of alternatives supported in alternative routes query (default: 3).
### route
@@ -45,15 +45,16 @@ Returns the fastest route between two or more coordinates while visiting the way
Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`.
- `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the coordinate snapping to streets in the given radius in meters. Can be `null` (unlimited, default) or `double >= 0`.
- `options.hints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Hints for the coordinate snapping. Array of base64 encoded strings.
- `options.alternatives` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Search for alternative routes and return as well.
_Please note that even if an alternative route is requested, a result cannot be guaranteed._ (optional, default `false`)
- `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Returned route steps for each route leg. (optional, default `false`)
- `options.alternatives` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Search for alternative routes. (optional, default `false`)
- `options.alternatives` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Search for up to this many alternative routes.
_Please note that even if alternative routes are requested, a result cannot be guaranteed._ (optional, default `0`)
- `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route steps for each route leg. (optional, default `false`)
- `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`)
- `options.geometries` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route geometry format (influences overview and per step). Can also be `geojson`. (optional, default `polyline`)
- `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`). (optional, default `simplified`)
- `options.continue_straight` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Forces the route to keep going straight at waypoints and don't do a uturn even if it would be faster. Default value depends on the profile.
`null`/`true`/`false`
- `options.approaches` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`.
`null`/`true`/`false`
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
**Examples**
@@ -194,14 +195,14 @@ if they can not be matched successfully.
- `options.bearings` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the search to segments with given bearing in degrees towards true north in clockwise direction.
Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`.
- `options.hints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Hints for the coordinate snapping. Array of base64 encoded strings.
- `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Returned route steps for each route. (optional, default `false`)
- `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route steps for each route. (optional, default `false`)
- `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`)
- `options.geometries` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route geometry format (influences overview and per step). Can also be `geojson`. (optional, default `polyline`)
- `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`). (optional, default `simplified`)
- `options.timestamps` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>?** Timestamp of the input location (integers, UNIX-like timestamp).
- `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Standard deviation of GPS precision used for map matching. If applicable use GPS accuracy. Can be `null` for default value `5` meters or `double >= 0`.
- `options.gaps` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Allows the input track splitting based on huge timestamp gaps between points. Either `split` or `ignore`. (optional, default `split`)
- `options.tidy` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Allows the input track modification to obtain better matching quality for noisy tracks. (optional, default `false`)
- `options.gaps` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** Allows the input track splitting based on huge timestamp gaps between points. Either `split` or `ignore` (optional, default `split`).
- `options.tidy` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Allows the input track modification to obtain better matching quality for noisy tracks (optional, default `false`).
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
**Examples**
@@ -235,25 +236,7 @@ The trip plugin solves the Traveling Salesman Problem using a greedy heuristic
waypoints. The returned path does not have to be the shortest path, _ as TSP is NP-hard it is
only an approximation.
**Parameters**
- `options` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Object literal containing parameters for the trip query.
- `options.coordinates` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** The coordinates this request will use, coordinates as `[{lon},{lat}]` values, in decimal degrees.
- `options.bearings` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the search to segments with given bearing in degrees towards true north in clockwise direction.
Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`.
- `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the coordinate snapping to streets in the given radius in meters. Can be `double >= 0` or `null` (unlimited, default).
- `options.hints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Hints for the coordinate snapping. Array of base64 encoded strings.
- `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Returned route steps for each route. (optional, default `false`)
- `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`)
- `options.geometries` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route geometry format (influences overview and per step). Can also be `geojson`. (optional, default `polyline`)
- `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` (optional, default `simplified`)
- `options.roundtrip` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Returned route is a roundtrip (route returns to first location). (optional, default `true`)
- `options.source` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route starts at `any` or `first` coordinate. (optional, default `any`)
- `options.destination` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route ends at `any` or `last` coordinate. (optional, default `any`)
- `options.approaches` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`.
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
A requirement for computing trips is that all input coordinates are connected.
Note that all input coordinates have to be connected for the trip service to work.
Currently, not all combinations of `roundtrip`, `source` and `destination` are supported.
Right now, the following combinations are possible:
@@ -268,6 +251,24 @@ Right now, the following combinations are possible:
| false | any | last | no |
| false | any | any | no |
**Parameters**
- `options` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Object literal containing parameters for the trip query.
- `options.coordinates` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** The coordinates this request will use, coordinates as `[{lon},{lat}]` values, in decimal degrees.
- `options.bearings` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the search to segments with given bearing in degrees towards true north in clockwise direction.
Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`.
- `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the coordinate snapping to streets in the given radius in meters. Can be `double >= 0` or `null` (unlimited, default).
- `options.hints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Hints for the coordinate snapping. Array of base64 encoded strings.
- `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route steps for each route. (optional, default `false`)
- `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`)
- `options.geometries` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route geometry format (influences overview and per step). Can also be `geojson`. (optional, default `polyline`)
- `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` (optional, default `simplified`)
- `options.roundtrip` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route is a roundtrip. (optional, default `true`)
- `options.source` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Return route starts at `any` or `first` coordinate. (optional, default `any`)
- `options.destination` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Return route ends at `any` or `last` coordinate. (optional, default `any`)
- `options.approaches` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`.
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
**Examples**
```javascript
+192 -45
View File
@@ -1,31 +1,97 @@
OSRM supports "profiles". Configurations representing different routing behaviours for (typically) different transport modes. A profile describes whether or not we route along a particular type of way, or over a particular node in the OpenStreetMap data, and also how quickly we'll be travelling when we do. This feeds into the way the routing graph is created and thus influences the output routes.
# OSRM profiles
OSRM supports "profiles". Profiles representing routing behavior for different transport modes like car, bike and foot. You can also create profiles for variations like a fastest/shortest car profile or fastest/safest/greenest bicycles profile.
A profile describes whether or not it's possible to route along a particular type of way, whether we can pass a particular node, and how quickly we'll be traveling when we do. This feeds into the way the routing graph is created and thus influences the output routes.
## 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.
Out-of-the-box OSRM comes with several different profiles, including car, bicycle and foot.
Profiles have a 'lua' extension, and are places in 'profiles' directory.
Profile configuration files have a 'lua' extension, and are found under the 'profiles' subdirectory.
Alternatively commands will take a lua profile specified with an explicit -p param, for example:
When running OSRM preprocessing commands you specify the profile with the --profile (or the shorthand -p) option, for example:
`osrm-extract -p ../profiles/car.lua planet-latest.osm.pbf`
`osrm-extract --profile ../profiles/car.lua planet-latest.osm.pbf`
And then **you will need to extract and contract again** (A change to the profile will typically affect the extract step as well as the contract step. See [Processing Flow](https://github.com/Project-OSRM/osrm-backend/wiki/Processing-Flow))
## Processing flow
It's important to understand that profiles are used when preprocessing the OSM data, NOT at query time when routes are computed.
## lua scripts?
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 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 not sufficiently straightforward, to simply define tag mappings. Lua scripting offers a powerful way of coping with the complexity of different node,way,relation,tag combinations found within OpenStreetMap data.
## 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 a profile
## 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.
You can understand these lua scripts enough to make interesting modifications, without needing to get to grips with how they work completely.
A profile will typically:
Towards the top of the file, a profile (such as [car.lua](../profiles/car.lua)) will typically define various configurations as global variables. A lot of these are look-up hashes of one sort or another.
- Define api version (required)
- Require library files (optional)
- Define setup function (required)
- Define process functions (some are required)
- Return functions table (required)
As you scroll down the file you'll see local variables, and then local functions, and finally...
A profile can also define various local functions it needs.
`way_function` and `node_function` are the important functions which are called when extracting OpenStreetMap data with `osrm-extract`.
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.
The following global properties can be set in your profile:
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.
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.
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`.
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.
## 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.
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.
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.
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.
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.
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 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.
## 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.
### Library files
The folder [profiles/lib/](../profiles/lib/) contains LUA library files for handling many common processing tasks.
File | Notes
------------------|------------------------------
way_handlers.lua | Functions for processing way tags
tags.lua | Functions for general parsing of OSM tags
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
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.
### 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.
The following global properties can be set under `properties` in the hash you return in the `setup` function:
Attribute | Type | Notes
-------------------------------------|----------|----------------------------------------------------------------------------
@@ -36,17 +102,40 @@ use_turn_restrictions | Boolean | Are turn instructions followed
continue_straight_at_waypoint | Boolean | Must the route continue straight on at a via point, or are U-turns allowed? (default `true`)
max_speed_for_map_matching | Float | Maximum vehicle speed to be assumed in matching (in m/s)
max_turn_weight | Float | Maximum turn penalty weight
force_split_edges | Boolean | True value forces a split of forward and backward edges of extracted ways and guarantees that `segment_function` will be called for all segments (default `false`)
force_split_edges | Boolean | True value forces a split of forward and backward edges of extracted ways and guarantees that `process_segment` will be called for all segments (default `false`)
## way_function
### process_node(profile, node, result)
Process an OSM node to determine whether this node is a barrier or can be passed and whether passing it incurs a delay.
Given an OpenStreetMap way, the `way_function` will either return nothing (meaning we are not going to route over this way at all), or it will set up a result hash to be returned. The most important thing it will do is set the value of `result.forward_speed` and `result.backward_speed` as a suitable integer value representing the speed for traversing the way.
Argument | Description
---------|-------------------------------------------------------
profile | The configuration table you returned in `setup`.
node | The input node to process (read-only).
result | The output that you will modify.
All other calculations stem from that, including the returned timings in driving directions, but also, less directly, it feeds into the actual routing decisions the engine will take (a way with a slow traversal speed, may be less favoured than a way with fast traversal speed, but it depends how long it is, and... what it connects to in the rest of the network graph)
The following attributes can be set 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 `way_function`. Instead a `way_function` will examine the tagging (e.g. `way:get_value_by_key("highway")` and many others), process this information in various ways, calling other local functions, referencing the global variables and look-up hashes, before arriving at the result.
Attribute | Type | Notes
----------------|---------|---------------------------------------------------------
barrier | Boolean | Is it an impassable barrier?
traffic_lights | Boolean | Is it a traffic light (incurs delay in `process_turn`)?
The following attributes can be set on the result in `way_function`:
## process_way(profile, way, result)
Given an OpenStreetMap way, the `process_way` function will either return nothing (meaning we are not going to route over this way at all), or it will set up a result hash.
Argument | Description
---------|-------------------------------------------------------
profile | The configuration table you returned in `setup`.
node | The input way to process (read-only).
result | The output that you will modify.
Importantly it will set `result.forward_mode` and `result.backward_mode` to indicate the travel mode in each direction, as well as set `result.forward_speed` and `result.backward_speed` to integer values representing the speed for traversing the way.
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.
The following attributes can be set on the result in `process_way`:
Attribute | Type | Notes
----------------------------------------|----------|--------------------------------------------------------------------------
@@ -60,7 +149,7 @@ forward_classes | Table | Mark this way as being of a
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 (normalised OSM `turn:lanes` value)
turn_lanes_forward | String | Directions for individual lanes (normalized OSM `turn:lanes` value)
turn_lanes_backward | String | " "
forward_restricted | Boolean | Is this a restricted access road? (e.g. private, or deliveries only; used to enable high turn penalty, so that way is only chosen for start/end of route)
backward_restricted | Boolean | " "
@@ -78,32 +167,19 @@ road_classification.road_priority_class | Enum | Guidance: order in priority
road_classification.may_be_ignored | Boolean | Guidance: way is non-highway
road_classification.num_lanes | Unsigned | Guidance: total number of lanes in way
### Guidance
### process_segment(profile, segment)
The `process_segment` function is called for every segment of OSM ways. A segment is a straight line between two OSM nodes.
The guidance parameters in profiles are currently a work in progress. They can and will change.
Please be aware of this when using guidance configuration possibilities.
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.
Guidance uses road classes to decide on when/if to emit specific instructions and to discover which road is obvious when following a route.
Classification uses three flags and a priority-category.
The flags indicate whether a road is a motorway (required for on/off ramps), a link type (the ramps itself, if also a motorway) and whether a road may be omittted in considerations (is considered purely for connectivity).
The priority-category influences the decision which road is considered the obvious choice and which roads can be seen as fork.
Forks can be emitted between roads of similar priority category only. Obvious choices follow a major priority road, if the priority difference is large.
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.
## node_function
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.
The following attributes can be set on the result in `node_function`:
Attribute | Type | Notes
----------------|---------|-------------------------------------------------------
barrier | Boolean | Is it an impassable barrier?
traffic_lights | Boolean | Is it a traffic light (incurs delay in `turn_function`)?
## segment_function
The following attributes can be read and set on the result in `segment_function`:
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 | " "
target.lon | Read | Float | Co-ordinates of segment end
@@ -112,17 +188,88 @@ target.distance | Read | Float | Length of segment
weight | Read/write | Float | Routing weight for this segment
duration | Read/write | Float | Duration for this segment
## turn_function
### process_turn(profile, turn)
The `process_turn` function is called for every possible turn in the network. Based on the angle and type of turn you assign the weight and duration of the movement.
The following attributes can be read and set on the result in `turn_function`:
The following attributes can be read and set on the result in `process_turn`:
Attribute | Read/write? | Type | Notes
-------------------|-------------|---------|------------------------------------------------------
direction_modifier | Read | Enum | Geometry of turn. Defined in `include/extractor/guidance/turn_instruction.hpp`
turn_type | Read | Enum | Priority of turn. Defined in `include/extractor/guidance/turn_instruction.hpp`
has_traffic_light | Read | Boolean | Is a traffic light present at this turn?
source_restricted | Read | Boolean | Is it from a restricted access road? (See definition in `way_function`)
target_restricted | Read | Boolean | Is it to a restricted access road? (See definition in `way_function`)
source_restricted | Read | Boolean | Is it from a restricted access road? (See definition in `process_way`)
target_restricted | Read | Boolean | Is it to a restricted access road? (See definition in `process_way`)
angle | Read | Float | Angle of turn in degrees (`0-360`: `0`=u-turn, `180`=straight on)
duration | Read/write | Float | Penalty to be applied for this turn (duration in deciseconds)
weight | Read/write | Float | Penalty to be applied for this turn (routing weight)
## Guidance
The guidance parameters in profiles are currently a work in progress. They can and will change.
Please be aware of this when using guidance configuration possibilities.
Guidance uses road classes to decide on when/if to emit specific instructions and to discover which road is obvious when following a route.
Classification uses three flags and a priority-category.
The flags indicate whether a road is a motorway (required for on/off ramps), a link type (the ramps itself, if also a motorway) and whether a road may be omitted in considerations (is considered purely for connectivity).
The priority-category influences the decision which road is considered the obvious choice and which roads can be seen as fork.
Forks can be emitted between roads of similar priority category only. Obvious choices follow a major priority road, if the priority difference is large.
### 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.
Use `raster:load()` in your `setup` function to load data and store the source in your configuration hash:
```lua
function setup()
return {
raster_source = raster:load(
"rastersource.asc", -- file to load
0, -- longitude min
0.1, -- longitude max
0, -- latitude min
0.1, -- latitude max
5, -- number of rows
4 -- number of columns
)
}
end
```
The input data must an ASCII file with rows of integers. e.g.:
```
0 0 0 0
0 0 0 250
0 0 250 500
0 0 0 250
0 0 0 0
```
In your `segment_function` you can then access the raster source and use `raster:query()` to query to find the nearest data point, or `raster:interpolate()` to interpolate a value based on nearby data points.
You must check whether the result is valid before use it.
Example:
```lua
function process_segment (profile, segment)
local sourceData = raster:query(profile.raster_source, segment.source.lon, segment.source.lat)
local targetData = raster:query(profile.raster_source, segment.target.lon, segment.target.lat)
local invalid = sourceData.invalid_data()
if sourceData.datum ~= invalid and targetData.datum ~= invalid then
-- use values to adjust weight and duration
[...]
end
```
See [rasterbot.lua](../profiles/rasterbot.lua) and [rasterbotinterp.lua](../profiles/rasterbotinterp.lua) for examples.
### Helper functions
There are a few helper functions defined in the global scope that profiles can use:
durationIsValid
parseDuration
trimLaneString
applyAccessTokens
canonicalizeStringList
+1 -1
View File
@@ -47,7 +47,7 @@ We may introduce forward-compatible changes: query parameters and response prope
4. Make sure the `package.json` is up to date.
5. Make sure all tests are passing (e.g. Travis CI gives you a :thumbs_up:)
6. Use an annotated tag to mark the release: `git tag vx.y.z -a` Body of the tag description should be the changelog entries.
7. Use `npm run build-api-docs` to generate the API documentation. Copy `build/docs/*` to `https://github.com/Project-OSRM/project-osrm.github.com` in the `docs/vN.N.N/api` directory
7. Use `npm run docs` to generate the API documentation. Copy `build/docs/*` to `https://github.com/Project-OSRM/project-osrm.github.com` in the `docs/vN.N.N/api` directory
8. Push tags and commits: `git push; git push --tags`
9. If not a release-candidate: Write a mailing-list post to osrm-talk@openstreetmap.org to announce the release
10. Wait until the travis build has been completed and check if the node binaries were published by doing:
+2 -3
View File
@@ -2,10 +2,9 @@
Feature: Bicycle - Route around alleys
Background:
Given the profile file
Given the profile file "bicycle" initialized with
"""
require 'bicycle'
properties.weight_name = 'cyclability'
profile.properties.weight_name = 'cyclability'
"""
Scenario: Bicycle - Avoid taking alleys
+1 -1
View File
@@ -4,7 +4,7 @@ Feature: Bicycle - Handle cycling
Background:
Given the profile "bicycle"
Scenario: Bicycle - Use a ferry route
Scenario: Bicycle - Use a movable bridge
Given the node map
"""
a b c
+2 -3
View File
@@ -2,10 +2,9 @@
Feature: Bicycle - Adds penalties to unsafe roads
Background:
Given the profile file
Given the profile file "bicycle" initialized with
"""
require 'bicycle'
properties.weight_name = 'cyclability'
profile.properties.weight_name = 'cyclability'
"""
Scenario: Bike - Apply penalties to ways without cycleways
+2 -3
View File
@@ -7,10 +7,9 @@ Feature: Turn Penalties
Scenario: Bicycle - Turn penalties on cyclability
Given the profile file
Given the profile file "bicycle" initialized with
"""
require 'bicycle'
properties.weight_name = 'cyclability'
profile.properties.weight_name = 'cyclability'
"""
Given the node map
@@ -739,3 +739,45 @@ Feature: Car - Turn restrictions
| from | to | route | turns |
| a | c | albic,dobe,dobe,albic,albic | depart,turn left,continue uturn,turn left,arrive |
| a | e | albic,dobe,dobe | depart,turn left,arrive |
@no_turning @conditionals
Scenario: Car - Conditional restriction with multiple time windows
Given the extract extra arguments "--parse-conditional-restrictions"
# 5pm Wed 02 May, 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493744400"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493744400"
Given the node map
"""
a f
| |
b - e - h
| | |
c d - g
1
"""
And the ways
| nodes |
| ab |
| bc |
| de |
| ef |
| be |
| eh |
| gh |
| dg |
And the relations
| type | way:from | way:to | way:via | restriction:conditional |
| restriction | ab | be | ef | no_uturn @ (Mo-Fr 07:00-11:00,16:00-18:30) |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ed | dg | d | no_uturn @ (Mo-Fr 07:00-11:00,16:00-18:30) |
When I route I should get
| from | to | route | # |
| a | f | ab,be,ef,ef | currently we do not handle conditional via-ways, this test will have to change when we do |
| f | 1 | ef,eh,gh,dg,dg | |
+522
View File
@@ -506,3 +506,525 @@ Feature: Car - Turn restrictions
| s | n | sj,nj,nj |
| s | e | sj,ej,ej |
@restriction @compression
Scenario: Restriction On Compressed Geometry
Given the node map
"""
i
|
f - e
| |
a - b - c - d
|
g
|
h
"""
And the ways
| nodes |
| abc |
| cde |
| efc |
| cgh |
| ei |
And the relations
| type | way:from | node:via | way:to | restriction |
| restriction | abc | c | cgh | no_right_turn |
When I route I should get
| from | to | route |
| a | h | abc,cde,efc,cgh,cgh |
@restriction-way
Scenario: Car - prohibit turn
Given the node map
"""
c
|
| f
| |
b---e
| |
a d
"""
And the ways
| nodes |
| ab |
| bc |
| be |
| de |
| ef |
And the relations
| type | way:from | way:via | way:to | restriction |
| restriction | ab | be | de | no_right_turn |
When I route I should get
| from | to | route | turns | locations |
| a | d | ab,be,ef,ef,de,de | depart,turn right,turn left,continue uturn,new name straight,arrive | a,b,e,f,e,d |
| a | f | ab,be,ef,ef | depart,turn right,turn left,arrive | a,b,e,f |
| c | d | bc,be,de,de | depart,turn left,turn right,arrive | c,b,e,d |
| c | f | bc,be,ef,ef | depart,turn left,turn left,arrive | c,b,e,f |
@restriction @overlap
Scenario: Car - prohibit turn
Given the node map
"""
c
|
| f
| |
b---e
| |
| d
|
a
"""
And the ways
| nodes |
| ab |
| bc |
| be |
| de |
| ef |
And the relations
| type | way:from | way:via | way:to | restriction |
| restriction | ab | be | de | no_right_turn |
| restriction | bc | be | ef | no_left_turn |
When I route I should get
| from | to | route |
| a | d | ab,be,ef,ef,de,de |
| a | f | ab,be,ef,ef |
| c | d | bc,be,de,de |
| c | f | bc,be,de,de,ef,ef |
@restriction-way @overlap
Scenario: Two times same way
Given the node map
"""
h g
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
a - b - c - - - - - - - - - - - - - - - - - - - f
| | \ /
i - d - e - - - - - - - - - - - - - - - - -
"""
# The long distances here are required to make other turns undesriable in comparison to the restricted turns.
# Otherwise they might just be picked without the actual turns being restricted
And the ways
| nodes | oneway |
| ab | no |
| bc | no |
| cd | yes |
| ce | yes |
| cf | yes |
| cg | yes |
| bh | no |
| fedib | yes |
And the relations
| type | way:from | way:via | way:to | restriction |
| restriction | ab | bc | ce | no_right_turn |
| restriction | ab | bc | cd | no_right_turn |
When I route I should get
| from | to | route |
| a | i | ab,bc,cf,fedib,fedib |
@restriction-way @overlap
Scenario: Car - prohibit turn
Given the node map
"""
a j
| |
b---i
| |
c---h
| |
d---g
| |
e f
"""
And the ways
| nodes | name | oneway |
| ab | left | yes |
| bc | left | yes |
| cd | left | yes |
| de | left | yes |
| fg | right | yes |
| gh | right | yes |
| hi | right | yes |
| ij | right | yes |
| dg | first | no |
| ch | second | no |
| bi | third | no |
And the relations
| type | way:from | way:via | way:to | restriction |
| restriction | ab | bi | ij | no_u_turn |
| restriction | bc | ch | hi | no_u_turn |
| restriction | fg | dg | de | no_u_turn |
| restriction | gh | ch | cd | no_u_turn |
When I route I should get
| from | to | route |
| a | j | left,first,right,right |
| f | e | right,third,left,left |
@restriction
Scenario: Car - allow only turn
Given the node map
"""
c
|
| f
| |
b---e
| |
a d
"""
And the ways
| nodes |
| ab |
| bc |
| be |
| de |
| ef |
And the relations
| type | way:from | way:via | way:to | restriction |
| restriction | ab | be | ef | only_left_on |
When I route I should get
| from | to | route | turns | locations |
| a | d | ab,be,ef,ef,de,de | depart,turn right,turn left,continue uturn,new name straight,arrive | a,b,e,f,e,d |
| a | f | ab,be,ef,ef | depart,turn right,turn left,arrive | a,b,e,f |
| c | d | bc,be,de,de | depart,turn left,turn right,arrive | c,b,e,d |
| c | f | bc,be,ef,ef | depart,turn left,turn left,arrive | c,b,e,f |
@restriction
Scenario: Car - allow only turn
Given the node map
"""
c
|
| f
| |
b---e
| |
a d
"""
And the ways
| nodes |
| ab |
| bc |
| be |
| de |
| ef |
And the relations
| type | way:from | way:via | way:to | restriction |
| restriction | ab | be | ed | only_right_on |
When I route I should get
| from | to | route |
| a | d | ab,be,de,de |
@restriction
Scenario: Multi Way restriction
Given the node map
"""
k j
| |
h - - g - f - - e
| |
| |
a - - b - c - - d
| |
l i
"""
And the ways
| nodes | name | oneway |
| ab | horiz | yes |
| bc | horiz | yes |
| cd | horiz | yes |
| ef | horiz | yes |
| fg | horiz | yes |
| gh | horiz | yes |
| ic | vert | yes |
| cf | vert | yes |
| fj | vert | yes |
| kg | vert | yes |
| gb | vert | yes |
| bl | vert | yes |
And the relations
| type | way:from | way:via | way:to | restriction |
| restriction | ab | bc,cf,fg | gh | no_u_turn |
When I route I should get
| from | to | route |
| a | h | horiz,vert,horiz,horiz |
@restriction
Scenario: Multi-Way overlapping single-way
Given the node map
"""
e
|
a - b - c - d
|
f - g
|
h
"""
And the ways
| nodes | name |
| ab | abcd |
| bc | abcd |
| cd | abcd |
| hf | hfb |
| fb | hfb |
| gf | gf |
| ce | ce |
And the relations
| type | way:from | way:via | way:to | restriction |
| restriction | ab | bc | ce | only_left_turn |
| restriction | gf | fb,bc | cd | only_u_turn |
When I route I should get
| from | to | route | turns | locations |
| a | d | abcd,ce,ce,abcd,abcd | depart,turn left,continue uturn,turn left,arrive | a,c,e,c,d |
| a | e | abcd,ce,ce | depart,turn left,arrive | a,c,e |
| a | f | abcd,hfb,hfb | depart,turn right,arrive | a,b,f |
| g | e | gf,hfb,abcd,ce,ce | depart,turn right,turn right,turn left,arrive | g,f,b,c,e |
| g | d | gf,hfb,abcd,abcd | depart,turn right,turn right,arrive | g,f,b,d |
| h | e | hfb,abcd,ce,ce | depart,end of road right,turn left,arrive | h,b,c,e |
| h | d | hfb,abcd,abcd | depart,end of road right,arrive | h,b,d |
@restriction
Scenario: Car - prohibit turn, traffic lights
Given the node map
"""
c
|
| f
| |
b---e
| |
a d
| |
g i
| |
h j
"""
And the ways
| nodes | name |
| hgab | ab |
| bc | bc |
| be | be |
| jide | de |
| ef | ef |
And the relations
| type | way:from | way:via | way:to | restriction |
| restriction | hgab | be | jide | no_right_turn |
And the nodes
| node | highway |
| g | traffic_signals |
| i | traffic_signals |
When I route I should get
| from | to | route | turns | locations |
| a | d | ab,be,ef,ef,de,de | depart,turn right,turn left,continue uturn,new name straight,arrive | a,b,e,f,e,d |
| a | f | ab,be,ef,ef | depart,turn right,turn left,arrive | a,b,e,f |
| c | d | bc,be,de,de | depart,turn left,turn right,arrive | c,b,e,d |
| c | f | bc,be,ef,ef | depart,turn left,turn left,arrive | c,b,e,f |
@restriction @overlap @geometry
Scenario: Geometry
Given the node map
"""
c
|
| f
| |
b-g-e
| |
| d
|
a
"""
And the ways
| nodes |
| ab |
| bc |
| bge |
| de |
| ef |
And the relations
| type | way:from | way:via | way:to | restriction |
| restriction | ab | bge | de | no_right_turn |
| restriction | bc | bge | ef | no_left_turn |
When I route I should get
| from | to | route |
| a | d | ab,bge,ef,ef,de,de |
| a | f | ab,bge,ef,ef |
| c | d | bc,bge,de,de |
| c | f | bc,bge,de,de,ef,ef |
@restriction @overlap @geometry @traffic-signals
Scenario: Geometry
Given the node map
"""
c
|
| f
| |
b-g-e
| |
| d
|
a
"""
And the ways
| nodes |
| ab |
| bc |
| bge |
| de |
| ef |
And the nodes
| node | highway |
| g | traffic_signals |
And the relations
| type | way:from | way:via | way:to | restriction |
| restriction | ab | bge | de | no_right_turn |
| restriction | bc | bge | ef | no_left_turn |
# this case is currently not handling the via-way restrictions and we need support for looking across traffic signals.
# It is mainly included to show limitations and to prove that we don't crash hard here
When I route I should get
| from | to | route |
| a | d | ab,bge,de,de |
| a | f | ab,bge,ef,ef |
| c | d | bc,bge,de,de |
| c | f | bc,bge,ef,ef |
# don't crash hard on invalid restrictions
@restriction @invalid
Scenario: Geometry
Given the node map
"""
c
|
| f
| |
b---e
| |
| d
|
a
"""
And the ways
| nodes | oneway |
| ab | |
| bc | |
| be | yes |
| de | |
| ef | |
And the relations
| type | way:from | way:via | way:to | restriction |
| restriction | de | be | ab | no_left_turn |
When I route I should get
| from | to | route |
| a | f | ab,be,ef,ef |
@restriction @overlap @geometry
Scenario: Duplicated restriction
Given the node map
"""
c
|
| f
| |
b-g-e
| |
| d
|
a
"""
And the ways
| nodes |
| ab |
| bc |
| bge |
| de |
| ef |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | bge | ef | e | no_left_turn |
And the relations
| type | way:from | way:via | way:to | restriction |
| restriction | ab | bge | de | no_right_turn |
| restriction | bc | bge | ef | no_left_turn |
When I route I should get
| from | to | route |
| a | d | ab,bc,bc,bge,de,de |
+13 -15
View File
@@ -1,18 +1,11 @@
@routing @testbot @sidebias
Feature: Testbot - side bias
Background:
Given the profile file
Scenario: Left-hand bias
Given the profile file "car" initialized with
"""
require 'testbot'
properties.left_hand_driving = true
"""
Scenario: Left hand bias
Given the profile file "car" extended with
"""
properties.left_hand_driving = true
profile.turn_bias = properties.left_hand_driving and 1/1.075 or 1.075
profile.left_hand_driving = true
profile.turn_bias = 1/1.075
"""
Given the node map
"""
@@ -31,11 +24,11 @@ Feature: Testbot - side bias
| d | a | bd,ab,ab | 24s +-1 |
| d | c | bd,bc,bc | 27s +-1 |
Scenario: Right hand bias
Given the profile file "car" extended with
Scenario: Right-hand bias
Given the profile file "car" initialized with
"""
properties.left_hand_driving = false
profile.turn_bias = properties.left_hand_driving and 1/1.075 or 1.075
profile.left_hand_driving = true
profile.turn_bias = 1.075
"""
And the node map
"""
@@ -56,6 +49,11 @@ Feature: Testbot - side bias
| d | c | bd,bc,bc | 24s +-1 |
Scenario: Roundabout exit counting for left sided driving
Given the profile file "testbot" initialized with
"""
profile.left_hand_driving = true
profile.turn_bias = 1/1.075
"""
And a grid size of 10 meters
And the node map
"""
+6 -8
View File
@@ -1,11 +1,9 @@
@routing @car @weight
Feature: Car - weights
Background: Use specific speeds
Given the profile "car"
Scenario: Only routes down service road when that's the destination
Given the node map
Given the profile "car"
And the node map
"""
a--b--c
|
@@ -25,7 +23,8 @@ Feature: Car - weights
| a | d | abc,bdf,bdf | 18 km/h | 71.7 |
Scenario: Does not jump off the highway to go down service road
Given the node map
Given the profile "car"
And the node map
"""
a
|
@@ -63,10 +62,9 @@ Feature: Car - weights
| a | e | ab,be,be | 14 km/h | 112 |
Scenario: Distance weights
Given the profile file "car" extended with
Given the profile file "car" initialized with
"""
api_version = 1
properties.weight_name = 'distance'
profile.properties.weight_name = 'distance'
"""
Given the node map
+31 -2
View File
@@ -582,9 +582,9 @@ Feature: Turn Lane Guidance
@anticipate
Scenario: No Lanes for Roundabouts, see #2626
Given the profile file "car" extended with
Given the profile file "car" initialized with
"""
properties.left_hand_driving = true
profile.left_hand_driving = true
"""
And the node map
"""
@@ -814,3 +814,32 @@ Feature: Turn Lane Guidance
| waypoints | route | turns | locations | lanes |
| a,i | road,road | depart,arrive | a,i | ;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:false;none:true none:true right:false, |
| a,j | road,7th,7th | depart,turn right,arrive | a,h,j | ;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:false none:false none:true;left:false none:false none:false none:true,none:false none:false right:true, |
@anticipate
Scenario: Oak St, Franklin St
Given a grid size of 10 meters
Given the node map
"""
g
. . f
. d `
e ` .
.
.
. . c
. b `
a `
"""
And the ways
| nodes | name | turn:lanes | oneway | highway |
| ab | Oak St | left\|left\|left | yes | secondary |
| cb | Oak St | right | yes | tertiary |
| bd | Franklin St | left;through\|through\|through;right\|right | yes | secondary |
| dg | Franklin St | | yes | secondary |
| edf | Fell St | | | secondary |
When I route I should get
| waypoints | route | turns | lanes |
| a,f | Oak St,Franklin St,Fell St,Fell St | depart,turn left,turn right,arrive | ,left:false left:true left:true,straight;left:false straight:false straight;right:true right:true, |
@@ -3,11 +3,10 @@ Feature: Basic Roundabout
Background:
Given a grid size of 10 meters
Given the profile file
"""
require 'car'
properties.left_hand_driving = true
"""
Given the profile file "car" initialized with
"""
profile.properties.left_hand_driving = true
"""
Scenario: Roundabout exit counting for left sided driving
And a grid size of 10 meters
+2 -2
View File
@@ -567,5 +567,5 @@ Feature: Basic Roundabout
| ab | residential | in | | |
When I route I should get
| waypoints | turns | route |
| a,f | depart,turn right,roundabout turn straight exit-1,arrive | in,through,through,through |
| waypoints | turns | route |
| a,f | depart,turn right,arrive | in,through,through |
+4 -4
View File
@@ -763,7 +763,7 @@ Feature: Basic Roundabout
When I route I should get
| waypoints | bearings | route | turns |
| e,f | 90 90 | edf,edf,edf | depart,roundabout-exit-1,arrive |
| e,f | 90 90 | edf,edf | depart,arrive |
| e,h | 90 135 | edf,gch,gch | depart,roundabout-exit-2,arrive |
| g,f | 45 90 | gch,edf,edf | depart,roundabout-exit-2,arrive |
| g,h | 45 135 | gch,gch,gch | depart,roundabout-exit-1,arrive |
@@ -843,6 +843,6 @@ Feature: Basic Roundabout
When I route I should get
| from | to | route | turns | distance |
| e | k | ebds,ebds,ds,ufghl,jhik,jhik | depart,rotary-exit-1,rotary-exit-1,rstur-exit-2,turn right,arrive | 189.1m |
| 1 | k | ebds,ds,ufghl,jhik,jhik | depart,rotary-exit-1,rstur-exit-2,turn right,arrive | 159.1m |
| from | to | route | turns | distance |
| e | k | ebds,ufghl,jhik,jhik | depart,rstur-exit-2,turn right,arrive | 189.1m |
| 1 | k | ebds,ufghl,jhik,jhik | depart,rstur-exit-2,turn right,arrive | 159.1m |
@@ -33,15 +33,25 @@ Feature: osrm-contract command line option: edge-weight-updates-over-factor
Scenario: Logging using weigts as durations for non-duration profile
Given the profile file "testbot" extended with
Given the profile file
"""
properties.weight_name = 'steps'
function way_function(way, result)
local functions = require('testbot')
functions.setup_testbot = functions.setup
functions.setup = function()
local profile = functions.setup_testbot()
profile.properties.weight_name = 'steps'
return profile
end
functions.process_way = function(profile, way, result)
result.forward_mode = mode.driving
result.backward_mode = mode.driving
result.weight = 1
result.duration = 1
end
return functions
"""
And the data has been saved to disk
+7 -2
View File
@@ -12,15 +12,20 @@ Feature: osrm-extract lua ways:get_nodes()
And the data has been saved to disk
Scenario: osrm-extract - Passing base file
Given the profile file "testbot" extended with
Given the profile file
"""
function way_function(way, result)
functions = require('testbot')
function way_function(profile, way, result)
for _, node in ipairs(way:get_nodes()) do
print('node id ' .. node:id())
end
result.forward_mode = mode.driving
result.forward_speed = 1
end
functions.process_way = way_function
return functions
"""
When I run "osrm-extract --profile {profile_file} {osm_file}"
Then it should exit successfully
@@ -0,0 +1,40 @@
Feature: Invalid profile API versions
Background:
Given a grid size of 100 meters
Scenario: Profile API version too low
Given the profile file
"""
api_version = -1
"""
And the node map
"""
ab
"""
And the ways
| nodes |
| ab |
And the data has been saved to disk
When I try to run "osrm-extract --profile {profile_file} {osm_file}"
Then it should exit with an error
And stderr should contain "Invalid profile API version"
Scenario: Profile API version too high
Given the profile file
"""
api_version = 3
"""
And the node map
"""
ab
"""
And the ways
| nodes |
| ab |
And the data has been saved to disk
When I try to run "osrm-extract --profile {profile_file} {osm_file}"
Then it should exit with an error
And stderr should contain "Invalid profile API version"
+87 -78
View File
@@ -1,84 +1,36 @@
Feature: Profile API version 0
Background:
Given a grid size of 100 meters
Scenario: Not-defined API version
Scenario: Profile api version 0
Given the profile file
"""
function way_function(way, result)
result.forward_mode = mode.driving
result.forward_speed = 1
end
"""
And the node map
"""
ab
"""
And the ways
| nodes |
| ab |
And the data has been saved to disk
When I try to run "osrm-extract --profile {profile_file} {osm_file}"
Then it should exit successfully
And stderr should not contain "Invalid profile API version"
Scenario: Out-bound API version
Given the profile file
"""
api_version = 2
"""
And the node map
"""
ab
"""
And the ways
| nodes |
| ab |
And the data has been saved to disk
When I try to run "osrm-extract --profile {profile_file} {osm_file}"
Then it should exit with an error
And stderr should contain "Invalid profile API version"
Scenario: Basic profile function calls and property values
Given the profile file
"""
api_version = 0
-- set profile properties
properties.u_turn_penalty = 20
properties.traffic_signal_penalty = 2
properties.max_speed_for_map_matching = 180/3.6
properties.use_turn_restrictions = true
properties.continue_straight_at_waypoint = true
properties.left_hand_driving = false
properties.weight_name = 'duration'
function node_function (node, result)
print ('node_function ' .. node:id())
end
function way_function(way, result)
result.name = way:get_value_by_key('name')
result.forward_mode = mode.driving
result.backward_mode = mode.driving
result.forward_speed = 36
result.backward_speed = 36
print ('way_function ' .. way:id() .. ' ' .. result.name)
end
function turn_function (angle)
print('turn_function ' .. angle)
return angle == 0 and 0 or 42
end
function segment_function (source, target, distance, weight)
print ('segment_function ' .. source.lon .. ' ' .. source.lat)
end
"""
"""
api_version = 0
-- set profile properties
properties.u_turn_penalty = 20
properties.traffic_signal_penalty = 2
properties.max_speed_for_map_matching = 180/3.6
properties.use_turn_restrictions = true
properties.continue_straight_at_waypoint = true
properties.left_hand_driving = false
properties.weight_name = 'duration'
function node_function (node, result)
print ('node_function ' .. node:id())
end
function way_function(way, result)
result.name = way:get_value_by_key('name')
result.forward_mode = mode.driving
result.backward_mode = mode.driving
result.forward_speed = 36
result.backward_speed = 36
print ('way_function ' .. way:id() .. ' ' .. result.name)
end
function turn_function (angle)
print('turn_function ' .. angle)
return angle == 0 and 0 or 42
end
function segment_function (source, target, distance, weight)
print ('segment_function ' .. source.lon .. ' ' .. source.lat)
end
"""
And the node map
"""
a
@@ -105,3 +57,60 @@ end
| a | b | ac,cb,cb | 24.2s |
| a | d | ac,cd,cd | 24.2s |
| a | e | ac,ce | 20s |
Scenario: Profile version undefined, assume version 0
Given the profile file
"""
-- set profile properties
properties.u_turn_penalty = 20
properties.traffic_signal_penalty = 2
properties.max_speed_for_map_matching = 180/3.6
properties.use_turn_restrictions = true
properties.continue_straight_at_waypoint = true
properties.left_hand_driving = false
properties.weight_name = 'duration'
function node_function (node, result)
print ('node_function ' .. node:id())
end
function way_function(way, result)
result.name = way:get_value_by_key('name')
result.forward_mode = mode.driving
result.backward_mode = mode.driving
result.forward_speed = 36
result.backward_speed = 36
print ('way_function ' .. way:id() .. ' ' .. result.name)
end
function turn_function (angle)
print('turn_function ' .. angle)
return angle == 0 and 0 or 42
end
function segment_function (source, target, distance, weight)
print ('segment_function ' .. source.lon .. ' ' .. source.lat)
end
"""
And the node map
"""
a
b c d
e
"""
And the ways
| nodes |
| ac |
| cb |
| cd |
| ce |
And the data has been saved to disk
When I run "osrm-extract --profile {profile_file} {osm_file}"
Then it should exit successfully
And stdout should contain "node_function"
And stdout should contain "way_function"
And stdout should contain "turn_function"
And stdout should contain "segment_function"
When I route I should get
| from | to | route | time |
| a | b | ac,cb,cb | 24.2s |
| a | d | ac,cd,cd | 24.2s |
| a | e | ac,ce | 20s |
+192 -29
View File
@@ -6,41 +6,42 @@ Feature: Profile API version 1
Scenario: Basic profile function calls and property values
Given the profile file
"""
api_version = 1
api_version = 1
-- set profile properties
properties.max_speed_for_map_matching = 180/3.6
properties.use_turn_restrictions = true
properties.continue_straight_at_waypoint = true
properties.weight_name = 'test_version1'
properties.weight_precision = 2
-- set profile properties
properties.max_speed_for_map_matching = 180/3.6
properties.use_turn_restrictions = true
properties.continue_straight_at_waypoint = true
properties.weight_name = 'test_version1'
properties.weight_precision = 2
assert(properties.max_turn_weight == 327.67)
assert(properties.max_turn_weight == 327.67)
function node_function (node, result)
print ('node_function ' .. node:id())
end
function node_function (node, result)
print(node, result)
print ('node_function ' .. node:id())
end
function way_function(way, result)
result.name = way:get_value_by_key('name')
result.weight = 10
result.forward_mode = mode.driving
result.backward_mode = mode.driving
result.forward_speed = 36
result.backward_speed = 36
print ('way_function ' .. way:id() .. ' ' .. result.name)
end
function way_function(way, result)
result.name = way:get_value_by_key('name')
result.weight = 10
result.forward_mode = mode.driving
result.backward_mode = mode.driving
result.forward_speed = 36
result.backward_speed = 36
print ('way_function ' .. way:id() .. ' ' .. result.name)
end
function turn_function (turn)
print('turn_function', turn.angle, turn.turn_type, turn.direction_modifier, turn.has_traffic_light)
turn.weight = turn.angle == 0 and 0 or 4.2
turn.duration = turn.weight
end
function turn_function (turn)
print('turn_function', turn.angle, turn.turn_type, turn.direction_modifier, turn.has_traffic_light)
turn.weight = turn.angle == 0 and 0 or 4.2
turn.duration = turn.weight
end
function segment_function (segment)
print ('segment_function ' .. segment.source.lon .. ' ' .. segment.source.lat)
end
"""
function segment_function (segment)
print ('segment_function ' .. segment.source.lon .. ' ' .. segment.source.lat)
end
"""
And the node map
"""
a
@@ -67,3 +68,165 @@ end
| a | b | ac,cb,cb | 19.2s |
| a | d | ac,cd,cd | 19.2s |
| a | e | ac,ce | 20s |
Scenario: Basic profile function calls and property values
Given the profile file
"""
api_version = 1
-- set profile properties
properties.max_speed_for_map_matching = 180/3.6
properties.use_turn_restrictions = true
properties.continue_straight_at_waypoint = true
properties.weight_name = 'test_version1'
properties.weight_precision = 2
assert(properties.max_turn_weight == 327.67)
function node_function (node, result)
print(node, result)
print ('node_function ' .. node:id())
end
function way_function(way, result)
result.name = way:get_value_by_key('name')
result.weight = 10
result.forward_mode = mode.driving
result.backward_mode = mode.driving
result.forward_speed = 36
result.backward_speed = 36
print ('way_function ' .. way:id() .. ' ' .. result.name)
end
function turn_function (turn)
print('turn_function', turn.angle, turn.turn_type, turn.direction_modifier, turn.has_traffic_light)
turn.weight = turn.angle == 0 and 0 or 4.2
turn.duration = turn.weight
end
function segment_function (segment)
print ('segment_function ' .. segment.source.lon .. ' ' .. segment.source.lat)
end
"""
And the node map
"""
a
bcd
e
"""
And the ways
| nodes |
| ac |
| cb |
| cd |
| ce |
And the data has been saved to disk
When I run "osrm-extract --profile {profile_file} {osm_file}"
Then it should exit successfully
And stdout should contain "node_function"
And stdout should contain "way_function"
And stdout should contain "turn_function"
And stdout should contain "segment_function"
When I route I should get
| from | to | route | time |
| a | b | ac,cb,cb | 19.2s |
| a | d | ac,cd,cd | 19.2s |
| a | e | ac,ce | 20s |
Scenario: Weighting based on raster sources
Given the profile file
"""
api_version = 1
properties.force_split_edges = true
function source_function()
local path = os.getenv('OSRM_RASTER_SOURCE')
if not path then
path = 'rastersource.asc'
end
raster_source = sources:load(
path,
0, -- lon_min
0.1, -- lon_max
0, -- lat_min
0.1, -- lat_max
5, -- nrows
4 -- ncols
)
end
function way_function (way, result)
result.name = way:get_value_by_key('name')
result.forward_mode = mode.cycling
result.backward_mode = mode.cycling
result.forward_speed = 15
result.backward_speed = 15
end
function segment_function (segment)
local sourceData = sources:query(raster_source, segment.source.lon, segment.source.lat)
local targetData = sources:query(raster_source, segment.target.lon, segment.target.lat)
io.write('evaluating segment: ' .. sourceData.datum .. ' ' .. targetData.datum .. '\n')
local invalid = sourceData.invalid_data()
local scaled_weight = segment.weight
local scaled_duration = segment.duration
if sourceData.datum ~= invalid and targetData.datum ~= invalid then
local slope = (targetData.datum - sourceData.datum) / segment.distance
scaled_weight = scaled_weight / (1.0 - (slope * 5.0))
scaled_duration = scaled_duration / (1.0 - (slope * 5.0))
io.write(' slope: ' .. slope .. '\n')
io.write(' was weight: ' .. segment.weight .. '\n')
io.write(' new weight: ' .. scaled_weight .. '\n')
io.write(' was duration: ' .. segment.duration .. '\n')
io.write(' new duration: ' .. scaled_duration .. '\n')
end
segment.weight = scaled_weight
segment.duration = scaled_duration
end
"""
And the node locations
| node | lat | lon |
| a | 0.1 | 0.1 |
| b | 0.05 | 0.1 |
| c | 0.0 | 0.1 |
| d | 0.05 | 0.03 |
| e | 0.05 | 0.066 |
| f | 0.075 | 0.066 |
And the ways
| nodes | highway |
| ab | primary |
| ad | primary |
| bc | primary |
| dc | primary |
| de | primary |
| eb | primary |
| df | primary |
| fb | primary |
And the raster source
"""
0 0 0 0
0 0 0 250
0 0 250 500
0 0 0 250
0 0 0 0
"""
And the data has been saved to disk
When I route I should get
| from | to | route | speed |
| a | b | ab,ab | 8 km/h |
| b | a | ab,ab | 22 km/h |
| a | c | ab,bc,bc | 12 km/h |
| b | c | bc,bc | 22 km/h |
| a | d | ad,ad | 15 km/h |
| d | c | dc,dc | 15 km/h |
| d | e | de,de | 10 km/h |
| e | b | eb,eb | 10 km/h |
| d | f | df,df | 15 km/h |
| f | b | fb,fb | 7 km/h |
| d | b | de,eb,eb | 10 km/h |
@@ -0,0 +1,87 @@
Feature: Profile API version 2
Background:
Given a grid size of 100 meters
Scenario: Basic profile function calls and property values
Given the profile file
"""
api_version = 2
Set = require('lib/set')
Sequence = require('lib/sequence')
Handlers = require("lib/way_handlers")
find_access_tag = require("lib/access").find_access_tag
limit = require("lib/maxspeed").limit
function setup()
return {
properties = {
max_speed_for_map_matching = 180/3.6,
use_turn_restrictions = true,
continue_straight_at_waypoint = true,
weight_name = 'test_version2',
weight_precision = 2
}
}
end
function process_node(profile, node, result)
print ('process_node ' .. node:id())
end
function process_way(profile, way, result)
result.name = way:get_value_by_key('name')
result.weight = 10
result.forward_mode = mode.driving
result.backward_mode = mode.driving
result.forward_speed = 36
result.backward_speed = 36
print ('process_way ' .. way:id() .. ' ' .. result.name)
end
function process_turn (profile, turn)
print('process_turn', turn.angle, turn.turn_type, turn.direction_modifier, turn.has_traffic_light)
turn.weight = turn.angle == 0 and 0 or 4.2
turn.duration = turn.weight
end
function process_segment (profile, segment)
print ('process_segment ' .. segment.source.lon .. ' ' .. segment.source.lat)
end
return {
setup = setup,
process_node = process_node,
process_way = process_way,
process_segment = process_segment,
process_turn = process_turn
}
"""
And the node map
"""
a
bcd
e
"""
And the ways
| nodes |
| ac |
| cb |
| cd |
| ce |
And the data has been saved to disk
When I run "osrm-extract --profile {profile_file} {osm_file}"
Then it should exit successfully
And stdout should contain "process_node"
And stdout should contain "process_way"
And stdout should contain "process_turn"
And stdout should contain "process_segment"
When I route I should get
| from | to | route | time |
| a | b | ac,cb,cb | 19.2s |
| a | d | ac,cd,cd | 19.2s |
| a | e | ac,ce | 20s |
+9 -6
View File
@@ -248,17 +248,20 @@ module.exports = function () {
fs.writeFile(this.penaltiesCacheFile, data, callback);
});
this.Given(/^the profile file(?: "([^"]*)" extended with)?$/, (profile, data, callback) => {
this.Given(/^the profile file(?: "([^"]*)" initialized with)?$/, (profile, data, callback) => {
const lua_profiles_path = this.PROFILES_PATH.split(path.sep).join('/');
let text = 'package.path = "' + lua_profiles_path + '/?.lua;" .. package.path\n';
if (profile == null) {
text += data + '\n';
} else {
text += 'local f = assert(io.open("' + lua_profiles_path + '/' + profile + '.lua", "r"))\n';
text += 'local s = f:read("*all") .. [[\n' + data + '\n]]\n';
text += 'f:close()\n';
text += 'local m = assert(loadstring and loadstring(s) or load(s))\n';
text += 'm()\n';
text += 'local functions = require("' + profile + '")\n';
text += 'functions.setup_parent = functions.setup\n';
text += 'functions.setup = function()\n';
text += 'local profile = functions.setup_parent()\n';
text += data + '\n';
text += 'return profile\n';
text += 'end\n';
text += 'return functions\n';
}
this.profileFile = this.profileCacheFile;
// TODO: Don't overwrite if it exists
+36 -5
View File
@@ -1,11 +1,9 @@
@routing @speed @annotations @turn_penalty
@routing @speed @annotations
Feature: Annotations
Background:
Scenario: Ensure that turn penalties aren't included in annotations
Given the profile "turnbot"
Given a grid size of 100 meters
Scenario: Ensure that turn penalties aren't included in annotations
Given the node map
"""
h i
@@ -27,4 +25,37 @@ Feature: Annotations
| from | to | route | a:speed | a:weight |
| h | j | hk,jk,jk | 6.7:6.7 | 15:15 |
| i | m | il,lm,lm | 6.7:6.7 | 15:15 |
| j | m | jk,lm | 6.7:6.7:6.7 | 15:15:15 |
| j | m | jk,lm | 6.7:6.7:6.7 | 15:15:15 |
Scenario: There should be different forward/reverse datasources
Given the profile "testbot"
And the node map
"""
a b c d e f g h i
"""
And the ways
| nodes | highway |
| abcdefghi | primary |
And the contract extra arguments "--segment-speed-file {speeds_file}"
And the customize extra arguments "--segment-speed-file {speeds_file}"
# Note: 180km/h == 50m/s for speed annotations
And the speed file
"""
1,2,180,1
2,1,180,1
3,4,180,1
5,6,180,1
8,7,180,1
"""
And the query options
| annotations | datasources,speed |
When I route I should get
| from | to | route | a:datasources | a:speed |
| a | i | abcdefghi,abcdefghi | 1:0:1:0:1:0:0:0 | 50:10:50:10:50:10:10:10 |
| i | a | abcdefghi,abcdefghi | 0:1:0:0:0:0:0:1 | 10:50:10:10:10:10:10:50 |
+29 -11
View File
@@ -221,15 +221,24 @@ Feature: Basic Distance Matrix
| 4 | 30 +-1 | 40 +-1 | 70 +-1 | 0 |
Scenario: Testbot - Travel time matrix based on segment durations
Given the profile file "testbot" extended with
Given the profile file
"""
api_version = 1
properties.traffic_signal_penalty = 0
properties.u_turn_penalty = 0
function segment_function (segment)
local functions = require('testbot')
functions.setup_testbot = functions.setup
functions.setup = function()
local profile = functions.setup_testbot()
profile.traffic_signal_penalty = 0
profile.u_turn_penalty = 0
return profile
end
functions.process_segment = function(profile, segment)
segment.weight = 2
segment.duration = 11
end
return functions
"""
And the node map
@@ -254,16 +263,25 @@ Feature: Basic Distance Matrix
Scenario: Testbot - Travel time matrix for alternative loop paths
Given the profile file "testbot" extended with
Given the profile file
"""
api_version = 1
properties.traffic_signal_penalty = 0
properties.u_turn_penalty = 0
properties.weight_precision = 3
function segment_function (segment)
local functions = require('testbot')
functions.setup_testbot = functions.setup
functions.setup = function()
local profile = functions.setup_testbot()
profile.traffic_signal_penalty = 0
profile.u_turn_penalty = 0
profile.weight_precision = 3
return profile
end
functions.process_segment = function(profile, segment)
segment.weight = 777
segment.duration = 3
end
return functions
"""
And the node map
"""
+17 -19
View File
@@ -1,29 +1,27 @@
@routing @testbot @nil
Feature: Testbot - Check assigning nil values
Scenario: Assign nil values to all way strings
Given the profile file "testbot" extended with
Given the profile file
"""
function way_function (way, result)
result.name = "name"
result.ref = "ref"
result.destinations = "destinations"
result.pronunciation = "pronunciation"
result.turn_lanes_forward = "turn_lanes_forward"
result.turn_lanes_backward = "turn_lanes_backward"
functions = require('testbot')
result.name = nil
result.ref = nil
result.destinations = nil
result.exits = nil
result.pronunciation = nil
result.turn_lanes_forward = nil
result.turn_lanes_backward = nil
function way_function(profile, way, result)
result.name = nil
result.ref = nil
result.destinations = nil
result.exits = nil
result.pronunciation = nil
result.turn_lanes_forward = nil
result.turn_lanes_backward = nil
result.forward_speed = 10
result.backward_speed = 10
result.forward_mode = mode.driving
result.backward_mode = mode.driving
result.forward_speed = 10
result.backward_speed = 10
result.forward_mode = mode.driving
result.backward_mode = mode.driving
end
functions.process_way = way_function
return functions
"""
Given the node map
"""
+7 -3
View File
@@ -39,13 +39,17 @@ Feature: Projection to nearest point on road
Scenario: Projection results negative duration
Given the profile file "testbot" extended with
Given the profile file
"""
api_version = 1
function segment_function (segment)
functions = require('testbot')
function segment_function(profile, segment)
segment.weight = 5.5
segment.duration = 2.8
end
functions.process_segment = segment_function
return functions
"""
Given the node locations
+4 -5
View File
@@ -84,12 +84,11 @@ Feature: Traffic - speeds
Scenario: Weighting based on speed file weights, ETA based on file durations
Given the profile file "testbot" extended with
Given the profile file "testbot" initialized with
"""
api_version = 1
properties.traffic_signal_penalty = 0
properties.u_turn_penalty = 0
properties.weight_precision = 2
profile.properties.traffic_signal_penalty = 0
profile.properties.u_turn_penalty = 0
profile.properties.weight_precision = 2
"""
And the contract extra arguments "--segment-speed-file {speeds_file}"
And the customize extra arguments "--segment-speed-file {speeds_file}"
@@ -8,12 +8,11 @@ Feature: Traffic - speeds edge cases
And the ways
| nodes | highway |
| ab | primary |
And the profile file "testbot" extended with
And the profile file "testbot" initialized with
"""
api_version = 1
properties.traffic_signal_penalty = 0
properties.u_turn_penalty = 0
properties.weight_precision = 2
profile.properties.traffic_signal_penalty = 0
profile.properties.u_turn_penalty = 0
profile.properties.weight_precision = 2
"""
And the contract extra arguments "--segment-speed-file {speeds_file}"
And the customize extra arguments "--segment-speed-file {speeds_file}"
+1 -4
View File
@@ -1,12 +1,9 @@
@routing @testbot @turn_penalty
Feature: Turn Penalties
Background:
Scenario: Turns should incur a delay that depend on the angle
Given the profile "turnbot"
Given a grid size of 200 meters
Scenario: Turns should incur a delay that depend on the angle
Given the node map
"""
c d e
+101 -44
View File
@@ -60,18 +60,27 @@ Feature: Weight tests
Scenario: Step weights -- way_function: fail if no weight or weight_per_meter property
Given the profile file "testbot" extended with
Given the profile file
"""
api_version = 1
properties.traffic_signal_penalty = 0
properties.u_turn_penalty = 0
properties.weight_name = 'steps'
function way_function(way, result)
local functions = require('testbot')
functions.setup_testbot = functions.setup
functions.setup = function()
local profile = functions.setup_testbot()
profile.properties.traffic_signal_penalty = 0
profile.properties.u_turn_penalty = 0
profile.properties.weight_name = 'steps'
return profile
end
functions.process_way = function(profile, way, result)
result.forward_mode = mode.driving
result.backward_mode = mode.driving
result.forward_speed = 42
result.backward_speed = 42
end
return functions
"""
And the node map
"""
@@ -87,18 +96,27 @@ Feature: Weight tests
And it should exit with an error
Scenario: Step weights -- way_function: second way wins
Given the profile file "testbot" extended with
Given the profile file
"""
api_version = 1
properties.traffic_signal_penalty = 0
properties.u_turn_penalty = 0
properties.weight_name = 'steps'
function way_function(way, result)
local functions = require('testbot')
functions.setup_testbot = functions.setup
functions.setup = function()
local profile = functions.setup_testbot()
profile.properties.traffic_signal_penalty = 0
profile.properties.u_turn_penalty = 0
profile.properties.weight_name = 'steps'
return profile
end
functions.process_way = function(profile, way, result)
result.forward_mode = mode.driving
result.backward_mode = mode.driving
result.duration = 42
result.weight = 35
end
return functions
"""
Given the node map
@@ -119,19 +137,28 @@ Feature: Weight tests
| h,a | , | 140m +-1 | 35,0 | 42s,0s |
Scenario: Step weights -- way_function: higher weight_per_meter is preferred
Given the profile file "testbot" extended with
Given the profile file
"""
api_version = 1
properties.traffic_signal_penalty = 0
properties.u_turn_penalty = 0
properties.weight_name = 'steps'
function way_function(way, result)
local functions = require('testbot')
functions.setup_testbot = functions.setup
functions.setup = function()
local profile = functions.setup_testbot()
profile.properties.traffic_signal_penalty = 0
profile.properties.u_turn_penalty = 0
profile.properties.weight_name = 'steps'
return profile
end
functions.process_way = function(profile, way, result)
result.forward_mode = mode.driving
result.backward_mode = mode.driving
result.duration = 42
result.forward_rate = 1
result.backward_rate = 0.5
end
return functions
"""
Given the node map
@@ -155,22 +182,32 @@ Feature: Weight tests
| h,f | , | 40m | 80,0 | 12s,0s |
Scenario: Step weights -- segment_function
Given the profile file "testbot" extended with
Given the profile file
"""
api_version = 1
properties.traffic_signal_penalty = 0
properties.u_turn_penalty = 0
properties.weight_name = 'steps'
function way_function(way, result)
local functions = require('testbot')
functions.setup_testbot = functions.setup
functions.setup = function()
local profile = functions.setup_testbot()
profile.properties.traffic_signal_penalty = 0
profile.properties.u_turn_penalty = 0
profile.properties.weight_name = 'steps'
return profile
end
functions.process_way = function(profile, way, result)
result.forward_mode = mode.driving
result.backward_mode = mode.driving
result.weight = 42
result.duration = 3
end
function segment_function (segment)
functions.process_segment = function(profile, segment)
segment.weight = 1
segment.duration = 11
end
return functions
"""
Given the node map
@@ -195,28 +232,39 @@ Feature: Weight tests
Scenario: Step weights -- segment_function and turn_function with weight precision
Given the profile file "testbot" extended with
Given the profile file
"""
api_version = 1
properties.traffic_signal_penalty = 0
properties.u_turn_penalty = 0
properties.weight_name = 'steps'
properties.weight_precision = 3
function way_function(way, result)
local functions = require('testbot')
functions.setup_testbot = functions.setup
functions.setup = function()
local profile = functions.setup_testbot()
profile.properties.traffic_signal_penalty = 0
profile.properties.u_turn_penalty = 0
profile.properties.weight_name = 'steps'
profile.properties.weight_precision = 3
return profile
end
functions.process_way = function(profile, way, result)
result.forward_mode = mode.driving
result.backward_mode = mode.driving
result.weight = 42
result.duration = 3
end
function segment_function (segment)
functions.process_segment = function(profile, segment)
segment.weight = 1.11
segment.duration = 100
end
function turn_function (turn)
functions.process_turn = function(profile, turn)
print (turn.angle)
turn.weight = 2 + turn.angle / 100
turn.duration = turn.angle
end
return functions
"""
Given the node map
@@ -241,22 +289,32 @@ Feature: Weight tests
@traffic @speed
Scenario: Step weights -- segment_function with speed and turn updates
Given the profile file "testbot" extended with
Given the profile file
"""
api_version = 1
properties.traffic_signal_penalty = 0
properties.u_turn_penalty = 0
properties.weight_name = 'steps'
function way_function(way, result)
local functions = require('testbot')
functions.setup_testbot = functions.setup
functions.setup = function()
local profile = functions.setup_testbot()
profile.properties.traffic_signal_penalty = 0
profile.properties.u_turn_penalty = 0
profile.properties.weight_name = 'steps'
return profile
end
functions.process_way = function(profile, way, result)
result.forward_mode = mode.driving
result.backward_mode = mode.driving
result.weight = 42
result.duration = 3
end
function segment_function (segment)
functions.process_segment = function(profile, segment)
segment.weight = 10
segment.duration = 11
end
return functions
"""
And the node map
@@ -289,10 +347,9 @@ Feature: Weight tests
@traffic @speed
Scenario: Step weights -- segment_function with speed and turn updates with fallback to durations
Given the profile file "testbot" extended with
Given the profile file "testbot" initialized with
"""
api_version = 1
properties.weight_precision = 3
profile.properties.weight_precision = 3
"""
And the node map
+19 -19
View File
@@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef CONTRACTOR_OPTIONS_HPP
#define CONTRACTOR_OPTIONS_HPP
#include "storage/io_config.hpp"
#include "updater/updater_config.hpp"
#include <boost/filesystem/path.hpp>
@@ -39,31 +40,30 @@ namespace osrm
namespace contractor
{
struct ContractorConfig
struct ContractorConfig final : storage::IOConfig
{
ContractorConfig() : requested_num_threads(0) {}
// Infer the output names from the path of the .osrm file
void UseDefaultOutputNames()
ContractorConfig()
: IOConfig(
{
".osrm",
},
{},
{".osrm.level", ".osrm.core", ".osrm.hsgr", ".osrm.enw"}),
requested_num_threads(0)
{
level_output_path = osrm_input_path.string() + ".level";
core_output_path = osrm_input_path.string() + ".core";
graph_output_path = osrm_input_path.string() + ".hsgr";
node_file_path = osrm_input_path.string() + ".enw";
updater_config.osrm_input_path = osrm_input_path;
updater_config.UseDefaultOutputNames();
}
// Infer the output names from the path of the .osrm file
void UseDefaultOutputNames(const boost::filesystem::path &base)
{
IOConfig::UseDefaultOutputNames(base);
updater_config.UseDefaultOutputNames(base);
}
bool IsValid() const { return IOConfig::IsValid() && updater_config.IsValid(); }
updater::UpdaterConfig updater_config;
boost::filesystem::path osrm_input_path;
std::string level_output_path;
std::string core_output_path;
std::string graph_output_path;
std::string node_file_path;
bool use_cached_priority;
unsigned requested_num_threads;
+17 -32
View File
@@ -1,52 +1,37 @@
#ifndef OSRM_CUSTOMIZE_CUSTOMIZER_CONFIG_HPP
#define OSRM_CUSTOMIZE_CUSTOMIZER_CONFIG_HPP
#include "updater/updater_config.hpp"
#include <boost/filesystem/path.hpp>
#include <array>
#include <string>
#include "storage/io_config.hpp"
#include "updater/updater_config.hpp"
namespace osrm
{
namespace customizer
{
struct CustomizationConfig
struct CustomizationConfig final : storage::IOConfig
{
CustomizationConfig() : requested_num_threads(0) {}
void UseDefaults()
CustomizationConfig()
: IOConfig(
{
".osrm",
},
{},
{".osrm.ebg", ".osrm.partition", ".osrm.cells", ".osrm.mldgr"}),
requested_num_threads(0)
{
std::string basepath = base_path.string();
const std::string ext = ".osrm";
const auto pos = basepath.find(ext);
if (pos != std::string::npos)
{
basepath.replace(pos, ext.size(), "");
}
else
{
// unknown extension
}
edge_based_graph_path = basepath + ".osrm.ebg";
mld_partition_path = basepath + ".osrm.partition";
mld_storage_path = basepath + ".osrm.cells";
mld_graph_path = basepath + ".osrm.mldgr";
updater_config.osrm_input_path = basepath + ".osrm";
updater_config.UseDefaultOutputNames();
}
// might be changed to the node based graph at some point
boost::filesystem::path base_path;
boost::filesystem::path edge_based_graph_path;
boost::filesystem::path mld_partition_path;
boost::filesystem::path mld_storage_path;
boost::filesystem::path mld_graph_path;
void UseDefaultOutputNames(const boost::filesystem::path &base)
{
IOConfig::UseDefaultOutputNames(base);
updater_config.UseDefaultOutputNames(base);
}
unsigned requested_num_threads;
+26
View File
@@ -0,0 +1,26 @@
#ifndef OSRM_ENGINE_DATAFACADE_DATAFACADE_HPP
#define OSRM_ENGINE_DATAFACADE_DATAFACADE_HPP
#ifdef OSRM_EXTERNAL_MEMORY
// Register your own data backend here
#error "No external memory implementation found"
#else
#include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
namespace osrm
{
namespace engine
{
using DataFacadeBase = datafacade::ContiguousInternalMemoryDataFacadeBase;
template <typename AlgorithmT>
using DataFacade = datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT>;
}
}
#endif
#endif
@@ -480,10 +480,17 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
data_layout.num_entries[storage::DataLayout::GEOMETRIES_REV_DURATION_LIST]),
num_entries);
auto datasources_list_ptr = data_layout.GetBlockPtr<DatasourceID>(
memory_block, storage::DataLayout::DATASOURCES_LIST);
util::vector_view<DatasourceID> datasources_list(
datasources_list_ptr, data_layout.num_entries[storage::DataLayout::DATASOURCES_LIST]);
auto geometries_fwd_datasources_list_ptr = data_layout.GetBlockPtr<DatasourceID>(
memory_block, storage::DataLayout::GEOMETRIES_FWD_DATASOURCES_LIST);
util::vector_view<DatasourceID> geometry_fwd_datasources_list(
geometries_fwd_datasources_list_ptr,
data_layout.num_entries[storage::DataLayout::GEOMETRIES_FWD_DATASOURCES_LIST]);
auto geometries_rev_datasources_list_ptr = data_layout.GetBlockPtr<DatasourceID>(
memory_block, storage::DataLayout::GEOMETRIES_REV_DATASOURCES_LIST);
util::vector_view<DatasourceID> geometry_rev_datasources_list(
geometries_rev_datasources_list_ptr,
data_layout.num_entries[storage::DataLayout::GEOMETRIES_REV_DATASOURCES_LIST]);
segment_data = extractor::SegmentDataView{std::move(geometry_begin_indices),
std::move(geometry_node_list),
@@ -491,7 +498,8 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
std::move(geometry_rev_weight_list),
std::move(geometry_fwd_duration_list),
std::move(geometry_rev_duration_list),
std::move(datasources_list)};
std::move(geometry_fwd_datasources_list),
std::move(geometry_rev_datasources_list)};
m_datasources = data_layout.GetBlockPtr<extractor::Datasources>(
memory_block, storage::DataLayout::DATASOURCES_NAMES);
+27 -18
View File
@@ -2,6 +2,7 @@
#define OSRM_ENGINE_DATAFACADE_PROVIDER_HPP
#include "engine/data_watchdog.hpp"
#include "engine/datafacade.hpp"
#include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
#include "engine/datafacade/process_memory_allocator.hpp"
@@ -9,48 +10,56 @@ namespace osrm
{
namespace engine
{
template <typename AlgorithmT> class DataFacadeProvider
namespace detail
{
using FacadeT = datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT>;
template <typename AlgorithmT, template <typename A> class FacadeT> class DataFacadeProvider
{
public:
using Facade = FacadeT<AlgorithmT>;
virtual ~DataFacadeProvider() = default;
virtual std::shared_ptr<const FacadeT> Get() const = 0;
virtual std::shared_ptr<const Facade> Get() const = 0;
};
template <typename AlgorithmT> class ImmutableProvider final : public DataFacadeProvider<AlgorithmT>
template <typename AlgorithmT, template <typename A> class FacadeT>
class ImmutableProvider final : public DataFacadeProvider<AlgorithmT, FacadeT>
{
using FacadeT = datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT>;
public:
using Facade = typename DataFacadeProvider<AlgorithmT, FacadeT>::Facade;
ImmutableProvider(const storage::StorageConfig &config)
: immutable_data_facade(std::make_shared<FacadeT>(
: immutable_data_facade(std::make_shared<Facade>(
std::make_shared<datafacade::ProcessMemoryAllocator>(config)))
{
}
std::shared_ptr<const FacadeT> Get() const override final { return immutable_data_facade; }
std::shared_ptr<const Facade> Get() const override final { return immutable_data_facade; }
private:
std::shared_ptr<const FacadeT> immutable_data_facade;
std::shared_ptr<const Facade> immutable_data_facade;
};
template <typename AlgorithmT> class WatchingProvider final : public DataFacadeProvider<AlgorithmT>
template <typename AlgorithmT, template <typename A> class FacadeT>
class WatchingProvider : public DataFacadeProvider<AlgorithmT, FacadeT>
{
using FacadeT = datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT>;
DataWatchdog<AlgorithmT> watchdog;
public:
std::shared_ptr<const FacadeT> Get() const override final
{
// We need a singleton here because multiple instances of DataWatchdog
// conflict on shared memory mappings
return watchdog.Get();
}
using Facade = typename DataFacadeProvider<AlgorithmT, FacadeT>::Facade;
std::shared_ptr<const Facade> Get() const override final { return watchdog.Get(); }
};
}
template <typename AlgorithmT>
using DataFacadeProvider = detail::DataFacadeProvider<AlgorithmT, DataFacade>;
template <typename AlgorithmT>
using WatchingProvider = detail::WatchingProvider<AlgorithmT, DataFacade>;
template <typename AlgorithmT>
using ImmutableProvider = detail::ImmutableProvider<AlgorithmT, DataFacade>;
}
}
#endif
+18 -24
View File
@@ -85,47 +85,41 @@ template <typename Algorithm> class Engine final : public EngineInterface
Status Route(const api::RouteParameters &params,
util::json::Object &result) const override final
{
auto facade = facade_provider->Get();
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, *facade};
return route_plugin.HandleRequest(*facade, algorithms, params, result);
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, facade_provider->Get()};
return route_plugin.HandleRequest(algorithms, params, result);
}
Status Table(const api::TableParameters &params,
util::json::Object &result) const override final
{
auto facade = facade_provider->Get();
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, *facade};
return table_plugin.HandleRequest(*facade, algorithms, params, result);
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, facade_provider->Get()};
return table_plugin.HandleRequest(algorithms, params, result);
}
Status Nearest(const api::NearestParameters &params,
util::json::Object &result) const override final
{
auto facade = facade_provider->Get();
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, *facade};
return nearest_plugin.HandleRequest(*facade, algorithms, params, result);
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, facade_provider->Get()};
return nearest_plugin.HandleRequest(algorithms, params, result);
}
Status Trip(const api::TripParameters &params, util::json::Object &result) const override final
{
auto facade = facade_provider->Get();
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, *facade};
return trip_plugin.HandleRequest(*facade, algorithms, params, result);
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, facade_provider->Get()};
return trip_plugin.HandleRequest(algorithms, params, result);
}
Status Match(const api::MatchParameters &params,
util::json::Object &result) const override final
{
auto facade = facade_provider->Get();
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, *facade};
return match_plugin.HandleRequest(*facade, algorithms, params, result);
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, facade_provider->Get()};
return match_plugin.HandleRequest(algorithms, params, result);
}
Status Tile(const api::TileParameters &params, std::string &result) const override final
{
auto facade = facade_provider->Get();
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, *facade};
return tile_plugin.HandleRequest(*facade, algorithms, params, result);
auto algorithms = RoutingAlgorithms<Algorithm>{heaps, facade_provider->Get()};
return tile_plugin.HandleRequest(algorithms, params, result);
}
static bool CheckCompability(const EngineConfig &config);
@@ -158,9 +152,9 @@ bool Engine<routing_algorithms::ch::Algorithm>::CheckCompability(const EngineCon
}
else
{
if (!boost::filesystem::exists(config.storage_config.hsgr_data_path))
if (!boost::filesystem::exists(config.storage_config.GetPath(".osrm.hsgr")))
return false;
storage::io::FileReader in(config.storage_config.hsgr_data_path,
storage::io::FileReader in(config.storage_config.GetPath(".osrm.hsgr"),
storage::io::FileReader::VerifyFingerprint);
auto size = in.GetSize();
@@ -189,9 +183,9 @@ bool Engine<routing_algorithms::corech::Algorithm>::CheckCompability(const Engin
}
else
{
if (!boost::filesystem::exists(config.storage_config.core_data_path))
if (!boost::filesystem::exists(config.storage_config.GetPath(".osrm.core")))
return false;
storage::io::FileReader in(config.storage_config.core_data_path,
storage::io::FileReader in(config.storage_config.GetPath(".osrm.core"),
storage::io::FileReader::VerifyFingerprint);
auto size = in.GetSize();
@@ -214,9 +208,9 @@ bool Engine<routing_algorithms::mld::Algorithm>::CheckCompability(const EngineCo
}
else
{
if (!boost::filesystem::exists(config.storage_config.mld_partition_path))
if (!boost::filesystem::exists(config.storage_config.GetPath(".osrm.partition")))
return false;
storage::io::FileReader in(config.storage_config.mld_partition_path,
storage::io::FileReader in(config.storage_config.GetPath(".osrm.partition"),
storage::io::FileReader::VerifyFingerprint);
auto size = in.GetSize();
+1 -2
View File
@@ -32,8 +32,7 @@ class MatchPlugin : public BasePlugin
{
}
Status HandleRequest(const datafacade::ContiguousInternalMemoryDataFacadeBase &facade,
const RoutingAlgorithmsInterface &algorithms,
Status HandleRequest(const RoutingAlgorithmsInterface &algorithms,
const api::MatchParameters &parameters,
util::json::Object &json_result) const;
+1 -2
View File
@@ -19,8 +19,7 @@ class NearestPlugin final : public BasePlugin
public:
explicit NearestPlugin(const int max_results);
Status HandleRequest(const datafacade::ContiguousInternalMemoryDataFacadeBase &facade,
const RoutingAlgorithmsInterface &algorithms,
Status HandleRequest(const RoutingAlgorithmsInterface &algorithms,
const api::NearestParameters &params,
util::json::Object &result) const;
+1 -2
View File
@@ -21,8 +21,7 @@ class TablePlugin final : public BasePlugin
public:
explicit TablePlugin(const int max_locations_distance_table);
Status HandleRequest(const datafacade::ContiguousInternalMemoryDataFacadeBase &facade,
const RoutingAlgorithmsInterface &algorithms,
Status HandleRequest(const RoutingAlgorithmsInterface &algorithms,
const api::TableParameters &params,
util::json::Object &result) const;
+1 -2
View File
@@ -26,8 +26,7 @@ namespace plugins
class TilePlugin final : public BasePlugin
{
public:
Status HandleRequest(const datafacade::ContiguousInternalMemoryDataFacadeBase &facade,
const RoutingAlgorithmsInterface &algorithms,
Status HandleRequest(const RoutingAlgorithmsInterface &algorithms,
const api::TileParameters &parameters,
std::string &pbf_buffer) const;
};
+1 -2
View File
@@ -38,8 +38,7 @@ class TripPlugin final : public BasePlugin
public:
explicit TripPlugin(const int max_locations_trip_) : max_locations_trip(max_locations_trip_) {}
Status HandleRequest(const datafacade::ContiguousInternalMemoryDataFacadeBase &facade,
const RoutingAlgorithmsInterface &algorithms,
Status HandleRequest(const RoutingAlgorithmsInterface &algorithms,
const api::TripParameters &parameters,
util::json::Object &json_result) const;
};
+1 -2
View File
@@ -32,8 +32,7 @@ class ViaRoutePlugin final : public BasePlugin
public:
explicit ViaRoutePlugin(int max_locations_viaroute, int max_alternatives);
Status HandleRequest(const datafacade::ContiguousInternalMemoryDataFacadeBase &facade,
const RoutingAlgorithmsInterface &algorithms,
Status HandleRequest(const RoutingAlgorithmsInterface &algorithms,
const api::RouteParameters &route_parameters,
util::json::Object &json_result) const;
};
+12 -10
View File
@@ -46,6 +46,8 @@ class RoutingAlgorithmsInterface
GetTileTurns(const std::vector<datafacade::BaseDataFacade::RTreeLeaf> &edges,
const std::vector<std::size_t> &sorted_edge_indexes) const = 0;
virtual const DataFacadeBase &GetFacade() const = 0;
virtual bool HasAlternativePathSearch() const = 0;
virtual bool HasShortestPathSearch() const = 0;
virtual bool HasDirectShortestPathSearch() const = 0;
@@ -59,7 +61,7 @@ template <typename Algorithm> class RoutingAlgorithms final : public RoutingAlgo
{
public:
RoutingAlgorithms(SearchEngineData<Algorithm> &heaps,
const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade)
std::shared_ptr<const DataFacade<Algorithm>> facade)
: heaps(heaps), facade(facade)
{
}
@@ -93,6 +95,8 @@ template <typename Algorithm> class RoutingAlgorithms final : public RoutingAlgo
GetTileTurns(const std::vector<datafacade::BaseDataFacade::RTreeLeaf> &edges,
const std::vector<std::size_t> &sorted_edge_indexes) const final override;
const DataFacadeBase &GetFacade() const final override { return *facade; }
bool HasAlternativePathSearch() const final override
{
return routing_algorithms::HasAlternativePathSearch<Algorithm>::value;
@@ -125,9 +129,7 @@ template <typename Algorithm> class RoutingAlgorithms final : public RoutingAlgo
private:
SearchEngineData<Algorithm> &heaps;
// Owned by shared-ptr passed to the query
const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade;
std::shared_ptr<const DataFacade<Algorithm>> facade;
};
template <typename Algorithm>
@@ -136,7 +138,7 @@ RoutingAlgorithms<Algorithm>::AlternativePathSearch(const PhantomNodes &phantom_
unsigned number_of_alternatives) const
{
return routing_algorithms::alternativePathSearch(
heaps, facade, phantom_node_pair, number_of_alternatives);
heaps, *facade, phantom_node_pair, number_of_alternatives);
}
template <typename Algorithm>
@@ -145,14 +147,14 @@ InternalRouteResult RoutingAlgorithms<Algorithm>::ShortestPathSearch(
const boost::optional<bool> continue_straight_at_waypoint) const
{
return routing_algorithms::shortestPathSearch(
heaps, facade, phantom_node_pair, continue_straight_at_waypoint);
heaps, *facade, phantom_node_pair, continue_straight_at_waypoint);
}
template <typename Algorithm>
InternalRouteResult
RoutingAlgorithms<Algorithm>::DirectShortestPathSearch(const PhantomNodes &phantom_nodes) const
{
return routing_algorithms::directShortestPathSearch(heaps, facade, phantom_nodes);
return routing_algorithms::directShortestPathSearch(heaps, *facade, phantom_nodes);
}
template <typename Algorithm>
@@ -162,7 +164,7 @@ RoutingAlgorithms<Algorithm>::ManyToManySearch(const std::vector<PhantomNode> &p
const std::vector<std::size_t> &target_indices) const
{
return routing_algorithms::manyToManySearch(
heaps, facade, phantom_nodes, source_indices, target_indices);
heaps, *facade, phantom_nodes, source_indices, target_indices);
}
template <typename Algorithm>
@@ -174,7 +176,7 @@ inline routing_algorithms::SubMatchingList RoutingAlgorithms<Algorithm>::MapMatc
const bool allow_splitting) const
{
return routing_algorithms::mapMatching(heaps,
facade,
*facade,
candidates_list,
trace_coordinates,
trace_timestamps,
@@ -187,7 +189,7 @@ inline std::vector<routing_algorithms::TurnData> RoutingAlgorithms<Algorithm>::G
const std::vector<datafacade::BaseDataFacade::RTreeLeaf> &edges,
const std::vector<std::size_t> &sorted_edge_indexes) const
{
return routing_algorithms::getTileTurns(facade, edges, sorted_edge_indexes);
return routing_algorithms::getTileTurns(*facade, edges, sorted_edge_indexes);
}
// CoreCH overrides
@@ -1,7 +1,7 @@
#ifndef ALTERNATIVE_PATH_ROUTING_HPP
#define ALTERNATIVE_PATH_ROUTING_HPP
#include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
#include "engine/datafacade.hpp"
#include "engine/internal_route_result.hpp"
#include "engine/algorithm.hpp"
@@ -16,17 +16,15 @@ namespace engine
namespace routing_algorithms
{
InternalManyRoutesResult
alternativePathSearch(SearchEngineData<ch::Algorithm> &search_engine_data,
const datafacade::ContiguousInternalMemoryDataFacade<ch::Algorithm> &facade,
const PhantomNodes &phantom_node_pair,
unsigned number_of_alternatives);
InternalManyRoutesResult alternativePathSearch(SearchEngineData<ch::Algorithm> &search_engine_data,
const DataFacade<ch::Algorithm> &facade,
const PhantomNodes &phantom_node_pair,
unsigned number_of_alternatives);
InternalManyRoutesResult
alternativePathSearch(SearchEngineData<mld::Algorithm> &search_engine_data,
const datafacade::ContiguousInternalMemoryDataFacade<mld::Algorithm> &facade,
const PhantomNodes &phantom_node_pair,
unsigned number_of_alternatives);
InternalManyRoutesResult alternativePathSearch(SearchEngineData<mld::Algorithm> &search_engine_data,
const DataFacade<mld::Algorithm> &facade,
const PhantomNodes &phantom_node_pair,
unsigned number_of_alternatives);
} // namespace routing_algorithms
} // namespace engine
@@ -2,7 +2,7 @@
#define DIRECT_SHORTEST_PATH_HPP
#include "engine/algorithm.hpp"
#include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
#include "engine/datafacade.hpp"
#include "engine/internal_route_result.hpp"
#include "engine/search_engine_data.hpp"
@@ -22,10 +22,9 @@ namespace routing_algorithms
/// This variation is only an optimazation for graphs with slow queries, for example
/// not fully contracted graphs.
template <typename Algorithm>
InternalRouteResult
directShortestPathSearch(SearchEngineData<Algorithm> &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
const PhantomNodes &phantom_nodes);
InternalRouteResult directShortestPathSearch(SearchEngineData<Algorithm> &engine_working_data,
const DataFacade<Algorithm> &facade,
const PhantomNodes &phantom_nodes);
} // namespace routing_algorithms
} // namespace engine
@@ -2,7 +2,7 @@
#define MANY_TO_MANY_ROUTING_HPP
#include "engine/algorithm.hpp"
#include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
#include "engine/datafacade.hpp"
#include "engine/search_engine_data.hpp"
#include "util/typedefs.hpp"
@@ -17,12 +17,11 @@ namespace routing_algorithms
{
template <typename Algorithm>
std::vector<EdgeWeight>
manyToManySearch(SearchEngineData<Algorithm> &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
const std::vector<PhantomNode> &phantom_nodes,
const std::vector<std::size_t> &source_indices,
const std::vector<std::size_t> &target_indices);
std::vector<EdgeWeight> manyToManySearch(SearchEngineData<Algorithm> &engine_working_data,
const DataFacade<Algorithm> &facade,
const std::vector<PhantomNode> &phantom_nodes,
const std::vector<std::size_t> &source_indices,
const std::vector<std::size_t> &target_indices);
} // namespace routing_algorithms
} // namespace engine
@@ -2,7 +2,7 @@
#define MAP_MATCHING_HPP
#include "engine/algorithm.hpp"
#include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
#include "engine/datafacade.hpp"
#include "engine/map_matching/sub_matching.hpp"
#include "engine/search_engine_data.hpp"
@@ -24,7 +24,7 @@ static const constexpr double DEFAULT_GPS_PRECISION = 5;
// P. Newson and J. Krumm; 2009; ACM GIS
template <typename Algorithm>
SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
const DataFacade<Algorithm> &facade,
const CandidateLists &candidates_list,
const std::vector<util::Coordinate> &trace_coordinates,
const std::vector<unsigned> &trace_timestamps,
@@ -4,7 +4,7 @@
#include "extractor/guidance/turn_instruction.hpp"
#include "engine/algorithm.hpp"
#include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
#include "engine/datafacade.hpp"
#include "engine/internal_route_result.hpp"
#include "engine/phantom_node.hpp"
#include "engine/search_engine_data.hpp"
@@ -329,7 +329,7 @@ void annotatePath(const FacadeT &facade,
}
template <typename Algorithm>
double getPathDistance(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
double getPathDistance(const DataFacade<Algorithm> &facade,
const std::vector<PathData> unpacked_path,
const PhantomNode &source_phantom,
const PhantomNode &target_phantom)
@@ -382,12 +382,11 @@ double getPathDistance(const datafacade::ContiguousInternalMemoryDataFacade<Algo
}
template <typename AlgorithmT>
InternalRouteResult
extractRoute(const datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT> &facade,
const EdgeWeight weight,
const PhantomNodes &phantom_nodes,
const std::vector<NodeID> &unpacked_nodes,
const std::vector<EdgeID> &unpacked_edges)
InternalRouteResult extractRoute(const DataFacade<AlgorithmT> &facade,
const EdgeWeight weight,
const PhantomNodes &phantom_nodes,
const std::vector<NodeID> &unpacked_nodes,
const std::vector<EdgeID> &unpacked_edges)
{
InternalRouteResult raw_route_data;
raw_route_data.segment_end_coordinates = {phantom_nodes};
@@ -2,7 +2,7 @@
#define OSRM_ENGINE_ROUTING_BASE_CH_HPP
#include "engine/algorithm.hpp"
#include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
#include "engine/datafacade.hpp"
#include "engine/routing_algorithms/routing_base.hpp"
#include "engine/search_engine_data.hpp"
@@ -23,7 +23,7 @@ namespace ch
// Stalling
template <bool DIRECTION, typename HeapT>
bool stallAtNode(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
bool stallAtNode(const DataFacade<Algorithm> &facade,
const NodeID node,
const EdgeWeight weight,
const HeapT &query_heap)
@@ -49,7 +49,7 @@ bool stallAtNode(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm>
}
template <bool DIRECTION>
void relaxOutgoingEdges(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
const NodeID node,
const EdgeWeight weight,
SearchEngineData<Algorithm>::QueryHeap &heap)
@@ -113,7 +113,7 @@ we need to add an offset to the termination criterion.
static constexpr bool ENABLE_STALLING = true;
static constexpr bool DISABLE_STALLING = false;
template <bool DIRECTION, bool STALLING = ENABLE_STALLING>
void routingStep(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
void routingStep(const DataFacade<Algorithm> &facade,
SearchEngineData<Algorithm>::QueryHeap &forward_heap,
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
NodeID &middle_node_id,
@@ -186,8 +186,7 @@ void routingStep(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm>
}
template <bool UseDuration>
EdgeWeight getLoopWeight(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
NodeID node)
EdgeWeight getLoopWeight(const DataFacade<Algorithm> &facade, NodeID node)
{
EdgeWeight loop_weight = UseDuration ? MAXIMAL_EDGE_DURATION : INVALID_EDGE_WEIGHT;
for (auto edge : facade.GetAdjacentEdgeRange(node))
@@ -227,7 +226,7 @@ EdgeWeight getLoopWeight(const datafacade::ContiguousInternalMemoryDataFacade<Al
* original edge found.
*/
template <typename BidirectionalIterator, typename Callback>
void unpackPath(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
void unpackPath(const DataFacade<Algorithm> &facade,
BidirectionalIterator packed_path_begin,
BidirectionalIterator packed_path_end,
Callback &&callback)
@@ -327,7 +326,7 @@ void unpackPath(const FacadeT &facade,
* @param to the node the CH edge finishes at
* @param unpacked_path the sequence of original NodeIDs that make up the expanded CH edge
*/
void unpackEdge(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
void unpackEdge(const DataFacade<Algorithm> &facade,
const NodeID from,
const NodeID to,
std::vector<NodeID> &unpacked_path);
@@ -354,7 +353,7 @@ void retrievePackedPathFromSingleHeap(const SearchEngineData<Algorithm>::QueryHe
// requires
// a force loop, if the heaps have been initialized with positive offsets.
void search(SearchEngineData<Algorithm> &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
const DataFacade<Algorithm> &facade,
SearchEngineData<Algorithm>::QueryHeap &forward_heap,
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
std::int32_t &weight,
@@ -367,14 +366,13 @@ void search(SearchEngineData<Algorithm> &engine_working_data,
// Requires the heaps for be empty
// If heaps should be adjusted to be initialized outside of this function,
// the addition of force_loop parameters might be required
double
getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<ch::Algorithm> &facade,
SearchEngineData<Algorithm>::QueryHeap &forward_heap,
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
const PhantomNode &source_phantom,
const PhantomNode &target_phantom,
int duration_upper_bound = INVALID_EDGE_WEIGHT);
double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
const DataFacade<ch::Algorithm> &facade,
SearchEngineData<Algorithm>::QueryHeap &forward_heap,
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
const PhantomNode &source_phantom,
const PhantomNode &target_phantom,
int duration_upper_bound = INVALID_EDGE_WEIGHT);
} // namespace ch
@@ -390,7 +388,7 @@ namespace corech
// requires
// a force loop, if the heaps have been initialized with positive offsets.
void search(SearchEngineData<Algorithm> &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<corech::Algorithm> &facade,
const DataFacade<corech::Algorithm> &facade,
SearchEngineData<ch::Algorithm>::QueryHeap &forward_heap,
SearchEngineData<ch::Algorithm>::QueryHeap &reverse_heap,
int &weight,
@@ -403,14 +401,13 @@ void search(SearchEngineData<Algorithm> &engine_working_data,
// Requires the heaps for be empty
// If heaps should be adjusted to be initialized outside of this function,
// the addition of force_loop parameters might be required
double
getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<corech::Algorithm> &facade,
SearchEngineData<ch::Algorithm>::QueryHeap &forward_heap,
SearchEngineData<ch::Algorithm>::QueryHeap &reverse_heap,
const PhantomNode &source_phantom,
const PhantomNode &target_phantom,
int duration_upper_bound = INVALID_EDGE_WEIGHT);
double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
const DataFacade<corech::Algorithm> &facade,
SearchEngineData<ch::Algorithm>::QueryHeap &forward_heap,
SearchEngineData<ch::Algorithm>::QueryHeap &reverse_heap,
const PhantomNode &source_phantom,
const PhantomNode &target_phantom,
int duration_upper_bound = INVALID_EDGE_WEIGHT);
template <typename RandomIter, typename FacadeT>
void unpackPath(const FacadeT &facade,
@@ -2,7 +2,7 @@
#define OSRM_ENGINE_ROUTING_BASE_MLD_HPP
#include "engine/algorithm.hpp"
#include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
#include "engine/datafacade.hpp"
#include "engine/routing_algorithms/routing_base.hpp"
#include "engine/search_engine_data.hpp"
@@ -131,7 +131,7 @@ retrievePackedPathFromHeap(const SearchEngineData<Algorithm>::QueryHeap &forward
}
template <bool DIRECTION, typename... Args>
void routingStep(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
void routingStep(const DataFacade<Algorithm> &facade,
SearchEngineData<Algorithm>::QueryHeap &forward_heap,
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
NodeID &middle_node,
@@ -262,7 +262,7 @@ using UnpackedPath = std::tuple<EdgeWeight, UnpackedNodes, UnpackedEdges>;
template <typename... Args>
UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
const DataFacade<Algorithm> &facade,
SearchEngineData<Algorithm>::QueryHeap &forward_heap,
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
const bool force_loop_forward,
@@ -390,7 +390,7 @@ UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
// Alias to be compatible with the CH-based search
inline void search(SearchEngineData<Algorithm> &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
const DataFacade<Algorithm> &facade,
SearchEngineData<Algorithm>::QueryHeap &forward_heap,
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
EdgeWeight &weight,
@@ -442,14 +442,13 @@ void unpackPath(const FacadeT &facade,
annotatePath(facade, phantom_nodes, unpacked_nodes, unpacked_edges, unpacked_path);
}
inline double
getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
SearchEngineData<Algorithm>::QueryHeap &forward_heap,
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
const PhantomNode &source_phantom,
const PhantomNode &target_phantom,
EdgeWeight weight_upper_bound = INVALID_EDGE_WEIGHT)
inline double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
const DataFacade<Algorithm> &facade,
SearchEngineData<Algorithm>::QueryHeap &forward_heap,
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
const PhantomNode &source_phantom,
const PhantomNode &target_phantom,
EdgeWeight weight_upper_bound = INVALID_EDGE_WEIGHT)
{
forward_heap.Clear();
reverse_heap.Clear();
@@ -14,11 +14,10 @@ namespace routing_algorithms
{
template <typename Algorithm>
InternalRouteResult
shortestPathSearch(SearchEngineData<Algorithm> &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
const std::vector<PhantomNodes> &phantom_nodes_vector,
const boost::optional<bool> continue_straight_at_waypoint);
InternalRouteResult shortestPathSearch(SearchEngineData<Algorithm> &engine_working_data,
const DataFacade<Algorithm> &facade,
const std::vector<PhantomNodes> &phantom_nodes_vector,
const boost::optional<bool> continue_straight_at_waypoint);
} // namespace routing_algorithms
} // namespace engine
@@ -2,7 +2,8 @@
#define OSRM_ENGINE_ROUTING_ALGORITHMS_TILE_TURNS_HPP
#include "engine/algorithm.hpp"
#include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
#include "engine/datafacade.hpp"
#include "engine/datafacade/datafacade_base.hpp"
#include "util/coordinate.hpp"
#include "util/typedefs.hpp"
@@ -28,15 +29,13 @@ struct TurnData final
using RTreeLeaf = datafacade::BaseDataFacade::RTreeLeaf;
std::vector<TurnData>
getTileTurns(const datafacade::ContiguousInternalMemoryDataFacade<ch::Algorithm> &facade,
const std::vector<RTreeLeaf> &edges,
const std::vector<std::size_t> &sorted_edge_indexes);
std::vector<TurnData> getTileTurns(const DataFacade<ch::Algorithm> &facade,
const std::vector<RTreeLeaf> &edges,
const std::vector<std::size_t> &sorted_edge_indexes);
std::vector<TurnData>
getTileTurns(const datafacade::ContiguousInternalMemoryDataFacade<mld::Algorithm> &facade,
const std::vector<RTreeLeaf> &edges,
const std::vector<std::size_t> &sorted_edge_indexes);
std::vector<TurnData> getTileTurns(const DataFacade<mld::Algorithm> &facade,
const std::vector<RTreeLeaf> &edges,
const std::vector<std::size_t> &sorted_edge_indexes);
} // namespace routing_algorithms
} // namespace engine
+22 -7
View File
@@ -17,6 +17,7 @@
#include "extractor/profile_properties.hpp"
#include "extractor/query_node.hpp"
#include "extractor/restriction_map.hpp"
#include "extractor/way_restriction_map.hpp"
#include "util/concurrent_id_map.hpp"
#include "util/deallocating_vector.hpp"
@@ -78,7 +79,6 @@ class EdgeBasedGraphFactory
CompressedEdgeContainer &compressed_edge_container,
const std::unordered_set<NodeID> &barrier_nodes,
const std::unordered_set<NodeID> &traffic_lights,
std::shared_ptr<const RestrictionMap> restriction_map,
const std::vector<util::Coordinate> &coordinates,
const extractor::PackedOSMIDs &osm_node_ids,
ProfileProperties profile_properties,
@@ -91,7 +91,9 @@ class EdgeBasedGraphFactory
const std::string &turn_weight_penalties_filename,
const std::string &turn_duration_penalties_filename,
const std::string &turn_penalties_index_filename,
const std::string &cnbg_ebg_mapping_path);
const std::string &cnbg_ebg_mapping_path,
const RestrictionMap &node_restriction_map,
const WayRestrictionMap &way_restriction_map);
// The following get access functions destroy the content in the factory
void GetEdgeBasedEdges(util::DeallocatingVector<EdgeBasedEdge> &edges);
@@ -106,7 +108,7 @@ class EdgeBasedGraphFactory
std::vector<util::guidance::BearingClass> GetBearingClasses() const;
std::vector<util::guidance::EntryClass> GetEntryClasses() const;
unsigned GetHighestEdgeID();
std::uint64_t GetNumberOfEdgeBasedNodes() const;
// Basic analysis of a turn (u --(e1)-- v --(e2)-- w)
// with known angle.
@@ -134,12 +136,17 @@ class EdgeBasedGraphFactory
std::vector<EdgeBasedNodeSegment> m_edge_based_node_segments;
EdgeBasedNodeDataContainer m_edge_based_node_container;
util::DeallocatingVector<EdgeBasedEdge> m_edge_based_edge_list;
EdgeID m_max_edge_id;
// The number of edge-based nodes is mostly made up out of the edges in the node-based graph.
// Any edge in the node-based graph represents a node in the edge-based graph. In addition, we
// add a set of artificial edge-based nodes into the mix to model via-way turn restrictions.
// See https://github.com/Project-OSRM/osrm-backend/issues/2681#issuecomment-313080353 for
// reference
std::uint64_t m_number_of_edge_based_nodes;
const std::vector<util::Coordinate> &m_coordinates;
const extractor::PackedOSMIDs &m_osm_node_ids;
std::shared_ptr<util::NodeBasedDynamicGraph> m_node_based_graph;
std::shared_ptr<RestrictionMap const> m_restriction_map;
const std::unordered_set<NodeID> &m_barrier_nodes;
const std::unordered_set<NodeID> &m_traffic_lights;
@@ -152,14 +159,22 @@ class EdgeBasedGraphFactory
unsigned RenumberEdges();
std::vector<NBGToEBG> GenerateEdgeExpandedNodes();
// During the generation of the edge-expanded nodes, we need to also generate duplicates that
// represent state during via-way restrictions (see
// https://github.com/Project-OSRM/osrm-backend/issues/2681#issuecomment-313080353). Access to
// the information on what to duplicate and how is provided via the way_restriction_map
std::vector<NBGToEBG> GenerateEdgeExpandedNodes(const WayRestrictionMap &way_restriction_map);
// Edge-expanded edges are generate for all valid turns. The validity can be checked via the
// restriction maps
void GenerateEdgeExpandedEdges(ScriptingEnvironment &scripting_environment,
const std::string &original_edge_data_filename,
const std::string &turn_lane_data_filename,
const std::string &turn_weight_penalties_filename,
const std::string &turn_duration_penalties_filename,
const std::string &turn_penalties_index_filename);
const std::string &turn_penalties_index_filename,
const RestrictionMap &node_restriction_map,
const WayRestrictionMap &way_restriction_map);
NBGToEBG InsertEdgeBasedNode(const NodeID u, const NodeID v);
+13 -6
View File
@@ -2,7 +2,6 @@
#define EXTRACTION_CONTAINERS_HPP
#include "extractor/first_and_last_segment_of_way.hpp"
#include "extractor/guidance/turn_lane_types.hpp"
#include "extractor/internal_extractor_edge.hpp"
#include "extractor/query_node.hpp"
#include "extractor/restriction.hpp"
@@ -28,7 +27,7 @@ class ExtractionContainers
void PrepareEdges(ScriptingEnvironment &scripting_environment);
void WriteNodes(storage::io::FileWriter &file_out) const;
void WriteRestrictions(const std::string &restrictions_file_name);
void WriteConditionalRestrictions(const std::string &restrictions_file_name);
void WriteEdges(storage::io::FileWriter &file_out) const;
void WriteCharData(const std::string &file_name);
@@ -36,7 +35,6 @@ class ExtractionContainers
using NodeIDVector = std::vector<OSMNodeID>;
using NodeVector = std::vector<QueryNode>;
using EdgeVector = std::vector<InternalExtractorEdge>;
using RestrictionsVector = std::vector<InputRestrictionContainer>;
using WayIDStartEndVector = std::vector<FirstAndLastSegmentOfWay>;
using NameCharData = std::vector<unsigned char>;
using NameOffsets = std::vector<unsigned>;
@@ -49,17 +47,26 @@ class ExtractionContainers
NameCharData name_char_data;
NameOffsets name_offsets;
// an adjacency array containing all turn lane masks
RestrictionsVector restrictions_list;
WayIDStartEndVector way_start_end_id_list;
unsigned max_internal_node_id;
// list of restrictions before we transform them into the output types. Input containers
// reference OSMNodeIDs. We can only transform them to the correct internal IDs after we've read
// everything. Without a multi-parse approach, we have to remember the output restrictions
// before converting them to the internal formats
std::vector<InputConditionalTurnRestriction> restrictions_list;
// turn restrictions split into conditional and unconditional turn restrictions
std::vector<ConditionalTurnRestriction> conditional_turn_restrictions;
std::vector<TurnRestriction> unconditional_turn_restrictions;
ExtractionContainers();
void PrepareData(ScriptingEnvironment &scripting_environment,
const std::string &output_file_name,
const std::string &osrm_path,
const std::string &restrictions_file_name,
const std::string &names_file_name);
const std::string &names_data_path);
};
}
}
-6
View File
@@ -85,12 +85,6 @@ class Extractor
std::vector<util::Coordinate> &coordinates,
extractor::PackedOSMIDs &osm_node_ids);
void WriteIntersectionClassificationData(
const std::string &output_file_name,
const std::vector<std::uint32_t> &node_based_intersection_classes,
const std::vector<util::guidance::BearingClass> &bearing_classes,
const std::vector<util::guidance::EntryClass> &entry_classes) const;
// Writes compressed node based graph and its embedding into a file for osrm-partition to use.
static void WriteCompressedNodeBasedGraph(const std::string &path,
const util::NodeBasedDynamicGraph &graph,
+2 -2
View File
@@ -42,10 +42,10 @@ namespace extractor
{
class ExtractionContainers;
struct InputRestrictionContainer;
struct ExtractionNode;
struct ExtractionWay;
struct ProfileProperties;
struct InputConditionalTurnRestriction;
/**
* This class is used by the extractor with the results of the
@@ -83,7 +83,7 @@ class ExtractorCallbacks
void ProcessNode(const osmium::Node &current_node, const ExtractionNode &result_node);
// warning: caller needs to take care of synchronization!
void ProcessRestriction(const boost::optional<InputRestrictionContainer> &restriction);
void ProcessRestriction(const InputConditionalTurnRestriction &restriction);
// warning: caller needs to take care of synchronization!
void ProcessWay(const osmium::Way &current_way, const ExtractionWay &result_way);
+34 -60
View File
@@ -33,83 +33,57 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <array>
#include <string>
#include "storage/io_config.hpp"
namespace osrm
{
namespace extractor
{
struct ExtractorConfig
struct ExtractorConfig final : storage::IOConfig
{
ExtractorConfig() noexcept : requested_num_threads(0) {}
void UseDefaultOutputNames()
ExtractorConfig() noexcept : IOConfig(
{
"",
},
{},
{".osrm",
".osrm.restrictions",
".osrm.names",
".osrm.tls",
".osrm.tld",
".osrm.timestamp",
".osrm.geometry",
".osrm.nbg_nodes",
".osrm.ebg_nodes",
".osrm.edges",
".osrm.ebg",
".osrm.ramIndex",
".osrm.fileIndex",
".osrm.turn_duration_penalties",
".osrm.turn_weight_penalties",
".osrm.turn_penalties_index",
".osrm.enw",
".osrm.properties",
".osrm.icd",
".osrm.cnbg",
".osrm.cnbg_to_ebg"}),
requested_num_threads(0)
{
std::string basepath = input_path.string();
}
auto pos = std::string::npos;
std::array<std::string, 5> known_extensions{
{".osm.bz2", ".osm.pbf", ".osm.xml", ".pbf", ".osm"}};
for (auto ext : known_extensions)
{
pos = basepath.find(ext);
if (pos != std::string::npos)
{
basepath.replace(pos, ext.size(), "");
break;
}
}
output_file_name = basepath + ".osrm";
restriction_file_name = basepath + ".osrm.restrictions";
names_file_name = basepath + ".osrm.names";
turn_lane_descriptions_file_name = basepath + ".osrm.tls";
turn_lane_data_file_name = basepath + ".osrm.tld";
timestamp_file_name = basepath + ".osrm.timestamp";
geometry_output_path = basepath + ".osrm.geometry";
node_based_nodes_data_path = basepath + ".osrm.nbg_nodes";
edge_based_nodes_data_path = basepath + ".osrm.ebg_nodes";
edge_output_path = basepath + ".osrm.edges";
edge_graph_output_path = basepath + ".osrm.ebg";
rtree_nodes_output_path = basepath + ".osrm.ramIndex";
rtree_leafs_output_path = basepath + ".osrm.fileIndex";
turn_duration_penalties_path = basepath + ".osrm.turn_duration_penalties";
turn_weight_penalties_path = basepath + ".osrm.turn_weight_penalties";
turn_penalties_index_path = basepath + ".osrm.turn_penalties_index";
edge_based_node_weights_output_path = basepath + ".osrm.enw";
profile_properties_output_path = basepath + ".osrm.properties";
intersection_class_data_output_path = basepath + ".osrm.icd";
compressed_node_based_graph_output_path = basepath + ".osrm.cnbg";
cnbg_ebg_graph_mapping_output_path = basepath + ".osrm.cnbg_to_ebg";
void UseDefaultOutputNames(const boost::filesystem::path &base)
{
IOConfig::UseDefaultOutputNames(base);
}
boost::filesystem::path input_path;
boost::filesystem::path profile_path;
std::string output_file_name;
std::string restriction_file_name;
std::string names_file_name;
std::string turn_lane_data_file_name;
std::string turn_lane_descriptions_file_name;
std::string timestamp_file_name;
std::string geometry_output_path;
std::string edge_output_path;
std::string edge_graph_output_path;
std::string node_based_nodes_data_path;
std::string edge_based_nodes_data_path;
std::string edge_based_node_weights_output_path;
std::string rtree_nodes_output_path;
std::string rtree_leafs_output_path;
std::string profile_properties_output_path;
std::string intersection_class_data_output_path;
std::string turn_weight_penalties_path;
std::string turn_duration_penalties_path;
std::string compressed_node_based_graph_output_path;
std::string cnbg_ebg_graph_mapping_output_path;
unsigned requested_num_threads;
unsigned small_component_size;
bool generate_edge_lookup;
std::string turn_penalties_index_path;
bool use_metadata;
bool parse_conditionals;
+2 -2
View File
@@ -225,7 +225,7 @@ inline void writeTurnData(const boost::filesystem::path &path, const TurnDataT &
serialization::write(writer, turn_data);
}
// reads .osrm.nodes_data
// reads .osrm.ebg_nodes
template <typename NodeDataT>
inline void readNodeData(const boost::filesystem::path &path, NodeDataT &node_data)
{
@@ -239,7 +239,7 @@ inline void readNodeData(const boost::filesystem::path &path, NodeDataT &node_da
serialization::read(reader, node_data);
}
// writes .osrm.nodes_data
// writes .osrm.ebg_nodes
template <typename NodeDataT>
inline void writeNodeData(const boost::filesystem::path &path, const NodeDataT &node_data)
{
+3 -2
View File
@@ -7,6 +7,7 @@
#include <memory>
#include <unordered_set>
#include <vector>
namespace osrm
{
@@ -14,7 +15,7 @@ namespace extractor
{
class CompressedEdgeContainer;
class RestrictionMap;
struct TurnRestriction;
class GraphCompressor
{
@@ -23,7 +24,7 @@ class GraphCompressor
public:
void Compress(const std::unordered_set<NodeID> &barrier_nodes,
const std::unordered_set<NodeID> &traffic_lights,
RestrictionMap &restriction_map,
std::vector<TurnRestriction> &turn_restrictions,
util::NodeBasedDynamicGraph &graph,
CompressedEdgeContainer &geometry_compressor);
@@ -3,6 +3,7 @@
#include "extractor/guidance/intersection.hpp"
#include "util/coordinate.hpp"
#include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp"
@@ -16,7 +17,7 @@ namespace guidance
{
std::pair<util::guidance::EntryClass, util::guidance::BearingClass>
classifyIntersection(Intersection intersection);
classifyIntersection(Intersection intersection, const osrm::util::Coordinate &location);
} // namespace guidance
} // namespace extractor
+10
View File
@@ -104,6 +104,16 @@ template <storage::Ownership Ownership> class EdgeBasedNodeDataContainerImpl
util::inplacePermutation(classes.begin(), classes.end(), permutation);
}
// all containers have the exact same size
std::size_t Size() const
{
BOOST_ASSERT(geometry_ids.size() == name_ids.size());
BOOST_ASSERT(geometry_ids.size() == component_ids.size());
BOOST_ASSERT(geometry_ids.size() == travel_modes.size());
BOOST_ASSERT(geometry_ids.size() == classes.size());
return geometry_ids.size();
}
private:
Vector<GeometryID> geometry_ids;
Vector<NameID> name_ids;
+2 -2
View File
@@ -125,10 +125,10 @@ class RasterSource
int _ymax);
};
class SourceContainer
class RasterContainer
{
public:
SourceContainer() = default;
RasterContainer() = default;
int LoadRasterSource(const std::string &path_string,
double xmin,
+224 -85
View File
@@ -5,6 +5,7 @@
#include "util/opening_hours.hpp"
#include "util/typedefs.hpp"
#include "mapbox/variant.hpp"
#include <limits>
namespace osrm
@@ -12,104 +13,242 @@ namespace osrm
namespace extractor
{
// OSM offers two types of restrictions, via node and via-way restrictions. We parse both into the
// same input container
//
// A restriction turning at a single node. This is the most common type of restriction:
//
// a - b - c
// |
// d
//
// ab via b to bd
struct InputNodeRestriction
{
OSMWayID from;
OSMNodeID via;
OSMWayID to;
};
// A restriction that uses a single via-way in between
//
// f - e - d
// |
// a - b - c
//
// ab via be to ef -- no u turn
struct InputWayRestriction
{
OSMWayID from;
OSMWayID via;
OSMWayID to;
};
// Outside view of the variant, these are equal to the `which()` results
enum RestrictionType
{
NODE_RESTRICTION = 0,
WAY_RESTRICTION = 1,
NUM_RESTRICTION_TYPES = 2
};
struct InputTurnRestriction
{
// keep in the same order as the turn restrictions below
mapbox::util::variant<InputNodeRestriction, InputWayRestriction> node_or_way;
bool is_only;
OSMWayID From() const
{
return node_or_way.which() == RestrictionType::NODE_RESTRICTION
? mapbox::util::get<InputNodeRestriction>(node_or_way).from
: mapbox::util::get<InputWayRestriction>(node_or_way).from;
}
OSMWayID To() const
{
return node_or_way.which() == RestrictionType::NODE_RESTRICTION
? mapbox::util::get<InputNodeRestriction>(node_or_way).to
: mapbox::util::get<InputWayRestriction>(node_or_way).to;
}
RestrictionType Type() const
{
BOOST_ASSERT(node_or_way.which() < RestrictionType::NUM_RESTRICTION_TYPES);
return static_cast<RestrictionType>(node_or_way.which());
}
InputWayRestriction &AsWayRestriction()
{
BOOST_ASSERT(node_or_way.which() == RestrictionType::WAY_RESTRICTION);
return mapbox::util::get<InputWayRestriction>(node_or_way);
}
const InputWayRestriction &AsWayRestriction() const
{
BOOST_ASSERT(node_or_way.which() == RestrictionType::WAY_RESTRICTION);
return mapbox::util::get<InputWayRestriction>(node_or_way);
}
InputNodeRestriction &AsNodeRestriction()
{
BOOST_ASSERT(node_or_way.which() == RestrictionType::NODE_RESTRICTION);
return mapbox::util::get<InputNodeRestriction>(node_or_way);
}
const InputNodeRestriction &AsNodeRestriction() const
{
BOOST_ASSERT(node_or_way.which() == RestrictionType::NODE_RESTRICTION);
return mapbox::util::get<InputNodeRestriction>(node_or_way);
}
};
struct InputConditionalTurnRestriction : InputTurnRestriction
{
std::vector<util::OpeningHours> condition;
};
// OSRM manages restrictions based on node IDs which refer to the last node along the edge. Note
// that this has the side-effect of not allowing parallel edges!
struct NodeRestriction
{
NodeID from;
NodeID via;
NodeID to;
// check if all parts of the restriction reference an actual node
bool Valid() const
{
return from != SPECIAL_NODEID && to != SPECIAL_NODEID && via != SPECIAL_NODEID;
};
bool operator==(const NodeRestriction &other) const
{
return std::tie(from, via, to) == std::tie(other.from, other.via, other.to);
}
};
// A way restriction in the context of OSRM requires translation into NodeIDs. This is due to the
// compression happening in the graph creation process which would make it difficult to track
// way-ids over a series of operations. Having access to the nodes directly allows look-up of the
// edges in the processed structures
struct WayRestriction
{
// a way restriction in OSRM is essentially a dual node turn restriction;
//
// | |
// c -x- b
// | |
// d a
//
// from ab via bxc to cd: no_uturn
//
// Technically, we would need only a,b,c,d to describe the full turn in terms of nodes. When
// parsing the relation, though, we do not know about the final representation in the node-based
// graph for the restriction. In case of a traffic light, for example, we might end up with bxc
// not being compressed to bc. For that reason, we need to maintain two node restrictions in
// case a way restrction is not fully collapsed
NodeRestriction in_restriction;
NodeRestriction out_restriction;
bool operator==(const WayRestriction &other) const
{
return std::tie(in_restriction, out_restriction) ==
std::tie(other.in_restriction, other.out_restriction);
}
};
// Wrapper for turn restrictions that gives more information on its type / handles the switch
// between node/way/multi-way restrictions
struct TurnRestriction
{
union WayOrNode {
OSMNodeID_weak node;
OSMEdgeID_weak way;
};
WayOrNode via;
WayOrNode from;
WayOrNode to;
// keep in the same order as the turn restrictions above
mapbox::util::variant<NodeRestriction, WayRestriction> node_or_way;
bool is_only;
std::vector<util::OpeningHours> condition;
// construction for NodeRestrictions
explicit TurnRestriction(NodeRestriction node_restriction, bool is_only = false)
: node_or_way(node_restriction), is_only(is_only)
{
}
struct Bits
{ // mostly unused
Bits()
: is_only(false), uses_via_way(false), unused2(false), unused3(false), unused4(false),
unused5(false), unused6(false), unused7(false)
// construction for WayRestrictions
explicit TurnRestriction(WayRestriction way_restriction, bool is_only = false)
: node_or_way(way_restriction), is_only(is_only)
{
}
explicit TurnRestriction()
{
node_or_way = NodeRestriction{SPECIAL_EDGEID, SPECIAL_NODEID, SPECIAL_EDGEID};
}
WayRestriction &AsWayRestriction()
{
BOOST_ASSERT(node_or_way.which() == RestrictionType::WAY_RESTRICTION);
return mapbox::util::get<WayRestriction>(node_or_way);
}
const WayRestriction &AsWayRestriction() const
{
BOOST_ASSERT(node_or_way.which() == RestrictionType::WAY_RESTRICTION);
return mapbox::util::get<WayRestriction>(node_or_way);
}
NodeRestriction &AsNodeRestriction()
{
BOOST_ASSERT(node_or_way.which() == RestrictionType::NODE_RESTRICTION);
return mapbox::util::get<NodeRestriction>(node_or_way);
}
const NodeRestriction &AsNodeRestriction() const
{
BOOST_ASSERT(node_or_way.which() == RestrictionType::NODE_RESTRICTION);
return mapbox::util::get<NodeRestriction>(node_or_way);
}
RestrictionType Type() const
{
BOOST_ASSERT(node_or_way.which() < RestrictionType::NUM_RESTRICTION_TYPES);
return static_cast<RestrictionType>(node_or_way.which());
}
// check if all elements of the edge are considered valid
bool Valid() const
{
if (node_or_way.which() == RestrictionType::WAY_RESTRICTION)
{
auto const &restriction = AsWayRestriction();
return restriction.in_restriction.Valid() && restriction.out_restriction.Valid();
}
else
{
auto const &restriction = AsNodeRestriction();
return restriction.Valid();
}
bool is_only : 1;
bool uses_via_way : 1;
bool unused2 : 1;
bool unused3 : 1;
bool unused4 : 1;
bool unused5 : 1;
bool unused6 : 1;
bool unused7 : 1;
} flags;
explicit TurnRestriction(NodeID node)
{
via.node = node;
from.node = SPECIAL_NODEID;
to.node = SPECIAL_NODEID;
}
explicit TurnRestriction(const bool is_only = false)
bool operator==(const TurnRestriction &other) const
{
via.node = SPECIAL_NODEID;
from.node = SPECIAL_NODEID;
to.node = SPECIAL_NODEID;
flags.is_only = is_only;
if (is_only != other.is_only)
return false;
if (Type() != other.Type())
return false;
if (Type() == RestrictionType::WAY_RESTRICTION)
{
return AsWayRestriction() == other.AsWayRestriction();
}
else
{
return AsNodeRestriction() == other.AsNodeRestriction();
}
}
};
/**
* This is just a wrapper around TurnRestriction used in the extractor.
*
* Could be merged with TurnRestriction. For now the type-destiction makes sense
* as the format in which the restriction is presented in the extractor and in the
* preprocessing is different. (see restriction_parser.cpp)
*/
struct InputRestrictionContainer
struct ConditionalTurnRestriction : TurnRestriction
{
TurnRestriction restriction;
InputRestrictionContainer(EdgeID fromWay, EdgeID toWay, EdgeID vw)
{
restriction.from.way = fromWay;
restriction.to.way = toWay;
restriction.via.way = vw;
}
explicit InputRestrictionContainer(bool is_only = false)
{
restriction.from.way = SPECIAL_EDGEID;
restriction.to.way = SPECIAL_EDGEID;
restriction.via.node = SPECIAL_NODEID;
restriction.flags.is_only = is_only;
}
static InputRestrictionContainer min_value() { return InputRestrictionContainer(0, 0, 0); }
static InputRestrictionContainer max_value()
{
return InputRestrictionContainer(SPECIAL_EDGEID, SPECIAL_EDGEID, SPECIAL_EDGEID);
}
};
struct CmpRestrictionContainerByFrom
{
using value_type = InputRestrictionContainer;
bool operator()(const InputRestrictionContainer &a, const InputRestrictionContainer &b) const
{
return a.restriction.from.way < b.restriction.from.way;
}
value_type max_value() const { return InputRestrictionContainer::max_value(); }
value_type min_value() const { return InputRestrictionContainer::min_value(); }
};
struct CmpRestrictionContainerByTo
{
using value_type = InputRestrictionContainer;
bool operator()(const InputRestrictionContainer &a, const InputRestrictionContainer &b) const
{
return a.restriction.to.way < b.restriction.to.way;
}
value_type max_value() const { return InputRestrictionContainer::max_value(); }
value_type min_value() const { return InputRestrictionContainer::min_value(); }
std::vector<util::OpeningHours> condition;
};
}
}
@@ -0,0 +1,46 @@
#ifndef OSRM_EXTRACTOR_RESTRICTION_COMPRESSOR_HPP_
#define OSRM_EXTRACTOR_RESTRICTION_COMPRESSOR_HPP_
#include "util/typedefs.hpp"
#include <boost/unordered_map.hpp>
#include <vector>
namespace osrm
{
namespace extractor
{
struct NodeRestriction;
struct TurnRestriction;
// OSRM stores restrictions in the form node -> node -> node instead of way -> node -> way (or
// way->way->way) as it is done in OSM. These restrictions need to match the state of graph
// compression which we perform in the graph compressor that removes certain degree two nodes from
// the graph (all but the ones with penalties/barriers, as of the state of writing).
// Since this graph compression ins performed after creating the restrictions in the extraction
// phase, we need to update the involved nodes whenever one of the nodes is compressed.
//
//
// !!!! Will bind to the restrictions vector and modify it in-place !!!!
class RestrictionCompressor
{
public:
RestrictionCompressor(std::vector<TurnRestriction> &restrictions);
// account for the compression of `from-via-to` into `from-to`
void Compress(const NodeID from, const NodeID via, const NodeID to);
private:
// a turn restriction is given as `from star via node to end`. Edges ending at `head` being
// contracted move the head pointer to their respective head. Edges starting at tail move the
// tail values to their respective tails. Way turn restrictions are represented by two
// node-restrictions, so we can focus on them alone
boost::unordered_multimap<NodeID, NodeRestriction *> starts;
boost::unordered_multimap<NodeID, NodeRestriction *> ends;
};
} // namespace extractor
} // namespace osrm
#endif // OSRM_EXTRACTOR_RESTRICTION_COMPRESSOR_HPP_
+23
View File
@@ -0,0 +1,23 @@
#ifndef OSRM_EXTRACTOR_RESTRICTION_FILTER_HPP_
#define OSRM_EXTRACTOR_RESTRICTION_FILTER_HPP_
#include "extractor/restriction.hpp"
#include "util/node_based_graph.hpp"
#include <vector>
namespace osrm
{
namespace extractor
{
// To avoid handling invalid restrictions / creating unnecessary duplicate nodes for via-ways, we do
// a pre-flight check for restrictions and remove all invalid restrictions from the data. Use as
// `restrictions = removeInvalidRestrictions(std::move(restrictions))`
std::vector<TurnRestriction> removeInvalidRestrictions(std::vector<TurnRestriction>,
const util::NodeBasedDynamicGraph &);
} // namespace extractor
} // namespace osrm
#endif // OSRM_EXTRACTOR_RESTRICTION_FILTER_HPP_
-53
View File
@@ -79,61 +79,8 @@ class RestrictionMap
RestrictionMap() : m_count(0) {}
RestrictionMap(const std::vector<TurnRestriction> &restriction_list);
// Replace end v with w in each turn restriction containing u as via node
template <class GraphT>
void FixupArrivingTurnRestriction(const NodeID node_u,
const NodeID node_v,
const NodeID node_w,
const GraphT &graph)
{
BOOST_ASSERT(node_u != SPECIAL_NODEID);
BOOST_ASSERT(node_v != SPECIAL_NODEID);
BOOST_ASSERT(node_w != SPECIAL_NODEID);
if (!IsViaNode(node_u))
{
return;
}
// find all potential start edges. It is more efficient to get a (small) list
// of potential start edges than iterating over all buckets
std::vector<NodeID> predecessors;
for (const EdgeID current_edge_id : graph.GetAdjacentEdgeRange(node_u))
{
const NodeID target = graph.GetTarget(current_edge_id);
if (node_v != target)
{
predecessors.push_back(target);
}
}
for (const NodeID node_x : predecessors)
{
const auto restriction_iterator = m_restriction_map.find({node_x, node_u});
if (restriction_iterator == m_restriction_map.end())
{
continue;
}
const unsigned index = restriction_iterator->second;
auto &bucket = m_restriction_bucket_list.at(index);
for (RestrictionTarget &restriction_target : bucket)
{
if (node_v == restriction_target.target_node)
{
restriction_target.target_node = node_w;
}
}
}
}
bool IsViaNode(const NodeID node) const;
// Replaces start edge (v, w) with (u, w). Only start node changes.
void
FixupStartingTurnRestriction(const NodeID node_u, const NodeID node_v, const NodeID node_w);
// Check if edge (u, v) is the start of any turn restriction.
// If so returns id of first target node.
NodeID CheckForEmanatingIsOnlyTurn(const NodeID node_u, const NodeID node_v) const;
+2 -1
View File
@@ -44,7 +44,8 @@ class RestrictionParser
RestrictionParser(bool use_turn_restrictions,
bool parse_conditionals,
std::vector<std::string> &restrictions);
std::vector<InputRestrictionContainer> TryParse(const osmium::Relation &relation) const;
boost::optional<InputConditionalTurnRestriction>
TryParse(const osmium::Relation &relation) const;
private:
bool ShouldIgnoreRestriction(const std::string &except_tag_string) const;
+6 -7
View File
@@ -54,16 +54,15 @@ class ScriptingEnvironment
virtual std::vector<std::string> GetNameSuffixList() = 0;
virtual std::vector<std::string> GetRestrictions() = 0;
virtual void SetupSources() = 0;
virtual void ProcessTurn(ExtractionTurn &turn) = 0;
virtual void ProcessSegment(ExtractionSegment &segment) = 0;
virtual void ProcessElements(
const osmium::memory::Buffer &buffer,
const RestrictionParser &restriction_parser,
std::vector<std::pair<const osmium::Node &, ExtractionNode>> &resulting_nodes,
std::vector<std::pair<const osmium::Way &, ExtractionWay>> &resulting_ways,
std::vector<boost::optional<InputRestrictionContainer>> &resulting_restrictions) = 0;
virtual void
ProcessElements(const osmium::memory::Buffer &buffer,
const RestrictionParser &restriction_parser,
std::vector<std::pair<const osmium::Node &, ExtractionNode>> &resulting_nodes,
std::vector<std::pair<const osmium::Way &, ExtractionWay>> &resulting_ways,
std::vector<InputConditionalTurnRestriction> &resulting_restrictions) = 0;
};
}
}
@@ -23,7 +23,7 @@ struct LuaScriptingContext final
void ProcessWay(const osmium::Way &, ExtractionWay &result);
ProfileProperties properties;
SourceContainer sources;
RasterContainer raster_sources;
sol::state state;
bool has_turn_penalty_function;
@@ -37,6 +37,7 @@ struct LuaScriptingContext final
sol::function segment_function;
int api_version;
sol::table profile_table;
};
/**
@@ -50,7 +51,7 @@ class Sol2ScriptingEnvironment final : public ScriptingEnvironment
{
public:
static const constexpr int SUPPORTED_MIN_API_VERSION = 0;
static const constexpr int SUPPORTED_MAX_API_VERSION = 1;
static const constexpr int SUPPORTED_MAX_API_VERSION = 2;
explicit Sol2ScriptingEnvironment(const std::string &file_name);
~Sol2ScriptingEnvironment() override = default;
@@ -59,18 +60,19 @@ class Sol2ScriptingEnvironment final : public ScriptingEnvironment
LuaScriptingContext &GetSol2Context();
std::vector<std::string> GetStringListFromTable(const std::string &table_name);
std::vector<std::string> GetStringListFromFunction(const std::string &function_name);
std::vector<std::string> GetNameSuffixList() override;
std::vector<std::string> GetRestrictions() override;
void SetupSources() override;
void ProcessTurn(ExtractionTurn &turn) override;
void ProcessSegment(ExtractionSegment &segment) override;
void ProcessElements(
const osmium::memory::Buffer &buffer,
const RestrictionParser &restriction_parser,
std::vector<std::pair<const osmium::Node &, ExtractionNode>> &resulting_nodes,
std::vector<std::pair<const osmium::Way &, ExtractionWay>> &resulting_ways,
std::vector<boost::optional<InputRestrictionContainer>> &resulting_restrictions) override;
void
ProcessElements(const osmium::memory::Buffer &buffer,
const RestrictionParser &restriction_parser,
std::vector<std::pair<const osmium::Node &, ExtractionNode>> &resulting_nodes,
std::vector<std::pair<const osmium::Way &, ExtractionWay>> &resulting_ways,
std::vector<InputConditionalTurnRestriction> &resulting_restrictions) override;
private:
void InitContext(LuaScriptingContext &context);
+15 -11
View File
@@ -55,6 +55,7 @@ template <storage::Ownership Ownership> class SegmentDataContainerImpl
using SegmentOffset = std::uint32_t;
using SegmentWeightVector = PackedVector<SegmentWeight, SEGMENT_WEIGHT_BITS>;
using SegmentDurationVector = PackedVector<SegmentDuration, SEGMENT_DURAITON_BITS>;
using SegmentDatasourceVector = Vector<DatasourceID>;
SegmentDataContainerImpl() = default;
@@ -64,10 +65,12 @@ template <storage::Ownership Ownership> class SegmentDataContainerImpl
SegmentWeightVector rev_weights_,
SegmentDurationVector fwd_durations_,
SegmentDurationVector rev_durations_,
Vector<DatasourceID> datasources_)
SegmentDatasourceVector fwd_datasources_,
SegmentDatasourceVector rev_datasources_)
: index(std::move(index_)), nodes(std::move(nodes_)), fwd_weights(std::move(fwd_weights_)),
rev_weights(std::move(rev_weights_)), fwd_durations(std::move(fwd_durations_)),
rev_durations(std::move(rev_durations_)), datasources(std::move(datasources_))
rev_durations(std::move(rev_durations_)), fwd_datasources(std::move(fwd_datasources_)),
rev_datasources(std::move(rev_datasources_))
{
}
@@ -118,16 +121,16 @@ template <storage::Ownership Ownership> class SegmentDataContainerImpl
auto GetForwardDatasources(const DirectionalGeometryID id)
{
const auto begin = datasources.begin() + index[id] + 1;
const auto end = datasources.begin() + index[id + 1];
const auto begin = fwd_datasources.begin() + index[id] + 1;
const auto end = fwd_datasources.begin() + index[id + 1];
return boost::make_iterator_range(begin, end);
}
auto GetReverseDatasources(const DirectionalGeometryID id)
{
const auto begin = datasources.begin() + index[id];
const auto end = datasources.begin() + index[id + 1] - 1;
const auto begin = rev_datasources.begin() + index[id];
const auto end = rev_datasources.begin() + index[id + 1] - 1;
return boost::adaptors::reverse(boost::make_iterator_range(begin, end));
}
@@ -179,16 +182,16 @@ template <storage::Ownership Ownership> class SegmentDataContainerImpl
auto GetForwardDatasources(const DirectionalGeometryID id) const
{
const auto begin = datasources.cbegin() + index[id] + 1;
const auto end = datasources.cbegin() + index[id + 1];
const auto begin = fwd_datasources.cbegin() + index[id] + 1;
const auto end = fwd_datasources.cbegin() + index[id + 1];
return boost::make_iterator_range(begin, end);
}
auto GetReverseDatasources(const DirectionalGeometryID id) const
{
const auto begin = datasources.cbegin() + index[id];
const auto end = datasources.cbegin() + index[id + 1] - 1;
const auto begin = rev_datasources.cbegin() + index[id];
const auto end = rev_datasources.cbegin() + index[id + 1] - 1;
return boost::adaptors::reverse(boost::make_iterator_range(begin, end));
}
@@ -210,7 +213,8 @@ template <storage::Ownership Ownership> class SegmentDataContainerImpl
SegmentWeightVector rev_weights;
SegmentDurationVector fwd_durations;
SegmentDurationVector rev_durations;
Vector<DatasourceID> datasources;
SegmentDatasourceVector fwd_datasources;
SegmentDatasourceVector rev_datasources;
};
}
+124 -30
View File
@@ -74,7 +74,8 @@ inline void read(storage::io::FileReader &reader,
util::serialization::read(reader, segment_data.rev_weights);
util::serialization::read(reader, segment_data.fwd_durations);
util::serialization::read(reader, segment_data.rev_durations);
storage::serialization::read(reader, segment_data.datasources);
storage::serialization::read(reader, segment_data.fwd_datasources);
storage::serialization::read(reader, segment_data.rev_datasources);
}
template <storage::Ownership Ownership>
@@ -87,7 +88,8 @@ inline void write(storage::io::FileWriter &writer,
util::serialization::write(writer, segment_data.rev_weights);
util::serialization::write(writer, segment_data.fwd_durations);
util::serialization::write(writer, segment_data.rev_durations);
storage::serialization::write(writer, segment_data.datasources);
storage::serialization::write(writer, segment_data.fwd_datasources);
storage::serialization::write(writer, segment_data.rev_datasources);
}
// read/write for turn data file
@@ -135,41 +137,71 @@ inline void write(storage::io::FileWriter &writer,
storage::serialization::write(writer, node_data_container.classes);
}
// read/write for conditional turn restrictions file
inline void read(storage::io::FileReader &reader, std::vector<TurnRestriction> &restrictions)
inline void read(storage::io::FileReader &reader, NodeRestriction &restriction)
{
auto num_indices = reader.ReadElementCount64();
restrictions.reserve(num_indices);
TurnRestriction restriction;
while (num_indices > 0)
{
bool is_only;
reader.ReadInto(restriction.via);
reader.ReadInto(restriction.from);
reader.ReadInto(restriction.to);
reader.ReadInto(is_only);
auto num_conditions = reader.ReadElementCount64();
restriction.condition.resize(num_conditions);
for (uint64_t i = 0; i < num_conditions; i++)
{
reader.ReadInto(restriction.condition[i].modifier);
storage::serialization::read(reader, restriction.condition[i].times);
storage::serialization::read(reader, restriction.condition[i].weekdays);
storage::serialization::read(reader, restriction.condition[i].monthdays);
}
restriction.flags.is_only = is_only;
reader.ReadInto(restriction.from);
reader.ReadInto(restriction.via);
reader.ReadInto(restriction.to);
}
restrictions.push_back(std::move(restriction));
num_indices--;
inline void write(storage::io::FileWriter &writer, const NodeRestriction &restriction)
{
writer.WriteOne(restriction.from);
writer.WriteOne(restriction.via);
writer.WriteOne(restriction.to);
}
inline void read(storage::io::FileReader &reader, WayRestriction &restriction)
{
read(reader, restriction.in_restriction);
read(reader, restriction.out_restriction);
}
inline void write(storage::io::FileWriter &writer, const WayRestriction &restriction)
{
write(writer, restriction.in_restriction);
write(writer, restriction.out_restriction);
}
inline void read(storage::io::FileReader &reader, TurnRestriction &restriction)
{
reader.ReadInto(restriction.is_only);
std::uint32_t restriction_type;
reader.ReadInto(restriction_type);
if (restriction_type == RestrictionType::WAY_RESTRICTION)
{
WayRestriction way_restriction;
read(reader, way_restriction);
restriction.node_or_way = std::move(way_restriction);
}
else
{
BOOST_ASSERT(restriction_type == RestrictionType::NODE_RESTRICTION);
NodeRestriction node_restriction;
read(reader, node_restriction);
restriction.node_or_way = std::move(node_restriction);
}
}
inline void write(storage::io::FileWriter &writer, const TurnRestriction &restriction)
{
writer.WriteOne(restriction.via);
writer.WriteOne(restriction.from);
writer.WriteOne(restriction.to);
writer.WriteOne(restriction.flags.is_only);
writer.WriteOne(restriction.is_only);
const std::uint32_t restriction_type = restriction.Type();
writer.WriteOne(restriction_type);
if (restriction.Type() == RestrictionType::WAY_RESTRICTION)
{
write(writer, mapbox::util::get<WayRestriction>(restriction.node_or_way));
}
else
{
BOOST_ASSERT(restriction.Type() == RestrictionType::NODE_RESTRICTION);
write(writer, mapbox::util::get<NodeRestriction>(restriction.node_or_way));
}
}
inline void write(storage::io::FileWriter &writer, const ConditionalTurnRestriction &restriction)
{
write(writer, static_cast<const TurnRestriction &>(restriction));
writer.WriteElementCount64(restriction.condition.size());
for (const auto &c : restriction.condition)
{
@@ -179,6 +211,68 @@ inline void write(storage::io::FileWriter &writer, const TurnRestriction &restri
storage::serialization::write(writer, c.monthdays);
}
}
inline void read(storage::io::FileReader &reader, ConditionalTurnRestriction &restriction)
{
read(reader, static_cast<TurnRestriction &>(restriction));
const auto num_conditions = reader.ReadElementCount64();
restriction.condition.resize(num_conditions);
for (uint64_t i = 0; i < num_conditions; i++)
{
reader.ReadInto(restriction.condition[i].modifier);
storage::serialization::read(reader, restriction.condition[i].times);
storage::serialization::read(reader, restriction.condition[i].weekdays);
storage::serialization::read(reader, restriction.condition[i].monthdays);
}
}
// read/write for conditional turn restrictions file
inline void read(storage::io::FileReader &reader, std::vector<TurnRestriction> &restrictions)
{
auto num_indices = reader.ReadElementCount64();
restrictions.reserve(num_indices);
TurnRestriction restriction;
while (num_indices-- > 0)
{
read(reader, restriction);
restrictions.push_back(std::move(restriction));
}
}
inline void write(storage::io::FileWriter &writer, const std::vector<TurnRestriction> &restrictions)
{
const auto num_indices = restrictions.size();
writer.WriteElementCount64(num_indices);
const auto write_restriction = [&writer](const auto &restriction) {
write(writer, restriction);
};
std::for_each(restrictions.begin(), restrictions.end(), write_restriction);
}
// read/write for conditional turn restrictions file
inline void read(storage::io::FileReader &reader,
std::vector<ConditionalTurnRestriction> &restrictions)
{
auto num_indices = reader.ReadElementCount64();
restrictions.reserve(num_indices);
ConditionalTurnRestriction restriction;
while (num_indices-- > 0)
{
read(reader, restriction);
restrictions.push_back(std::move(restriction));
}
}
inline void write(storage::io::FileWriter &writer,
const std::vector<ConditionalTurnRestriction> &restrictions)
{
const auto num_indices = restrictions.size();
writer.WriteElementCount64(num_indices);
const auto write_restriction = [&writer](const auto &restriction) {
write(writer, restriction);
};
std::for_each(restrictions.begin(), restrictions.end(), write_restriction);
}
}
}
}
+89
View File
@@ -0,0 +1,89 @@
#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 "util/integer_range.hpp"
#include "util/typedefs.hpp"
// Given the compressed representation of via-way turn restrictions, we provide a fast access into
// the restrictions to indicate which turns may be restricted due to a way in between
namespace osrm
{
namespace extractor
{
class WayRestrictionMap
{
public:
struct ViaWay
{
NodeID from;
NodeID to;
};
WayRestrictionMap(const std::vector<TurnRestriction> &turn_restrictions);
// Check if an edge between two nodes is a restricted turn. The check needs to be performed to
// find duplicated nodes during the creation of edge-based-edges
bool IsViaWay(const NodeID from, const NodeID to) const;
// Every via-way results in a duplicated node that is required in the edge-based-graph. This
// count is essentially the same as the number of valid via-way restrictions (except for
// non-only restrictions that share the same in/via combination)
std::size_t NumberOfDuplicatedNodes() const;
// Returns a representative for each duplicated node, consisting of the representative ID (first
// ID of the nodes restrictions) and the from/to vertices of the via-way
// This is used to construct edge based nodes that act as intermediate nodes.
std::vector<ViaWay> DuplicatedNodeRepresentatives() const;
// Access all duplicated NodeIDs for a set of nodes indicating a via way
util::range<DuplicatedNodeID> DuplicatedNodeIDs(const NodeID from, const NodeID to) const;
// check whether a turn onto a given node is restricted, when coming from a duplicated node
bool IsRestricted(DuplicatedNodeID duplicated_node, const NodeID to) const;
// changes edge_based_node to the correct duplicated_node_id in case node_based_from,
// node_based_via, node_based_to can be identified with a restriction group
NodeID RemapIfRestricted(const NodeID edge_based_node,
const NodeID node_based_from,
const NodeID node_based_via,
const NodeID node_based_to,
const NodeID number_of_edge_based_nodes) const;
private:
DuplicatedNodeID AsDuplicatedNodeID(const RestrictionID restriction_id) const;
// access all restrictions that have the same starting way and via way. Any duplicated node
// represents the same in-way + via-way combination. This vector contains data about all
// restrictions and their assigned duplicated nodes. It indicates the minimum restriciton ID
// that is represented by the next node. The ID of a node is defined as the position of the
// lower bound of the restrictions ID within this array
//
// a - b
// |
// y - c - x
//
// restriction nodes | restriction id
// a - b - c - x : 5
// a - b - c - y : 6
//
// EBN: 0 . | 2 | 3 | 4 ...
// duplicated node groups: ... | 5 | 7 | ...
std::vector<DuplicatedNodeID> duplicated_node_groups;
boost::unordered_multimap<std::pair<NodeID, NodeID>, RestrictionID> restriction_starts;
boost::unordered_multimap<std::pair<NodeID, NodeID>, RestrictionID> restriction_ends;
std::vector<TurnRestriction> restriction_data;
};
} // namespace extractor
} // namespace osrm
#endif // OSRM_EXTRACTOR_WAY_RESTRICTION_MAP_HPP_
+11 -36
View File
@@ -6,56 +6,31 @@
#include <array>
#include <string>
#include "storage/io_config.hpp"
namespace osrm
{
namespace partition
{
struct PartitionConfig
struct PartitionConfig final : storage::IOConfig
{
PartitionConfig()
: requested_num_threads(0), balance(1.2), boundary_factor(0.25), num_optimizing_cuts(10),
: IOConfig(
{".osrm", ".osrm.fileIndex", ".osrm.ebg_nodes"},
{".osrm.hsgr", ".osrm.cnbg"},
{".osrm.ebg", ".osrm.cnbg", ".osrm.cnbg_to_ebg", ".osrm.partition", ".osrm.cells"}),
requested_num_threads(0), balance(1.2), boundary_factor(0.25), num_optimizing_cuts(10),
small_component_size(1000),
max_cell_sizes{128, 128 * 32, 128 * 32 * 16, 128 * 32 * 16 * 32}
max_cell_sizes({128, 128 * 32, 128 * 32 * 16, 128 * 32 * 16 * 32})
{
}
void UseDefaults()
void UseDefaultOutputNames(const boost::filesystem::path &base)
{
std::string basepath = base_path.string();
const std::string ext = ".osrm";
const auto pos = basepath.find(ext);
if (pos != std::string::npos)
{
basepath.replace(pos, ext.size(), "");
}
else
{
// unknown extension
}
edge_based_graph_path = basepath + ".osrm.ebg";
compressed_node_based_graph_path = basepath + ".osrm.cnbg";
cnbg_ebg_mapping_path = basepath + ".osrm.cnbg_to_ebg";
file_index_path = basepath + ".osrm.fileIndex";
partition_path = basepath + ".osrm.partition";
storage_path = basepath + ".osrm.cells";
node_data_path = basepath + ".osrm.ebg_nodes";
hsgr_path = basepath + ".osrm.hsgr";
IOConfig::UseDefaultOutputNames(base);
}
// might be changed to the node based graph at some point
boost::filesystem::path base_path;
boost::filesystem::path edge_based_graph_path;
boost::filesystem::path compressed_node_based_graph_path;
boost::filesystem::path cnbg_ebg_mapping_path;
boost::filesystem::path partition_path;
boost::filesystem::path file_index_path;
boost::filesystem::path storage_path;
boost::filesystem::path node_data_path;
boost::filesystem::path hsgr_path;
unsigned requested_num_threads;
double balance;
+85
View File
@@ -0,0 +1,85 @@
#ifndef OSRM_IO_CONFIG_HPP
#define OSRM_IO_CONFIG_HPP
#include "util/exception.hpp"
#include <array>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/path.hpp>
#include <string>
namespace osrm
{
namespace storage
{
struct IOConfig
{
IOConfig(std::vector<boost::filesystem::path> required_input_files_,
std::vector<boost::filesystem::path> optional_input_files_,
std::vector<boost::filesystem::path> output_files_)
: required_input_files(required_input_files_), optional_input_files(optional_input_files_),
output_files(output_files_)
{
}
bool IsValid() const;
boost::filesystem::path GetPath(const std::string &fileName) const
{
if (!IsConfigured(fileName, required_input_files) &&
!IsConfigured(fileName, optional_input_files) && !IsConfigured(fileName, output_files))
{
throw util::exception("Tried to access file which is not configured: " + fileName);
}
return {base_path.string() + fileName};
}
boost::filesystem::path base_path;
protected:
// Infer the base path from the path of the .osrm file
void UseDefaultOutputNames(const boost::filesystem::path &base)
{
// potentially strip off the .osrm (or other) extensions for
// determining the base path=
std::string path = base.string();
std::array<std::string, 6> known_extensions{
{".osm.bz2", ".osm.pbf", ".osm.xml", ".pbf", ".osm", ".osrm"}};
for (auto ext : known_extensions)
{
const auto pos = path.find(ext);
if (pos != std::string::npos)
{
path.replace(pos, ext.size(), "");
break;
}
}
base_path = {path};
}
private:
static bool IsConfigured(const std::string &fileName,
const std::vector<boost::filesystem::path> &paths)
{
for (auto &path : paths)
{
if (boost::algorithm::ends_with(path.string(), fileName))
{
return true;
}
}
return false;
}
std::vector<boost::filesystem::path> required_input_files;
std::vector<boost::filesystem::path> optional_input_files;
std::vector<boost::filesystem::path> output_files;
};
}
}
#endif
+4 -2
View File
@@ -38,11 +38,12 @@ const constexpr char *block_id_to_name[] = {"NAME_CHAR_DATA",
"GEOMETRIES_REV_WEIGHT_LIST",
"GEOMETRIES_FWD_DURATION_LIST",
"GEOMETRIES_REV_DURATION_LIST",
"GEOMETRIES_FWD_DATASOURCES_LIST",
"GEOMETRIES_REV_DATASOURCES_LIST",
"HSGR_CHECKSUM",
"TIMESTAMP",
"FILE_INDEX_PATH",
"CH_CORE_MARKER",
"DATASOURCES_LIST",
"DATASOURCES_NAMES",
"PROPERTIES",
"BEARING_CLASSID",
@@ -95,11 +96,12 @@ struct DataLayout
GEOMETRIES_REV_WEIGHT_LIST,
GEOMETRIES_FWD_DURATION_LIST,
GEOMETRIES_REV_DURATION_LIST,
GEOMETRIES_FWD_DATASOURCES_LIST,
GEOMETRIES_REV_DATASOURCES_LIST,
HSGR_CHECKSUM,
TIMESTAMP,
FILE_INDEX_PATH,
CH_CORE_MARKER,
DATASOURCES_LIST,
DATASOURCES_NAMES,
PROPERTIES,
BEARING_CLASSID,
+31 -31
View File
@@ -30,6 +30,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/filesystem/path.hpp>
#include "storage/io_config.hpp"
namespace osrm
{
namespace storage
@@ -40,39 +42,37 @@ namespace storage
*
* \see OSRM, EngineConfig
*/
struct StorageConfig final
struct StorageConfig final : IOConfig
{
StorageConfig() = default;
StorageConfig(const boost::filesystem::path &base) : StorageConfig()
{
IOConfig::UseDefaultOutputNames(base);
}
/**
* Constructs a storage configuration setting paths based on a base path.
*
* \param base The base path (e.g. france.pbf.osrm) to derive auxiliary file suffixes from.
*/
StorageConfig(const boost::filesystem::path &base);
bool IsValid() const;
boost::filesystem::path ram_index_path;
boost::filesystem::path file_index_path;
boost::filesystem::path hsgr_data_path;
boost::filesystem::path node_based_nodes_data_path;
boost::filesystem::path edge_based_nodes_data_path;
boost::filesystem::path edges_data_path;
boost::filesystem::path core_data_path;
boost::filesystem::path geometries_path;
boost::filesystem::path timestamp_path;
boost::filesystem::path turn_weight_penalties_path;
boost::filesystem::path turn_duration_penalties_path;
boost::filesystem::path datasource_names_path;
boost::filesystem::path datasource_indexes_path;
boost::filesystem::path names_data_path;
boost::filesystem::path properties_path;
boost::filesystem::path intersection_class_path;
boost::filesystem::path turn_lane_data_path;
boost::filesystem::path turn_lane_description_path;
boost::filesystem::path mld_partition_path;
boost::filesystem::path mld_storage_path;
boost::filesystem::path mld_graph_path;
StorageConfig()
: IOConfig({".osrm.ramIndex",
".osrm.fileIndex",
".osrm.edges",
".osrm.geometry",
".osrm.timestamp",
".osrm.turn_weight_penalties",
".osrm.turn_duration_penalties",
".osrm.datasource_names",
".osrm.names",
".osrm.properties",
".osrm.icd"},
{".osrm.hsgr",
".osrm.nbg_nodes",
".osrm.ebg_nodes",
".osrm.core",
".osrm.cells",
".osrm.mldgr",
".osrm.tld",
".osrm.tls",
".osrm.partition"},
{})
{
}
};
}
}
+26 -30
View File
@@ -33,51 +33,47 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <chrono>
#include <string>
#include "storage/io_config.hpp"
#include "storage/storage_config.hpp"
namespace osrm
{
namespace updater
{
struct UpdaterConfig final
struct UpdaterConfig final : storage::IOConfig
{
// Infer the output names from the path of the .osrm file
void UseDefaultOutputNames()
UpdaterConfig()
: IOConfig(
{
".osrm.ebg",
".osrm.turn_weight_penalties",
".osrm.turn_duration_penalties",
".osrm.turn_penalties_index",
".osrm.nbg_nodes",
".osrm.ebg_nodes",
".osrm.edges",
".osrm.geometry",
".osrm.fileIndex",
".osrm.datasource_names",
".osrm.properties",
".osrm.restrictions",
},
{},
{})
{
edge_based_graph_path = osrm_input_path.string() + ".ebg";
turn_weight_penalties_path = osrm_input_path.string() + ".turn_weight_penalties";
turn_duration_penalties_path = osrm_input_path.string() + ".turn_duration_penalties";
turn_penalties_index_path = osrm_input_path.string() + ".turn_penalties_index";
node_based_nodes_data_path = osrm_input_path.string() + ".nbg_nodes";
edge_based_nodes_data_path = osrm_input_path.string() + ".ebg_nodes";
edge_data_path = osrm_input_path.string() + ".edges";
geometry_path = osrm_input_path.string() + ".geometry";
rtree_leaf_path = osrm_input_path.string() + ".fileIndex";
datasource_names_path = osrm_input_path.string() + ".datasource_names";
profile_properties_path = osrm_input_path.string() + ".properties";
turn_restrictions_path = osrm_input_path.string() + ".restrictions";
}
boost::filesystem::path osrm_input_path;
std::string edge_based_graph_path;
std::string turn_weight_penalties_path;
std::string turn_duration_penalties_path;
std::string turn_penalties_index_path;
std::string node_based_nodes_data_path;
std::string edge_based_nodes_data_path;
std::string edge_data_path;
std::string geometry_path;
std::string rtree_leaf_path;
void UseDefaultOutputNames(const boost::filesystem::path &base)
{
IOConfig::UseDefaultOutputNames(base);
}
double log_edge_updates_factor;
std::time_t valid_now;
std::vector<std::string> segment_speed_lookup_paths;
std::vector<std::string> turn_penalty_lookup_paths;
std::string datasource_names_path;
std::string profile_properties_path;
std::string turn_restrictions_path;
std::string tz_file_path;
};
}
+2 -1
View File
@@ -43,7 +43,8 @@ class EntryClass
// we are hiding the access to the flags behind a protection wall, to make sure the bit logic
// isn't tempered with. zero based indexing
void activate(std::uint32_t index);
// return true if was activated and false if activation failed
bool activate(std::uint32_t index);
// check whether a certain turn allows entry
bool allowsEntry(std::uint32_t index) const;
+1
View File
@@ -12,6 +12,7 @@ namespace util
{
// Helper classes for "opening hours" format http://wiki.openstreetmap.org/wiki/Key:opening_hours
// Grammar https://wiki.openstreetmap.org/wiki/Key:opening_hours/specification
// Supported simplified features in CheckOpeningHours:
// - Year/Month/Day ranges
// - Weekday ranges
+1 -1
View File
@@ -66,7 +66,7 @@ template <typename EdgeDataT>
inline void read(storage::io::FileReader &reader, DynamicGraph<EdgeDataT> &graph)
{
storage::serialization::read(reader, graph.node_array);
auto num_edges = reader.ReadElementCount64();
const auto num_edges = reader.ReadElementCount64();
graph.edge_list.resize(num_edges);
for (auto index : irange<std::size_t>(0, num_edges))
{
+15 -8
View File
@@ -45,22 +45,29 @@ struct osm_node_id
struct osm_way_id
{
};
struct duplicated_node
{
};
}
using OSMNodeID = osrm::Alias<std::uint64_t, tag::osm_node_id>;
static_assert(std::is_pod<OSMNodeID>(), "OSMNodeID is not a valid alias");
using OSMWayID = osrm::Alias<std::uint64_t, tag::osm_way_id>;
static_assert(std::is_pod<OSMWayID>(), "OSMWayID is not a valid alias");
static const OSMNodeID SPECIAL_OSM_NODEID = OSMNodeID{std::numeric_limits<std::uint64_t>::max()};
static const OSMWayID SPECIAL_OSM_WAYID = OSMWayID{std::numeric_limits<std::uint32_t>::max()};
using DuplicatedNodeID = std::uint64_t;
using RestrictionID = std::uint64_t;
static const OSMNodeID MAX_OSM_NODEID = OSMNodeID{std::numeric_limits<std::uint64_t>::max()};
static const OSMNodeID MIN_OSM_NODEID = OSMNodeID{std::numeric_limits<std::uint64_t>::min()};
static const OSMWayID MAX_OSM_WAYID = OSMWayID{std::numeric_limits<std::uint32_t>::max()};
static const OSMWayID MIN_OSM_WAYID = OSMWayID{std::numeric_limits<std::uint32_t>::min()};
static const OSMNodeID SPECIAL_OSM_NODEID =
OSMNodeID{std::numeric_limits<OSMNodeID::value_type>::max()};
static const OSMWayID SPECIAL_OSM_WAYID =
OSMWayID{std::numeric_limits<OSMWayID::value_type>::max()};
using OSMNodeID_weak = std::uint64_t;
using OSMEdgeID_weak = std::uint64_t;
static const OSMNodeID MAX_OSM_NODEID =
OSMNodeID{std::numeric_limits<OSMNodeID::value_type>::max()};
static const OSMNodeID MIN_OSM_NODEID =
OSMNodeID{std::numeric_limits<OSMNodeID::value_type>::min()};
static const OSMWayID MAX_OSM_WAYID = OSMWayID{std::numeric_limits<OSMWayID::value_type>::max()};
static const OSMWayID MIN_OSM_WAYID = OSMWayID{std::numeric_limits<OSMWayID::value_type>::min()};
using NodeID = std::uint32_t;
using EdgeID = std::uint32_t;
+3513 -1196
View File
File diff suppressed because it is too large Load Diff
+4 -3
View File
@@ -1,12 +1,12 @@
{
"name": "osrm",
"version": "5.9.2",
"version": "5.10.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": {
"nan": "^2.6.2",
"node-cmake": "^2.3.2",
"node-pre-gyp": "^0.6.34"
"node-pre-gyp": "^0.6.36"
},
"browserify": {
"transform": [
@@ -37,6 +37,7 @@
},
"devDependencies": {
"aws-sdk": "~2.0.31",
"babel-plugin-transform-class-properties": "^6.24.1",
"chalk": "^1.1.3",
"cucumber": "^1.2.1",
"d3-queue": "^2.0.3",
@@ -49,7 +50,7 @@
"polyline": "^0.2.0",
"request": "^2.69.0",
"rimraf": "^2.5.4",
"tape": "^4.2.2",
"tape": "^4.7.0",
"xmlbuilder": "^4.2.1"
},
"bundleDependencies": [
+240 -249
View File
@@ -1,205 +1,202 @@
api_version = 1
-- Bicycle profile
local find_access_tag = require("lib/access").find_access_tag
local Set = require('lib/set')
local Sequence = require('lib/sequence')
local Handlers = require("lib/handlers")
local next = next -- bind to local for speed
local limit = require("lib/maxspeed").limit
-- these need to be global because they are accesed externaly
properties.max_speed_for_map_matching = 110/3.6 -- kmph -> m/s
properties.use_turn_restrictions = false
properties.continue_straight_at_waypoint = false
properties.weight_name = 'duration'
--properties.weight_name = 'cyclability'
api_version = 2
-- Set to true if you need to call the node_function for every node.
-- Generally can be left as false to avoid unnecessary Lua calls
-- (which slow down pre-processing).
properties.call_tagless_node_function = false
Set = require('lib/set')
Sequence = require('lib/sequence')
Handlers = require("lib/way_handlers")
find_access_tag = require("lib/access").find_access_tag
limit = require("lib/maxspeed").limit
function setup()
local default_speed = 15
local walking_speed = 6
local default_speed = 15
local walking_speed = 6
return {
properties = {
u_turn_penalty = 20,
traffic_light_penalty = 2,
--weight_name = 'cyclability',
weight_name = 'duration',
process_call_tagless_node = false,
max_speed_for_map_matching = 110/3.6, -- kmph -> m/s
use_turn_restrictions = false,
continue_straight_at_waypoint = false
},
local profile = {
default_mode = mode.cycling,
default_speed = 15,
oneway_handling = true,
traffic_light_penalty = 2,
u_turn_penalty = 20,
turn_penalty = 6,
turn_bias = 1.4,
use_public_transport = true,
default_mode = mode.cycling,
default_speed = default_speed,
walking_speed = walking_speed,
oneway_handling = true,
turn_penalty = 6,
turn_bias = 1.4,
use_public_transport = true,
allowed_start_modes = Set {
mode.cycling,
mode.pushing_bike
},
allowed_start_modes = Set {
mode.cycling,
mode.pushing_bike
},
barrier_whitelist = Set {
'sump_buster',
'bus_trap',
'cycle_barrier',
'bollard',
'entrance',
'cattle_grid',
'border_control',
'toll_booth',
'sally_port',
'gate',
'no',
'block'
},
barrier_whitelist = Set {
'sump_buster',
'bus_trap',
'cycle_barrier',
'bollard',
'entrance',
'cattle_grid',
'border_control',
'toll_booth',
'sally_port',
'gate',
'no',
'block'
},
access_tag_whitelist = Set {
'yes',
'permissive',
'designated'
},
access_tag_whitelist = Set {
'yes',
'permissive',
'designated'
},
access_tag_blacklist = Set {
'no',
'private',
'agricultural',
'forestry',
'delivery'
},
access_tag_blacklist = Set {
'no',
'private',
'agricultural',
'forestry',
'delivery'
},
restricted_access_tag_list = Set { },
restricted_access_tag_list = Set { },
restricted_highway_whitelist = Set { },
restricted_highway_whitelist = Set { },
construction_whitelist = Set {
'no',
'widening',
'minor',
},
construction_whitelist = Set {
'no',
'widening',
'minor',
},
access_tags_hierarchy = Sequence {
'bicycle',
'vehicle',
'access'
},
access_tags_hierarchy = Sequence {
'bicycle',
'vehicle',
'access'
},
restrictions = Set {
'bicycle'
},
restrictions = Set {
'bicycle'
},
cycleway_tags = Set {
'track',
'lane',
'opposite',
'opposite_lane',
'opposite_track',
'share_busway',
'sharrow',
'shared',
'shared_lane'
},
cycleway_tags = Set {
'track',
'lane',
'opposite',
'opposite_lane',
'opposite_track',
'share_busway',
'sharrow',
'shared',
'shared_lane'
},
-- reduce the driving speed by 30% for unsafe roads
-- only used for cyclability metric
unsafe_highway_list = {
primary = 0.7,
secondary = 0.75,
tertiary = 0.8,
primary_link = 0.7,
secondary_link = 0.75,
tertiary_link = 0.8,
},
-- reduce the driving speed by 30% for unsafe roads
-- only used for cyclability metric
unsafe_highway_list = {
primary = 0.7,
secondary = 0.75,
tertiary = 0.8,
primary_link = 0.7,
secondary_link = 0.75,
tertiary_link = 0.8,
},
service_penalties = {
alley = 0.5,
},
service_penalties = {
alley = 0.5,
},
bicycle_speeds = {
cycleway = default_speed,
primary = default_speed,
primary_link = default_speed,
secondary = default_speed,
secondary_link = default_speed,
tertiary = default_speed,
tertiary_link = default_speed,
residential = default_speed,
unclassified = default_speed,
living_street = default_speed,
road = default_speed,
service = default_speed,
track = 12,
path = 12
},
bicycle_speeds = {
cycleway = default_speed,
primary = default_speed,
primary_link = default_speed,
secondary = default_speed,
secondary_link = default_speed,
tertiary = default_speed,
tertiary_link = default_speed,
residential = default_speed,
unclassified = default_speed,
living_street = default_speed,
road = default_speed,
service = default_speed,
track = 12,
path = 12
},
pedestrian_speeds = {
footway = walking_speed,
pedestrian = walking_speed,
steps = 2
},
pedestrian_speeds = {
footway = walking_speed,
pedestrian = walking_speed,
steps = 2
},
railway_speeds = {
train = 10,
railway = 10,
subway = 10,
light_rail = 10,
monorail = 10,
tram = 10
},
railway_speeds = {
train = 10,
railway = 10,
subway = 10,
light_rail = 10,
monorail = 10,
tram = 10
},
platform_speeds = {
platform = walking_speed
},
platform_speeds = {
platform = walking_speed
},
amenity_speeds = {
parking = 10,
parking_entrance = 10
},
amenity_speeds = {
parking = 10,
parking_entrance = 10
},
man_made_speeds = {
pier = walking_speed
},
man_made_speeds = {
pier = walking_speed
},
route_speeds = {
ferry = 5
},
route_speeds = {
ferry = 5
},
bridge_speeds = {
movable = 5
},
bridge_speeds = {
movable = 5
},
surface_speeds = {
asphalt = default_speed,
["cobblestone:flattened"] = 10,
paving_stones = 10,
compacted = 10,
cobblestone = 6,
unpaved = 6,
fine_gravel = 6,
gravel = 6,
pebblestone = 6,
ground = 6,
dirt = 6,
earth = 6,
grass = 6,
mud = 3,
sand = 3,
sett = 10
},
surface_speeds = {
asphalt = default_speed,
["cobblestone:flattened"] = 10,
paving_stones = 10,
compacted = 10,
cobblestone = 6,
unpaved = 6,
fine_gravel = 6,
gravel = 6,
pebblestone = 6,
ground = 6,
dirt = 6,
earth = 6,
grass = 6,
mud = 3,
sand = 3,
sett = 10
},
tracktype_speeds = {
},
tracktype_speeds = {
},
smoothness_speeds = {
},
smoothness_speeds = {
},
avoid = Set {
'impassable',
'construction',
'proposed'
avoid = Set {
'impassable',
'construction'
}
}
}
end
local function parse_maxspeed(source)
if not source then
@@ -215,13 +212,7 @@ local function parse_maxspeed(source)
return n
end
function get_restrictions(vector)
for i,v in ipairs(profile.restrictions) do
vector:Add(v)
end
end
function node_function (node, result)
function process_node(profile, node, result)
-- parse access and barrier tags
local highway = node:get_value_by_key("highway")
local is_crossing = highway and highway == "crossing"
@@ -249,41 +240,8 @@ function node_function (node, result)
end
end
function way_function (way, result)
-- the intial filtering of ways based on presence of tags
-- affects processing times significantly, because all ways
-- have to be checked.
-- to increase performance, prefetching and intial tag check
-- is done in directly instead of via a handler.
-- in general we should try to abort as soon as
-- possible if the way is not routable, to avoid doing
-- unnecessary work. this implies we should check things that
-- commonly forbids access early, and handle edge cases later.
-- data table for storing intermediate values during processing
local data = {
-- prefetch tags
highway = way:get_value_by_key('highway'),
}
local handlers = Sequence {
-- set the default mode for this profile. if can be changed later
-- in case it turns we're e.g. on a ferry
'handle_default_mode',
-- check various tags that could indicate that the way is not
-- routable. this includes things like status=impassable,
-- toll=yes and oneway=reversible
'handle_blocked_ways',
}
if Handlers.run(handlers,way,result,data,profile) == false then
return
end
-- initial routability check, filters out buildings, boundaries, etc
function handle_bicycle_tags(profile,way,result,data)
-- initial routability check, filters out buildings, boundaries, etc
local route = way:get_value_by_key("route")
local man_made = way:get_value_by_key("man_made")
local railway = way:get_value_by_key("railway")
@@ -299,13 +257,13 @@ function way_function (way, result)
(not public_transport or public_transport=='') and
(not bridge or bridge=='')
then
return
return false
end
-- access
local access = find_access_tag(way, profile.access_tags_hierarchy)
if access and profile.access_tag_blacklist[access] then
return
return false
end
-- other tags
@@ -377,8 +335,8 @@ function way_function (way, result)
way_type_allows_pushing = true
elseif access and profile.access_tag_whitelist[access] then
-- unknown way, but valid access tag
result.forward_speed = default_speed
result.backward_speed = default_speed
result.forward_speed = profile.default_speed
result.backward_speed = profile.default_speed
way_type_allows_pushing = true
end
@@ -453,18 +411,18 @@ function way_function (way, result)
push_backward_speed = profile.man_made_speeds[man_made]
else
if foot == 'yes' then
push_forward_speed = walking_speed
push_forward_speed = profile.walking_speed
if not implied_oneway then
push_backward_speed = walking_speed
push_backward_speed = profile.walking_speed
end
elseif foot_forward == 'yes' then
push_forward_speed = walking_speed
push_forward_speed = profile.walking_speed
elseif foot_backward == 'yes' then
push_backward_speed = walking_speed
push_backward_speed = profile.walking_speed
elseif way_type_allows_pushing then
push_forward_speed = walking_speed
push_forward_speed = profile.walking_speed
if not implied_oneway then
push_backward_speed = walking_speed
push_backward_speed = profile.walking_speed
end
end
end
@@ -487,8 +445,8 @@ function way_function (way, result)
if bicycle == "dismount" then
result.forward_mode = mode.pushing_bike
result.backward_mode = mode.pushing_bike
result.forward_speed = walking_speed
result.backward_speed = walking_speed
result.forward_speed = profile.walking_speed
result.backward_speed = profile.walking_speed
end
@@ -508,7 +466,7 @@ function way_function (way, result)
-- convert duration into cyclability
if properties.weight_name == 'cyclability' then
if profile.properties.weight_name == 'cyclability' then
local safety_penalty = profile.unsafe_highway_list[data.highway] or 1.
local is_unsafe = safety_penalty < 1
local forward_is_unsafe = is_unsafe and not has_cycleway_right
@@ -540,29 +498,59 @@ function way_function (way, result)
result.weight = result.duration / forward_penalty
end
end
end
function process_way(profile, way, result)
-- the initial filtering of ways based on presence of tags
-- affects processing times significantly, because all ways
-- have to be checked.
-- to increase performance, prefetching and initial tag check
-- is done directly instead of via a handler.
local handlers = Sequence {
-- compute speed taking into account way type, maxspeed tags, etc.
'handle_surface',
-- in general we should try to abort as soon as
-- possible if the way is not routable, to avoid doing
-- unnecessary work. this implies we should check things that
-- commonly forbids access early, and handle edge cases later.
-- handle turn lanes and road classification, used for guidance
'handle_classification',
-- data table for storing intermediate values during processing
-- handle various other flags
'handle_roundabouts',
-- handle allowed start/end modes
'handle_startpoint',
-- set name, ref and pronunciation
'handle_names'
local data = {
-- prefetch tags
highway = way:get_value_by_key('highway'),
}
Handlers.run(handlers,way,result,data,profile)
local handlers = Sequence {
-- set the default mode for this profile. if can be changed later
-- in case it turns we're e.g. on a ferry
WayHandlers.default_mode,
-- check various tags that could indicate that the way is not
-- routable. this includes things like status=impassable,
-- toll=yes and oneway=reversible
WayHandlers.blocked_ways,
-- our main handler
handle_bicycle_tags,
-- compute speed taking into account way type, maxspeed tags, etc.
WayHandlers.surface,
-- handle turn lanes and road classification, used for guidance
WayHandlers.classification,
-- handle allowed start/end modes
WayHandlers.startpoint,
-- handle roundabouts
WayHandlers.roundabouts,
-- set name, ref and pronunciation
WayHandlers.names
}
WayHandlers.run(profile,way,result,data,handlers)
end
function turn_function(turn)
function process_turn(profile, turn)
-- compute turn penalty as angle^2, with a left/right bias
local normalized_angle = turn.angle / 90.0
if normalized_angle >= 0.0 then
@@ -572,17 +560,20 @@ function turn_function(turn)
end
if turn.direction_modifier == direction_modifier.uturn then
turn.duration = turn.duration + profile.u_turn_penalty
turn.duration = turn.duration + profile.properties.u_turn_penalty
end
if turn.has_traffic_light then
turn.duration = turn.duration + profile.traffic_light_penalty
turn.duration = turn.duration + profile.properties.traffic_light_penalty
end
if properties.weight_name == 'cyclability' then
turn.weight = turn.duration
-- penalize turns from non-local access only segments onto local access only tags
if not turn.source_restricted and turn.target_restricted then
turn.weight = turn.weight + 3000
end
if profile.properties.weight_name == 'cyclability' then
turn.weight = turn.duration
end
end
return {
setup = setup,
process_way = process_way,
process_node = process_node,
process_turn = process_turn
}
+259 -267
View File
@@ -1,156 +1,146 @@
-- Car profile
api_version = 1
api_version = 2
local find_access_tag = require("lib/access").find_access_tag
local Set = require('lib/set')
local Sequence = require('lib/sequence')
local Handlers = require("lib/handlers")
local next = next -- bind to local for speed
Set = require('lib/set')
Sequence = require('lib/sequence')
Handlers = require("lib/way_handlers")
find_access_tag = require("lib/access").find_access_tag
limit = require("lib/maxspeed").limit
-- set profile properties
properties.max_speed_for_map_matching = 180/3.6 -- 180kmph -> m/s
properties.use_turn_restrictions = true
properties.continue_straight_at_waypoint = true
properties.left_hand_driving = false
-- For routing based on duration, but weighted for preferring certain roads
properties.weight_name = 'routability'
-- For shortest duration without penalties for accessibility
--properties.weight_name = 'duration'
-- For shortest distance without penalties for accessibility
--properties.weight_name = 'distance'
function setup()
local use_left_hand_driving = false
return {
properties = {
max_speed_for_map_matching = 180/3.6, -- 180kmph -> m/s
left_hand_driving = use_left_hand_driving,
-- For routing based on duration, but weighted for preferring certain roads
weight_name = 'routability',
-- For shortest duration without penalties for accessibility
-- weight_name = 'duration',
-- For shortest distance without penalties for accessibility
-- weight_name = 'distance',
process_call_tagless_node = false,
u_turn_penalty = 20,
continue_straight_at_waypoint = true,
use_turn_restrictions = true,
traffic_light_penalty = 2,
},
-- Set to true if you need to call the node_function for every node.
-- Generally can be left as false to avoid unnecessary Lua calls
-- (which slow down pre-processing).
properties.call_tagless_node_function = false
default_mode = mode.driving,
default_speed = 10,
oneway_handling = true,
side_road_multiplier = 0.8,
turn_penalty = 7.5,
speed_reduction = 0.8,
-- Note: this biases right-side driving.
-- Should be inverted for left-driving countries.
turn_bias = use_left_hand_driving and 1/1.075 or 1.075,
local profile = {
default_mode = mode.driving,
default_speed = 10,
oneway_handling = true,
-- a list of suffixes to suppress in name change instructions
suffix_list = {
'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'North', 'South', 'West', 'East'
},
side_road_multiplier = 0.8,
turn_penalty = 7.5,
speed_reduction = 0.8,
traffic_light_penalty = 2,
u_turn_penalty = 20,
barrier_whitelist = Set {
'cattle_grid',
'border_control',
'checkpoint',
'toll_booth',
'sally_port',
'gate',
'lift_gate',
'no',
'entrance'
},
-- Note: this biases right-side driving.
-- Should be inverted for left-driving countries.
turn_bias = properties.left_hand_driving and 1/1.075 or 1.075,
access_tag_whitelist = Set {
'yes',
'motorcar',
'motor_vehicle',
'vehicle',
'permissive',
'designated',
'hov'
},
-- a list of suffixes to suppress in name change instructions
suffix_list = {
'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'North', 'South', 'West', 'East'
},
access_tag_blacklist = Set {
'no',
'agricultural',
'forestry',
'emergency',
'psv',
'customers',
'private',
'delivery',
'destination'
},
barrier_whitelist = Set {
'cattle_grid',
'border_control',
'checkpoint',
'toll_booth',
'sally_port',
'gate',
'lift_gate',
'no',
'entrance'
},
restricted_access_tag_list = Set {
'private',
'delivery',
'destination',
'customers',
},
access_tag_whitelist = Set {
'yes',
'motorcar',
'motor_vehicle',
'vehicle',
'permissive',
'designated',
'hov'
},
access_tags_hierarchy = Sequence {
'motorcar',
'motor_vehicle',
'vehicle',
'access'
},
access_tag_blacklist = Set {
'no',
'agricultural',
'forestry',
'emergency',
'psv',
'customers',
'private',
'delivery',
'destination'
},
service_tag_forbidden = Set {
'emergency_access'
},
restricted_access_tag_list = Set {
'private',
'delivery',
'destination',
'customers',
},
restrictions = Sequence {
'motorcar',
'motor_vehicle',
'vehicle'
},
access_tags_hierarchy = Sequence {
'motorcar',
'motor_vehicle',
'vehicle',
'access'
},
avoid = Set {
'area',
-- 'toll', -- uncomment this to avoid tolls
'reversible',
'impassable',
'hov_lanes',
'steps',
'construction',
'proposed'
},
construction_whitelist = Set {
'no',
'widening',
'minor',
},
speeds = Sequence {
highway = {
motorway = 90,
motorway_link = 45,
trunk = 85,
trunk_link = 40,
primary = 65,
primary_link = 30,
secondary = 55,
secondary_link = 25,
tertiary = 40,
tertiary_link = 20,
unclassified = 25,
residential = 25,
living_street = 10,
service = 15
}
},
service_penalties = {
alley = 0.5,
parking = 0.5,
parking_aisle = 0.5,
driveway = 0.5,
["drive-through"] = 0.5,
["drive-thru"] = 0.5
},
service_tag_forbidden = Set {
'emergency_access'
},
restrictions = Sequence {
'motorcar',
'motor_vehicle',
'vehicle'
},
avoid = Set {
'area',
-- 'toll', -- uncomment this to avoid tolls
'reversible',
'impassable',
'hov_lanes',
'steps',
'construction',
'proposed'
},
speeds = Sequence {
highway = {
motorway = 90,
motorway_link = 45,
trunk = 85,
trunk_link = 40,
primary = 65,
primary_link = 30,
secondary = 55,
secondary_link = 25,
tertiary = 40,
tertiary_link = 20,
unclassified = 25,
residential = 25,
living_street = 10,
service = 15
}
},
service_penalties = {
alley = 0.5,
parking = 0.5,
parking_aisle = 0.5,
driveway = 0.5,
["drive-through"] = 0.5,
["drive-thru"] = 0.5
},
restricted_highway_whitelist = Set {
restricted_highway_whitelist = Set {
'motorway',
'motorway_link',
'trunk',
@@ -163,127 +153,122 @@ local profile = {
'tertiary_link',
'residential',
'living_street',
},
},
route_speeds = {
ferry = 5,
shuttle_train = 10
},
construction_whitelist = Set {
'no',
'widening',
'minor',
},
bridge_speeds = {
movable = 5
},
route_speeds = {
ferry = 5,
shuttle_train = 10
},
-- surface/trackype/smoothness
-- values were estimated from looking at the photos at the relevant wiki pages
bridge_speeds = {
movable = 5
},
-- max speed for surfaces
surface_speeds = {
asphalt = nil, -- nil mean no limit. removing the line has the same effect
concrete = nil,
["concrete:plates"] = nil,
["concrete:lanes"] = nil,
paved = nil,
-- surface/trackype/smoothness
-- values were estimated from looking at the photos at the relevant wiki pages
cement = 80,
compacted = 80,
fine_gravel = 80,
-- max speed for surfaces
surface_speeds = {
asphalt = nil, -- nil mean no limit. removing the line has the same effect
concrete = nil,
["concrete:plates"] = nil,
["concrete:lanes"] = nil,
paved = nil,
paving_stones = 60,
metal = 60,
bricks = 60,
cement = 80,
compacted = 80,
fine_gravel = 80,
grass = 40,
wood = 40,
sett = 40,
grass_paver = 40,
gravel = 40,
unpaved = 40,
ground = 40,
dirt = 40,
pebblestone = 40,
tartan = 40,
paving_stones = 60,
metal = 60,
bricks = 60,
cobblestone = 30,
clay = 30,
grass = 40,
wood = 40,
sett = 40,
grass_paver = 40,
gravel = 40,
unpaved = 40,
ground = 40,
dirt = 40,
pebblestone = 40,
tartan = 40,
earth = 20,
stone = 20,
rocky = 20,
sand = 20,
cobblestone = 30,
clay = 30,
mud = 10
},
earth = 20,
stone = 20,
rocky = 20,
sand = 20,
-- max speed for tracktypes
tracktype_speeds = {
grade1 = 60,
grade2 = 40,
grade3 = 30,
grade4 = 25,
grade5 = 20
},
mud = 10
},
-- max speed for smoothnesses
smoothness_speeds = {
intermediate = 80,
bad = 40,
very_bad = 20,
horrible = 10,
very_horrible = 5,
impassable = 0
},
-- max speed for tracktypes
tracktype_speeds = {
grade1 = 60,
grade2 = 40,
grade3 = 30,
grade4 = 25,
grade5 = 20
},
-- http://wiki.openstreetmap.org/wiki/Speed_limits
maxspeed_table_default = {
urban = 50,
rural = 90,
trunk = 110,
motorway = 130
},
-- max speed for smoothnesses
smoothness_speeds = {
intermediate = 80,
bad = 40,
very_bad = 20,
horrible = 10,
very_horrible = 5,
impassable = 0
},
-- List only exceptions
maxspeed_table = {
["ch:rural"] = 80,
["ch:trunk"] = 100,
["ch:motorway"] = 120,
["de:living_street"] = 7,
["ru:living_street"] = 20,
["ru:urban"] = 60,
["ua:urban"] = 60,
["at:rural"] = 100,
["de:rural"] = 100,
["at:trunk"] = 100,
["cz:trunk"] = 0,
["ro:trunk"] = 100,
["cz:motorway"] = 0,
["de:motorway"] = 0,
["ru:motorway"] = 110,
["gb:nsl_single"] = (60*1609)/1000,
["gb:nsl_dual"] = (70*1609)/1000,
["gb:motorway"] = (70*1609)/1000,
["uk:nsl_single"] = (60*1609)/1000,
["uk:nsl_dual"] = (70*1609)/1000,
["uk:motorway"] = (70*1609)/1000,
["nl:rural"] = 80,
["nl:trunk"] = 100,
["none"] = 140
-- http://wiki.openstreetmap.org/wiki/Speed_limits
maxspeed_table_default = {
urban = 50,
rural = 90,
trunk = 110,
motorway = 130
},
-- List only exceptions
maxspeed_table = {
["ch:rural"] = 80,
["ch:trunk"] = 100,
["ch:motorway"] = 120,
["de:living_street"] = 7,
["ru:living_street"] = 20,
["ru:urban"] = 60,
["ua:urban"] = 60,
["at:rural"] = 100,
["de:rural"] = 100,
["at:trunk"] = 100,
["cz:trunk"] = 0,
["ro:trunk"] = 100,
["cz:motorway"] = 0,
["de:motorway"] = 0,
["ru:motorway"] = 110,
["gb:nsl_single"] = (60*1609)/1000,
["gb:nsl_dual"] = (70*1609)/1000,
["gb:motorway"] = (70*1609)/1000,
["uk:nsl_single"] = (60*1609)/1000,
["uk:nsl_dual"] = (70*1609)/1000,
["uk:motorway"] = (70*1609)/1000,
["nl:rural"] = 80,
["nl:trunk"] = 100,
["none"] = 140
}
}
}
function get_name_suffix_list(vector)
for index,suffix in ipairs(profile.suffix_list) do
vector:Add(suffix)
end
end
function get_restrictions(vector)
for i,v in ipairs(profile.restrictions) do
vector:Add(v)
end
end
function node_function (node, result)
function process_node(profile, node, result)
-- parse access and barrier tags
local access = find_access_tag(node, profile.access_tags_hierarchy)
if access then
@@ -310,7 +295,7 @@ function node_function (node, result)
end
end
function way_function(way, result)
function process_way(profile, way, result)
-- the intial filtering of ways based on presence of tags
-- affects processing times significantly, because all ways
-- have to be checked.
@@ -342,61 +327,61 @@ function way_function(way, result)
handlers = Sequence {
-- set the default mode for this profile. if can be changed later
-- in case it turns we're e.g. on a ferry
'handle_default_mode',
WayHandlers.default_mode,
-- check various tags that could indicate that the way is not
-- routable. this includes things like status=impassable,
-- toll=yes and oneway=reversible
'handle_blocked_ways',
WayHandlers.blocked_ways,
-- determine access status by checking our hierarchy of
-- access tags, e.g: motorcar, motor_vehicle, vehicle
'handle_access',
WayHandlers.access,
-- check whether forward/backward directions are routable
'handle_oneway',
WayHandlers.oneway,
-- check a road's destination
'handle_destinations',
WayHandlers.destinations,
-- check whether we're using a special transport mode
'handle_ferries',
'handle_movables',
WayHandlers.ferries,
WayHandlers.movables,
-- handle service road restrictions
'handle_service',
WayHandlers.service,
-- handle hov
'handle_hov',
WayHandlers.hov,
-- compute speed taking into account way type, maxspeed tags, etc.
'handle_speed',
'handle_surface',
'handle_maxspeed',
'handle_penalties',
WayHandlers.speed,
WayHandlers.surface,
WayHandlers.maxspeed,
WayHandlers.penalties,
-- compute class labels
'handle_classes',
WayHandlers.classes,
-- handle turn lanes and road classification, used for guidance
'handle_turn_lanes',
'handle_classification',
WayHandlers.turn_lanes,
WayHandlers.classification,
-- handle various other flags
'handle_roundabouts',
'handle_startpoint',
WayHandlers.roundabouts,
WayHandlers.startpoint,
-- set name, ref and pronunciation
'handle_names',
WayHandlers.names,
-- set weight properties of the way
'handle_weights'
WayHandlers.weights
}
Handlers.run(handlers,way,result,data,profile)
WayHandlers.run(profile,way,result,data,handlers)
end
function turn_function (turn)
function process_turn(profile, turn)
-- Use a sigmoid function to return a penalty that maxes out at turn_penalty
-- over the space of 0-180 degrees. Values here were chosen by fitting
-- the function to some turn penalty samples from real driving.
@@ -404,7 +389,7 @@ function turn_function (turn)
local turn_bias = profile.turn_bias
if turn.has_traffic_light then
turn.duration = profile.traffic_light_penalty
turn.duration = profile.properties.traffic_light_penalty
end
if turn.turn_type ~= turn_type.no_turn then
@@ -415,21 +400,28 @@ function turn_function (turn)
end
if turn.direction_modifier == direction_modifier.u_turn then
turn.duration = turn.duration + profile.u_turn_penalty
turn.duration = turn.duration + profile.properties.u_turn_penalty
end
end
-- for distance based routing we don't want to have penalties based on turn angle
if properties.weight_name == 'distance' then
if profile.properties.weight_name == 'distance' then
turn.weight = 0
else
turn.weight = turn.duration
end
if properties.weight_name == 'routability' then
if profile.properties.weight_name == 'routability' then
-- penalize turns from non-local access only segments onto local access only tags
if not turn.source_restricted and turn.target_restricted then
turn.weight = properties.max_turn_weight;
turn.weight = constants.max_turn_weight
end
end
end
return {
setup = setup,
process_way = process_way,
process_node = process_node,
process_turn = process_turn
}
+153 -152
View File
@@ -1,151 +1,145 @@
-- Foot profile
api_version = 1
api_version = 2
local find_access_tag = require("lib/access").find_access_tag
local Set = require('lib/set')
local Sequence = require('lib/sequence')
local Handlers = require("lib/handlers")
local next = next -- bind to local for speed
Set = require('lib/set')
Sequence = require('lib/sequence')
Handlers = require("lib/way_handlers")
find_access_tag = require("lib/access").find_access_tag
properties.max_speed_for_map_matching = 40/3.6 -- kmph -> m/s
properties.use_turn_restrictions = false
properties.continue_straight_at_waypoint = false
properties.weight_name = 'duration'
--properties.weight_name = 'routability'
-- Set to true if you need to call the node_function for every node.
-- Generally can be left as false to avoid unnecessary Lua calls
-- (which slow down pre-processing).
properties.call_tagless_node_function = false
local walking_speed = 5
local profile = {
default_mode = mode.walking,
default_speed = walking_speed,
oneway_handling = 'specific', -- respect 'oneway:foot' but not 'oneway'
traffic_light_penalty = 2,
u_turn_penalty = 2,
barrier_whitelist = Set {
'cycle_barrier',
'bollard',
'entrance',
'cattle_grid',
'border_control',
'toll_booth',
'sally_port',
'gate',
'no',
'kerb',
'block'
},
access_tag_whitelist = Set {
'yes',
'foot',
'permissive',
'designated'
},
access_tag_blacklist = Set {
'no',
'agricultural',
'forestry',
'private',
'delivery',
},
restricted_access_tag_list = Set { },
restricted_highway_whitelist = Set { },
construction_whitelist = Set {},
access_tags_hierarchy = Sequence {
'foot',
'access'
},
restrictions = Sequence {
'foot'
},
-- list of suffixes to suppress in name change instructions
suffix_list = Set {
'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'North', 'South', 'West', 'East'
},
avoid = Set {
'impassable',
'construction',
'proposed'
},
speeds = Sequence {
highway = {
primary = walking_speed,
primary_link = walking_speed,
secondary = walking_speed,
secondary_link = walking_speed,
tertiary = walking_speed,
tertiary_link = walking_speed,
unclassified = walking_speed,
residential = walking_speed,
road = walking_speed,
living_street = walking_speed,
service = walking_speed,
track = walking_speed,
path = walking_speed,
steps = walking_speed,
pedestrian = walking_speed,
footway = walking_speed,
pier = walking_speed,
function setup()
local walking_speed = 5
return {
properties = {
weight_name = 'duration',
max_speed_for_map_matching = 40/3.6, -- kmph -> m/s
call_tagless_node_function = false,
traffic_light_penalty = 2,
u_turn_penalty = 2,
continue_straight_at_waypoint = false,
use_turn_restrictions = false,
},
railway = {
platform = walking_speed
default_mode = mode.walking,
default_speed = walking_speed,
oneway_handling = 'specific', -- respect 'oneway:foot' but not 'oneway'
barrier_whitelist = Set {
'cycle_barrier',
'bollard',
'entrance',
'cattle_grid',
'border_control',
'toll_booth',
'sally_port',
'gate',
'no',
'kerb',
'block'
},
amenity = {
parking = walking_speed,
parking_entrance= walking_speed
access_tag_whitelist = Set {
'yes',
'foot',
'permissive',
'designated'
},
man_made = {
pier = walking_speed
access_tag_blacklist = Set {
'no',
'agricultural',
'forestry',
'private',
'delivery',
},
leisure = {
track = walking_speed
restricted_access_tag_list = Set { },
restricted_highway_whitelist = Set { },
construction_whitelist = Set {},
access_tags_hierarchy = Sequence {
'foot',
'access'
},
restrictions = Sequence {
'foot'
},
-- list of suffixes to suppress in name change instructions
suffix_list = Set {
'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'North', 'South', 'West', 'East'
},
avoid = Set {
'impassable'
},
speeds = Sequence {
highway = {
primary = walking_speed,
primary_link = walking_speed,
secondary = walking_speed,
secondary_link = walking_speed,
tertiary = walking_speed,
tertiary_link = walking_speed,
unclassified = walking_speed,
residential = walking_speed,
road = walking_speed,
living_street = walking_speed,
service = walking_speed,
track = walking_speed,
path = walking_speed,
steps = walking_speed,
pedestrian = walking_speed,
footway = walking_speed,
pier = walking_speed,
},
railway = {
platform = walking_speed
},
amenity = {
parking = walking_speed,
parking_entrance= walking_speed
},
man_made = {
pier = walking_speed
},
leisure = {
track = walking_speed
}
},
route_speeds = {
ferry = 5
},
bridge_speeds = {
},
surface_speeds = {
fine_gravel = walking_speed*0.75,
gravel = walking_speed*0.75,
pebblestone = walking_speed*0.75,
mud = walking_speed*0.5,
sand = walking_speed*0.5
},
tracktype_speeds = {
},
smoothness_speeds = {
}
},
route_speeds = {
ferry = 5
},
bridge_speeds = {
},
surface_speeds = {
fine_gravel = walking_speed*0.75,
gravel = walking_speed*0.75,
pebblestone = walking_speed*0.75,
mud = walking_speed*0.5,
sand = walking_speed*0.5
},
tracktype_speeds = {
},
smoothness_speeds = {
}
}
end
function node_function (node, result)
function process_node(profile, node, result)
-- parse access and barrier tags
local access = find_access_tag(node, profile.access_tags_hierarchy)
if access then
@@ -173,7 +167,7 @@ function node_function (node, result)
end
-- main entry point for processsing a way
function way_function(way, result)
function process_way(profile, way, result)
-- the intial filtering of ways based on presence of tags
-- affects processing times significantly, because all ways
-- have to be checked.
@@ -210,59 +204,66 @@ function way_function(way, result)
local handlers = Sequence {
-- set the default mode for this profile. if can be changed later
-- in case it turns we're e.g. on a ferry
'handle_default_mode',
WayHandlers.default_mode,
-- check various tags that could indicate that the way is not
-- routable. this includes things like status=impassable,
-- toll=yes and oneway=reversible
'handle_blocked_ways',
WayHandlers.blocked_ways,
-- determine access status by checking our hierarchy of
-- access tags, e.g: motorcar, motor_vehicle, vehicle
'handle_access',
WayHandlers.access,
-- check whether forward/backward directons are routable
'handle_oneway',
WayHandlers.oneway,
-- check whether forward/backward directons are routable
'handle_destinations',
WayHandlers.destinations,
-- check whether we're using a special transport mode
'handle_ferries',
'handle_movables',
WayHandlers.ferries,
WayHandlers.movables,
-- compute speed taking into account way type, maxspeed tags, etc.
'handle_speed',
'handle_surface',
WayHandlers.speed,
WayHandlers.surface,
-- handle turn lanes and road classification, used for guidance
'handle_classification',
WayHandlers.classification,
-- handle various other flags
'handle_roundabouts',
'handle_startpoint',
WayHandlers.roundabouts,
WayHandlers.startpoint,
-- set name, ref and pronunciation
'handle_names'
WayHandlers.names
}
Handlers.run(handlers,way,result,data,profile)
WayHandlers.run(profile,way,result,data,handlers)
end
function turn_function (turn)
function process_turn (profile, turn)
turn.duration = 0.
if turn.direction_modifier == direction_modifier.u_turn then
turn.duration = turn.duration + profile.u_turn_penalty
turn.duration = turn.duration + profile.properties.u_turn_penalty
end
if turn.has_traffic_light then
turn.duration = profile.traffic_light_penalty
turn.duration = profile.properties.traffic_light_penalty
end
if properties.weight_name == 'routability' then
if profile.properties.weight_name == 'routability' then
-- penalize turns from non-local access only segments onto local access only tags
if not turn.source_restricted and turn.target_restricted then
turn.weight = turn.weight + 3000
end
end
end
return {
setup = setup,
process_way = process_way,
process_node = process_node,
process_turn = process_turn
}
+5 -4
View File
@@ -87,7 +87,8 @@ function Debug.report_tag_fetches()
end
function Debug.load_profile(profile)
require(profile)
Debug.functions = require(profile)
Debug.profile = Debug.functions.setup()
end
function Debug.reset_tag_fetch_counts()
@@ -112,7 +113,7 @@ function Debug.register_tag_fetch(k)
end
function Debug.way_function(way,result)
function Debug.process_way(way,result)
-- setup result table
result.road_classification = {}
@@ -131,8 +132,8 @@ function Debug.way_function(way,result)
-- reset tag counts
Debug:reset_tag_fetch_counts()
-- call the global method defined in the profile file
way_function(way,result)
-- call the way processsing function
Debug.functions.process_way(Debug.profile,way,result)
end
return Debug
+1 -1
View File
@@ -1,7 +1,7 @@
-- Sequence of items
-- Ordered, but have to loop through items to check for inclusion.
-- Currently the same as a table.
-- Adds the convenience function append() to append to the sequnce.
function Sequence(source)
return source
@@ -9,25 +9,26 @@ local set_classification = require("lib/guidance").set_classification
local get_destination = require("lib/destination").get_destination
local Tags = require('lib/tags')
Handlers = {}
WayHandlers = {}
-- check that way has at least one tag that could imply routability-
-- we store the checked tags in data, to avoid fetching again later
function Handlers.handle_tag_prefetch(way,result,data,profile)
function WayHandlers.tag_prefetch(profile,way,result,data)
for key,v in pairs(profile.prefetch) do
data[key] = way:get_value_by_key( key )
end
return next(data) ~= nil
end
-- set default mode
function Handlers.handle_default_mode(way,result,data,profile)
function WayHandlers.default_mode(profile,way,result,data)
result.forward_mode = profile.default_mode
result.backward_mode = profile.default_mode
end
-- handles name, including ref and pronunciation
function Handlers.handle_names(way,result,data,profile)
function WayHandlers.names(profile,way,result,data)
-- parse the remaining tags
local name = way:get_value_by_key("name")
local pronunciation = way:get_value_by_key("name:pronunciation")
@@ -53,7 +54,7 @@ function Handlers.handle_names(way,result,data,profile)
end
-- junctions
function Handlers.handle_roundabouts(way,result,data,profile)
function WayHandlers.roundabouts(profile,way,result,data)
local junction = way:get_value_by_key("junction");
if junction == "roundabout" then
@@ -69,7 +70,7 @@ function Handlers.handle_roundabouts(way,result,data,profile)
end
-- determine if this way can be used as a start/end point for routing
function Handlers.handle_startpoint(way,result,data,profile)
function WayHandlers.startpoint(profile,way,result,data)
-- if profile specifies set of allowed start modes, then check for that
-- otherwise require default mode
if profile.allowed_start_modes then
@@ -82,7 +83,7 @@ function Handlers.handle_startpoint(way,result,data,profile)
end
-- handle turn lanes
function Handlers.handle_turn_lanes(way,result,data,profile)
function WayHandlers.turn_lanes(profile,way,result,data)
local forward, backward = get_turn_lanes(way,data)
if forward then
@@ -95,12 +96,12 @@ function Handlers.handle_turn_lanes(way,result,data,profile)
end
-- set the road classification based on guidance globals configuration
function Handlers.handle_classification(way,result,data,profile)
function WayHandlers.classification(profile,way,result,data)
set_classification(data.highway,result,way)
end
-- handle destination tags
function Handlers.handle_destinations(way,result,data,profile)
function WayHandlers.destinations(profile,way,result,data)
if data.is_forward_oneway or data.is_reverse_oneway then
local destination = get_destination(way, data.is_forward_oneway)
result.destinations = canonicalizeStringList(destination, ",")
@@ -108,7 +109,7 @@ function Handlers.handle_destinations(way,result,data,profile)
end
-- handling ferries and piers
function Handlers.handle_ferries(way,result,data,profile)
function WayHandlers.ferries(profile,way,result,data)
local route = data.route
if route then
local route_speed = profile.route_speeds[route]
@@ -126,7 +127,7 @@ function Handlers.handle_ferries(way,result,data,profile)
end
-- handling movable bridges
function Handlers.handle_movables(way,result,data,profile)
function WayHandlers.movables(profile,way,result,data)
local bridge = data.bridge
if bridge then
local bridge_speed = profile.bridge_speeds[bridge]
@@ -148,7 +149,7 @@ function Handlers.handle_movables(way,result,data,profile)
end
-- service roads
function Handlers.handle_service(way,result,data,profile)
function WayHandlers.service(profile,way,result,data)
local service = way:get_value_by_key("service")
if service then
-- Set don't allow access to certain service roads
@@ -161,7 +162,7 @@ function Handlers.handle_service(way,result,data,profile)
end
-- all lanes restricted to hov vehicles?
function Handlers.has_all_designated_hov_lanes(lanes)
function WayHandlers.has_all_designated_hov_lanes(lanes)
if not lanes then
return false
end
@@ -176,7 +177,7 @@ function Handlers.has_all_designated_hov_lanes(lanes)
end
-- handle high occupancy vehicle tags
function Handlers.handle_hov(way,result,data,profile)
function WayHandlers.hov(profile,way,result,data)
-- respect user-preference for HOV
if not profile.avoid.hov_lanes then
return
@@ -189,11 +190,11 @@ function Handlers.handle_hov(way,result,data,profile)
end
data.hov_lanes_forward, data.hov_lanes_backward = Tags.get_forward_backward_by_key(way,data,'hov:lanes')
local all_hov_forward = Handlers.has_all_designated_hov_lanes(data.hov_lanes_forward)
local all_hov_backward = Handlers.has_all_designated_hov_lanes(data.hov_lanes_backward)
local all_hov_forward = WayHandlers.has_all_designated_hov_lanes(data.hov_lanes_forward)
local all_hov_backward = WayHandlers.has_all_designated_hov_lanes(data.hov_lanes_backward)
-- in this case we will use turn penalties instead of filtering out
if properties.weight_name == 'routability' then
if profile.properties.weight_name == 'routability' then
if (all_hov_forward) then
result.forward_restricted = true
end
@@ -213,7 +214,7 @@ function Handlers.handle_hov(way,result,data,profile)
end
-- check accessibility by traversing our access tag hierarchy
function Handlers.handle_access(way,result,data,profile)
function WayHandlers.access(profile,way,result,data)
data.forward_access, data.backward_access =
Tags.get_forward_backward_by_set(way,data,profile.access_tags_hierarchy)
@@ -242,7 +243,7 @@ function Handlers.handle_access(way,result,data,profile)
end
-- handle speed (excluding maxspeed)
function Handlers.handle_speed(way,result,data,profile)
function WayHandlers.speed(profile,way,result,data)
if result.forward_speed ~= -1 then
return -- abort if already set, eg. by a route
end
@@ -278,7 +279,7 @@ function Handlers.handle_speed(way,result,data,profile)
end
-- add class information
function Handlers.handle_classes(way,result,data,profile)
function WayHandlers.classes(profile,way,result,data)
local forward_toll, backward_toll = Tags.get_forward_backward_by_key(way, data, "toll")
local forward_route, backward_route = Tags.get_forward_backward_by_key(way, data, "route")
@@ -310,7 +311,7 @@ function Handlers.handle_classes(way,result,data,profile)
end
-- reduce speed on bad surfaces
function Handlers.handle_surface(way,result,data,profile)
function WayHandlers.surface(profile,way,result,data)
local surface = way:get_value_by_key("surface")
local tracktype = way:get_value_by_key("tracktype")
local smoothness = way:get_value_by_key("smoothness")
@@ -330,7 +331,7 @@ function Handlers.handle_surface(way,result,data,profile)
end
-- scale speeds to get better average driving times
function Handlers.handle_penalties(way,result,data,profile)
function WayHandlers.penalties(profile,way,result,data)
-- heavily penalize a way tagged with all HOV lanes
-- in order to only route over them if there is no other option
local service_penalty = 1.0
@@ -375,7 +376,7 @@ function Handlers.handle_penalties(way,result,data,profile)
local forward_penalty = math.min(service_penalty, width_penalty, alternating_penalty, sideroad_penalty)
local backward_penalty = math.min(service_penalty, width_penalty, alternating_penalty, sideroad_penalty)
if properties.weight_name == 'routability' then
if profile.properties.weight_name == 'routability' then
if result.forward_speed > 0 then
result.forward_rate = (result.forward_speed * forward_penalty) / 3.6
end
@@ -389,11 +390,11 @@ function Handlers.handle_penalties(way,result,data,profile)
end
-- maxspeed and advisory maxspeed
function Handlers.handle_maxspeed(way,result,data,profile)
function WayHandlers.maxspeed(profile,way,result,data)
local keys = Sequence { 'maxspeed:advisory', 'maxspeed' }
local forward, backward = Tags.get_forward_backward_by_set(way,data,keys)
forward = Handlers.parse_maxspeed(forward,profile)
backward = Handlers.parse_maxspeed(backward,profile)
forward = WayHandlers.parse_maxspeed(forward,profile)
backward = WayHandlers.parse_maxspeed(backward,profile)
if forward and forward > 0 then
result.forward_speed = forward * profile.speed_reduction
@@ -404,7 +405,7 @@ function Handlers.handle_maxspeed(way,result,data,profile)
end
end
function Handlers.parse_maxspeed(source,profile)
function WayHandlers.parse_maxspeed(source,profile)
if not source then
return 0
end
@@ -429,7 +430,7 @@ function Handlers.parse_maxspeed(source,profile)
end
-- handle oneways tags
function Handlers.handle_oneway(way,result,data,profile)
function WayHandlers.oneway(profile,way,result,data)
if not profile.oneway_handling then
return
end
@@ -476,8 +477,8 @@ function Handlers.handle_oneway(way,result,data,profile)
end
end
function Handlers.handle_weights(way,result,data,profile)
if properties.weight_name == 'distance' then
function WayHandlers.weights(profile,way,result,data)
if profile.properties.weight_name == 'distance' then
result.weight = -1
-- set weight rates to 1 for the distance weight, edge weights are distance / rate
if (result.forward_mode ~= mode.inaccessible and result.forward_speed > 0) then
@@ -490,7 +491,7 @@ function Handlers.handle_weights(way,result,data,profile)
end
-- handle various that can block access
function Handlers.handle_blocked_ways(way,result,data,profile)
function WayHandlers.blocked_ways(profile,way,result,data)
-- areas
if profile.avoid.area and way:get_value_by_key("area") == "yes" then
@@ -554,27 +555,27 @@ end
-- Call a sequence of handlers, aborting in case a handler returns false. Example:
--
-- handlers = Sequence {
-- 'handle_tag_prefetch',
-- 'handle_default_mode',
-- 'handle_blocked_ways',
-- 'handle_access',
-- 'handle_speed',
-- 'handle_names'
-- WayHandlers.tag_prefetch,
-- WayHandlers.default_mode,
-- WayHandlers.blocked_ways,
-- WayHandlers.access,
-- WayHandlers.speed,
-- WayHandlers.names
-- }
--
-- Handlers.run(handlers,way,result,data,profile)
-- WayHandlers.run(handlers,way,result,data,profile)
--
-- Each method in the list will be called on the Handlers object.
-- All handlers must accept the parameteres (way,result,data,profile) and return false
-- Each method in the list will be called on the WayHandlers object.
-- All handlers must accept the parameteres (profile,way,result,data) and return false
-- if the handler chain should be aborted.
-- To ensure the correct order of method calls, use a Sequence of handler names.
function Handlers.run(handlers,way,result,data,profile)
function WayHandlers.run(profile,way,result,data,handlers)
for i,handler in ipairs(handlers) do
if Handlers[handler](way,result,data,profile) == false then
if handler(profile,way,result,data) == false then
return false
end
end
end
return Handlers
return WayHandlers
+30 -29
View File
@@ -1,19 +1,30 @@
api_version = 1
-- Rasterbot profile
properties.force_split_edges = true
api_version = 2
-- Set to true if you need to call the node_function for every node.
-- Generally can be left as false to avoid unnecessary Lua calls
-- (which slow down pre-processing).
properties.call_tagless_node_function = false
function setup()
local raster_path = os.getenv('OSRM_RASTER_SOURCE') or "rastersource.asc"
-- Minimalist node_ and way_functions in order to test source_ and segment_functions
function node_function (node, result)
return {
properties = {
force_split_edges = true,
process_call_tagless_node = false,
},
raster_source = raster:load(
raster_path,
0, -- lon_min
0.1, -- lon_max
0, -- lat_min
0.1, -- lat_max
5, -- nrows
4 -- ncols
)
}
end
function way_function (way, result)
-- Minimalist process_ways in order to test source_ and process_segments
function process_way (profile, way, result)
local highway = way:get_value_by_key("highway")
local name = way:get_value_by_key("name")
@@ -28,25 +39,9 @@ function way_function (way, result)
result.backward_speed = 15
end
function source_function ()
local path = os.getenv('OSRM_RASTER_SOURCE')
if not path then
path = "rastersource.asc"
end
raster_source = sources:load(
path,
0, -- lon_min
0.1, -- lon_max
0, -- lat_min
0.1, -- lat_max
5, -- nrows
4 -- ncols
)
end
function segment_function (segment)
local sourceData = sources:query(raster_source, segment.source.lon, segment.source.lat)
local targetData = sources:query(raster_source, segment.target.lon, segment.target.lat)
function process_segment (profile, segment)
local sourceData = raster:query(profile.raster_source, segment.source.lon, segment.source.lat)
local targetData = raster:query(profile.raster_source, segment.target.lon, segment.target.lat)
io.write("evaluating segment: " .. sourceData.datum .. " " .. targetData.datum .. "\n")
local invalid = sourceData.invalid_data()
local scaled_weight = segment.weight
@@ -66,3 +61,9 @@ function segment_function (segment)
segment.weight = scaled_weight
segment.duration = scaled_duration
end
return {
setup = setup,
process_way = process_way,
process_segment = process_segment
}
+7 -45
View File
@@ -1,50 +1,10 @@
api_version = 1
-- Rasterbot profile
-- Rasterbot with interpolation profile
-- Set to true if you need to call the node_function for every node.
-- Generally can be left as false to avoid unnecessary Lua calls
-- (which slow down pre-processing).
properties.call_tagless_node_function = false
functions = require('rasterbot')
-- Minimalist node_ and way_functions in order to test source_ and segment_functions
function node_function (node, result)
end
function way_function (way, result)
local highway = way:get_value_by_key("highway")
local name = way:get_value_by_key("name")
if name then
result.name = name
end
result.forward_mode = mode.cycling
result.backward_mode = mode.cycling
result.forward_speed = 15
result.backward_speed = 15
end
function source_function ()
local path = os.getenv('OSRM_RASTER_SOURCE')
if not path then
path = "rastersource.asc"
end
raster_source = sources:load(
path,
0, -- lon_min
0.1, -- lon_max
0, -- lat_min
0.1, -- lat_max
5, -- nrows
4 -- ncols
)
end
function segment_function (segment)
local sourceData = sources:interpolate(raster_source, segment.source.lon, segment.source.lat)
local targetData = sources:interpolate(raster_source, segment.target.lon, segment.target.lat)
functions.process_segment = function(profile, segment)
local sourceData = raster:interpolate(profile.raster_source, segment.source.lon, segment.source.lat)
local targetData = raster:interpolate(profile.raster_source, segment.target.lon, segment.target.lat)
io.write("evaluating segment: " .. sourceData.datum .. " " .. targetData.datum .. "\n")
local invalid = sourceData.invalid_data()
local scaled_weight = segment.weight
@@ -64,3 +24,5 @@ function segment_function (segment)
segment.weight = scaled_weight
segment.duration = scaled_duration
end
return functions
+34 -41
View File
@@ -1,49 +1,35 @@
api_version = 1
-- Testbot profile
-- Moves at fixed, well-known speeds, practical for testing speed and travel times:
-- Primary road: 36km/h = 36000m/3600s = 100m/10s
-- Secondary road: 18km/h = 18000m/3600s = 100m/20s
-- Tertiary road: 12km/h = 12000m/3600s = 100m/30s
speed_profile = {
["primary"] = 36,
["secondary"] = 18,
["tertiary"] = 12,
["steps"] = 6,
["default"] = 24
}
api_version = 2
-- these settings are read directly by osrm
function setup()
return {
properties = {
continue_straight_at_waypoint = true,
max_speed_for_map_matching = 30/3.6, --km -> m/s
weight_name = 'duration',
process_call_tagless_node = false,
uturn_penalty = 20,
traffic_light_penalty = 7, -- seconds
use_turn_restrictions = true
},
properties.continue_straight_at_waypoint = true
properties.use_turn_restrictions = true
properties.max_speed_for_map_matching = 30/3.6 --km -> m/s
properties.weight_name = 'duration'
-- Set to true if you need to call the node_function for every node.
-- Generally can be left as false to avoid unnecessary Lua calls
-- (which slow down pre-processing).
properties.call_tagless_node_function = false
local uturn_penalty = 20
local traffic_light_penalty = 7 -- seconds
function limit_speed(speed, limits)
-- don't use ipairs(), since it stops at the first nil value
for i=1, #limits do
limit = limits[i]
if limit ~= nil and limit > 0 then
if limit < speed then
return limit -- stop at first speedlimit that's smaller than speed
end
end
end
return speed
default_speed = 24,
speeds = {
primary = 36,
secondary = 18,
tertiary = 12,
steps = 6,
}
}
end
function node_function (node, result)
function process_node (profile, node, result)
local traffic_signal = node:get_value_by_key("highway")
if traffic_signal and traffic_signal == "traffic_signals" then
@@ -52,7 +38,7 @@ function node_function (node, result)
end
end
function way_function (way, result)
function process_way (profile, way, result)
local highway = way:get_value_by_key("highway")
local name = way:get_value_by_key("name")
local oneway = way:get_value_by_key("oneway")
@@ -75,7 +61,7 @@ function way_function (way, result)
result.forward_mode = mode.route
result.backward_mode = mode.route
else
local speed_forw = speed_profile[highway] or speed_profile['default']
local speed_forw = profile.speeds[highway] or profile.default_speed
local speed_back = speed_forw
if highway == "river" then
@@ -122,12 +108,19 @@ function way_function (way, result)
end
end
function turn_function (turn)
function process_turn (profile, turn)
if turn.direction_modifier == direction_modifier.uturn then
turn.duration = uturn_penalty
turn.weight = uturn_penalty
turn.duration = profile.properties.uturn_penalty
turn.weight = profile.properties.uturn_penalty
end
if turn.has_traffic_light then
turn.duration = turn.duration + traffic_light_penalty
turn.duration = turn.duration + profile.properties.traffic_light_penalty
end
end
return {
setup = setup,
process_way = process_way,
process_node = process_node,
process_turn = process_turn
}
+5 -5
View File
@@ -1,10 +1,10 @@
api_version = 1
-- Testbot, with turn penalty
-- Used for testing turn penalties
require 'testbot'
functions = require 'testbot'
function turn_function (turn)
turn.duration = 20 * math.abs(turn.angle) / 180
functions.process_turn = function(profile, turn)
turn.duration = 20 * math.abs(turn.angle) / 180
end
return functions
+3 -3
View File
@@ -10,13 +10,13 @@ set -o nounset
# http://git.661346.n2.nabble.com/subtree-merges-lose-prefix-after-rebase-td7332850.html
OSMIUM_REPO="https://github.com/osmcode/libosmium.git"
OSMIUM_TAG=v2.11.0
OSMIUM_TAG=v2.11.3
VARIANT_REPO="https://github.com/mapbox/variant.git"
VARIANT_TAG=v1.1.0
VARIANT_TAG=v1.1.3
SOL_REPO="https://github.com/ThePhD/sol2.git"
SOL_TAG=v2.15.8
SOL_TAG=v2.17.5
RAPIDJSON_REPO="https://github.com/miloyip/rapidjson.git"
RAPIDJSON_TAG=v1.1.0
+5 -5
View File
@@ -47,7 +47,7 @@ int Contractor::Run()
util::Log() << "Reading node weights.";
std::vector<EdgeWeight> node_weights;
{
storage::io::FileReader reader(config.node_file_path,
storage::io::FileReader reader(config.GetPath(".osrm.enw"),
storage::io::FileReader::VerifyFingerprint);
storage::serialization::read(reader, node_weights);
}
@@ -67,7 +67,7 @@ int Contractor::Run()
std::vector<float> node_levels;
if (config.use_cached_priority)
{
files::readLevels(config.level_output_path, node_levels);
files::readLevels(config.GetPath(".osrm.level"), node_levels);
}
util::DeallocatingVector<QueryEdge> contracted_edge_list;
@@ -90,15 +90,15 @@ int Contractor::Run()
RangebasedCRC32 crc32_calculator;
const unsigned checksum = crc32_calculator(contracted_edge_list);
files::writeGraph(config.graph_output_path,
files::writeGraph(config.GetPath(".osrm.hsgr"),
checksum,
QueryGraph{max_edge_id + 1, std::move(contracted_edge_list)});
}
files::writeCoreMarker(config.core_output_path, is_core_node);
files::writeCoreMarker(config.GetPath(".osrm.core"), is_core_node);
if (!config.use_cached_priority)
{
files::writeLevels(config.level_output_path, node_levels);
files::writeLevels(config.GetPath(".osrm.level"), node_levels);
}
TIMER_STOP(preparing);
+4 -4
View File
@@ -98,12 +98,12 @@ int Customizer::Run(const CustomizationConfig &config)
TIMER_START(loading_data);
partition::MultiLevelPartition mlp;
partition::files::readPartition(config.mld_partition_path, mlp);
partition::files::readPartition(config.GetPath(".osrm.partition"), mlp);
auto edge_based_graph = LoadAndUpdateEdgeExpandedGraph(config, mlp);
partition::CellStorage storage;
partition::files::readCells(config.mld_storage_path, storage);
partition::files::readCells(config.GetPath(".osrm.cells"), storage);
TIMER_STOP(loading_data);
util::Log() << "Loading partition data took " << TIMER_SEC(loading_data) << " seconds";
@@ -114,12 +114,12 @@ int Customizer::Run(const CustomizationConfig &config)
util::Log() << "Cells customization took " << TIMER_SEC(cell_customize) << " seconds";
TIMER_START(writing_mld_data);
partition::files::writeCells(config.mld_storage_path, storage);
partition::files::writeCells(config.GetPath(".osrm.cells"), storage);
TIMER_STOP(writing_mld_data);
util::Log() << "MLD customization writing took " << TIMER_SEC(writing_mld_data) << " seconds";
TIMER_START(writing_graph);
partition::files::writeGraph(config.mld_graph_path, *edge_based_graph);
partition::files::writeGraph(config.GetPath(".osrm.mldgr"), *edge_based_graph);
TIMER_STOP(writing_graph);
util::Log() << "Graph writing took " << TIMER_SEC(writing_graph) << " seconds";

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