Compare commits

...

165 Commits

Author SHA1 Message Date
Patrick Niklaus adee18468c Bump RC to 4 2018-04-13 13:23:35 +00:00
Patrick Niklaus 9a9abf4c11 Remove double log printing 2018-04-13 10:14:23 +00:00
karenzshea 331eeca4c1 empty list of shmem regions if none found 2018-04-13 10:12:20 +00:00
karenzshea f8d6e4750a log err instead of throwing when no shmem regions found 2018-04-13 10:12:05 +00:00
Michael Krasnyk cf505386f9 Bump version to 5.17.0-rc.3 2018-04-12 10:12:28 +02:00
Michael Krasnyk e346e9ae07 Avoid using signed integers for edge IDs 2018-04-12 10:11:52 +02:00
Michael Krasnyk ad37fcce2d Bump version to 5.17.0-rc.2 2018-04-10 21:17:33 +02:00
Patrick Niklaus 0e19f07c3c Use byte based tar size encoding above 8GB 2018-04-10 21:14:29 +02:00
Patrick Niklaus 59c0795c7f Add test case for writing and reading huge tar file
This test case is disabled by default because it needs too much storage,
but serves as documentation for the future.
2018-04-10 21:14:27 +02:00
Michael Krasnyk 3653e51f67 Use base-256 encoding for files larger 68G
Reference:
http://lists.busybox.net/pipermail/busybox/2011-May/075596.html
2018-04-10 21:14:25 +02:00
Michael Krasnyk 8c24507f8f Use 12 octal digits in mtar_raw_header_t::size 2018-04-10 21:14:23 +02:00
Michael Krasnyk 3e444777e0 Fix mtar file size truncation to 4G 2018-04-10 21:14:20 +02:00
Patrick Niklaus 670cd8813c Bump OSRM version 2018-04-09 13:13:44 +00:00
Michael Krasnyk c4bf450fc6 Restore storage constructors with one arguments 2018-04-09 15:08:00 +02:00
Patrick Niklaus bf2b45120a Use ArrayStorage for boundary nodes to optimize MLD
For the MLD algorithm we can partition the NodeID range into boundary
and non-boundary nodes. Since there are only we boundary nodes we can
use the ArrayStorage for those yielding much faster query times.
2018-04-09 15:08:00 +02:00
Patrick Niklaus 7edf0f218c Better statistics for osrm-partition and osrm-custimize 2018-04-09 13:39:39 +02:00
Patrick Niklaus 600ca06166 Simplify toEdges and make it more robust against accidental memory allocations 2018-04-09 13:03:28 +02:00
Michael Krasnyk 8d8042ebae Use ranges with fixed types 2018-04-09 11:05:01 +02:00
Kajari Ghosh be123cd72f Use ranges in datafacade instead of vectors
Range type must use immutable references due to a
regression in `boost::any_range`.
References:
https://svn.boost.org/trac10/ticket/10493
https://stackoverflow.com/questions/42427395/boostany-range-with-optimization-level-o2-causes-crash/42427662
2018-04-09 11:05:01 +02:00
Daniel Patterson 282415bbc1 Honour British spelling of manoeuvre relation (#5004)
* Support British spelling of manoeuvre to comply with OSM standards.
2018-04-06 17:08:30 -07:00
Patrick Niklaus b08191b2c4 Add changelog entry for osrm-datastore 2018-04-07 00:22:29 +02:00
Patrick Niklaus 39dd484f45 Restore the connectivity checksum check 2018-04-07 00:22:29 +02:00
Patrick Niklaus 5450574d63 Better test coverage for datastore options 2018-04-07 00:22:29 +02:00
Patrick Niklaus 29d1b34140 Fix formating 2018-04-07 00:22:29 +02:00
Patrick Niklaus a915542916 Add option to only update the metric dependent data 2018-04-07 00:22:29 +02:00
Patrick Niklaus fea07f343b Load data in two separate data regions 2018-04-07 00:22:29 +02:00
Patrick Niklaus c7daa521ad Address PR comments 2018-04-05 15:12:47 +02:00
Patrick Niklaus c2532b1589 Add test case from @oxidase for datastore parameters 2018-04-05 15:12:47 +02:00
Patrick Niklaus 4610fd9ff1 Fix formating 2018-04-05 15:12:47 +02:00
Patrick Niklaus c4b90f52c0 Run cucumber in its own dataset namespace so it does not interfere 2018-04-05 15:12:47 +02:00
Patrick Niklaus 0e8b8b4901 Add nodejs test for dataset name 2018-04-05 15:12:47 +02:00
Patrick Niklaus 2c80f76004 Add support for naming the dataset 2018-04-05 15:12:47 +02:00
Patrick Niklaus 666ce46d36 Refactor shared memory storage to allow for multiple named datasets 2018-04-05 15:12:47 +02:00
Michael Krasnyk bc120776f0 Don't apply unimplemented SH and PH conditions 2018-04-05 13:31:48 +02:00
Daniel Patterson 5693ffd2cf Validate format of changelog entries. 2018-04-05 10:56:28 +02:00
Patrick Niklaus 51fe0dd5a0 Add missing check of a tar writing function 2018-04-05 00:54:50 +02:00
Michael Krasnyk 14d2199cd8 Always create a new kv pair to avoid using shared strings 2018-04-04 12:38:40 +02:00
Patrick Niklaus 9889a454ce Fix test compilation 2018-04-04 12:38:40 +02:00
Patrick Niklaus cb4586ebee Make use of the view factory in the data facade 2018-04-04 12:38:40 +02:00
Patrick Niklaus 44924b4bb4 Refactor view creation to own header file 2018-04-04 12:38:40 +02:00
Patrick Niklaus 3af3e06e75 Remove canary to get a consistent interface for getting a block pointer 2018-04-04 12:38:40 +02:00
Patrick Niklaus 39effb8f7e Fix checking for non-empty string in prefix check 2018-04-04 12:38:40 +02:00
Patrick Niklaus 5a68f4c214 Refactor setting up vector_view 2018-04-04 12:38:40 +02:00
Patrick Niklaus f558b16147 First step for better vector encapsulation 2018-04-04 12:38:40 +02:00
Patrick Niklaus 4c2d578561 Fix unit-test compilation due to broken readGraph 2018-04-04 12:38:40 +02:00
Patrick Niklaus 81a4747acb Fix formating 2018-04-04 12:38:40 +02:00
Patrick Niklaus 9fc2c32408 Fix errors when loading an incompatible dataset. 2018-04-04 12:38:40 +02:00
Patrick Niklaus 24e0028afb Remove CheckCompability because it now duplicates logic in the datafacade 2018-04-04 12:38:40 +02:00
Patrick Niklaus c334d11e95 Refactor metric storage 2018-04-04 12:38:40 +02:00
Patrick Niklaus aec9b6a178 Fixed reading DataLayout from shared memory 2018-04-04 12:38:40 +02:00
Patrick Niklaus 81929c984b Use boost array sink to avoid copying buffer for BufferReader 2018-04-04 12:38:40 +02:00
Patrick Niklaus 5395290fd5 Add directory listing 2018-04-04 12:38:40 +02:00
Patrick Niklaus b3ef2a0383 More refactor 2018-04-04 12:38:40 +02:00
Patrick Niklaus 9e97748700 Add datalayout tests 2018-04-04 12:38:40 +02:00
Patrick Niklaus 4a9fdca7b2 Remove fixed block identifiers 2018-04-04 12:38:40 +02:00
Daniel Patterson f3b7ab92ff Fix typo. 2018-04-04 12:24:09 +02:00
Daniel Patterson eae9e7fab6 Only listen on 127.0.0.1 (unless overriden by environment) during test runs by default. 2018-04-04 12:24:09 +02:00
Daniel Patterson 649d4ee512 Add support for the 'straight' maneuver direction (#4995)
Add support for the 'straight' maneuver direction
2018-04-03 17:20:18 -07:00
Daniel Patterson b5a4ffed96 Return datasource names along with datasource annotation (#4973)
* Add new `datasource_names` annotation that returns the string version of the `datasources` annotation
2018-04-03 15:13:25 -07:00
Duane Gearhart 8a63ad9b4b Added post process logic to collapse segregated turn instructions (#4925)
* Added post process logic to collapse segregated turn instructions

* format updates

* Fixed coordinates to reflect reality
Updated left turn road name

* fixed coordinates to fix test

* Skip last step when processing segregated steps

* updated segregated turn test

* Updated segregated test

* Updated test: Segregated Intersection, Cross Belonging to Correct Street - features/guidance/collapse.feature:79

* Fixed all but one for features/guidance/collapse.feature:124

* Fixed Scenario: Partly Segregated Intersection, Two Segregated Roads, Intersection belongs to Second - features/guidance/collapse.feature:219

* Fixed 7 of th 9 failures for Scenario: Partly Segregated Intersection, Two Segregated Roads, Intersection belongs to Second - features/guidance/collapse.feature:219

* Fixed 7 of the 9 failures for Scenario: Segregated Intersection, Cross Belonging to Mixed Streets - Slight Angles (2) - features/guidance/collapse.feature:318

* Fixed Scenario: Segregated Intersection into Slight Turn - features/guidance/collapse.feature:581

* Updated Scenario: U-turn after a traffic light - features/guidance/turn-lanes.feature:1220

* Updated how we combine segregated steps

* Added test to Verify end of road left turn across divided roads

* Fixed divided highwat tests

* Fixed test failure

* fixed Scenario: Partitioned turn, Slight Curve - maxspeed - features/guidance/turn-lanes.feature:936

* Fixed Scenario: Partitioned turn, Slight Curve - features/guidance/turn-lanes.feature:961

* Added strategies to combine segrgated intersections

* Added setModifier alias for readability

* Added strategies to combine segrgated intersections

* Format updates

* Fixes segregated indentification to not mark `circular` edge as segregated

* Added intersection prior to turn so we still call out end of road

* updated expectation to be turn instead of continue

* Confirmed with @oxidase that the lane information if correct - updated the expectation

* Added logic to handle wider straights
Fixed tests

* Update CHANGELOG.md

Added #4925

* Removed TODO

* Process straight step prior to wider straight step
2018-03-30 07:43:56 -04:00
karenzshea 0d9f18fe1f add microtar to executables 2018-03-27 20:50:34 +02:00
Patrick Niklaus 2690dd0621 Merge pull request #4960 from Project-OSRM/refactor/tar_files
Use tar-format to encapsulate data
2018-03-27 14:34:08 +02:00
Patrick Niklaus 4ef331db1f Use read-only mmap as member in StaticRTree 2018-03-27 10:20:33 +00:00
Michael Krasnyk e572d6c340 msvc fixes 2018-03-26 21:45:27 -04:00
Patrick Niklaus 0c48f5fe2f Make sure to return const char* paths for mtar 2018-03-26 13:13:17 +00:00
Patrick Niklaus 3ee8a963cb Fix formating again 2018-03-26 12:13:07 +00:00
Patrick Niklaus c322d93435 Make the block size of vector<bool> consistent 2018-03-26 12:12:41 +00:00
Patrick Niklaus c0dd5d7c76 Fix formating 2018-03-26 11:02:34 +00:00
Patrick Niklaus 993f5badf1 Use OSRM runtime error for tar reader as well 2018-03-26 11:02:34 +00:00
Patrick Niklaus a542da3678 Remove old io::FileWrite serialization code 2018-03-26 11:02:34 +00:00
Patrick Niklaus f1a392c4df Fix test include path 2018-03-26 11:02:33 +00:00
Patrick Niklaus f2bace6c1f Wrap lambda in std::function because of boost version issues 2018-03-26 11:02:33 +00:00
Patrick Niklaus 921235b2dc Use pair instead of tuple for implicit construction 2018-03-26 11:02:33 +00:00
Patrick Niklaus bde51a9ef5 Add tar file mmaping 2018-03-26 11:02:33 +00:00
Patrick Niklaus a52213c885 Get offset of data inside tar file 2018-03-26 11:02:33 +00:00
Patrick Niklaus 8e800c48bc Add function to stop and continue writing to a tar file 2018-03-26 11:02:33 +00:00
Patrick Niklaus e25654c210 MICROTAR: Patch microtar to allow reading from files we are writing to. 2018-03-26 11:02:33 +00:00
Patrick Niklaus ee447afd72 Fix DealloctingVector from initializer list constructor
It was not setting the number of elements.
2018-03-26 11:02:33 +00:00
Patrick Niklaus c410c200bd Port .cnbg file to tar format 2018-03-26 11:02:33 +00:00
Patrick Niklaus 8152dcfb4c Port .ramIndex to tar file and mmap .fileIndex directly 2018-03-26 11:02:33 +00:00
Patrick Niklaus 86ffce3a50 Fix missing removal of timestamp in offline facade 2018-03-26 11:02:33 +00:00
Patrick Niklaus bed53f5fd5 Remove timestamp file 2018-03-26 11:02:31 +00:00
Patrick Niklaus 2b010fc6f3 Port .enw file to tar format 2018-03-26 11:02:04 +00:00
Patrick Niklaus b8260e44fa Port .names file to tar 2018-03-26 11:02:04 +00:00
Patrick Niklaus a594008e57 Port .edges file to tar 2018-03-26 11:02:04 +00:00
Patrick Niklaus f407afa694 Move .osrm file to tar format 2018-03-26 11:02:04 +00:00
Patrick Niklaus 06f28ffd34 Add BufferWriter/BufferReader and simplify interface for ConditionalRestrictions 2018-03-26 11:02:04 +00:00
Patrick Niklaus 4f454a3761 Add buffer reader/writer for per-element serialization 2018-03-26 11:02:04 +00:00
Patrick Niklaus d4300e73f3 Remove line reading interface from FileReader 2018-03-26 11:02:04 +00:00
Patrick Niklaus 990e411361 Port turn duration penalties to tar 2018-03-26 11:02:04 +00:00
Patrick Niklaus 73b3d37837 Port maneuver overrides to tar 2018-03-26 11:02:04 +00:00
Patrick Niklaus 5d7d5fceba Port .tld and .tls data 2018-03-26 11:02:04 +00:00
Patrick Niklaus b1dfbce675 Port .ebg_nodes to tar file 2018-03-26 11:02:04 +00:00
Patrick Niklaus da5aebaef3 Port .geometry file to tar format 2018-03-26 11:02:04 +00:00
Patrick Niklaus bced9a5a6d Port .datasource_names to tar format 2018-03-26 11:02:04 +00:00
Patrick Niklaus 2c5e4e6c02 Add test cases for range table and packed vector serialization 2018-03-26 11:02:04 +00:00
Patrick Niklaus 6ea296fb5c Port .nbg_nodes file to tar 2018-03-26 11:02:04 +00:00
Patrick Niklaus cf5f6be472 Swtich EBG to tar file 2018-03-26 11:02:04 +00:00
Patrick Niklaus c61198b26b Port over profile properties 2018-03-26 11:02:04 +00:00
Patrick Niklaus 5d1b4ce71d Port .osrm.icd file over to tar 2018-03-26 11:02:03 +00:00
Patrick Niklaus c664d0392a Add test cases for int and unsigned vector for tar 2018-03-26 11:02:03 +00:00
Patrick Niklaus aaf39162a8 Fix vector<bool> serialization for tar files and add unit tests 2018-03-26 11:02:03 +00:00
Patrick Niklaus cb31f9ec29 Port hsgr file to tar 2018-03-26 11:02:03 +00:00
Patrick Niklaus fed77c4066 Port cell metrics to tar files 2018-03-26 11:02:03 +00:00
Patrick Niklaus 6a09d2aa9b Remove file size checks from compability logic 2018-03-26 11:02:03 +00:00
Patrick Niklaus 15b53de056 Switch over partition/ files to tar format 2018-03-26 11:02:03 +00:00
Patrick Niklaus 6d96a9a2e3 Serialize mldgr using the new tar writer 2018-03-26 11:02:03 +00:00
Patrick Niklaus 653f647fee Use static alignment for DataLayout 2018-03-26 11:02:03 +00:00
Patrick Niklaus f7b7335d75 Write/read tar for mldgr 2018-03-26 11:02:03 +00:00
Patrick Niklaus 495131efd7 Add vector serialization 2018-03-26 11:02:03 +00:00
Patrick Niklaus 2eb633bc41 Add unit tests for tar reading 2018-03-26 11:02:03 +00:00
Patrick Niklaus 86bfe1ede1 First step towards reading/writing tar 2018-03-26 11:02:03 +00:00
Patrick Niklaus c04e1b2ded Merge commit '098d77c658fa846aff55a35c0ad42955e9f736ee' as 'third_party/microtar' 2018-03-26 11:01:50 +00:00
Patrick Niklaus 098d77c658 Squashed 'third_party/microtar/' content from commit 956791770
git-subtree-dir: third_party/microtar
git-subtree-split: 956791770defa4d06696b30db276e88a09ad3538
2018-03-26 11:01:50 +00:00
Patrick Niklaus 385bba4949 Add microtar to dependencies 2018-03-26 10:59:55 +00:00
Duane Gearhart bc980e72bf Update CHANGELOG.md
Updated #4968: Updated segregated intersection identification
2018-03-23 11:41:52 +01:00
Duane Gearhart 535bb49893 Fixed segregated identification code to not mark circular edges as segregated 2018-03-21 18:02:26 +01:00
Michael Krasnyk b56a7579a8 Review updates 2018-03-20 16:33:15 +01:00
Michael Krasnyk 8b52c6c7ac Update tests expectations and obvious detection 2018-03-20 16:33:15 +01:00
Michael Krasnyk d166fc6a75 Restructure Obvious Turn Handling, code transfer from #4426 2018-03-20 16:33:15 +01:00
Huyen Chau Nguyen bdb116afe5 Fix wrong one-way identification in the bike profile
* upgrade to api version 4

* set bike pushing speed to 4km/h and add mode change penalty

* set cycleways for two-way and one-way roads according correctly

* add changelog

* adjust tests according to change of the walking speed

* adjust tests according to new behaviour of opposite, track and lane in one-ways

* refactor the cycleway identification

* comment to understand weird counterintuitive testcase

* adjust sliproad test because walking speed is now slower
2018-03-19 16:02:25 +01:00
Michael Krasnyk 873e766d2e Add Github releases step 2018-03-18 15:27:11 +01:00
Huyen Chau Nguyen a84277f246 add tests in left-side-countries 2018-03-18 14:30:40 +01:00
Patrick Niklaus b80764b6b8 Refactor shared memory layout to expose Block as interface 2018-03-14 17:05:55 +01:00
Frédéric Rodrigo 14082d0e00 Fix typo 'Maximum number of classes if' 2018-03-14 03:16:13 +01:00
Daniel Patterson f7775f5e0b Add source phantom weight to first segment when merging legs (#4949)
Fix annotation values for annotations on edges where phantom nodes are snapped.
2018-03-13 11:31:29 -07:00
Michael Krasnyk b7af6eb2a4 Remove correctly the last segment in annotation 2018-03-09 15:59:21 +01:00
Daniel Patterson a4ee2ccb13 Avoid copying json::Value objects a lot when reallocating vector 2018-03-08 16:01:16 +01:00
Manuel Martin c61acaf8be Add documentation about OSM node ids in nearest service response 2018-03-06 16:10:22 +01:00
Michael Krasnyk 0fc8b6289c Merge IntersectionShapeData and IntersectionEdgeGeometry 2018-03-05 13:19:57 +01:00
Michael Krasnyk 0f93a7dd05 Cleanup EBGF code 2018-03-05 13:19:57 +01:00
Michael Krasnyk 4d0fb89489 Adjust Straight direction modifiers of side roads in driveway handler 2018-03-05 13:19:57 +01:00
Michael Krasnyk 6f4af330ed Handle oneways in get_forward_backward_by_key 2018-03-05 13:19:57 +01:00
Michael Krasnyk 7c8c25f7bc Don't use obviousness for links bifurcations 2018-03-05 13:19:57 +01:00
Michael Krasnyk cf56b5ddbf Increase precision of coordinates in OSM links 2018-03-05 13:19:57 +01:00
Lev Dragunov ac23e3b223 clang-format 2018-03-01 11:32:18 +01:00
Lev Dragunov 7922a6172a Bearing calculation on matching short segments fix. 2018-03-01 11:32:18 +01:00
Daniel Patterson e34f2db4db Get OSRM_VERSION_* fields from package.json so we don't have to change things in two places.
No longer need to update CMakeLists.txt version field manually.
2018-03-01 12:05:00 +11:00
Daniel Patterson 5df33e5b90 Make alternative routes tests stable by only being single-threaded 2018-03-01 12:03:18 +11:00
karenzshea db608559f6 avoid testing self-intersecting way 2018-02-28 15:21:47 +01:00
Michael Krasnyk c048a36a4c Use smaller range for U-turn angles in map-matching 2018-02-28 15:21:47 +01:00
Duane Gearhart 33021d37a1 Updated segregated intersection identification (#4845)
* Initial internal intersection updates
paired with @oxidase and @kdiluca
TODO fix tests and add in new ones

* Added Internal Intersection Model

* removed debug info

* updates per PR 4845

* fixing build errors

* fixing all compile errors

* fixed EdgeID param

* Added is_internal_straight lambda
Added/Updated constexpr names and values

* added rejection case turn degree logic

* debug logging

* added turn angle logic to reject if there are incoming edges that have opposite turn degrees than outgoing edges or if the outgoing edges have opposing turn degrees; also merged with master v5.16

* fixed formatting

* fix to decrease tile size based on latest turn angle internal intersection updates

* Removed breaks

Breaks in code were a mistake and caused a change in the internal intersection identification.

* Update segregated_intersection_classification.cpp

* Update CHANGELOG.md

Added CHANGED #4845: Updated segregated intersection identification to Unreleased
2018-02-27 15:11:23 -05:00
Patrick Niklaus 31d6d74f90 Update documentation and changelog 2018-02-26 23:32:34 +01:00
Patrick Niklaus bec57258a4 Add mmap allocator 2018-02-26 23:32:34 +01:00
Karen Shea 43f0723b73 Remove deduplication of unpacked_path_segments in MM collapsing (#4911)
* remove deduplication of unpacked_path_segments
2018-02-24 12:42:11 +11:00
Huyen Chau Nguyen 9b74a47c91 build osx binary for node4 and bump to RC 2 2018-02-24 11:42:08 +11:00
Huyen Chau Nguyen 993a36ea20 update master changelog after version release 2018-02-24 11:42:08 +11:00
Huyen Chau Nguyen 8b5af24eb8 add 5.15.2 to changelog (#4910) 2018-02-23 14:41:02 +01:00
Thomas Brüggemann 5c9a7a0152 Fixed the order of lon/lat in osrm.route() example 2018-02-22 23:41:54 +01:00
Michael Krasnyk 83588fd00f Renumber node IDs in .osrm.maneuver_overrides 2018-02-22 11:42:33 +01:00
Michael Krasnyk 5acf660f37 Check required tags of maneuver relations 2018-02-21 14:49:15 +01:00
Michael Krasnyk de13834c12 Handle motorway forks with links as a normal motorway ...
passing some ramps or mering onto another motorway
2018-02-21 14:19:53 +01:00
Michael Krasnyk 49811e1f46 Test case for a highway fork with a link 2018-02-21 14:19:53 +01:00
Mateusz Loskot 8788b0fae8 Add .editorconfig file
Propose basic settings for controlling EOL encoding and
space-only indentation of CMake and other scripts.
2018-02-20 16:16:26 +01:00
Michael Krasnyk 1cafafc4cd Don't use obvious directions at ramp bifurcations, #4895 2018-02-20 09:02:24 +01:00
Michael Krasnyk e2c1956aa5 Test for a ramp bifurcation obviousness 2018-02-20 09:02:24 +01:00
Huyen Chau Nguyen a8bc2cf8a7 update package.json (#4889) 2018-02-15 16:14:18 +01:00
Huyen Chau Nguyen 975ede4bec Update package.json
add mkdirp and rimraf to bundledependencies in order for node-pre-gyp to properly install with node
2018-02-15 14:34:35 +01:00
Mateusz Loskot faff2c774d [msvc] Fix quoting of OSRM_PROJECT_DIR as preprocessor define
It looks MSVC still special handling, no quotoing as well as
additional quoting like add_definitions(-DFOO="\\"foo\\"")
as per https://cmake.org/pipermail/cmake/2007-June/014611.html
does not seem to handle CMake variables correctly.

This Visual C++ specific fix is based on this solution
https://cmake.org/pipermail/cmake/2006-September/011292.html
2018-02-14 13:54:54 +01:00
Mateusz Loskot d8e3b03ec1 Ignore CMakeSettings.json for CMake integration with VS2017
CMakeSettings.json is an auxiliary file used to customize
CMake configuration while building from within VS2017.

[ci skip]
2018-02-14 13:30:32 +01:00
Mateusz Loskot ae41066fbe Prefer logical punctuators instead of named operator keywords
Some compilers (eg. MSVC) still require inclusion of <ciso646>
in order to import named operator keywords.
It is easier to stick with traditional punctuators.
2018-02-14 13:26:41 +01:00
Fred-Byrd 342da81591 web_mercator to double 2018-02-13 12:54:52 +01:00
Fred-Byrd df9195b939 coordinate_calculation doubles 2018-02-13 12:54:52 +01:00
Michael Krasnyk 519eae63c6 Use links with lower priority in the motorway handler
Ref:
https://wiki.openstreetmap.org/wiki/Highway_link
https://wiki.openstreetmap.org/wiki/Link_roads_between_different_highways_types
2018-02-13 11:20:27 +01:00
Michael Krasnyk 5f598da76d Add OSM node barrier=height_restrictor handling 2018-02-12 11:40:35 +01:00
244 changed files with 10168 additions and 5247 deletions
+30
View File
@@ -0,0 +1,30 @@
# EditorConfig is awesome: http://EditorConfig.org
#
# NOTE: Keep settings in sync with the master .clang-format file
#
# top-most EditorConfig file
root = true
# CMake configuration files
[{CMakeLists.txt,CMakeSettings.json,*.cmake}]
indent_size = 2
indent_style = space
trim_trailing_whitespace = true
# CI configuration files
[{.travis.yml,appveyor.yml}]
indent_size = 2
indent_style = space
trim_trailing_whitespace = true
# Unix shell scripts
[*.sh]
end_of_line = lf
indent_style = space
trim_trailing_whitespace = true
# Windows shell scripts
[*.bat]
end_of_line = crlf
indent_style = space
trim_trailing_whitespace = true
+1
View File
@@ -66,6 +66,7 @@ Thumbs.db
######################################
/.vs*
/*.local.bat
/CMakeSettings.json
# stxxl related files #
#######################
+10
View File
@@ -15,6 +15,7 @@ branches:
- master
# enable building tags
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/
- "5.17"
cache:
yarn: true
@@ -59,6 +60,7 @@ matrix:
- ./scripts/check_taginfo.py taginfo.json profiles/car.lua
- ${MASON} install clang-format 3.8.1
- PATH=$(${MASON} prefix clang-format 3.8.1)/bin:${PATH} ./scripts/format.sh && ./scripts/error_on_dirty.sh
- node ./scripts/validate_changelog.js
# See issue 4043
#- npm run docs && ./scripts/error_on_dirty.sh
after_success:
@@ -161,6 +163,14 @@ matrix:
after_success:
- ./scripts/travis/publish.sh
- os: osx
osx_image: xcode9.2
compiler: "mason-osx-release-node-4"
# we use the xcode provides clang and don't install our own
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON ENABLE_LTO=ON NODE="4"
after_success:
- ./scripts/travis/publish.sh
# Shared Library
- os: linux
compiler: "gcc-7-release-shared"
+53 -3
View File
@@ -1,13 +1,63 @@
# UNRELEASED
- Changes from 5.15.1:
# 5.17.0
- Changes from 5.16.0:
- Bugfixes:
- FIXED: deduplication of route steps when waypoints are used [#4909](https://github.com/Project-OSRM/osrm-backend/issues/4909)
- FIXED: Use smaller range for U-turn angles in map-matching [#4920](https://github.com/Project-OSRM/osrm-backend/pull/4920)
- FIXED: Remove the last short annotation segment in `trimShortSegments` [#4946](https://github.com/Project-OSRM/osrm-backend/pull/4946)
- FIXED: Properly calculate annotations for speeds, durations and distances when waypoints are used with mapmatching [#4949](https://github.com/Project-OSRM/osrm-backend/pull/4949)
- FIXED: Don't apply unimplemented SH and PH conditions in OpeningHours and add inversed date ranges [#4992](https://github.com/Project-OSRM/osrm-backend/issues/4992)
- FIXED: integer overflow in `DynamicGraph::Renumber` [#5021](https://github.com/Project-OSRM/osrm-backend/pull/5021)
- Profile:
- CHANGED: Handle oneways in get_forward_backward_by_key [#4929](https://github.com/Project-OSRM/osrm-backend/pull/4929)
- FIXED: Do not route against oneway road if there is a cycleway in the wrong direction; also review bike profile [#4943](https://github.com/Project-OSRM/osrm-backend/issues/4943)
- Guidance:
- CHANGED: Don't use obviousness for links bifurcations [#4929](https://github.com/Project-OSRM/osrm-backend/pull/4929)
- FIXED: Adjust Straight direction modifiers of side roads in driveway handler [#4929](https://github.com/Project-OSRM/osrm-backend/pull/4929)
- CHANGED: Added post process logic to collapse segregated turn instructions [#4925](https://github.com/Project-OSRM/osrm-backend/pull/4925)
- ADDED: Maneuver relation now supports `straight` as a direction [#4995](https://github.com/Project-OSRM/osrm-backend/pull/4995)
- FIXED: Support spelling maneuver relation with British spelling [#4950](https://github.com/Project-OSRM/osrm-backend/issues/4950)
- Tools:
- ADDED: `osrm-routed` accepts a new property `--memory_file` to store memory in a file on disk. [#4881](https://github.com/Project-OSRM/osrm-backend/pull/4881)
- ADDED: `osrm-datastore` accepts a new parameter `--dataset-name` to select the name of the dataset. [#4982](https://github.com/Project-OSRM/osrm-backend/pull/4982)
- ADDED: `osrm-datastore` accepts a new parameter `--list` to list all datasets loaded into memory. [#4982](https://github.com/Project-OSRM/osrm-backend/pull/4982)
- ADDED: `osrm-datastore` accepts a new parameter `--only-metric` to only reload the data that can be updated by a weight update (reduces memory for traffic updates). [#5002](https://github.com/Project-OSRM/osrm-backend/pull/5002)
- ADDED: `osrm-routed` accepts a new parameter `--dataset-name` to select the shared-memory dataset to use. [#4982](https://github.com/Project-OSRM/osrm-backend/pull/4982)
- NodeJS:
- ADDED: `OSRM` object accepts a new option `memory_file` that stores the memory in a file on disk. [#4881](https://github.com/Project-OSRM/osrm-backend/pull/4881)
- ADDED: `OSRM` object accepts a new option `dataset_name` to select the shared-memory dataset. [#4982](https://github.com/Project-OSRM/osrm-backend/pull/4982)
- Internals
- CHANGED: Updated segregated intersection identification [#4845](https://github.com/Project-OSRM/osrm-backend/pull/4845) [#4968](https://github.com/Project-OSRM/osrm-backend/pull/4968)
- REMOVED: Remove `.timestamp` file since it was unused [#4960](https://github.com/Project-OSRM/osrm-backend/pull/4960)
- Documentation:
- ADDED: Add documentation about OSM node ids in nearest service response [#4436](https://github.com/Project-OSRM/osrm-backend/pull/4436)
- Performance
- FIXED: Speed up response time when lots of legs exist and geojson is used with `steps=true` [#4936](https://github.com/Project-OSRM/osrm-backend/pull/4936)
- FIXED: Return iterators instead of vectors in datafacade_base functions [#4969](https://github.com/Project-OSRM/osrm-backend/issues/4969)
- Misc:
- ADDED: expose name for datasource annotations as metadata [#4973](https://github.com/Project-OSRM/osrm-backend/pull/4973)
# 5.16.0
- Changes from 5.15.2:
- Guidance
- ADDED #4676: Support for maneuver override relation, allowing data-driven overrides for turn-by-turn instructions [#4676](https://github.com/Project-OSRM/osrm-backend/pull/4676)
- CHANGED #4830: Announce reference change if names are empty
- CHANGED #4835: MAXIMAL_ALLOWED_SEPARATION_WIDTH increased to 12 meters
- CHANGED #4842: Lower priority links from a motorway now are used as motorway links [#4842](https://github.com/Project-OSRM/osrm-backend/pull/4842)
- CHANGED #4895: Use ramp bifurcations as fork intersections [#4895](https://github.com/Project-OSRM/osrm-backend/issues/4895)
- CHANGED #4893: Handle motorway forks with links as normal motorway intersections[#4893](https://github.com/Project-OSRM/osrm-backend/issues/4893)
- FIXED #4905: Check required tags of `maneuver` relations [#4905](https://github.com/Project-OSRM/osrm-backend/pull/4905)
- Profile:
- FIXED: `highway=service` will now be used for restricted access, `access=private` is still disabled for snapping.
- ADDED #4775: Exposes more information to the turn function, now being able to set turn weights with highway and access information of the turn as well as other roads at the intersection [#4775](https://github.com/Project-OSRM/osrm-backend/issues/4775)
- FIXED: #4763: Add support for non-numerical units in car profile for maxheight [#4763](https://github.com/Project-OSRM/osrm-backend/issues/4763)
- FIXED #4763: Add support for non-numerical units in car profile for maxheight [#4763](https://github.com/Project-OSRM/osrm-backend/issues/4763)
- ADDED #4872: Handling of `barrier=height_restrictor` nodes [#4872](https://github.com/Project-OSRM/osrm-backend/pull/4872)
# 5.15.2
- Changes from 5.15.1:
- Features:
- ADDED: Exposed the waypoints parameter in the node bindings interface
- Bugfixes:
- FIXED: Segfault causing bug in leg collapsing map matching when traversing edges in reverse
# 5.15.1
- Changes from 5.15.0:
+36 -22
View File
@@ -1,5 +1,4 @@
cmake_minimum_required(VERSION 2.8.11)
# we depend on 2.8.11 introducing target_include_directories
cmake_minimum_required(VERSION 3.1)
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR AND NOT MSVC_IDE)
message(FATAL_ERROR "In-source builds are not allowed.
@@ -59,12 +58,26 @@ if (POLICY CMP0048)
cmake_policy(SET CMP0048 OLD)
endif()
project(OSRM C CXX)
set(OSRM_VERSION_MAJOR 5)
set(OSRM_VERSION_MINOR 16)
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}")
include(JSONParser)
file(READ "package.json" packagejsonraw)
sbeParseJson(packagejson packagejsonraw)
if (packagejson.version MATCHES "^([0-9]+)\.([0-9]+)\.([0-9]+)")
set(OSRM_VERSION_MAJOR ${CMAKE_MATCH_1})
set(OSRM_VERSION_MINOR ${CMAKE_MATCH_2})
set(OSRM_VERSION_PATCH ${CMAKE_MATCH_3})
set(OSRM_VERSION "${OSRM_VERSION_MAJOR}.${OSRM_VERSION_MINOR}.${OSRM_VERSION_PATCH}")
else()
message(FATAL_ERROR "Version from package.json cannot be parsed, expected semver compatible X.Y.Z, but found ${packagejson.version}")
endif()
if (MSVC)
add_definitions("-DOSRM_PROJECT_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}\"")
else()
add_definitions(-DOSRM_PROJECT_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
endif()
# these two functions build up custom variables:
# DEPENDENCIES_INCLUDE_DIRS and OSRM_DEFINES
@@ -153,15 +166,15 @@ add_executable(osrm-partition src/tools/partition.cpp)
add_executable(osrm-customize src/tools/customize.cpp)
add_executable(osrm-contract src/tools/contract.cpp)
add_executable(osrm-routed src/tools/routed.cpp $<TARGET_OBJECTS:SERVER> $<TARGET_OBJECTS:UTIL>)
add_executable(osrm-datastore src/tools/store.cpp $<TARGET_OBJECTS:UTIL>)
add_library(osrm src/osrm/osrm.cpp $<TARGET_OBJECTS:ENGINE> $<TARGET_OBJECTS:UTIL> $<TARGET_OBJECTS:STORAGE>)
add_executable(osrm-datastore src/tools/store.cpp $<TARGET_OBJECTS:MICROTAR> $<TARGET_OBJECTS:UTIL>)
add_library(osrm src/osrm/osrm.cpp $<TARGET_OBJECTS:ENGINE> $<TARGET_OBJECTS:STORAGE> $<TARGET_OBJECTS:MICROTAR> $<TARGET_OBJECTS:UTIL> )
add_library(osrm_contract src/osrm/contractor.cpp $<TARGET_OBJECTS:CONTRACTOR> $<TARGET_OBJECTS:UTIL>)
add_library(osrm_extract src/osrm/extractor.cpp $<TARGET_OBJECTS:EXTRACTOR> $<TARGET_OBJECTS:UTIL>)
add_library(osrm_extract src/osrm/extractor.cpp $<TARGET_OBJECTS:EXTRACTOR> $<TARGET_OBJECTS:MICROTAR> $<TARGET_OBJECTS:UTIL>)
add_library(osrm_guidance $<TARGET_OBJECTS:GUIDANCE> $<TARGET_OBJECTS:UTIL>)
add_library(osrm_partition src/osrm/partitioner.cpp $<TARGET_OBJECTS:PARTITIONER> $<TARGET_OBJECTS:UTIL>)
add_library(osrm_customize src/osrm/customizer.cpp $<TARGET_OBJECTS:CUSTOMIZER> $<TARGET_OBJECTS:UTIL>)
add_library(osrm_update $<TARGET_OBJECTS:UPDATER> $<TARGET_OBJECTS:UTIL>)
add_library(osrm_store $<TARGET_OBJECTS:STORAGE> $<TARGET_OBJECTS:UTIL>)
add_library(osrm_partition src/osrm/partitioner.cpp $<TARGET_OBJECTS:PARTITIONER> $<TARGET_OBJECTS:MICROTAR> $<TARGET_OBJECTS:UTIL>)
add_library(osrm_customize src/osrm/customizer.cpp $<TARGET_OBJECTS:CUSTOMIZER> $<TARGET_OBJECTS:MICROTAR> $<TARGET_OBJECTS:UTIL>)
add_library(osrm_update $<TARGET_OBJECTS:UPDATER> $<TARGET_OBJECTS:MICROTAR> $<TARGET_OBJECTS:UTIL>)
add_library(osrm_store $<TARGET_OBJECTS:STORAGE> $<TARGET_OBJECTS:MICROTAR> $<TARGET_OBJECTS:UTIL>)
if(ENABLE_GOLD_LINKER)
execute_process(COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
@@ -482,9 +495,6 @@ if(ENABLE_MASON)
# note: we avoid calling find_package(Osmium ...) here to ensure that the
# expat and bzip2 are used from mason rather than the system
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/libosmium/include)
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/rapidjson/include)
else()
find_package(Boost 1.54 REQUIRED COMPONENTS ${BOOST_COMPONENTS})
@@ -542,12 +552,16 @@ else()
endif()
find_package(Osmium REQUIRED COMPONENTS io)
include_directories(SYSTEM ${OSMIUM_INCLUDE_DIR})
set(RAPIDJSON_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/rapidjson/include")
include_directories(SYSTEM ${RAPIDJSON_INCLUDE_DIR})
endif()
set(RAPIDJSON_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/rapidjson/include")
include_directories(SYSTEM ${RAPIDJSON_INCLUDE_DIR})
set(MICROTAR_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/microtar/src")
include_directories(SYSTEM ${MICROTAR_INCLUDE_DIR})
add_library(MICROTAR OBJECT "${CMAKE_CURRENT_SOURCE_DIR}/third_party/microtar/src/microtar.c")
set_property(TARGET MICROTAR PROPERTY POSITION_INDEPENDENT_CODE ON)
# prefix compilation with ccache by default if available and on clang or gcc
if(ENABLE_CCACHE AND (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU"))
find_program(CCACHE_FOUND ccache)
@@ -686,7 +700,7 @@ target_link_libraries(osrm_customize ${CUSTOMIZER_LIBRARIES} osrm_update osrm_st
target_link_libraries(osrm_store ${STORAGE_LIBRARIES})
# BUILD_COMPONENTS
add_executable(osrm-components src/tools/components.cpp $<TARGET_OBJECTS:UTIL>)
add_executable(osrm-components src/tools/components.cpp $<TARGET_OBJECTS:MICROTAR> $<TARGET_OBJECTS:UTIL>)
target_link_libraries(osrm-components ${TBB_LIBRARIES} ${BOOST_BASE_LIBRARIES} ${UTIL_LIBRARIES})
install(TARGETS osrm-components DESTINATION bin)
+290
View File
@@ -0,0 +1,290 @@
# https://github.com/sbellus/json-cmake/blob/9913da8800b95322d393894d3525d634568f305e/JSONParser.cmake
# MIT Licensed - https://github.com/sbellus/json-cmake/blob/master/LICENSE
cmake_minimum_required(VERSION 3.1)
if (DEFINED JSonParserGuard)
return()
endif()
set(JSonParserGuard yes)
macro(sbeParseJson prefix jsonString)
cmake_policy(PUSH)
set(json_string "${${jsonString}}")
string(LENGTH "${json_string}" json_jsonLen)
set(json_index 0)
set(json_AllVariables ${prefix})
set(json_ArrayNestingLevel 0)
set(json_MaxArrayNestingLevel 0)
_sbeParse(${prefix})
unset(json_index)
unset(json_AllVariables)
unset(json_jsonLen)
unset(json_string)
unset(json_value)
unset(json_inValue)
unset(json_name)
unset(json_inName)
unset(json_newPrefix)
unset(json_reservedWord)
unset(json_arrayIndex)
unset(json_char)
unset(json_end)
unset(json_ArrayNestingLevel)
foreach(json_nestingLevel RANGE ${json_MaxArrayNestingLevel})
unset(json_${json_nestingLevel}_arrayIndex)
endforeach()
unset(json_nestingLevel)
unset(json_MaxArrayNestingLevel)
cmake_policy(POP)
endmacro()
macro(sbeClearJson prefix)
foreach(json_var ${${prefix}})
unset(${json_var})
endforeach()
unset(${prefix})
unset(json_var)
endmacro()
macro(sbePrintJson prefix)
foreach(json_var ${${prefix}})
message("${json_var} = ${${json_var}}")
endforeach()
endmacro()
macro(_sbeParse prefix)
while(${json_index} LESS ${json_jsonLen})
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
if("\"" STREQUAL "${json_char}")
_sbeParseNameValue(${prefix})
elseif("{" STREQUAL "${json_char}")
_sbeMoveToNextNonEmptyCharacter()
_sbeParseObject(${prefix})
elseif("[" STREQUAL "${json_char}")
_sbeMoveToNextNonEmptyCharacter()
_sbeParseArray(${prefix})
endif()
if(${json_index} LESS ${json_jsonLen})
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
else()
break()
endif()
if ("}" STREQUAL "${json_char}" OR "]" STREQUAL "${json_char}")
break()
endif()
_sbeMoveToNextNonEmptyCharacter()
endwhile()
endmacro()
macro(_sbeParseNameValue prefix)
set(json_name "")
set(json_inName no)
while(${json_index} LESS ${json_jsonLen})
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
# check if name ends
if("\"" STREQUAL "${json_char}" AND json_inName)
set(json_inName no)
_sbeMoveToNextNonEmptyCharacter()
if(NOT ${json_index} LESS ${json_jsonLen})
break()
endif()
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
set(json_newPrefix ${prefix}.${json_name})
set(json_name "")
if(":" STREQUAL "${json_char}")
_sbeMoveToNextNonEmptyCharacter()
if(NOT ${json_index} LESS ${json_jsonLen})
break()
endif()
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
if("\"" STREQUAL "${json_char}")
_sbeParseValue(${json_newPrefix})
break()
elseif("{" STREQUAL "${json_char}")
_sbeMoveToNextNonEmptyCharacter()
_sbeParseObject(${json_newPrefix})
break()
elseif("[" STREQUAL "${json_char}")
_sbeMoveToNextNonEmptyCharacter()
_sbeParseArray(${json_newPrefix})
break()
else()
# reserved word starts
_sbeParseReservedWord(${json_newPrefix})
break()
endif()
else()
# name without value
list(APPEND ${json_AllVariables} ${json_newPrefix})
set(${json_newPrefix} "")
break()
endif()
endif()
if(json_inName)
# remove escapes
if("\\" STREQUAL "${json_char}")
math(EXPR json_index "${json_index} + 1")
if(NOT ${json_index} LESS ${json_jsonLen})
break()
endif()
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
endif()
set(json_name "${json_name}${json_char}")
endif()
# check if name starts
if("\"" STREQUAL "${json_char}" AND NOT json_inName)
set(json_inName yes)
endif()
_sbeMoveToNextNonEmptyCharacter()
endwhile()
endmacro()
macro(_sbeParseReservedWord prefix)
set(json_reservedWord "")
set(json_end no)
while(${json_index} LESS ${json_jsonLen} AND NOT json_end)
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
if("," STREQUAL "${json_char}" OR "}" STREQUAL "${json_char}" OR "]" STREQUAL "${json_char}")
set(json_end yes)
else()
set(json_reservedWord "${json_reservedWord}${json_char}")
math(EXPR json_index "${json_index} + 1")
endif()
endwhile()
list(APPEND ${json_AllVariables} ${prefix})
string(STRIP "${json_reservedWord}" json_reservedWord)
set(${prefix} ${json_reservedWord})
endmacro()
macro(_sbeParseValue prefix)
cmake_policy(SET CMP0054 NEW) # turn off implicit expansions in if statement
set(json_value "")
set(json_inValue no)
while(${json_index} LESS ${json_jsonLen})
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
# check if json_value ends, it is ended by "
if("\"" STREQUAL "${json_char}" AND json_inValue)
set(json_inValue no)
set(${prefix} ${json_value})
list(APPEND ${json_AllVariables} ${prefix})
_sbeMoveToNextNonEmptyCharacter()
break()
endif()
if(json_inValue)
# if " is escaped consume
if("\\" STREQUAL "${json_char}")
math(EXPR json_index "${json_index} + 1")
if(NOT ${json_index} LESS ${json_jsonLen})
break()
endif()
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
if(NOT "\"" STREQUAL "${json_char}")
# if it is not " then copy also escape character
set(json_char "\\${json_char}")
endif()
endif()
_sbeAddEscapedCharacter("${json_char}")
endif()
# check if value starts
if("\"" STREQUAL "${json_char}" AND NOT json_inValue)
set(json_inValue yes)
endif()
math(EXPR json_index "${json_index} + 1")
endwhile()
endmacro()
macro(_sbeAddEscapedCharacter char)
string(CONCAT json_value "${json_value}" "${char}")
endmacro()
macro(_sbeParseObject prefix)
_sbeParse(${prefix})
_sbeMoveToNextNonEmptyCharacter()
endmacro()
macro(_sbeParseArray prefix)
math(EXPR json_ArrayNestingLevel "${json_ArrayNestingLevel} + 1")
set(json_${json_ArrayNestingLevel}_arrayIndex 0)
set(${prefix} "")
list(APPEND ${json_AllVariables} ${prefix})
while(${json_index} LESS ${json_jsonLen})
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
if("\"" STREQUAL "${json_char}")
# simple value
list(APPEND ${prefix} ${json_${json_ArrayNestingLevel}_arrayIndex})
_sbeParseValue(${prefix}_${json_${json_ArrayNestingLevel}_arrayIndex})
elseif("{" STREQUAL "${json_char}")
# object
_sbeMoveToNextNonEmptyCharacter()
list(APPEND ${prefix} ${json_${json_ArrayNestingLevel}_arrayIndex})
_sbeParseObject(${prefix}_${json_${json_ArrayNestingLevel}_arrayIndex})
else()
list(APPEND ${prefix} ${json_${json_ArrayNestingLevel}_arrayIndex})
_sbeParseReservedWord(${prefix}_${json_${json_ArrayNestingLevel}_arrayIndex})
endif()
if(NOT ${json_index} LESS ${json_jsonLen})
break()
endif()
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
if("]" STREQUAL "${json_char}")
_sbeMoveToNextNonEmptyCharacter()
break()
elseif("," STREQUAL "${json_char}")
math(EXPR json_${json_ArrayNestingLevel}_arrayIndex "${json_${json_ArrayNestingLevel}_arrayIndex} + 1")
endif()
_sbeMoveToNextNonEmptyCharacter()
endwhile()
if(${json_MaxArrayNestingLevel} LESS ${json_ArrayNestingLevel})
set(json_MaxArrayNestingLevel ${json_ArrayNestingLevel})
endif()
math(EXPR json_ArrayNestingLevel "${json_ArrayNestingLevel} - 1")
endmacro()
macro(_sbeMoveToNextNonEmptyCharacter)
math(EXPR json_index "${json_index} + 1")
if(${json_index} LESS ${json_jsonLen})
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
while(${json_char} MATCHES "[ \t\n\r]" AND ${json_index} LESS ${json_jsonLen})
math(EXPR json_index "${json_index} + 1")
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
endwhile()
endif()
endmacro()
+18 -1
View File
@@ -120,6 +120,7 @@ In addition to the [general options](#general-options) the following options are
- `code` if the request was successful `Ok` otherwise see the service dependent and general status codes.
- `waypoints` array of `Waypoint` objects sorted by distance to the input coordinate. Each object has at least the following additional properties:
- `distance`: Distance in meters to the supplied input coordinate.
- `nodes`: Array of OpenStreetMap node ids.
#### Example Requests
@@ -134,6 +135,10 @@ curl 'http://router.project-osrm.org/nearest/v1/driving/13.388860,52.517037?numb
{
"waypoints" : [
{
"nodes": [
2264199819,
0
],
"hint" : "KSoKADRYroqUBAEAEAAAABkAAAAGAAAAAAAAABhnCQCLtwAA_0vMAKlYIQM8TMwArVghAwEAAQH1a66g",
"distance" : 4.152629,
"name" : "Friedrichstraße",
@@ -143,6 +148,10 @@ curl 'http://router.project-osrm.org/nearest/v1/driving/13.388860,52.517037?numb
]
},
{
"nodes": [
2045820592,
0
],
"hint" : "KSoKADRYroqUBAEABgAAAAAAAAAAAAAAKQAAABhnCQCLtwAA7kvMAAxZIQM8TMwArVghAwAAAQH1a66g",
"distance" : 11.811961,
"name" : "Friedrichstraße",
@@ -152,6 +161,10 @@ curl 'http://router.project-osrm.org/nearest/v1/driving/13.388860,52.517037?numb
]
},
{
"nodes": [
0,
21487242
],
"hint" : "KioKgDbbDgCUBAEAAAAAABoAAAAAAAAAPAAAABlnCQCLtwAA50vMADJZIQM8TMwArVghAwAAAQH1a66g",
"distance" : 15.872438,
"name" : "Friedrichstraße",
@@ -534,6 +547,7 @@ With `steps=false` and `annotations=true`:
"distance": [5,5,10,5,5],
"duration": [15,15,40,15,15],
"datasources": [1,0,0,0,1],
"metadata": { "datasource_names": ["traffic","lua profile","lua profile","lua profile","traffic"] },
"nodes": [49772551,49772552,49786799,49786800,49786801,49786802],
"speed": [0.3, 0.3, 0.3, 0.3, 0.3]
}
@@ -548,10 +562,12 @@ Annotation of the whole route leg with fine-grained information about each segme
- `distance`: The distance, in metres, between each pair of coordinates
- `duration`: The duration between each pair of coordinates, in seconds. Does not include the duration of any turns.
- `datasources`: The index of the datasource for the speed between each pair of coordinates. `0` is the default profile, other values are supplied via `--segment-speed-file` to `osrm-contract`
- `datasources`: The index of the datasource for the speed between each pair of coordinates. `0` is the default profile, other values are supplied via `--segment-speed-file` to `osrm-contract` or `osrm-customize`. String-like names are in the `metadata.datasource_names` array.
- `nodes`: The OSM node ID for each coordinate along the route, excluding the first/last user-supplied coordinates
- `weight`: The weights between each pair of coordinates. Does not include any turn costs.
- `speed`: Convenience field, calculation of `distance / duration` rounded to one decimal place
- `metadata`: Metadata related to other annotations
- `datasource_names`: The names of the datasources used for the speed between each pair of coordinates. `lua profile` is the default profile, other values arethe filenames supplied via `--segment-speed-file` to `osrm-contract` or `osrm-customize`
#### Example
@@ -560,6 +576,7 @@ Annotation of the whole route leg with fine-grained information about each segme
"distance": [5,5,10,5,5],
"duration": [15,15,40,15,15],
"datasources": [1,0,0,0,1],
"metadata": { "datasource_names": ["traffic","lua profile","lua profile","lua profile","traffic"] },
"nodes": [49772551,49772552,49786799,49786800,49786801,49786802],
"weight": [15,15,40,15,15]
}
+2 -1
View File
@@ -25,6 +25,7 @@ var osrm = new OSRM('network.osrm');
Make sure you prepared the dataset with the correct toolchain.
- `options.shared_memory` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Connects to the persistent shared memory datastore.
This requires you to run `osrm-datastore` prior to creating an `OSRM` object.
- `options.memory_file` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** Path to a file on disk to store the memory using mmap.
- `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 (default: unlimited).
@@ -61,7 +62,7 @@ Returns the fastest route between two or more coordinates while visiting the way
```javascript
var osrm = new OSRM("berlin-latest.osrm");
osrm.route({coordinates: [[52.519930,13.438640], [52.513191,13.415852]]}, function(err, result) {
osrm.route({coordinates: [[13.438640,52.519930], [13.415852,52.513191]]}, function(err, result) {
if(err) throw err;
console.log(result.waypoints); // array of Waypoint objects representing all waypoints in order
console.log(result.routes); // array of Route objects ordered by descending recommendation rank
+8 -6
View File
@@ -43,12 +43,14 @@ We may introduce forward-compatible changes: query parameters and response prope
1. Check out the appropriate release branch `x.y`
2. Make sure `CHANGELOG.md` is up to date.
3. Make sure the OSRM version in `CMakeLists.txt` is up to date
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 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`
3. Make sure the `package.json` is up to date.
4. Make sure all tests are passing (e.g. Travis CI gives you a :thumbs_up:)
5. Use an annotated tag to mark the release: `git tag vx.y.z -a` Body of the tag description should be the changelog entries.
6. 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
7. Push tags and commits: `git push; git push --tags`
8. On https://github.com/Project-OSRM/osrm-backend/releases press `Draft a new release`,
write the release tag `vx.y.z` in the `Tag version` field, write the changelog entries in the `Describe this release` field
and press `Publish release`.
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:
`rm -rf node_modules && npm install` locally.
+10 -8
View File
@@ -46,12 +46,14 @@ Feature: Bike - Cycle tracks/lanes
| primary | | | | x | x |
| motorway | | | | | |
| motorway | track | | | x | |
| motorway | opposite | | | | x |
| motorway | | track | | | x |
| motorway | | opposite | | | x |
| motorway | opposite | | | x | x |
| motorway | | track | | x | |
| motorway | | opposite | | x | x |
| motorway | | | track | x | |
| motorway | | | opposite | x | |
| motorway | | track | track | x | x |
| motorway | | | opposite | x | x |
# motorways are implicit oneways and cycleway tracks next to oneways always
# follow the oneway direction (unless tagged as opposite)
| motorway | | track | track | x | |
| motorway | | opposite | opposite | x | x |
| motorway | | track | opposite | x | x |
| motorway | | opposite | track | x | x |
@@ -92,6 +94,6 @@ Feature: Bike - Cycle tracks/lanes
Then routability should be
| highway | cycleway | oneway | forw | backw |
| motorway | track | yes | 15 km/h | |
| residential | track | yes | 15 km/h | 6 km/h +-1 |
| cycleway | track | yes | 15 km/h | 6 km/h +-1 |
| footway | track | yes | 15 km/h | 6 km/h +-1 |
| residential | track | yes | 15 km/h | 4 km/h +-1 |
| cycleway | track | yes | 15 km/h | 4 km/h +-1 |
| footway | track | yes | 15 km/h | 4 km/h +-1 |
+9 -2
View File
@@ -141,5 +141,12 @@ Feature: Bike - Oneway streets
| highway | oneway | cycleway:left | cycleway:right | forw | backw |
| primary | yes | | | cycling | pushing bike |
| primary | yes | | track | cycling | pushing bike |
| primary | yes | track | | cycling | cycling |
| primary | yes | track | track | cycling | cycling |
| primary | yes | track | | cycling | pushing bike |
| primary | yes | track | track | cycling | pushing bike |
Scenario: Bike - Left/right cycleways on any oneways
Then routability should be
| foot | oneway | cycleway:left | cycleway:right | forw | backw |
| no | yes | track | | cycling | |
| yes | yes | track | | cycling | pushing bike |
| yes | -1 | track | | pushing bike | cycling |
+9 -9
View File
@@ -19,7 +19,7 @@ Feature: Bicycle - Adds penalties to unsafe roads
| tertiary_link | | 15 km/h | 15 km/h | 3.3 | 3.3 |
| residential | | 15 km/h | 15 km/h | 4.2 | 4.2 |
| cycleway | | 15 km/h | 15 km/h | 4.2 | 4.2 |
| footway | | 6 km/h +-1 | 6 km/h +-1 | 1.7 | 1.7 |
| footway | | 4 km/h +-1 | 4 km/h +-1 | 1.1 | 1.1 |
Scenario: Bike - Apply no penalties to ways with cycleways
Then routability should be
@@ -59,8 +59,8 @@ Feature: Bicycle - Adds penalties to unsafe roads
| tertiary_link | track | | 15 km/h | 15 km/h | 4.2 | 3.3 |
| residential | track | | 15 km/h | 15 km/h | 4.2 | 4.2 |
| cycleway | track | | 15 km/h | 15 km/h | 4.2 | 4.2 |
| footway | track | | 15 km/h | 6 km/h +-1 | 4.2 | 1.7 |
| motorway | | track | | 15 km/h | | 4.2 |
| footway | track | | 15 km/h | 4 km/h +-1 | 4.2 | 1.1 |
| motorway | | track | 15 km/h | | 4.2 | |
| primary | | track | 15 km/h | 15 km/h | 2.9 | 4.2 |
| secondary | | track | 15 km/h | 15 km/h | 3.1 | 4.2 |
| tertiary | | track | 15 km/h | 15 km/h | 3.3 | 4.2 |
@@ -69,7 +69,7 @@ Feature: Bicycle - Adds penalties to unsafe roads
| tertiary_link | | track | 15 km/h | 15 km/h | 3.3 | 4.2 |
| residential | | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| cycleway | | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| footway | | track | 6 km/h +-1 | 15 km/h | 1.7 | 4.2 |
| footway | | track | 4 km/h +-1 | 15 km/h | 1.1 | 4.2 |
| motorway | lane | | 15 km/h | | 4.2 | |
| primary | lane | | 15 km/h | 15 km/h | 4.2 | 2.9 |
| secondary | lane | | 15 km/h | 15 km/h | 4.2 | 3.1 |
@@ -79,8 +79,8 @@ Feature: Bicycle - Adds penalties to unsafe roads
| tertiary_link | lane | | 15 km/h | 15 km/h | 4.2 | 3.3 |
| residential | lane | | 15 km/h +-1 | 15 km/h +-1 | 4.2 | 4.2 |
| cycleway | lane | | 15 km/h | 15 km/h | 4.2 | 4.2 |
| footway | lane | | 15 km/h | 6 km/h +-1 | 4.2 | 1.7 |
| motorway | | lane | | 15 km/h | | 4.2 |
| footway | lane | | 15 km/h | 4 km/h +-1 | 4.2 | 1.1 |
| motorway | | lane | 15 km/h | | 4.2 | |
| primary | | lane | 15 km/h | 15 km/h | 2.9 | 4.2 |
| secondary | | lane | 15 km/h +-1 | 15 km/h +-1 | 3.1 | 4.2 |
| tertiary | | lane | 15 km/h | 15 km/h | 3.3 | 4.2 |
@@ -89,10 +89,10 @@ Feature: Bicycle - Adds penalties to unsafe roads
| tertiary_link | | lane | 15 km/h | 15 km/h | 3.3 | 4.2 |
| residential | | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| cycleway | | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| footway | | lane | 6 km/h +-1 | 15 km/h | 1.7 | 4.2 |
| footway | | lane | 4 km/h +-1 | 15 km/h | 1.1 | 4.2 |
| motorway | shared_lane | | 15 km/h | | 4.2 | |
| primary | shared_lane | | 15 km/h | 15 km/h | 4.2 | 2.9 |
| motorway | | shared_lane | | 15 km/h | | 4.2 |
| motorway | | shared_lane | 15 km/h | | 4.2 | |
| primary | | shared_lane | 15 km/h | 15 km/h | 2.9 | 4.2 |
@@ -101,4 +101,4 @@ Feature: Bicycle - Adds penalties to unsafe roads
| highway | cycleway | forw | backw | forw_rate | backw_rate |
| tertiary | shared_lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| tertiary | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| tertiary | opposite | 15 km/h | 15 km/h | 3.3 | 4.2 |
| tertiary | opposite | 15 km/h | 15 km/h | 3.3 | 3.3 |
+3 -3
View File
@@ -54,6 +54,6 @@ Feature: Bike - Surfaces
When I route I should get
| from | to | route | modes | speed |
| a | b | ab,ab | cycling,cycling | 15 km/h |
| b | a | ab,ab | pushing bike,pushing bike | 6 km/h |
| c | d | cd,cd | pushing bike,pushing bike | 6 km/h |
| d | c | cd,cd | pushing bike,pushing bike | 6 km/h |
| b | a | ab,ab | pushing bike,pushing bike | 4 km/h |
| c | d | cd,cd | pushing bike,pushing bike | 4 km/h |
| d | c | cd,cd | pushing bike,pushing bike | 4 km/h |
+8
View File
@@ -45,3 +45,11 @@ Feature: Car - Barriers
| bollard | | |
| bollard | rising | x |
| bollard | removable | |
Scenario: Car - Height restrictions
Then routability should be
| node/barrier | node/maxheight | bothw |
| height_restrictor | | x |
| height_restrictor | 1 | |
| height_restrictor | 3 | x |
| height_restrictor | default | x |
+18 -18
View File
@@ -691,14 +691,14 @@ Feature: Car - Turn restrictions
# """
Given the node locations
| node | lat | lon |
| a | 38.9113 | -77.0091 |
| b | 38.9108 | -77.0091 |
| c | 38.9104 | -77.0091 |
| d | 38.9110 | -77.0096 |
| e | 38.9106 | -77.0086 |
| f | 38.9105 | -77.0090 |
| g | 38.9108 | -77.0090 |
| h | 38.9113 | -77.0090 |
| a | 38.91124 | -77.00909 |
| b | 38.91080 | -77.00909 |
| c | 38.91038 | -77.00909 |
| d | 38.91105 | -77.00967 |
| e | 38.91037 | -77.00807 |
| f | 38.91036 | -77.00899 |
| g | 38.91076 | -77.00901 |
| h | 38.91124 | -77.00900 |
And the ways
| nodes | oneway | name |
@@ -719,7 +719,7 @@ Feature: Car - Turn restrictions
When I route I should get
| from | to | route | turns |
| a | e | cap south,florida nw,florida nw,florida ne | depart,turn right,continue uturn,arrive |
| f | d | cap north,florida,florida nw | depart,turn left,arrive |
| f | d | cap north,florida nw,florida nw | depart,turn left,arrive |
| e | c | florida ne,florida nw,cap south,cap south | depart,continue uturn,turn right,arrive |
@no_turning @conditionals
@@ -738,14 +738,14 @@ Feature: Car - Turn restrictions
# """
Given the node locations
| node | lat | lon |
| a | 38.9113 | -77.0091 |
| b | 38.9108 | -77.0091 |
| c | 38.9104 | -77.0091 |
| d | 38.9110 | -77.0096 |
| e | 38.9106 | -77.0086 |
| f | 38.9105 | -77.0090 |
| g | 38.9108 | -77.0090 |
| h | 38.9113 | -77.0090 |
| a | 38.91124 | -77.00909 |
| b | 38.91080 | -77.00909 |
| c | 38.91038 | -77.00909 |
| d | 38.91105 | -77.00967 |
| e | 38.91037 | -77.00807 |
| f | 38.91036 | -77.00899 |
| g | 38.91076 | -77.00901 |
| h | 38.91124 | -77.00900 |
And the ways
| nodes | oneway | name |
@@ -765,7 +765,7 @@ Feature: Car - Turn restrictions
When I route I should get
| from | to | route | turns |
| a | e | cap south,florida,florida ne | depart,turn left,arrive |
| a | e | cap south,florida ne,florida ne | depart,turn left,arrive |
| f | d | cap north,florida ne,florida ne,florida nw | depart,turn sharp right,continue uturn,arrive |
| e | c | florida ne,cap south,cap south | depart,turn left,arrive |
+9 -8
View File
@@ -135,12 +135,12 @@ Feature: Car - Destination only, no passing through
Scenario: Car - Routing through a parking lot tagged access=destination,service
Given the node map
"""
a----c++++b+++g----h---i
| + + + |
| + + + |
| + + + |
a----c++++b+++g------h---i
| + + + /
| + + + /
| + + + /
| d++++e+f /
z---------------y
z--------------y
"""
And the ways
@@ -155,9 +155,10 @@ Feature: Car - Destination only, no passing through
| gf | destination | service |
When I route I should get
| from | to | route |
| a | i | azyhi,azyhi |
| b | f | be,def,def |
| from | to | route |
| a | i | azyhi,azyhi |
| b | f | be,def,def |
| b | i | cbg,ghi,azyhi,azyhi |
Scenario: Car - Disallow snapping to access=private,highway=service
Given a grid size of 20 meters
+5 -5
View File
@@ -22,11 +22,11 @@ Feature: Bike - Mode flag
| c | traffic_signals |
And the ways
| nodes | highway | name | oneway:bicycle |
| abcd | cycleway | street | |
| eb | path | | yes |
| icef | tertiary | road | |
| geh | secondary | street | |
| nodes | highway | name | oneway:bicycle | maxspeed:forward |
| abcd | cycleway | street | | 4 km/h |
| eb | path | | yes | |
| icef | tertiary | road | | 4 km/h |
| geh | secondary | street | | |
When I route I should get
| waypoints | route | turns |
+55 -53
View File
@@ -35,20 +35,20 @@ Feature: Collapse
| waypoints | route | turns | locations |
| a,l | first,second,second | depart,turn right,arrive | a,b,l |
| a,d | first,first | depart,arrive | a,d |
| a,j | first,second,second | depart,turn left,arrive | a,c,j |
| a,h | first,first,first | depart,continue uturn,arrive | a,c,h |
| a,j | first,second,second | depart,turn left,arrive | a,b,j |
| a,h | first,first,first | depart,continue uturn,arrive | a,b,h |
| e,j | first,second,second | depart,turn right,arrive | e,f,j |
| e,h | first,first | depart,arrive | e,h |
| e,l | first,second,second | depart,turn left,arrive | e,g,l |
| e,d | first,first,first | depart,continue uturn,arrive | e,g,d |
| e,l | first,second,second | depart,turn left,arrive | e,f,l |
| e,d | first,first,first | depart,continue uturn,arrive | e,f,d |
| k,h | second,first,first | depart,turn right,arrive | k,g,h |
| k,l | second,second | depart,arrive | k,l |
| k,d | second,first,first | depart,turn left,arrive | k,b,d |
| k,j | second,second,second | depart,continue uturn,arrive | k,b,j |
| k,d | second,first,first | depart,turn left,arrive | k,g,d |
| k,j | second,second,second | depart,continue uturn,arrive | k,g,j |
| i,d | second,first,first | depart,turn right,arrive | i,c,d |
| i,j | second,second | depart,arrive | i,j |
| i,h | second,first,first | depart,turn left,arrive | i,f,h |
| i,l | second,second,second | depart,continue uturn,arrive | i,f,l |
| i,h | second,first,first | depart,turn left,arrive | i,c,h |
| i,l | second,second,second | depart,continue uturn,arrive | i,c,l |
Scenario: Segregated Intersection, Cross Belonging to Single Street
Given the node map
@@ -74,7 +74,7 @@ Feature: Collapse
When I route I should get
| waypoints | route | turns | locations |
| a,i | first,second,third,third | depart,turn left,turn slight left,arrive | a,b,e,i |
| a,i | first,third,third | depart,turn sharp left,arrive | a,b,i |
Scenario: Segregated Intersection, Cross Belonging to Correct Street
Given the node map
@@ -106,20 +106,20 @@ Feature: Collapse
| waypoints | route | turns | locations |
| a,l | first,second,second | depart,turn right,arrive | a,b,l |
| a,d | first,first | depart,arrive | a,d |
| a,j | first,second,second | depart,turn left,arrive | a,c,j |
| a,h | first,first,first | depart,continue uturn,arrive | a,c,h |
| a,j | first,second,second | depart,turn left,arrive | a,b,j |
| a,h | first,first,first | depart,continue uturn,arrive | a,b,h |
| e,j | first,second,second | depart,turn right,arrive | e,f,j |
| e,h | first,first | depart,arrive | e,h |
| e,l | first,second,second | depart,turn left,arrive | e,g,l |
| e,d | first,first,first | depart,continue uturn,arrive | e,g,d |
| e,l | first,second,second | depart,turn left,arrive | e,f,l |
| e,d | first,first,first | depart,continue uturn,arrive | e,f,d |
| k,h | second,first,first | depart,turn right,arrive | k,g,h |
| k,l | second,second | depart,arrive | k,l |
| k,d | second,first,first | depart,turn left,arrive | k,b,d |
| k,j | second,second,second | depart,continue uturn,arrive | k,b,j |
| k,d | second,first,first | depart,turn left,arrive | k,g,d |
| k,j | second,second,second | depart,continue uturn,arrive | k,g,j |
| i,d | second,first,first | depart,turn right,arrive | i,c,d |
| i,j | second,second | depart,arrive | i,j |
| i,h | second,first,first | depart,turn left,arrive | i,f,h |
| i,l | second,second,second | depart,continue uturn,arrive | i,f,l |
| i,h | second,first,first | depart,turn left,arrive | i,c,h |
| i,l | second,second,second | depart,continue uturn,arrive | i,c,l |
Scenario: Segregated Intersection, Cross Belonging to Mixed Streets
Given the node map
@@ -151,20 +151,20 @@ Feature: Collapse
| waypoints | route | turns | locations |
| a,l | first,second,second | depart,turn right,arrive | a,b,l |
| a,d | first,first | depart,arrive | a,d |
| a,j | first,second,second | depart,turn left,arrive | a,c,j |
| a,h | first,first,first | depart,continue uturn,arrive | a,c,h |
| a,j | first,second,second | depart,turn left,arrive | a,b,j |
| a,h | first,first,first | depart,continue uturn,arrive | a,b,h |
| e,j | first,second,second | depart,turn right,arrive | e,f,j |
| e,h | first,first | depart,arrive | e,h |
| e,l | first,second,second | depart,turn left,arrive | e,g,l |
| e,d | first,first,first | depart,continue uturn,arrive | e,g,d |
| e,l | first,second,second | depart,turn left,arrive | e,f,l |
| e,d | first,first,first | depart,continue uturn,arrive | e,f,d |
| k,h | second,first,first | depart,turn right,arrive | k,g,h |
| k,l | second,second | depart,arrive | k,l |
| k,d | second,first,first | depart,turn left,arrive | k,b,d |
| k,j | second,second,second | depart,continue uturn,arrive | k,b,j |
| k,d | second,first,first | depart,turn left,arrive | k,g,d |
| k,j | second,second,second | depart,continue uturn,arrive | k,g,j |
| i,d | second,first,first | depart,turn right,arrive | i,c,d |
| i,j | second,second | depart,arrive | i,j |
| i,h | second,first,first | depart,turn left,arrive | i,f,h |
| i,l | second,second,second | depart,continue uturn,arrive | i,f,l |
| i,h | second,first,first | depart,turn left,arrive | i,c,h |
| i,l | second,second,second | depart,continue uturn,arrive | i,c,l |
Scenario: Partly Segregated Intersection, Two Segregated Roads
Given the node map
@@ -209,11 +209,11 @@ Feature: Collapse
| d,c | first,first,first | depart,continue uturn,arrive | d,e,c |
| g,c | second,first,first | depart,turn right,arrive | g,b,c |
| g,j | second,second | depart,arrive | g,j |
| g,f | second,first,first | depart,turn left,arrive | g,e,f |
| g,f | second,first,first | depart,turn left,arrive | g,b,f |
| g,h | second,second,second | depart,continue uturn,arrive | g,b,h |
| i,f | second,first,first | depart,turn right,arrive | i,e,f |
| i,h | second,second | depart,arrive | i,h |
| i,c | second,first,first | depart,turn left,arrive | i,b,c |
| i,c | second,first,first | depart,turn left,arrive | i,e,c |
| i,j | second,second,second | depart,continue uturn,arrive | i,e,j |
Scenario: Partly Segregated Intersection, Two Segregated Roads, Intersection belongs to Second
@@ -263,11 +263,11 @@ Feature: Collapse
| d,c | first,first,first | depart,continue uturn,arrive | d,e,c |
| g,c | second,first,first | depart,turn right,arrive | g,b,c |
| g,j | second,second | depart,arrive | g,j |
| g,f | second,first,first | depart,turn left,arrive | g,e,f |
| g,f | second,first,first | depart,turn left,arrive | g,b,f |
| g,h | second,second,second | depart,continue uturn,arrive | g,b,h |
| i,f | second,first,first | depart,turn right,arrive | i,e,f |
| i,h | second,second | depart,arrive | i,h |
| i,c | second,first,first | depart,turn left,arrive | i,b,c |
| i,c | second,first,first | depart,turn left,arrive | i,e,c |
| i,j | second,second,second | depart,continue uturn,arrive | i,e,j |
Scenario: Segregated Intersection, Cross Belonging to Mixed Streets - Slight Angles
@@ -300,20 +300,20 @@ Feature: Collapse
| waypoints | route | turns | locations |
| a,l | first,second,second | depart,turn right,arrive | a,b,l |
| a,d | first,first | depart,arrive | a,d |
| a,j | first,second,second | depart,turn left,arrive | a,c,j |
| a,h | first,first,first | depart,continue uturn,arrive | a,c,h |
| a,j | first,second,second | depart,turn left,arrive | a,b,j |
| a,h | first,first,first | depart,continue uturn,arrive | a,b,h |
| e,j | first,second,second | depart,turn right,arrive | e,f,j |
| e,h | first,first | depart,arrive | e,h |
| e,l | first,second,second | depart,turn left,arrive | e,g,l |
| e,d | first,first,first | depart,continue uturn,arrive | e,g,d |
| e,l | first,second,second | depart,turn left,arrive | e,f,l |
| e,d | first,first,first | depart,continue uturn,arrive | e,f,d |
| k,h | second,first,first | depart,turn right,arrive | k,g,h |
| k,l | second,second | depart,arrive | k,l |
| k,d | second,first,first | depart,turn left,arrive | k,b,d |
| k,j | second,second,second | depart,continue uturn,arrive | k,b,j |
| k,d | second,first,first | depart,turn left,arrive | k,g,d |
| k,j | second,second,second | depart,continue uturn,arrive | k,g,j |
| i,d | second,first,first | depart,turn right,arrive | i,c,d |
| i,j | second,second | depart,arrive | i,j |
| i,h | second,first,first | depart,turn left,arrive | i,f,h |
| i,l | second,second,second | depart,continue uturn,arrive | i,f,l |
| i,h | second,first,first | depart,turn left,arrive | i,c,h |
| i,l | second,second,second | depart,continue uturn,arrive | i,c,l |
Scenario: Segregated Intersection, Cross Belonging to Mixed Streets - Slight Angles (2)
Given the node map
@@ -345,28 +345,29 @@ Feature: Collapse
| waypoints | route | turns | locations |
| a,l | first,second,second | depart,turn right,arrive | a,b,l |
| a,d | first,first | depart,arrive | a,d |
| a,j | first,second,second | depart,turn left,arrive | a,c,j |
| a,h | first,first,first | depart,continue uturn,arrive | a,c,h |
| a,j | first,second,second | depart,turn left,arrive | a,b,j |
| a,h | first,first,first | depart,continue uturn,arrive | a,b,h |
| e,j | first,second,second | depart,turn right,arrive | e,f,j |
| e,h | first,first | depart,arrive | e,h |
| e,l | first,second,second | depart,turn left,arrive | e,g,l |
| e,d | first,first,first | depart,continue uturn,arrive | e,g,d |
| e,l | first,second,second | depart,turn left,arrive | e,f,l |
| e,d | first,first,first | depart,continue uturn,arrive | e,f,d |
| k,h | second,first,first | depart,turn right,arrive | k,g,h |
| k,l | second,second | depart,arrive | k,l |
| k,d | second,first,first | depart,turn left,arrive | k,b,d |
| k,j | second,second,second | depart,continue uturn,arrive | k,b,j |
| k,d | second,first,first | depart,turn left,arrive | k,g,d |
| k,j | second,second,second | depart,continue uturn,arrive | k,g,j |
| i,d | second,first,first | depart,turn right,arrive | i,c,d |
| i,j | second,second | depart,arrive | i,j |
| i,h | second,first,first | depart,turn left,arrive | i,f,h |
| i,l | second,second,second | depart,continue uturn,arrive | i,f,l |
| i,h | second,first,first | depart,turn left,arrive | i,c,h |
| i,l | second,second,second | depart,continue uturn,arrive | i,c,l |
Scenario: Entering a segregated road
Given the node map
"""
a f g
| | . '
b-e '
/ /
h
a f | g
| | i '
b-e ' |
/ / j
/ /
c d
"""
@@ -376,7 +377,8 @@ Feature: Collapse
| abc | primary | first | yes |
| def | primary | first | yes |
| be | primary | first | no |
| ge | primary | second | no |
| gie | primary | second | no |
| hij | primary | maple | no |
When I route I should get
| waypoints | route | turns | locations |
@@ -385,7 +387,7 @@ Feature: Collapse
| a,g | first,second,second | depart,turn left,arrive | a,b,g |
| d,g | first,second,second | depart,turn right,arrive | d,e,g |
| g,f | second,first,first | depart,turn right,arrive | g,e,f |
| g,c | second,first,first | depart,turn left,arrive | g,e,c |
| g,c | second,first,first | depart,end of road left,arrive | g,e,c |
Scenario: Do not collapse turning roads
Given the node map
@@ -603,7 +605,7 @@ Feature: Collapse
When I route I should get
| waypoints | route | turns | locations |
| i,h | in,road,road | depart,turn left,arrive | i,f,h |
| i,h | in,road,road | depart,turn slight left,arrive | i,c,h |
| a,d | road,road | depart,arrive | a,d |
| a,j | road,out,out | depart,turn slight right,arrive | a,b,j |
@@ -1010,7 +1012,7 @@ Feature: Collapse
| f,j | hohe,hohe | depart,arrive | f,j |
| a,t | hohe,a100,a100 | depart,on ramp right,arrive | a,b,t |
| f,e | | | |
| q,j | a100,hohe,hohe | depart,turn right,arrive | q,p,j |
| q,j | a100,hohe,hohe | depart,turn right,arrive | q,i,j |
| q,e | a100,hohebruecke,hohe | depart,turn left,arrive | q,p,e |
Scenario: Forking before a turn (forky)
@@ -687,7 +687,7 @@ Feature: Slipways and Dedicated Turn Lanes
When I route I should get
| waypoints | route | turns | locations |
| s,f | sabc,ae,dbef,dbef | depart,turn slight right,turn right,arrive | s,a,e,f |
| s,f | sabc,ae,dbef,dbef | depart,fork slight right,turn right,arrive | s,a,e,f |
@sliproads
Scenario: Traffic Signal on Sliproad
+50 -13
View File
@@ -13,19 +13,23 @@ Feature: Divided road entry
d-------e-----f
|
|
g
i---g---j
|
|
h
"""
And the ways
| nodes | name | highway | oneway |
| abc | main st | residential | -1 |
| def | main st | residential | yes |
| be | main st | residential | |
| eg | side st | residential | |
| nodes | name | highway | oneway |
| abc | main st | residential | -1 |
| def | main st | residential | yes |
| be | main st | residential | |
| egh | side st | residential | |
| igj | maple st | residential | |
When I route I should get
| waypoints | route | turns |
| g,a | side st,main st,main st| depart,end of road left,arrive |
| h,a | side st,main st,main st| depart,end of road left,arrive |
# Similar to previous one, but the joining way is tagged with the side-street name
@@ -37,18 +41,22 @@ Feature: Divided road entry
d-------e-----f
|
|
g
i---g---j
|
|
h
"""
And the ways
| nodes | name | highway | oneway |
| abc | main st | residential | -1 |
| def | main st | residential | yes |
| beg | side st | residential | |
| nodes | name | highway | oneway |
| abc | main st | residential | -1 |
| def | main st | residential | yes |
| begh | side st | residential | |
| igj | maple st | residential | |
When I route I should get
| waypoints | route | turns |
| g,a | side st,main st,main st| depart,end of road left,arrive |
| h,a | side st,main st,main st| depart,end of road left,arrive |
# Center join named after crossroad
@@ -100,3 +108,32 @@ Feature: Divided road entry
When I route I should get
| waypoints | route | turns |
| g,a | side st,main st,main st| depart,turn left,arrive |
# Verify end of road left turn across divided roads
Scenario: Join on a divided road, named after the side street
Given the node map
"""
a-----h--b-----c
| |
d-----i--e-----f
| |
| |
m---j--g---n
| |
| |
k l
"""
And the ways
| nodes | name | highway | oneway |
| ahbc | main st | residential | -1 |
| dief | main st | residential | yes |
| begl | side st | residential | -1 |
| hijk | side st | residential | yes |
| mjgn | maple st| residential | no |
When I route I should get
| waypoints | route | turns |
| l,a | side st,main st,main st| depart,end of road left,arrive |
+20
View File
@@ -46,3 +46,23 @@ Feature: Driveways intersections
When I route I should get
| waypoints | route | turns | locations |
| a,d | ,second | depart,arrive | a,d |
Scenario: Road with a turn to service road
Given the node map
"""
/-----------------e
a---b------------------c
`-----------------d
"""
And the ways
| nodes | highway | name | oneway |
| abc | trunk | road | yes |
| bd | service | serv | yes |
| be | service | serv | yes |
When I route I should get
| waypoints | route | turns | locations |
| a,d | road,serv,serv | depart,turn slight right,arrive | a,b,d |
| a,e | road,serv,serv | depart,turn slight left,arrive | a,b,e |
@@ -0,0 +1,46 @@
@guidance
Feature: Internal Intersection Model
Background:
Given the profile "car"
Given a grid size of 10 meters
Scenario: Dual-carriage way intersection
Given the node map
"""
a b
| |
c--d--e--f
| |
g--h--i--j
| |
k l
"""
And the ways
| nodes | oneway | name |
| adhk | yes | Broken Land Parkway |
| lieb | yes | Broken Land Parkway |
| fed | yes | Snowden River Parkway |
| dc | yes | Patuxent Woods Drive |
| gh | yes | Patuxent Woods Drive |
| hij | yes | Snowden River Parkway |
When I route I should get
| waypoints | route | turns | # |
| a,k | Broken Land Parkway,Broken Land Parkway | depart,arrive ||
| l,b | Broken Land Parkway,Broken Land Parkway | depart,arrive ||
# | g,j | Patuxent Woods Drive,Snowden River Parkway,Snowden River Parkway | depart,continue,arrive | did not work as expected - might be another issue to handle in post process? |
# | f,c | Snowden River Parkway,Patuxent Woods Drive,Patuxent Woods Drive | depart,continue,arrive | did not work as expected - might be another issue to handle in post process? |
| a,c | Broken Land Parkway,Patuxent Woods Drive,Patuxent Woods Drive | depart,turn right,arrive ||
| g,k | Patuxent Woods Drive,Broken Land Parkway,Broken Land Parkway | depart,turn right,arrive ||
| l,j | Broken Land Parkway,Snowden River Parkway,Snowden River Parkway | depart,turn right,arrive ||
| f,b | Snowden River Parkway,Broken Land Parkway,Broken Land Parkway | depart,turn right,arrive ||
| a,j | Broken Land Parkway,Snowden River Parkway,Snowden River Parkway | depart,turn left,arrive ||
| g,b | Patuxent Woods Drive,Broken Land Parkway,Broken Land Parkway | depart,turn left,arrive ||
| l,c | Broken Land Parkway,Patuxent Woods Drive,Patuxent Woods Drive | depart,turn left,arrive ||
| f,k | Snowden River Parkway,Broken Land Parkway,Broken Land Parkway | depart,turn left,arrive ||
| a,b | Broken Land Parkway,Broken Land Parkway,Broken Land Parkway | depart,continue uturn,arrive ||
| g,c | Patuxent Woods Drive,Patuxent Woods Drive,Patuxent Woods Drive | depart,continue uturn,arrive ||
| l,k | Broken Land Parkway,Broken Land Parkway,Broken Land Parkway | depart,continue uturn,arrive ||
| f,j | Snowden River Parkway,Snowden River Parkway,Snowden River Parkway | depart,continue uturn,arrive ||
+3 -3
View File
@@ -64,9 +64,9 @@ Feature: Exceptions for routing onto low-priority roads
| bc | service | |
When I route I should get
| waypoints | route | turns |
| e,c | service, | depart,arrive |
| c,e | ,service,service | depart,turn straight,arrive |
| waypoints | route | turns |
| e,c | service, | depart,arrive |
| c,e | ,service | depart,arrive |
Scenario: Straight onto low-priority
Given the node map
+31 -7
View File
@@ -27,14 +27,23 @@ Feature: Maneuver tag support
| maneuver | abc | c | cgi | turn | sharp_right |
| maneuver | hij | i | cde | turn | sharp_left |
| maneuver | abc | c | cde | turn | slight_left |
| maneuver | cde | c | cgi | turn | straight |
| manoeuvre| cgi | c | abc | turn | right |
And the relations
| type | way:from | node:via | way:to | manoeuvre | maneuver | direction |
| maneuver | cgi | c | cde | fork | turn | slight_right |
When I route I should get
| waypoints | route | turns |
# Testing directly connected from/to
# Testing directly connected from/to
| a,j | A Street,C Street,J Street,J Street | depart,turn sharp right,turn left,arrive |
| b,g | A Street,C Street,C Street | depart,turn sharp right,arrive |
# Testing re-awakening suppressed turns
| a,e | A Street,B Street,B Street | depart,turn slight left,arrive |
| e,i | B Street,C Street,C Street | depart,turn straight,arrive |
| i,e | C Street,B Street,B Street | depart,fork slight right,arrive |
| i,a | C Street,A Street,A Street | depart,turn right,arrive |
Scenario: single via-way
Given the node map
@@ -198,11 +207,26 @@ Feature: Maneuver tag support
| pt | 395 | no | primary |
And the relations
| type | way:from | node:via | way:via | way:to | maneuver |
| maneuver | zy | p | yp | pt | suppress |
| type | way:from | node:via | way:via | way:to | maneuver | # |
| maneuver | zy | p | yp | pt | suppress | original: depart,on ramp left,fork slight left,arrive |
And the relations
| type | way:from | way:via | way:to | maneuver | # |
| maneuver | zy | yp | pb | suppress | invalid relation: missing node:via |
And the relations
| type | node:via | way:via | way:to | maneuver | # |
| maneuver | p | yp | pb | suppress | invalid relation: missing way:from |
And the relations
| type | way:from | node:via | way:via | maneuver | # |
| maneuver | zy | p | yp | suppress | invalid relation: missing way:to |
And the relations
| type | way:from | node:via | way:via | way:to | maneuver | # |
| maneuver | zy | y, p | yp | pb | suppress | invalid relation: multiple node:via |
When I route I should get
| waypoints | route | turns |
| z,t | NY Ave,395,395 | depart,on ramp left,arrive |
#original | z,t | NY Ave,,395,395 | depart,on ramp left,fork slight left,arrive |
| waypoints | route | turns |
| z,t | NY Ave,395,395 | depart,on ramp left,arrive |
| z,b | NY Ave,,4th St,4th St | depart,on ramp left,fork slight right,arrive |
@@ -384,9 +384,9 @@ Feature: Merge Segregated Roads
| cd | right | no |
When I route I should get
| waypoints | route | intersections |
| a,d | left,circle,circle,right,right | true:90;false:90 true:120 false:270;true:60 true:180 false:300;true:90 false:240 true:270;true:270 |
| g,d | bottom,circle,right,right | true:0;true:60 false:180 false:300;true:90 false:240 true:270;true:270 |
| waypoints | route | intersections |
| a,d | left,circle,right,right | true:90,false:90 true:120 false:270;true:60 true:180 false:300;true:90 false:240 true:270;true:270 |
| g,d | bottom,circle,right,right | true:0;true:60 false:180 false:300;true:90 false:240 true:270;true:270 |
Scenario: Middle Island
Given the node map
@@ -644,7 +644,7 @@ Feature: Merge Segregated Roads
| k,j | marianne,albrecht,luise,luise | depart,turn left,turn left,arrive |
| k,d | marianne,schwert,schwert | depart,turn right,arrive |
| i,j | luise,luise | depart,arrive |
| i,d | luise,albrecht,schwert,schwert | depart,turn left,turn straight,arrive |
| i,d | luise,albrecht,schwert | depart,turn left,arrive |
| i,l | luise,albrecht,marianne,marianne | depart,turn left,turn left,arrive |
# https://www.openstreetmap.org/#map=19/52.46339/13.40272
+67 -3
View File
@@ -81,7 +81,7 @@ Feature: Motorway Guidance
"""
,g,e
,f,d
a-b-c
a-b-c
"""
And the ways
@@ -201,7 +201,7 @@ Feature: Motorway Guidance
| a,e | abcde,abcde | depart,arrive |
| f,e | fgc,abcde,abcde | depart,merge slight left,arrive |
| a,i | abcde,chi,chi | depart,off ramp slight right,arrive |
| f,i | fgc,chi,chi | depart,off ramp right,arrive |
| f,i | fgc,chi,chi | depart,off ramp slight right,arrive |
Scenario: On And Off Ramp Left
Given the node map
@@ -221,7 +221,7 @@ Feature: Motorway Guidance
| a,e | abcde,abcde | depart,arrive |
| f,e | fgc,abcde,abcde | depart,merge slight right,arrive |
| a,i | abcde,chi,chi | depart,off ramp slight left,arrive |
| f,i | fgc,chi,chi | depart,off ramp left,arrive |
| f,i | fgc,chi,chi | depart,off ramp slight left,arrive |
Scenario: Merging Motorways
Given the node map
@@ -281,3 +281,67 @@ Feature: Motorway Guidance
| waypoints | route | turns |
| a,d | , | depart,arrive |
| b,d | , | depart,arrive |
Scenario: Ramp Exit with Lower Priority
Given the node map
"""
a-b-c-d-e
`--f-g
"""
And the ways
| nodes | highway | oneway |
| abcde | trunk | |
| bfg | primary_link | yes |
When I route I should get
| waypoints | route | turns |
| a,e | abcde,abcde | depart,arrive |
| a,g | abcde,bfg,bfg | depart,off ramp slight right,arrive |
# https://www.openstreetmap.org/node/67366428#map=18/33.64613/-84.44425
Scenario: Ramp Bifurcations should not be suppressed
Given the node map
"""
/-----------c /-----------e
a---b------------------d------------f
"""
And the ways
| nodes | highway | name | destination |
| ab | motorway | | |
| bc | motorway_link | | City 17 |
| bd | motorway_link | | |
| de | motorway_link | | Domestic Terminal;Camp Creek Parkway;Riverdale Road |
| df | motorway_link | | Montgomery |
When I route I should get
| waypoints | route | turns |
| a,c | ,, | depart,fork slight left,arrive |
| a,e | ,,, | depart,fork slight right,fork slight left,arrive |
| a,f | ,,, | depart,fork slight right,fork slight right,arrive |
# https://www.openstreetmap.org/#map=19/53.46186/-2.24509
Scenario: Highway Fork with a Link
Given the node map
"""
/-----------d
a-b-c------------e
\-----------f
"""
And the ways
| nodes | highway |
| abce | motorway |
| cf | motorway |
| cd | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,d | abce,cd,cd | depart,off ramp slight left,arrive |
| a,e | abce,abce | depart,arrive |
| a,f | abce,cf,cf | depart,turn slight right,arrive |
File diff suppressed because it is too large Load Diff
+8 -7
View File
@@ -848,6 +848,7 @@ Feature: Simple Turns
| h,a | Heide,Perle,Perle | depart,turn left,arrive | true:16;true:90 true:195 true:270 true:345;true:90 |
#http://www.openstreetmap.org/#map=19/52.53293/13.32956
# adjusted ways to reflect the case geometry for 2/3/2018
Scenario: Curved Exit from Curved Road
Given the node map
"""
@@ -874,16 +875,16 @@ Feature: Simple Turns
And the ways
| nodes | name | oneway | lanes | highway |
| abcd | Siemens | no | 5 | secondary |
| defg | Erna | no | 3 | secondary |
| ab | Siemens | no | 5 | secondary |
| bcdefg | Erna | no | 3 | secondary |
| dhij | Siemens | no | | residential |
When I route I should get
| waypoints | route | turns |
| a,j | Siemens,Siemens,Siemens | depart,continue slight right,arrive |
| a,g | Siemens,Erna | depart,arrive |
| g,j | Erna,Siemens,Siemens | depart,turn left,arrive |
| g,a | Erna,Siemens | depart,arrive |
| waypoints | route | turns |
| a,j | Siemens,Siemens,Siemens | depart,turn slight right,arrive |
| a,g | Siemens,Erna | depart,arrive |
| g,j | Erna,Siemens,Siemens | depart,turn left,arrive |
| g,a | Erna,Siemens | depart,arrive |
#http://www.openstreetmap.org/#map=19/52.51303/13.32170
Scenario: Ernst Reuter Platz
+26 -21
View File
@@ -301,7 +301,7 @@ Feature: Turn Lane Guidance
| e,l | road,cross,cross | depart,turn right,arrive | ,none:false straight:false straight;right:true, |
| i,h | cross,road,road | depart,turn right,arrive | ,, |
| i,j | cross,cross | depart,arrive | ;;left:false straight:true, |
| i,l | cross,cross,cross | depart,continue uturn,arrive | ;,left:true straight:false;left:true straight:false;left:false straight:true, |
| i,l | cross,cross,cross | depart,continue uturn,arrive | ,left:true straight:false;left:true straight:false;left:true straight:false;left:false straight:true, |
@partition-lanes
Scenario: Turn Lanes at Segregated Road
@@ -614,8 +614,9 @@ Feature: Turn Lane Guidance
| |
| |
b d
h c
' -- g - - f
h-----c
| `-f
g
"""
And the ways
@@ -936,48 +937,52 @@ Feature: Turn Lane Guidance
Scenario: Partitioned turn, Slight Curve - maxspeed
Given the node map
"""
f e
| |
| |
| c
a - b ' |
g d
f e
| |
i | |
| | c
h - a - b ' |
j g d
"""
And the ways
| nodes | name | highway | oneway | turn:lanes:forward | maxspeed |
| ha | road | primary | yes | | 1 |
| ab | road | primary | yes | left\|right | 1 |
| bc | cross | primary | yes | | 1 |
| fbg | cross | primary | yes | | 1 |
| dce | cross | primary | yes | | 1 |
| iaj | kross | primary | no | | 1 |
When I route I should get
| waypoints | route | turns | lanes | locations |
| a,g | road,cross,cross | depart,turn right,arrive | ,left:false right:true, | a,b,g |
| a,e | road,cross,cross | depart,end of road left,arrive | ;left:true right:false,left:true right:false, | a,c,e |
| h,g | road,cross,cross | depart,turn right,arrive | ;,left:false right:true, | h,b,g |
| h,e | road,cross,cross | depart,end of road left,arrive | ;,left:true right:false;left:true right:false, | h,b,e |
Scenario: Partitioned turn, Slight Curve
Given the node map
"""
f e
| |
| |
| c
a - b ' |
g d
f e
| |
i | |
| | c
h - a - b ' |
j g d
"""
And the ways
| nodes | name | highway | oneway | turn:lanes:forward |
| ha | road | primary | yes | |
| ab | road | primary | yes | left\|right |
| bc | cross | primary | yes | |
| fbg | cross | primary | yes | |
| dce | cross | primary | yes | |
| iaj | kross | primary | no | |
When I route I should get
| waypoints | route | turns | lanes | locations |
| a,g | road,cross,cross | depart,turn right,arrive | ,left:false right:true, | a,b,g |
| a,e | road,cross,cross | depart,end of road left,arrive | ;left:true right:false,left:true right:false, | a,c,e |
| waypoints | route | turns | lanes | locations |
| h,g | road,cross,cross | depart,turn right,arrive | ;,left:false right:true, | h,b,g |
| h,e | road,cross,cross | depart,end of road left,arrive | ;,left:true right:false;left:true right:false, | h,b,e |
Scenario: Lane Parsing Issue #2694
Given the node map
@@ -1243,4 +1248,4 @@ Feature: Turn Lane Guidance
When I route I should get
| waypoints | route | turns | lanes | locations |
| a,f | road1,road1,road1 | depart,continue uturn,arrive | ;left:false straight:true straight;right:false,left:true straight:false straight;right:false;;, | a,d,f |
| a,f | road1,road1,road1 | depart,continue uturn,arrive | ,;left:true straight:false straight;right:false;;, | a,c,f |
+59 -29
View File
@@ -899,9 +899,9 @@ Feature: Simple Turns
"""
And the ways
| nodes | highway | name |
| abc | primary | road |
| bd | residential | in |
| nodes | highway | name | lanes |
| abc | primary | road | 3 |
| bd | residential | in | 1 |
When I route I should get
| waypoints | turns | route |
@@ -964,15 +964,15 @@ Feature: Simple Turns
Given the node map
"""
g
f y
i
j k a b x
e c
d
|
_--f-----y
i-' |
j-k-a]|[b---x
e 'c
|'d'
|
h
|
q
"""
@@ -1373,6 +1373,36 @@ Feature: Simple Turns
| a,d | ab,bcd,bcd | depart,fork slight right,arrive |
| a,g | ab,befg,befg | depart,fork slight left,arrive |
@routing @car
Scenario: No turn instruction when turning from unnamed onto unnamed
Given the node map
"""
a
|
|
|
|
b----------------c
|
|
|
|
|
|
d
"""
And the ways
| nodes | highway | name | ref |
| ab | trunk_link | | |
| db | secondary | | L 460 |
| bc | secondary | | |
When I route I should get
| from | to | route | ref | turns |
| d | c | ,, | L 460,, | depart,turn right,arrive |
| c | d | ,, | ,L 460,L 460 | depart,turn left,arrive |
# https://www.openstreetmap.org/#map=18/52.25130/10.42545
Scenario: Turn for roads with no name, ref changes
Given the node map
@@ -1404,21 +1434,21 @@ Feature: Simple Turns
Scenario: Turn for roads with no name, ref changes
Given the node map
"""
x
.
.
d
. .
. .
. .
e. . t . c . p. .f
. .
. .
. .
b
.
.
a
x
.
.
d
. .
. .
. .
e. . t . c . p. .f
. .
. .
. .
b
.
.
a
"""
And the ways
@@ -1430,6 +1460,6 @@ Feature: Simple Turns
| etcpf | primary | B 1 | | no |
When I route I should get
| waypoints | route | turns |
| e,x | ,,, | depart,turn sharp left,turn right,arrive |
| f,a | ,, | depart,turn left,arrive |
| waypoints | route | turns |
| e,x | ,, | depart,turn left,arrive |
| f,a | ,, | depart,turn left,arrive |
+6 -5
View File
@@ -47,7 +47,7 @@ class OSRMBaseLoader{
if (err) {
if (retryCount < 10) {
retryCount++;
setTimeout(() => { tryConnect(this.scope.OSRM_PORT, retry); }, 10);
setTimeout(() => { tryConnect(this.scope.OSRM_IP, this.scope.OSRM_PORT, retry); }, 10);
} else {
callback(new Error("Could not connect to osrm-routed after ten retries."));
}
@@ -58,7 +58,7 @@ class OSRMBaseLoader{
}
};
tryConnect(this.scope.OSRM_PORT, retry);
tryConnect(this.scope.OSRM_IP, this.scope.OSRM_PORT, retry);
}
};
@@ -77,7 +77,7 @@ class OSRMDirectLoader extends OSRMBaseLoader {
osrmUp (callback) {
if (this.osrmIsRunning()) return callback(new Error("osrm-routed already running!"));
const command_arguments = util.format('%s -p %d -a %s', this.inputFile, this.scope.OSRM_PORT, this.scope.ROUTING_ALGORITHM);
const command_arguments = util.format('%s -p %d -i %s -a %s', this.inputFile, this.scope.OSRM_PORT, this.scope.OSRM_IP, this.scope.ROUTING_ALGORITHM);
this.child = this.scope.runBin('osrm-routed', command_arguments, this.scope.environment, (err) => {
if (err && err.signal !== 'SIGINT') {
this.child = null;
@@ -107,7 +107,8 @@ class OSRMDatastoreLoader extends OSRMBaseLoader {
}
loadData (callback) {
this.scope.runBin('osrm-datastore', this.inputFile, this.scope.environment, (err) => {
const command_arguments = util.format('--dataset-name=%s %s', this.scope.DATASET_NAME, this.inputFile);
this.scope.runBin('osrm-datastore', command_arguments, this.scope.environment, (err) => {
if (err) return callback(new Error('*** osrm-datastore exited with ' + err.code + ': ' + err));
callback();
});
@@ -116,7 +117,7 @@ class OSRMDatastoreLoader extends OSRMBaseLoader {
osrmUp (callback) {
if (this.osrmIsRunning()) return callback();
const command_arguments = util.format('--shared-memory=1 -p %d -a %s', this.scope.OSRM_PORT, this.scope.ROUTING_ALGORITHM);
const command_arguments = util.format('--dataset-name=%s -s -i %s -p %d -a %s', this.scope.DATASET_NAME, this.scope.OSRM_IP, this.scope.OSRM_PORT, this.scope.ROUTING_ALGORITHM);
this.child = this.scope.runBin('osrm-routed', command_arguments, this.scope.environment, (err) => {
if (err && err.signal !== 'SIGINT') {
this.child = null;
+2 -2
View File
@@ -3,8 +3,8 @@
const net = require('net');
const Timeout = require('node-timeout');
module.exports = function tryConnect(port, callback) {
net.connect({ port: port, host: '127.0.0.1' })
module.exports = function tryConnect(host, port, callback) {
net.connect({ port: port, host: host })
.on('connect', () => { callback(); })
.on('error', () => {
callback(new Error('Could not connect.'));
@@ -0,0 +1,44 @@
@datastore @options @help
Feature: osrm-datastore command line options
Background:
Given the profile "testbot"
And the node map
"""
a b
"""
And the ways
| nodes |
| ab |
And the data has been contracted
Scenario: osrm-datastore - Help should be shown when no options are passed
When I try to run "osrm-datastore --dataset-name test_dataset_42 {processed_file}"
Then it should exit successfully
When I try to run "osrm-datastore --list"
Then it should exit successfully
And stdout should contain "test_dataset_42/static"
And stdout should contain "test_dataset_42/updatable"
Scenario: osrm-datastore - Only metric update should work
Given the speed file
"""
0,1,50
"""
And the data has been extracted
When I try to run "osrm-datastore {processed_file} --dataset-name cucumber/only_metric_test"
Then it should exit successfully
When I try to run "osrm-customize --segment-speed-file {speeds_file} {processed_file}"
Then it should exit successfully
When I try to run "osrm-datastore {processed_file} --dataset-name cucumber/only_metric_test --only-metric"
Then it should exit successfully
Scenario: osrm-datastore - Displaying help should work
When I try to run "osrm-datastore {processed_file} --help"
Then it should exit successfully
Scenario: osrm-datastore - Errors on invalid path
When I try to run "osrm-datastore invalid_path.osrm"
Then stderr should contain "[error] Config contains invalid file paths."
And stderr should contain "Missing/Broken"
And it should exit with an error
+7 -2
View File
@@ -129,8 +129,12 @@ Feature: osrm-extract lua ways:get_nodes()
"""
functions = require('testbot')
functions.process_node = function(profile, node, result, relations)
print ('node ' .. tostring(node:get_location_tag('answer')))
end
functions.process_way = function(profile, way, result, relations)
print ('answer ' .. tostring(way:get_location_tag('answer')))
print ('way ' .. tostring(way:get_location_tag('answer')))
result.forward_mode = mode.driving
result.forward_speed = 1
end
@@ -148,4 +152,5 @@ Feature: osrm-extract lua ways:get_nodes()
When I run "osrm-extract --profile {profile_file} {osm_file} --location-dependent-data test/data/regions/null-island.geojson"
Then it should exit successfully
And stdout should contain "answer 42"
And stdout should contain "node 42"
And stdout should contain "way 42"
@@ -152,7 +152,7 @@ Feature: Turn Function Information
And stdout should contain "number_of_roads 3"
And stdout should contain "source_priority_class 4"
And stdout should contain "target_priority_class 0"
And stdout should contain "target_priority_class 11"
And stdout should contain "target_priority_class 10"
# turning abd, give information about bc
And stdout should contain /roads_on_the_right \[1\] speed: [0-9]+, is_incoming: false, is_outgoing: true, highway_turn_classification: 4, access_turn_classification: 0/
# turning abc, give information about bd
@@ -180,7 +180,3 @@ Feature: Turn Function Information
And stdout should contain /roads_on_the_right \[1\] speed: [0-9]+, is_incoming: true, is_outgoing: false, highway_turn_classification: 3, access_turn_classification: 0/
# turning abc, give information about about db
And stdout should contain /roads_on_the_left \[1\] speed: [0-9]+, is_incoming: true, is_outgoing: false, highway_turn_classification: 0, access_turn_classification: 1/
+1 -1
View File
@@ -74,7 +74,7 @@ module.exports = function () {
if (headers.has('turns')) {
if (json.matchings.length != 1) throw new Error('*** Checking turns only supported for matchings with one subtrace');
turns = this.turnList(json.matchings[0].instructions);
turns = this.turnList(json.matchings[0]);
}
if (headers.has('route')) {
+4 -2
View File
@@ -27,6 +27,7 @@ module.exports = function () {
return callback(new Error('*** '+stxxl_config+ 'does not exist'));
}
this.DATASET_NAME = 'cucumber';
this.PLATFORM_WINDOWS = process.platform.match(/^win.*/);
this.DEFAULT_ENVIRONMENT = Object.assign({STXXLCFG: stxxl_config}, process.env);
this.DEFAULT_PROFILE = 'bicycle';
@@ -43,7 +44,8 @@ module.exports = function () {
this.TIMEZONE_NAMES = this.PLATFORM_WINDOWS ? 'win' : 'iana';
this.OSRM_PORT = process.env.OSRM_PORT && parseInt(process.env.OSRM_PORT) || 5000;
this.HOST = 'http://127.0.0.1:' + this.OSRM_PORT;
this.OSRM_IP = process.env.OSRM_IP || '127.0.0.1';
this.HOST = `http://${this.OSRM_IP}:${this.OSRM_PORT}`;
this.OSRM_PROFILE = process.env.OSRM_PROFILE;
@@ -93,7 +95,7 @@ module.exports = function () {
};
this.verifyOSRMIsNotRunning = (callback) => {
tryConnect(this.OSRM_PORT, (err) => {
tryConnect(this.OSRM_IP, this.OSRM_PORT, (err) => {
if (!err) return callback(new Error('*** osrm-routed is already running.'));
else callback();
});
+14 -2
View File
@@ -199,14 +199,26 @@ module.exports = function () {
var merged = {};
instructions.legs.map(l => {
Object.keys(l.annotation).forEach(a => {
Object.keys(l.annotation).filter(a => !a.match(/metadata/)).forEach(a => {
if (!merged[a]) merged[a] = [];
merged[a].push(l.annotation[a].join(':'));
});
if (l.annotation.metadata) {
merged.metadata = {};
Object.keys(l.annotation.metadata).forEach(a => {
if (!merged.metadata[a]) merged.metadata[a] = [];
merged.metadata[a].push(l.annotation.metadata[a].join(':'));
});
}
});
Object.keys(merged).map(a => {
Object.keys(merged).filter(k => !k.match(/metadata/)).map(a => {
merged[a] = merged[a].join(',');
});
if (merged.metadata) {
Object.keys(merged.metadata).map(a => {
merged.metadata[a] = merged.metadata[a].join(',');
});
}
return merged;
};
+9 -1
View File
@@ -158,7 +158,8 @@ module.exports = function () {
// if header matches 'a:*', parse out the values for *
// and return in that header
headers.forEach((k) => {
let whitelist = ['duration', 'distance', 'datasources', 'nodes', 'weight', 'speed'];
let whitelist = ['duration', 'distance', 'datasources', 'nodes', 'weight', 'speed' ];
let metadata_whitelist = [ 'datasource_names' ];
if (k.match(/^a:/)) {
let a_type = k.slice(2);
if (whitelist.indexOf(a_type) == -1)
@@ -166,6 +167,13 @@ module.exports = function () {
if (annotation && !annotation[a_type])
return cb(new Error('Annotation not found in response', a_type));
got[k] = annotation && annotation[a_type] || '';
} else if (k.match(/^am:/)) {
let a_type = k.slice(3);
if (metadata_whitelist.indexOf(a_type) == -1)
return cb(new Error('Unrecognized annotation field', a_type));
if (annotation && (!annotation.metadata || !annotation.metadata[a_type]))
return cb(new Error('Annotation not found in response', a_type));
got[k] = (annotation && annotation.metadata && annotation.metadata[a_type]) || '';
}
});
+8
View File
@@ -4,6 +4,14 @@ Feature: Alternative route
Background:
Given the profile "testbot"
And a grid size of 200 meters
# Force data preparation to single-threaded to ensure consistent
# results for alternative generation during tests (alternative
# finding is highly sensitive to graph shape, which is in turn
# affected by parallelism during generation)
And the contract extra arguments "--threads 1"
And the extract extra arguments "--threads 1"
And the customize extra arguments "--threads 1"
And the partition extra arguments "--threads 1"
And the node map
"""
@@ -4,6 +4,14 @@ Feature: Alternative route
Background:
Given the profile "testbot"
Given a grid size of 200 meters
# Force data preparation to single-threaded to ensure consistent
# results for alternative generation during tests (alternative
# finding is highly sensitive to graph shape, which is in turn
# affected by parallelism during generation)
And the contract extra arguments "--threads 1"
And the extract extra arguments "--threads 1"
And the customize extra arguments "--threads 1"
And the partition extra arguments "--threads 1"
Scenario: Alternative Loop Paths
Given the node map
+40 -7
View File
@@ -11,7 +11,7 @@ Feature: Annotations
"""
And the query options
| annotations | duration,speed,weight |
| annotations | duration,speed,weight,nodes |
And the ways
| nodes | highway |
@@ -22,10 +22,10 @@ Feature: Annotations
| lm | residential |
When I route I should get
| 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 |
| from | to | route | a:speed | a:weight | a:nodes |
| h | j | hk,jk,jk | 6.7:6.7 | 15:15 | 1:4:3 |
| i | m | il,lm,lm | 6.7:6.7 | 15:15 | 2:5:6 |
| j | m | jk,lm | 6.7:6.7:6.7 | 15:15:15 | 3:4:5:6 |
Scenario: There should be different forward/reverse datasources
@@ -60,6 +60,39 @@ Feature: Annotations
| 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 |
Scenario: datasource name annotations
Given the profile "testbot"
And the node map
"""
a b c
"""
And the ways
| nodes |
| abc |
And the contract extra arguments "--segment-speed-file {speeds_file}"
And the customize extra arguments "--segment-speed-file {speeds_file}"
And the speed file
"""
1,2,180,1
2,1,180,1
"""
And the query options
| annotations | datasources |
# Note - the source names here are specific to how the tests are constructed,
# so if this test is moved around (changes line number) or support code
# changes how the filenames are generated, this test will need to be updated
When I route I should get
| from | to | route | am:datasource_names |
| a | c | abc,abc | lua profile:63_datasource_name_annotations_speeds |
| c | a | abc,abc | lua profile:63_datasource_name_annotations_speeds |
Scenario: Speed annotations should handle zero segments
Given the profile "testbot"
@@ -81,5 +114,5 @@ Feature: Annotations
| bearings | 90,5;180,5 |
When I route I should get
| from | to | route | a:speed | a:distance | a:duration | a:nodes |
| a | c | abc,abc | 10:10:10 | 249.998641:299.931643:0 | 25:30:0 | 1:2:3 |
| from | to | route | a:speed | a:distance | a:duration | a:nodes |
| a | c | abc,abc | 10:10 | 249.998641:299.931643 | 25:30 | 1:2:3 |
+88
View File
@@ -74,6 +74,7 @@ Feature: Approach parameter
| from | to | approaches | route |
| s | e | unrestricted curb | ab,bc |
###############
# Oneway Test #
###############
@@ -226,3 +227,90 @@ Feature: Approach parameter
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted curb | ab,bc |
#######################
# Left-side countries #
#######################
Scenario: [Left-hand-side] Start End same approach, option unrestricted for Start and End
Given the profile file "car" initialized with
"""
profile.properties.left_hand_driving = true
"""
And the node map
"""
s e
a------b------c
"""
And the ways
| nodes |
| ab |
| bc |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted unrestricted | ab,bc |
Scenario: [Left-hand-side] Start End same approach, option unrestricted for Start and curb for End
Given the profile file "car" initialized with
"""
profile.properties.left_hand_driving = true
"""
And the node map
"""
s
a------b------c
e
"""
And the ways
| nodes |
| ab |
| bc |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted curb | ab,bc,bc |
Scenario: [Left-hand-side] Start End opposite approach, option unrestricted for Start and End
Given the profile file "car" initialized with
"""
profile.properties.left_hand_driving = true
"""
And the node map
"""
s
a------b------c
e
"""
And the ways
| nodes |
| ab |
| bc |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted unrestricted | ab,bc |
Scenario: [Left-hand-side] Start End opposite approach, option unrestricted for Start and curb for End
Given the profile file "car" initialized with
"""
profile.properties.left_hand_driving = true
"""
And the node map
"""
s e
a------b------c
"""
And the ways
| nodes |
| ab |
| bc |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted curb | ab,bc |
+9 -9
View File
@@ -108,12 +108,12 @@ Feature: Bearing parameter
| ha | yes | ring |
When I route I should get
| from | to | bearings | route | bearing |
| 0 | q | 0 90 | ia,ring,ring,ring,ring | 0->0,0->90,180->270,270->0,90->0 |
| 0 | a | 45 90 | jb,ring,ring,ring,ring | 0->45,45->180,180->270,270->0,90->0 |
| 0 | q | 90 90 | kc,ring,ring,ring | 0->90,90->180,270->0,90->0 |
| 0 | a | 135 90 | ld,ring,ring,ring | 0->135,135->270,270->0,90->0 |
| 0 | a | 180 90 | me,ring,ring,ring | 0->180,180->270,270->0,90->0 |
| 0 | a | 225 90 | nf,ring,ring | 0->225,225->0,90->0 |
| 0 | a | 270 90 | og,ring,ring | 0->270,270->0,90->0 |
| 0 | a | 315 90 | ph,ring,ring | 0->315,315->90,90->0 |
| from | to | bearings | route | bearing |
| 0 | q | 0 90 | ia,ring,ring,ring,ring,ring | 0->0,0->90,180->270,270->0,0->90,90->0 |
| 0 | a | 45 90 | jb,ring,ring,ring,ring,ring | 0->45,45->180,180->270,270->0,0->90,90->0 |
| 0 | q | 90 90 | kc,ring,ring,ring,ring | 0->90,90->180,270->0,0->90,90->0 |
| 0 | a | 135 90 | ld,ring,ring,ring,ring | 0->135,135->270,270->0,0->90,90->0 |
| 0 | a | 180 90 | me,ring,ring,ring,ring | 0->180,180->270,270->0,0->90,90->0 |
| 0 | a | 225 90 | nf,ring,ring,ring | 0->225,225->0,0->90,90->0 |
| 0 | a | 270 90 | og,ring,ring,ring | 0->270,270->0,0->90,90->0 |
| 0 | a | 315 90 | ph,ring,ring | 0->315,315->90,90->0 |
+167
View File
@@ -626,3 +626,170 @@ Feature: Basic Map Matching
| trace | timestamps | matchings | code |
| abbecd | 10 11 27 1516914902 1516914913 1516914952 | ab,ecd | Ok |
Scenario: Regression test - waypoints trimming too much geometry
# fixes bug in map matching collapsing that was dropping path geometries
# after segments that had 0 distance in internal route results
Given the node map
"""
ad
|
|
|
|
|e g
b--------------c
f h
"""
And the ways
| nodes |
| ab |
| bc |
Given the query options
| waypoints | 0;4 |
| overview | full |
When I match I should get
| trace | geometry | code |
| defgh | 1,1,1,0.999461,1.000674,0.999461 | Ok |
@match @testbot
Scenario: Regression test - waypoints trimming too much geometry
Given the profile "testbot"
Given a grid size of 10 meters
Given the query options
| geometries | geojson |
Given the node map
"""
bh
|
|
|
c
g\
\k
\
\
\
j f
"""
And the ways
| nodes |
| hc |
| cf |
Given the query options
| waypoints | 0;3 |
| overview | full |
When I match I should get
| trace | geometry | code |
| bgkj | 1.000135,1,1.000135,0.99964,1.000387,0.999137 | Ok |
@match @testbot
# Regression test for issue #4919
Scenario: Regression test - non-uturn maneuver preferred over uturn
Given the profile "testbot"
Given a grid size of 10 meters
Given the query options
| geometries | geojson |
Given the node map
"""
e
;
;
a----hb-----c
;
;
d
"""
And the ways
| nodes |
| abc |
| dbe |
Given the query options
| waypoints | 0;2 |
| overview | full |
| steps | true |
When I match I should get
| trace | geometry | turns | code |
| abc | 1,0.99973,1.00027,0.99973,1.000539,0.99973 | depart,arrive | Ok |
| abd | 1,0.99973,1.00027,0.99973,1.00027,0.999461 | depart,turn right,arrive | Ok |
| abe | 1,0.99973,1.00027,0.99973,1.00027,1 | depart,turn left,arrive | Ok |
| ahd | 1,0.99973,1.00027,0.99973,1.00027,0.999461 | depart,turn right,arrive | Ok |
| ahe | 1,0.99973,1.00027,0.99973,1.00027,1 | depart,turn left,arrive | Ok |
@match @testbot
Scenario: Regression test - add source phantoms properly (one phantom on one edge)
Given the profile "testbot"
Given a grid size of 10 meters
Given the node map
"""
a--1-b2-cd3--e
"""
And the ways
| nodes |
| ab |
| bcd |
| de |
Given the query options
| geometries | geojson |
| overview | full |
| steps | true |
| waypoints | 0;2 |
| annotations | duration,weight |
| generate_hints | false |
When I match I should get
| trace | geometry | a:duration | a:weight | duration |
| 123 | 1.000135,1,1.000225,1,1.00036,1,1.000405,1,1.00045,1 | 1:1.5:0.5:0.5 | 1:1.5:0.5:0.5 | 3.5 |
| 321 | 1.00045,1,1.000405,1,1.00036,1,1.000225,1,1.000135,1 | 0.5:0.5:1.5:1 | 0.5:0.5:1.5:1 | 3.5 |
@match @testbot
Scenario: Regression test - add source phantom properly (two phantoms on one edge)
Given the profile "testbot"
Given a grid size of 10 meters
Given the node map
"""
a--1-b23-c4--d
"""
And the ways
| nodes |
| ab |
| bc |
| cd |
Given the query options
| geometries | geojson |
| overview | full |
| steps | true |
| waypoints | 0;3 |
| annotations | duration,weight |
| generate_hints | false |
When I match I should get
| trace | geometry | a:duration | a:weight | duration |
| 1234 | 1.000135,1,1.000225,1,1.000405,1,1.00045,1 | 1:2:0.5 | 1:2:0.5 | 3.5 |
| 4321 | 1.00045,1,1.000405,1,1.000225,1,1.000135,1 | 0.5:2:1 | 0.5:2:1 | 3.5 |
@match @testbot
Scenario: Regression test - add source phantom properly (two phantoms on one edge)
Given the profile "testbot"
Given a grid size of 10 meters
Given the node map
"""
a--12345-b
"""
And the ways
| nodes |
| ab |
Given the query options
| geometries | geojson |
| overview | full |
| steps | true |
| waypoints | 0;3 |
| annotations | duration,weight,distance |
| generate_hints | false |
# These should have the same weights/duration in either direction
When I match I should get
| trace | geometry | a:distance | a:duration | a:weight | duration |
| 2345 | 1.00018,1,1.000315,1 | 15.013264 | 1.5 | 1.5 | 1.5 |
| 4321 | 1.00027,1,1.000135,1 | 15.013264 | 1.5 | 1.5 | 1.5 |
+20 -20
View File
@@ -48,10 +48,10 @@ Feature: Traffic - speeds
When I route I should get
| from | to | route | speed | weights | a:datasources |
| a | b | ad,de,eb,eb | 30 km/h | 1275.7,400.4,378.2,0 | 1:0:0:0 |
| a | b | ad,de,eb,eb | 30 km/h | 1275.7,400.4,378.2,0 | 1:0:0 |
| a | c | ad,dc,dc | 31 km/h | 1275.7,956.8,0 | 1:0 |
| b | c | bc,bc | 27 km/h | 741.5,0 | 1:0 |
| a | d | ad,ad | 27 km/h | 1275.7,0 | 1:0 |
| b | c | bc,bc | 27 km/h | 741.5,0 | 1 |
| a | d | ad,ad | 27 km/h | 1275.7,0 | 1 |
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 |
| g | b | fb,fb | 36 km/h | 164.7,0 | 0 |
| a | g | ad,df,fb,fb | 30 km/h | 1275.7,487.5,304.7,0 | 1:0:0 |
@@ -74,12 +74,12 @@ Feature: Traffic - speeds
When I route I should get
| from | to | route | speed | weights | a:datasources |
| a | b | ad,de,eb,eb | 30 km/h | 1275.7,400.4,378.2,0 | 1:0:0:0 |
| a | b | ad,de,eb,eb | 30 km/h | 1275.7,400.4,378.2,0 | 1:0:0 |
| a | c | ad,dc,dc | 31 km/h | 1275.7,956.8,0 | 1:0 |
| b | c | bc,bc | 27 km/h | 741.5,0 | 1:0 |
| a | d | ad,ad | 27 km/h | 1275.7,0 | 1:0 |
| b | c | bc,bc | 27 km/h | 741.5,0 | 1 |
| a | d | ad,ad | 27 km/h | 1275.7,0 | 1 |
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 |
| g | b | ab,ab | 1 km/h | 10010.4,0 | 1:0 |
| g | b | ab,ab | 1 km/h | 10010.4,0 | 1 |
| a | g | ab,ab | 1 km/h | 10010.3,0 | 1 |
@@ -106,14 +106,14 @@ Feature: Traffic - speeds
When I route I should get
| from | to | route | speed | weights | a:datasources |
| a | b | ab,ab | 1 km/h | 20020.73,0 | 1:0 |
| a | c | ab,bc,bc | 2 km/h | 20020.73,741.51,0 | 1:1:0 |
| b | c | bc,bc | 27 km/h | 741.51,0 | 1:0 |
| a | b | ab,ab | 1 km/h | 20020.73,0 | 1 |
| a | c | ab,bc,bc | 2 km/h | 20020.73,741.51,0 | 1:1 |
| b | c | bc,bc | 27 km/h | 741.51,0 | 1 |
| a | d | ab,eb,de,de | 2 km/h | 20020.73,378.17,400.41,0 | 1:0:0 |
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 |
| g | b | ab,ab | 1 km/h | 10010.37,0 | 1:0 |
| g | b | ab,ab | 1 km/h | 10010.37,0 | 1 |
| a | g | ab,ab | 1 km/h | 10010.36,0 | 1 |
| g | a | ab,ab | 1 km/h | 10010.36,0 | 1:1 |
| g | a | ab,ab | 1 km/h | 10010.36,0 | 1 |
Scenario: Speeds that isolate a single node (a)
@@ -135,14 +135,14 @@ Feature: Traffic - speeds
| annotations | true |
When I route I should get
| from | to | route | speed | weights | a:datasources |
| a | b | fb,fb | 36 km/h | 329.4,0 | 0 |
| a | c | fb,bc,bc | 30 km/h | 329.4,741.5,0 | 0:1:0 |
| b | c | bc,bc | 27 km/h | 741.5,0 | 1:0 |
| a | d | fb,df,df | 36 km/h | 140,487.5,0 | 0:0:0 |
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 |
| g | b | fb,fb | 36 km/h | 164.7,0 | 0 |
| a | g | fb,fb | 36 km/h | 164.7,0 | 0 |
| from | to | route | speed | weights | a:datasources | a:speed | a:nodes|
| a | b | fb,fb | 36 km/h | 329.4,0 | 0 | 10 | 6:2 |
| a | c | fb,bc,bc | 30 km/h | 329.4,741.5,0 | 0:1 | 10:7.5 | 6:2:3 |
| b | c | bc,bc | 27 km/h | 741.5,0 | 1 | 7.5 | 2:3 |
| a | d | fb,df,df | 36 km/h | 140,487.5,0 | 0:0 | 10:10 | 2:6:4 |
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 | 10 | 4:3 |
| g | b | fb,fb | 36 km/h | 164.7,0 | 0 | 10 | 6:2 |
| a | g | fb,fb | 36 km/h | 164.7,0 | 0 | 10 | 6:2 |
Scenario: Verify that negative values cause an error, they're not valid at all
+2 -2
View File
@@ -53,8 +53,8 @@ Feature: Weight tests
When I route I should get
| waypoints | route | distances | weights | times | a:distance | a:duration | a:weight | a:speed |
| s,t | abc,abc | 20m,0m | 2.1,0 | 2.1s,0s | 20.017685 | 3 | 3 | 6.7 |
| t,s | abc,abc | 20m,0m | 2.1,0 | 2.1s,0s | 20.017685 | 3.1 | 3.1 | 6.5 |
| s,t | abc,abc | 20m,0m | 2.1,0 | 2.1s,0s | 20.017685 | 2.1 | 2.1 | 9.5 |
| t,s | abc,abc | 20m,0m | 2.1,0 | 2.1s,0s | 20.017685 | 2.1 | 2.1 | 9.5 |
| s,e | abc,abc | 40m,0m | 4.1,0 | 4.1s,0s | 30.026527:10.008842 | 3.1:1 | 3.1:1 | 9.7:10 |
| e,s | abc,abc | 40m,0m | 4.1,0 | 4.1s,0s | 10.008842:30.026527 | 1:3.1 | 1:3.1 | 10:9.7 |
+25
View File
@@ -0,0 +1,25 @@
#ifndef OSMR_CONTRACTOR_CONTRACTED_METRIC_HPP
#define OSMR_CONTRACTOR_CONTRACTED_METRIC_HPP
#include "contractor/query_graph.hpp"
namespace osrm
{
namespace contractor
{
namespace detail
{
template <storage::Ownership Ownership> struct ContractedMetric
{
detail::QueryGraph<Ownership> graph;
std::vector<util::ViewOrVector<bool, Ownership>> edge_filter;
};
}
using ContractedMetric = detail::ContractedMetric<storage::Ownership::Container>;
using ContractedMetricView = detail::ContractedMetric<storage::Ownership::View>;
}
}
#endif
+25 -42
View File
@@ -1,12 +1,9 @@
#ifndef OSRM_CONTRACTOR_FILES_HPP
#define OSRM_CONTRACTOR_FILES_HPP
#include "contractor/query_graph.hpp"
#include "contractor/serialization.hpp"
#include "util/serialization.hpp"
#include "storage/io.hpp"
#include "storage/serialization.hpp"
#include <unordered_map>
namespace osrm
{
@@ -15,59 +12,45 @@ namespace contractor
namespace files
{
// reads .osrm.hsgr file
template <typename QueryGraphT, typename EdgeFilterT>
template <typename ContractedMetricT>
inline void readGraph(const boost::filesystem::path &path,
unsigned &checksum,
QueryGraphT &graph,
std::vector<EdgeFilterT> &edge_filter,
std::unordered_map<std::string, ContractedMetricT> &metrics,
std::uint32_t &connectivity_checksum)
{
static_assert(std::is_same<QueryGraphView, QueryGraphT>::value ||
std::is_same<QueryGraph, QueryGraphT>::value,
"graph must be of type QueryGraph<>");
static_assert(std::is_same<EdgeFilterT, std::vector<bool>>::value ||
std::is_same<EdgeFilterT, util::vector_view<bool>>::value,
"edge_filter must be a container of vector<bool> or vector_view<bool>");
static_assert(std::is_same<ContractedMetric, ContractedMetricT>::value ||
std::is_same<ContractedMetricView, ContractedMetricT>::value,
"metric must be of type ContractedMetric<>");
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
storage::io::FileReader reader{path, fingerprint};
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
storage::tar::FileReader reader{path, fingerprint};
reader.ReadInto(checksum);
util::serialization::read(reader, graph);
auto count = reader.ReadElementCount64();
edge_filter.resize(count);
for (const auto index : util::irange<std::size_t>(0, count))
reader.ReadInto("/ch/connectivity_checksum", connectivity_checksum);
for (auto &pair : metrics)
{
storage::serialization::read(reader, edge_filter[index]);
serialization::read(reader, "/ch/metrics/" + pair.first, pair.second);
}
reader.ReadInto(connectivity_checksum);
}
// writes .osrm.hsgr file
template <typename QueryGraphT, typename EdgeFilterT>
template <typename ContractedMetricT>
inline void writeGraph(const boost::filesystem::path &path,
unsigned checksum,
const QueryGraphT &graph,
const std::vector<EdgeFilterT> &edge_filter,
const std::unordered_map<std::string, ContractedMetricT> &metrics,
const std::uint32_t connectivity_checksum)
{
static_assert(std::is_same<QueryGraphView, QueryGraphT>::value ||
std::is_same<QueryGraph, QueryGraphT>::value,
"graph must be of type QueryGraph<>");
static_assert(std::is_same<EdgeFilterT, std::vector<bool>>::value ||
std::is_same<EdgeFilterT, util::vector_view<bool>>::value,
"edge_filter must be a container of vector<bool> or vector_view<bool>");
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint;
storage::io::FileWriter writer{path, fingerprint};
static_assert(std::is_same<ContractedMetric, ContractedMetricT>::value ||
std::is_same<ContractedMetricView, ContractedMetricT>::value,
"metric must be of type ContractedMetric<>");
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
storage::tar::FileWriter writer{path, fingerprint};
writer.WriteOne(checksum);
util::serialization::write(writer, graph);
writer.WriteElementCount64(edge_filter.size());
for (const auto &filter : edge_filter)
writer.WriteElementCount64("/ch/connectivity_checksum", 1);
writer.WriteFrom("/ch/connectivity_checksum", connectivity_checksum);
for (const auto &pair : metrics)
{
storage::serialization::write(writer, filter);
serialization::write(writer, "/ch/metrics/" + pair.first, pair.second);
}
writer.WriteOne(connectivity_checksum);
}
}
}
@@ -128,23 +128,24 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
template <class Edge, typename GraphT> inline std::vector<Edge> toEdges(GraphT graph)
{
std::vector<Edge> edges;
edges.reserve(graph.GetNumberOfEdges());
util::Log() << "Converting contracted graph with " << graph.GetNumberOfEdges()
<< " to edge list (" << (graph.GetNumberOfEdges() * sizeof(Edge)) << " bytes)";
std::vector<Edge> edges(graph.GetNumberOfEdges());
util::UnbufferedLog log;
log << "Getting edges of minimized graph ";
util::Percent p(log, graph.GetNumberOfNodes());
const NodeID number_of_nodes = graph.GetNumberOfNodes();
if (graph.GetNumberOfNodes())
{
Edge new_edge;
util::UnbufferedLog log;
log << "Getting edges of minimized graph ";
util::Percent p(log, graph.GetNumberOfNodes());
const NodeID number_of_nodes = graph.GetNumberOfNodes();
std::size_t edge_index = 0;
for (const auto node : util::irange(0u, number_of_nodes))
{
p.PrintStatus(node);
for (auto edge : graph.GetAdjacentEdgeRange(node))
{
const NodeID target = graph.GetTarget(edge);
const ContractorGraph::EdgeData &data = graph.GetEdgeData(edge);
const auto &data = graph.GetEdgeData(edge);
auto &new_edge = edges[edge_index++];
new_edge.source = node;
new_edge.target = target;
BOOST_ASSERT_MSG(SPECIAL_NODEID != new_edge.target, "Target id invalid");
@@ -156,16 +157,12 @@ template <class Edge, typename GraphT> inline std::vector<Edge> toEdges(GraphT g
"edge id invalid");
new_edge.data.forward = data.forward;
new_edge.data.backward = data.backward;
edges.push_back(new_edge);
}
}
BOOST_ASSERT(edge_index == edges.size());
}
// sort and remove duplicates
tbb::parallel_sort(edges.begin(), edges.end());
auto new_end = std::unique(edges.begin(), edges.end());
edges.resize(new_end - edges.begin());
edges.shrink_to_fit();
return edges;
}
+53
View File
@@ -0,0 +1,53 @@
#ifndef OSRM_CONTRACTOR_SERIALIZATION_HPP
#define OSRM_CONTRACTOR_SERIALIZATION_HPP
#include "contractor/contracted_metric.hpp"
#include "util/serialization.hpp"
#include "storage/serialization.hpp"
#include "storage/tar.hpp"
namespace osrm
{
namespace contractor
{
namespace serialization
{
template <storage::Ownership Ownership>
void write(storage::tar::FileWriter &writer,
const std::string &name,
const detail::ContractedMetric<Ownership> &metric)
{
util::serialization::write(writer, name + "/contracted_graph", metric.graph);
writer.WriteElementCount64(name + "/exclude", metric.edge_filter.size());
for (const auto index : util::irange<std::size_t>(0, metric.edge_filter.size()))
{
storage::serialization::write(writer,
name + "/exclude/" + std::to_string(index) + "/edge_filter",
metric.edge_filter[index]);
}
}
template <storage::Ownership Ownership>
void read(storage::tar::FileReader &reader,
const std::string &name,
detail::ContractedMetric<Ownership> &metric)
{
util::serialization::read(reader, name + "/contracted_graph", metric.graph);
metric.edge_filter.resize(reader.ReadElementCount64(name + "/exclude"));
for (const auto index : util::irange<std::size_t>(0, metric.edge_filter.size()))
{
storage::serialization::read(reader,
name + "/exclude/" + std::to_string(index) + "/edge_filter",
metric.edge_filter[index]);
}
}
}
}
}
#endif
+37 -16
View File
@@ -3,10 +3,12 @@
#include "customizer/serialization.hpp"
#include "storage/io.hpp"
#include "storage/tar.hpp"
#include "util/integer_range.hpp"
#include <unordered_map>
namespace osrm
{
namespace customizer
@@ -16,40 +18,59 @@ namespace files
// reads .osrm.cell_metrics file
template <typename CellMetricT>
inline void readCellMetrics(const boost::filesystem::path &path, std::vector<CellMetricT> &metrics)
inline void readCellMetrics(const boost::filesystem::path &path,
std::unordered_map<std::string, std::vector<CellMetricT>> &metrics)
{
static_assert(std::is_same<CellMetricView, CellMetricT>::value ||
std::is_same<CellMetric, CellMetricT>::value,
"");
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
storage::io::FileReader reader{path, fingerprint};
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
storage::tar::FileReader reader{path, fingerprint};
auto num_metrics = reader.ReadElementCount64();
metrics.resize(num_metrics);
for (auto &metric : metrics)
for (auto &pair : metrics)
{
serialization::read(reader, metric);
const auto &metric_name = pair.first;
auto &metric_exclude_classes = pair.second;
auto prefix = "/mld/metrics/" + metric_name + "/exclude";
auto num_exclude_classes = reader.ReadElementCount64(prefix);
metric_exclude_classes.resize(num_exclude_classes);
auto id = 0;
for (auto &metric : metric_exclude_classes)
{
serialization::read(reader, prefix + "/" + std::to_string(id++), metric);
}
}
}
// writes .osrm.cell_metrics file
template <typename CellMetricT>
inline void writeCellMetrics(const boost::filesystem::path &path,
const std::vector<CellMetricT> &metrics)
inline void
writeCellMetrics(const boost::filesystem::path &path,
const std::unordered_map<std::string, std::vector<CellMetricT>> &metrics)
{
static_assert(std::is_same<CellMetricView, CellMetricT>::value ||
std::is_same<CellMetric, CellMetricT>::value,
"");
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint;
storage::io::FileWriter writer{path, fingerprint};
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
storage::tar::FileWriter writer{path, fingerprint};
writer.WriteElementCount64(metrics.size());
for (const auto &metric : metrics)
for (const auto &pair : metrics)
{
serialization::write(writer, metric);
const auto &metric_name = pair.first;
const auto &metric_exclude_classes = pair.second;
auto prefix = "/mld/metrics/" + metric_name + "/exclude";
writer.WriteElementCount64(prefix, metric_exclude_classes.size());
auto id = 0;
for (auto &exclude_metric : metric_exclude_classes)
{
serialization::write(writer, prefix + "/" + std::to_string(id++), exclude_metric);
}
}
}
}
+11 -7
View File
@@ -3,9 +3,9 @@
#include "partitioner/cell_storage.hpp"
#include "storage/io.hpp"
#include "storage/serialization.hpp"
#include "storage/shared_memory_ownership.hpp"
#include "storage/tar.hpp"
namespace osrm
{
@@ -15,17 +15,21 @@ namespace serialization
{
template <storage::Ownership Ownership>
inline void read(storage::io::FileReader &reader, detail::CellMetricImpl<Ownership> &metric)
inline void read(storage::tar::FileReader &reader,
const std::string &name,
detail::CellMetricImpl<Ownership> &metric)
{
storage::serialization::read(reader, metric.weights);
storage::serialization::read(reader, metric.durations);
storage::serialization::read(reader, name + "/weights", metric.weights);
storage::serialization::read(reader, name + "/durations", metric.durations);
}
template <storage::Ownership Ownership>
inline void write(storage::io::FileWriter &writer, const detail::CellMetricImpl<Ownership> &metric)
inline void write(storage::tar::FileWriter &writer,
const std::string &name,
const detail::CellMetricImpl<Ownership> &metric)
{
storage::serialization::write(writer, metric.weights);
storage::serialization::write(writer, metric.durations);
storage::serialization::write(writer, name + "/weights", metric.weights);
storage::serialization::write(writer, name + "/durations", metric.durations);
}
}
}
+5
View File
@@ -30,6 +30,11 @@ template <typename AlgorithmT> const char *name();
template <> inline const char *name<ch::Algorithm>() { return "CH"; }
template <> inline const char *name<mld::Algorithm>() { return "MLD"; }
// Algorithm identifier
template <typename AlgorithmT> const char *identifier();
template <> inline const char *identifier<ch::Algorithm>() { return "ch"; }
template <> inline const char *identifier<mld::Algorithm>() { return "mld"; }
template <typename AlgorithmT> struct HasAlternativePathSearch final : std::false_type
{
};
+43 -44
View File
@@ -34,56 +34,55 @@ class NearestAPI final : public BaseAPI
util::json::Array waypoints;
waypoints.values.resize(phantom_nodes.front().size());
std::transform(phantom_nodes.front().begin(),
phantom_nodes.front().end(),
waypoints.values.begin(),
[this](const PhantomNodeWithDistance &phantom_with_distance) {
auto &phantom_node = phantom_with_distance.phantom_node;
auto waypoint = MakeWaypoint(phantom_node);
waypoint.values["distance"] = phantom_with_distance.distance;
std::transform(
phantom_nodes.front().begin(),
phantom_nodes.front().end(),
waypoints.values.begin(),
[this](const PhantomNodeWithDistance &phantom_with_distance) {
auto &phantom_node = phantom_with_distance.phantom_node;
auto waypoint = MakeWaypoint(phantom_node);
waypoint.values["distance"] = phantom_with_distance.distance;
util::json::Array nodes;
util::json::Array nodes;
std::uint64_t from_node = 0;
std::uint64_t to_node = 0;
std::uint64_t from_node = 0;
std::uint64_t to_node = 0;
std::vector<NodeID> forward_geometry;
if (phantom_node.forward_segment_id.enabled)
{
auto segment_id = phantom_node.forward_segment_id.id;
const auto geometry_id = facade.GetGeometryIndex(segment_id).id;
forward_geometry =
facade.GetUncompressedForwardGeometry(geometry_id);
datafacade::BaseDataFacade::NodeForwardRange forward_geometry;
if (phantom_node.forward_segment_id.enabled)
{
auto segment_id = phantom_node.forward_segment_id.id;
const auto geometry_id = facade.GetGeometryIndex(segment_id).id;
forward_geometry = facade.GetUncompressedForwardGeometry(geometry_id);
auto osm_node_id = facade.GetOSMNodeIDOfNode(
forward_geometry[phantom_node.fwd_segment_position]);
to_node = static_cast<std::uint64_t>(osm_node_id);
}
auto osm_node_id = facade.GetOSMNodeIDOfNode(
forward_geometry(phantom_node.fwd_segment_position));
to_node = static_cast<std::uint64_t>(osm_node_id);
}
if (phantom_node.reverse_segment_id.enabled)
{
auto segment_id = phantom_node.reverse_segment_id.id;
const auto geometry_id = facade.GetGeometryIndex(segment_id).id;
std::vector<NodeID> geometry =
facade.GetUncompressedForwardGeometry(geometry_id);
auto osm_node_id = facade.GetOSMNodeIDOfNode(
geometry[phantom_node.fwd_segment_position + 1]);
from_node = static_cast<std::uint64_t>(osm_node_id);
}
else if (phantom_node.forward_segment_id.enabled &&
phantom_node.fwd_segment_position > 0)
{
// In the case of one way, rely on forward segment only
auto osm_node_id = facade.GetOSMNodeIDOfNode(
forward_geometry[phantom_node.fwd_segment_position - 1]);
from_node = static_cast<std::uint64_t>(osm_node_id);
}
nodes.values.push_back(from_node);
nodes.values.push_back(to_node);
waypoint.values["nodes"] = std::move(nodes);
if (phantom_node.reverse_segment_id.enabled)
{
auto segment_id = phantom_node.reverse_segment_id.id;
const auto geometry_id = facade.GetGeometryIndex(segment_id).id;
const auto geometry = facade.GetUncompressedForwardGeometry(geometry_id);
auto osm_node_id =
facade.GetOSMNodeIDOfNode(geometry(phantom_node.fwd_segment_position + 1));
from_node = static_cast<std::uint64_t>(osm_node_id);
}
else if (phantom_node.forward_segment_id.enabled &&
phantom_node.fwd_segment_position > 0)
{
// In the case of one way, rely on forward segment only
auto osm_node_id = facade.GetOSMNodeIDOfNode(
forward_geometry(phantom_node.fwd_segment_position - 1));
from_node = static_cast<std::uint64_t>(osm_node_id);
}
nodes.values.push_back(from_node);
nodes.values.push_back(to_node);
waypoint.values["nodes"] = std::move(nodes);
return waypoint;
});
return waypoint;
});
response.values["code"] = "Ok";
response.values["waypoints"] = std::move(waypoints);
+26 -2
View File
@@ -148,6 +148,9 @@ class RouteAPI : public BaseAPI
// processing is performed
guidance::applyOverrides(BaseAPI::facade, steps, leg_geometry);
// Collapse segregated steps before others
steps = guidance::collapseSegregatedTurnInstructions(std::move(steps));
/* Perform step-based post-processing.
*
* Using post-processing on basis of route-steps for a single leg at a time
@@ -211,12 +214,16 @@ class RouteAPI : public BaseAPI
}
std::vector<util::json::Value> step_geometries;
const auto total_step_count =
std::accumulate(legs.begin(), legs.end(), 0, [](const auto &v, const auto &leg) {
return v + leg.steps.size();
});
step_geometries.reserve(total_step_count);
for (const auto idx : util::irange<std::size_t>(0UL, legs.size()))
{
auto &leg_geometry = leg_geometries[idx];
step_geometries.reserve(step_geometries.size() + legs[idx].steps.size());
std::transform(
legs[idx].steps.begin(),
legs[idx].steps.end(),
@@ -317,6 +324,23 @@ class RouteAPI : public BaseAPI
}
annotation.values["nodes"] = std::move(nodes);
}
// Add any supporting metadata, if needed
if (requested_annotations & RouteParameters::AnnotationsType::Datasources)
{
const auto MAX_DATASOURCE_ID = 255u;
util::json::Object metadata;
util::json::Array datasource_names;
for (auto i = 0u; i < MAX_DATASOURCE_ID; i++)
{
const auto name = facade.GetDatasourceName(i);
// Length of 0 indicates the first empty name, so we can stop here
if (name.size() == 0)
break;
datasource_names.values.push_back(std::string(facade.GetDatasourceName(i)));
}
metadata.values["datasource_names"] = datasource_names;
annotation.values["metadata"] = metadata;
}
annotations.push_back(std::move(annotation));
}
+2 -2
View File
@@ -87,7 +87,7 @@ inline std::string encodeBase64(const std::string &x) { return encodeBase64(x.da
// Encode any sufficiently trivial object to Base64.
template <typename T> std::string encodeBase64Bytewise(const T &x)
{
#if not defined __GNUC__ or __GNUC__ > 4
#if !defined(__GNUC__) || (__GNUC__ > 4)
static_assert(std::is_trivially_copyable<T>::value, "requires a trivially copyable type");
#endif
@@ -124,7 +124,7 @@ inline std::string decodeBase64(const std::string &encoded)
// Decodes from Base 64 to any sufficiently trivial object.
template <typename T> T decodeBase64Bytewise(const std::string &encoded)
{
#if not defined __GNUC__ or __GNUC__ > 4
#if !defined(__GNUC__) || (__GNUC__ > 4)
static_assert(std::is_trivially_copyable<T>::value, "requires a trivially copyable type");
#endif
+46 -15
View File
@@ -32,20 +32,35 @@ template <typename AlgorithmT, typename FacadeT> class DataWatchdogImpl;
template <typename AlgorithmT>
class DataWatchdogImpl<AlgorithmT, datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT>> final
{
using mutex_type = typename storage::SharedMonitor<storage::SharedDataTimestamp>::mutex_type;
using mutex_type = typename storage::SharedMonitor<storage::SharedRegionRegister>::mutex_type;
using Facade = datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT>;
public:
DataWatchdogImpl() : active(true), timestamp(0)
DataWatchdogImpl(const std::string &dataset_name) : dataset_name(dataset_name), active(true)
{
// create the initial facade before launching the watchdog thread
{
boost::interprocess::scoped_lock<mutex_type> current_region_lock(barrier.get_mutex());
auto &shared_register = barrier.data();
auto static_region_id = shared_register.Find(dataset_name + "/static");
auto updatable_region_id = shared_register.Find(dataset_name + "/updatable");
if (static_region_id == storage::SharedRegionRegister::INVALID_REGION_ID ||
updatable_region_id == storage::SharedRegionRegister::INVALID_REGION_ID)
{
throw util::exception("Could not find shared memory region for \"" + dataset_name +
"/data\". Did you run osrm-datastore?");
}
static_shared_region = &shared_register.GetRegion(static_region_id);
updatable_shared_region = &shared_register.GetRegion(updatable_region_id);
static_region = *static_shared_region;
updatable_region = *updatable_shared_region;
facade_factory =
DataFacadeFactory<datafacade::ContiguousInternalMemoryDataFacade, AlgorithmT>(
std::make_shared<datafacade::SharedMemoryAllocator>(barrier.data().region));
timestamp = barrier.data().timestamp;
std::make_shared<datafacade::SharedMemoryAllocator>(
std::vector<storage::SharedRegionRegister::ShmKey>{
static_region.shm_key, updatable_region.shm_key}));
}
watcher = std::thread(&DataWatchdogImpl::Run, this);
@@ -74,30 +89,46 @@ class DataWatchdogImpl<AlgorithmT, datafacade::ContiguousInternalMemoryDataFacad
{
boost::interprocess::scoped_lock<mutex_type> current_region_lock(barrier.get_mutex());
while (active && timestamp == barrier.data().timestamp)
while (active && static_region.timestamp == static_shared_region->timestamp &&
updatable_region.timestamp == updatable_shared_region->timestamp)
{
barrier.wait(current_region_lock);
}
if (timestamp != barrier.data().timestamp)
if (!active)
break;
if (static_region.timestamp != static_shared_region->timestamp)
{
auto region = barrier.data().region;
facade_factory =
DataFacadeFactory<datafacade::ContiguousInternalMemoryDataFacade, AlgorithmT>(
std::make_shared<datafacade::SharedMemoryAllocator>(region));
timestamp = barrier.data().timestamp;
util::Log() << "updated facade to region " << region << " with timestamp "
<< timestamp;
static_region = *static_shared_region;
}
if (updatable_region.timestamp != updatable_shared_region->timestamp)
{
updatable_region = *updatable_shared_region;
}
util::Log() << "updated facade to regions " << (int)static_region.shm_key << " and "
<< (int)updatable_region.shm_key << " with timestamps "
<< static_region.timestamp << " and " << updatable_region.timestamp;
facade_factory =
DataFacadeFactory<datafacade::ContiguousInternalMemoryDataFacade, AlgorithmT>(
std::make_shared<datafacade::SharedMemoryAllocator>(
std::vector<storage::SharedRegionRegister::ShmKey>{
static_region.shm_key, updatable_region.shm_key}));
}
util::Log() << "DataWatchdog thread stopped";
}
storage::SharedMonitor<storage::SharedDataTimestamp> barrier;
const std::string dataset_name;
storage::SharedMonitor<storage::SharedRegionRegister> barrier;
std::thread watcher;
bool active;
unsigned timestamp;
storage::SharedRegion static_region;
storage::SharedRegion updatable_region;
storage::SharedRegion *static_shared_region;
storage::SharedRegion *updatable_shared_region;
DataFacadeFactory<datafacade::ContiguousInternalMemoryDataFacade, AlgorithmT> facade_factory;
};
}
@@ -65,6 +65,8 @@ template <> class AlgorithmDataFacade<MLD>
// search graph access
virtual unsigned GetNumberOfNodes() const = 0;
virtual unsigned GetMaxBorderNodeID() const = 0;
virtual unsigned GetNumberOfEdges() const = 0;
virtual unsigned GetOutDegree(const NodeID n) const = 0;
@@ -1,7 +1,7 @@
#ifndef OSRM_ENGINE_DATAFACADE_CONTIGUOUS_BLOCK_ALLOCATOR_HPP_
#define OSRM_ENGINE_DATAFACADE_CONTIGUOUS_BLOCK_ALLOCATOR_HPP_
#include "storage/shared_datatype.hpp"
#include "storage/shared_data_index.hpp"
namespace osrm
{
@@ -16,8 +16,7 @@ class ContiguousBlockAllocator
virtual ~ContiguousBlockAllocator() = default;
// interface to give access to the datafacades
virtual storage::DataLayout &GetLayout() = 0;
virtual char *GetMemory() = 0;
virtual const storage::SharedDataIndex &GetIndex() = 0;
};
} // namespace datafacade
@@ -9,44 +9,13 @@
#include "engine/approach.hpp"
#include "engine/geospatial_query.hpp"
#include "customizer/edge_based_graph.hpp"
#include "extractor/datasources.hpp"
#include "extractor/edge_based_node.hpp"
#include "extractor/intersection_bearings_container.hpp"
#include "extractor/maneuver_override.hpp"
#include "extractor/node_data_container.hpp"
#include "extractor/packed_osm_ids.hpp"
#include "extractor/profile_properties.hpp"
#include "extractor/segment_data_container.hpp"
#include "extractor/turn_lane_types.hpp"
#include "guidance/turn_bearing.hpp"
#include "guidance/turn_data_container.hpp"
#include "guidance/turn_instruction.hpp"
#include "contractor/query_graph.hpp"
#include "partitioner/cell_storage.hpp"
#include "partitioner/multi_level_partition.hpp"
#include "storage/shared_datatype.hpp"
#include "storage/shared_memory_ownership.hpp"
#include "storage/view_factory.hpp"
#include "util/exception.hpp"
#include "util/exception_utils.hpp"
#include "util/filtered_graph.hpp"
#include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp"
#include "util/guidance/turn_lanes.hpp"
#include "util/log.hpp"
#include "util/name_table.hpp"
#include "util/packed_vector.hpp"
#include "util/range_table.hpp"
#include "util/rectangle.hpp"
#include "util/static_graph.hpp"
#include "util/static_rtree.hpp"
#include "util/typedefs.hpp"
#include <boost/assert.hpp>
@@ -81,44 +50,22 @@ class ContiguousInternalMemoryAlgorithmDataFacade<CH> : public datafacade::Algor
// allocator that keeps the allocation data
std::shared_ptr<ContiguousBlockAllocator> allocator;
void InitializeGraphPointer(storage::DataLayout &data_layout,
char *memory_block,
const std::size_t exclude_index)
{
auto graph_nodes_ptr = data_layout.GetBlockPtr<GraphNode>(
memory_block, storage::DataLayout::CH_GRAPH_NODE_LIST);
auto graph_edges_ptr = data_layout.GetBlockPtr<GraphEdge>(
memory_block, storage::DataLayout::CH_GRAPH_EDGE_LIST);
auto filter_block_id = static_cast<storage::DataLayout::BlockID>(
storage::DataLayout::CH_EDGE_FILTER_0 + exclude_index);
auto edge_filter_ptr = data_layout.GetBlockPtr<unsigned>(memory_block, filter_block_id);
util::vector_view<GraphNode> node_list(
graph_nodes_ptr, data_layout.num_entries[storage::DataLayout::CH_GRAPH_NODE_LIST]);
util::vector_view<GraphEdge> edge_list(
graph_edges_ptr, data_layout.num_entries[storage::DataLayout::CH_GRAPH_EDGE_LIST]);
util::vector_view<bool> edge_filter(edge_filter_ptr,
data_layout.num_entries[filter_block_id]);
m_query_graph = QueryGraph({node_list, edge_list}, edge_filter);
}
public:
ContiguousInternalMemoryAlgorithmDataFacade(
std::shared_ptr<ContiguousBlockAllocator> allocator_, std::size_t exclude_index)
std::shared_ptr<ContiguousBlockAllocator> allocator_,
const std::string &metric_name,
std::size_t exclude_index)
: allocator(std::move(allocator_))
{
InitializeInternalPointers(allocator->GetLayout(), allocator->GetMemory(), exclude_index);
InitializeInternalPointers(allocator->GetIndex(), metric_name, exclude_index);
}
void InitializeInternalPointers(storage::DataLayout &data_layout,
char *memory_block,
void InitializeInternalPointers(const storage::SharedDataIndex &index,
const std::string &metric_name,
const std::size_t exclude_index)
{
InitializeGraphPointer(data_layout, memory_block, exclude_index);
m_query_graph =
make_filtered_graph_view(index, "/ch/metrics/" + metric_name, exclude_index);
}
// search graph access
@@ -190,7 +137,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
extractor::ProfileProperties *m_profile_properties;
extractor::Datasources *m_datasources;
unsigned m_check_sum;
std::uint32_t m_check_sum;
util::vector_view<util::Coordinate> m_coordinate_list;
extractor::PackedOSMIDsView m_osmnodeid_list;
util::vector_view<std::uint32_t> m_lane_description_offsets;
@@ -209,13 +156,13 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
util::vector_view<extractor::StorageManeuverOverride> m_maneuver_overrides;
util::vector_view<NodeID> m_maneuver_override_node_sequences;
std::unique_ptr<SharedRTree> m_static_rtree;
SharedRTree m_static_rtree;
std::unique_ptr<SharedGeospatialQuery> m_geospatial_query;
boost::filesystem::path file_index_path;
extractor::IntersectionBearingsView intersection_bearings_view;
util::NameTable m_name_table;
extractor::NameTableView m_name_table;
// the look-up table for entry classes. An entry class lists the possibility of entry for all
// available turns. Such a class id is stored with every edge.
util::vector_view<util::guidance::EntryClass> m_entry_class_table;
@@ -223,328 +170,62 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
// allocator that keeps the allocation data
std::shared_ptr<ContiguousBlockAllocator> allocator;
void InitializeProfilePropertiesPointer(storage::DataLayout &data_layout,
char *memory_block,
const std::size_t exclude_index)
{
m_profile_properties = data_layout.GetBlockPtr<extractor::ProfileProperties>(
memory_block, storage::DataLayout::PROPERTIES);
exclude_mask = m_profile_properties->excludable_classes[exclude_index];
}
void InitializeTimestampPointer(storage::DataLayout &data_layout, char *memory_block)
{
auto timestamp_ptr =
data_layout.GetBlockPtr<char>(memory_block, storage::DataLayout::TIMESTAMP);
m_timestamp.resize(data_layout.GetBlockSize(storage::DataLayout::TIMESTAMP));
std::copy(timestamp_ptr,
timestamp_ptr + data_layout.GetBlockSize(storage::DataLayout::TIMESTAMP),
m_timestamp.begin());
}
void InitializeChecksumPointer(storage::DataLayout &data_layout, char *memory_block)
{
m_check_sum =
*data_layout.GetBlockPtr<unsigned>(memory_block, storage::DataLayout::HSGR_CHECKSUM);
util::Log() << "set checksum: " << m_check_sum;
}
void InitializeRTreePointers(storage::DataLayout &data_layout, char *memory_block)
{
BOOST_ASSERT_MSG(!m_coordinate_list.empty(), "coordinates must be loaded before r-tree");
const auto file_index_ptr =
data_layout.GetBlockPtr<char>(memory_block, storage::DataLayout::FILE_INDEX_PATH);
file_index_path = boost::filesystem::path(file_index_ptr);
if (!boost::filesystem::exists(file_index_path))
{
util::Log(logDEBUG) << "Leaf file name " << file_index_path.string();
throw util::exception("Could not load " + file_index_path.string() +
"Is any data loaded into shared memory?" + SOURCE_REF);
}
auto tree_nodes_ptr =
data_layout.GetBlockPtr<RTreeNode>(memory_block, storage::DataLayout::R_SEARCH_TREE);
auto tree_level_sizes_ptr = data_layout.GetBlockPtr<std::uint64_t>(
memory_block, storage::DataLayout::R_SEARCH_TREE_LEVELS);
m_static_rtree.reset(
new SharedRTree(tree_nodes_ptr,
data_layout.num_entries[storage::DataLayout::R_SEARCH_TREE],
tree_level_sizes_ptr,
data_layout.num_entries[storage::DataLayout::R_SEARCH_TREE_LEVELS],
file_index_path,
m_coordinate_list));
m_geospatial_query.reset(
new SharedGeospatialQuery(*m_static_rtree, m_coordinate_list, *this));
}
void InitializeNodeInformationPointers(storage::DataLayout &layout, char *memory_ptr)
{
const auto coordinate_list_ptr =
layout.GetBlockPtr<util::Coordinate>(memory_ptr, storage::DataLayout::COORDINATE_LIST);
m_coordinate_list.reset(coordinate_list_ptr,
layout.num_entries[storage::DataLayout::COORDINATE_LIST]);
const auto osmnodeid_ptr = layout.GetBlockPtr<extractor::PackedOSMIDsView::block_type>(
memory_ptr, storage::DataLayout::OSM_NODE_ID_LIST);
m_osmnodeid_list = extractor::PackedOSMIDsView(
util::vector_view<extractor::PackedOSMIDsView::block_type>(
osmnodeid_ptr, layout.num_entries[storage::DataLayout::OSM_NODE_ID_LIST]),
// We (ab)use the number of coordinates here because we know we have the same amount of
// ids
layout.num_entries[storage::DataLayout::COORDINATE_LIST]);
}
void InitializeEdgeBasedNodeDataInformationPointers(storage::DataLayout &layout,
char *memory_ptr)
{
const auto edge_based_node_list_ptr = layout.GetBlockPtr<extractor::EdgeBasedNode>(
memory_ptr, storage::DataLayout::EDGE_BASED_NODE_DATA_LIST);
util::vector_view<extractor::EdgeBasedNode> edge_based_node_data_list(
edge_based_node_list_ptr,
layout.num_entries[storage::DataLayout::EDGE_BASED_NODE_DATA_LIST]);
const auto annotation_data_list_ptr =
layout.GetBlockPtr<extractor::NodeBasedEdgeAnnotation>(
memory_ptr, storage::DataLayout::ANNOTATION_DATA_LIST);
util::vector_view<extractor::NodeBasedEdgeAnnotation> annotation_data(
annotation_data_list_ptr,
layout.num_entries[storage::DataLayout::ANNOTATION_DATA_LIST]);
edge_based_node_data = extractor::EdgeBasedNodeDataView(
std::move(edge_based_node_data_list), std::move(annotation_data));
}
void InitializeEdgeInformationPointers(storage::DataLayout &layout, char *memory_ptr)
{
const auto lane_data_id_ptr =
layout.GetBlockPtr<LaneDataID>(memory_ptr, storage::DataLayout::LANE_DATA_ID);
util::vector_view<LaneDataID> lane_data_ids(
lane_data_id_ptr, layout.num_entries[storage::DataLayout::LANE_DATA_ID]);
const auto turn_instruction_list_ptr = layout.GetBlockPtr<guidance::TurnInstruction>(
memory_ptr, storage::DataLayout::TURN_INSTRUCTION);
util::vector_view<guidance::TurnInstruction> turn_instructions(
turn_instruction_list_ptr, layout.num_entries[storage::DataLayout::TURN_INSTRUCTION]);
const auto entry_class_id_list_ptr =
layout.GetBlockPtr<EntryClassID>(memory_ptr, storage::DataLayout::ENTRY_CLASSID);
util::vector_view<EntryClassID> entry_class_ids(
entry_class_id_list_ptr, layout.num_entries[storage::DataLayout::ENTRY_CLASSID]);
const auto pre_turn_bearing_ptr = layout.GetBlockPtr<guidance::TurnBearing>(
memory_ptr, storage::DataLayout::PRE_TURN_BEARING);
util::vector_view<guidance::TurnBearing> pre_turn_bearings(
pre_turn_bearing_ptr, layout.num_entries[storage::DataLayout::PRE_TURN_BEARING]);
const auto post_turn_bearing_ptr = layout.GetBlockPtr<guidance::TurnBearing>(
memory_ptr, storage::DataLayout::POST_TURN_BEARING);
util::vector_view<guidance::TurnBearing> post_turn_bearings(
post_turn_bearing_ptr, layout.num_entries[storage::DataLayout::POST_TURN_BEARING]);
turn_data = guidance::TurnDataView(std::move(turn_instructions),
std::move(lane_data_ids),
std::move(entry_class_ids),
std::move(pre_turn_bearings),
std::move(post_turn_bearings));
}
void InitializeNamePointers(storage::DataLayout &data_layout, char *memory_block)
{
auto name_data_ptr =
data_layout.GetBlockPtr<char>(memory_block, storage::DataLayout::NAME_CHAR_DATA);
const auto name_data_size = data_layout.num_entries[storage::DataLayout::NAME_CHAR_DATA];
m_name_table.reset(name_data_ptr, name_data_ptr + name_data_size);
}
void InitializeTurnLaneDescriptionsPointers(storage::DataLayout &data_layout,
char *memory_block)
{
auto offsets_ptr = data_layout.GetBlockPtr<std::uint32_t>(
memory_block, storage::DataLayout::LANE_DESCRIPTION_OFFSETS);
util::vector_view<std::uint32_t> offsets(
offsets_ptr, data_layout.num_entries[storage::DataLayout::LANE_DESCRIPTION_OFFSETS]);
m_lane_description_offsets = std::move(offsets);
auto masks_ptr = data_layout.GetBlockPtr<extractor::TurnLaneType::Mask>(
memory_block, storage::DataLayout::LANE_DESCRIPTION_MASKS);
util::vector_view<extractor::TurnLaneType::Mask> masks(
masks_ptr, data_layout.num_entries[storage::DataLayout::LANE_DESCRIPTION_MASKS]);
m_lane_description_masks = std::move(masks);
const auto lane_tupel_id_pair_ptr =
data_layout.GetBlockPtr<util::guidance::LaneTupleIdPair>(
memory_block, storage::DataLayout::TURN_LANE_DATA);
util::vector_view<util::guidance::LaneTupleIdPair> lane_tupel_id_pair(
lane_tupel_id_pair_ptr, data_layout.num_entries[storage::DataLayout::TURN_LANE_DATA]);
m_lane_tupel_id_pairs = std::move(lane_tupel_id_pair);
}
void InitializeTurnPenalties(storage::DataLayout &data_layout, char *memory_block)
{
auto turn_weight_penalties_ptr = data_layout.GetBlockPtr<TurnPenalty>(
memory_block, storage::DataLayout::TURN_WEIGHT_PENALTIES);
m_turn_weight_penalties = util::vector_view<TurnPenalty>(
turn_weight_penalties_ptr,
data_layout.num_entries[storage::DataLayout::TURN_WEIGHT_PENALTIES]);
auto turn_duration_penalties_ptr = data_layout.GetBlockPtr<TurnPenalty>(
memory_block, storage::DataLayout::TURN_DURATION_PENALTIES);
m_turn_duration_penalties = util::vector_view<TurnPenalty>(
turn_duration_penalties_ptr,
data_layout.num_entries[storage::DataLayout::TURN_DURATION_PENALTIES]);
}
void InitializeGeometryPointers(storage::DataLayout &data_layout, char *memory_block)
{
auto geometries_index_ptr =
data_layout.GetBlockPtr<unsigned>(memory_block, storage::DataLayout::GEOMETRIES_INDEX);
util::vector_view<unsigned> geometry_begin_indices(
geometries_index_ptr, data_layout.num_entries[storage::DataLayout::GEOMETRIES_INDEX]);
auto num_entries = data_layout.num_entries[storage::DataLayout::GEOMETRIES_NODE_LIST];
auto geometries_node_list_ptr = data_layout.GetBlockPtr<NodeID>(
memory_block, storage::DataLayout::GEOMETRIES_NODE_LIST);
util::vector_view<NodeID> geometry_node_list(geometries_node_list_ptr, num_entries);
auto geometries_fwd_weight_list_ptr =
data_layout.GetBlockPtr<extractor::SegmentDataView::SegmentWeightVector::block_type>(
memory_block, storage::DataLayout::GEOMETRIES_FWD_WEIGHT_LIST);
extractor::SegmentDataView::SegmentWeightVector geometry_fwd_weight_list(
util::vector_view<extractor::SegmentDataView::SegmentWeightVector::block_type>(
geometries_fwd_weight_list_ptr,
data_layout.num_entries[storage::DataLayout::GEOMETRIES_FWD_WEIGHT_LIST]),
num_entries);
auto geometries_rev_weight_list_ptr =
data_layout.GetBlockPtr<extractor::SegmentDataView::SegmentWeightVector::block_type>(
memory_block, storage::DataLayout::GEOMETRIES_REV_WEIGHT_LIST);
extractor::SegmentDataView::SegmentWeightVector geometry_rev_weight_list(
util::vector_view<extractor::SegmentDataView::SegmentWeightVector::block_type>(
geometries_rev_weight_list_ptr,
data_layout.num_entries[storage::DataLayout::GEOMETRIES_REV_WEIGHT_LIST]),
num_entries);
auto geometries_fwd_duration_list_ptr =
data_layout.GetBlockPtr<extractor::SegmentDataView::SegmentDurationVector::block_type>(
memory_block, storage::DataLayout::GEOMETRIES_FWD_DURATION_LIST);
extractor::SegmentDataView::SegmentDurationVector geometry_fwd_duration_list(
util::vector_view<extractor::SegmentDataView::SegmentDurationVector::block_type>(
geometries_fwd_duration_list_ptr,
data_layout.num_entries[storage::DataLayout::GEOMETRIES_FWD_DURATION_LIST]),
num_entries);
auto geometries_rev_duration_list_ptr =
data_layout.GetBlockPtr<extractor::SegmentDataView::SegmentDurationVector::block_type>(
memory_block, storage::DataLayout::GEOMETRIES_REV_DURATION_LIST);
extractor::SegmentDataView::SegmentDurationVector geometry_rev_duration_list(
util::vector_view<extractor::SegmentDataView::SegmentDurationVector::block_type>(
geometries_rev_duration_list_ptr,
data_layout.num_entries[storage::DataLayout::GEOMETRIES_REV_DURATION_LIST]),
num_entries);
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),
std::move(geometry_fwd_weight_list),
std::move(geometry_rev_weight_list),
std::move(geometry_fwd_duration_list),
std::move(geometry_rev_duration_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);
}
void InitializeIntersectionClassPointers(storage::DataLayout &data_layout, char *memory_block)
{
auto bearing_class_id_ptr = data_layout.GetBlockPtr<BearingClassID>(
memory_block, storage::DataLayout::BEARING_CLASSID);
util::vector_view<BearingClassID> bearing_class_id(
bearing_class_id_ptr, data_layout.num_entries[storage::DataLayout::BEARING_CLASSID]);
auto bearing_values_ptr = data_layout.GetBlockPtr<DiscreteBearing>(
memory_block, storage::DataLayout::BEARING_VALUES);
util::vector_view<DiscreteBearing> bearing_values(
bearing_values_ptr, data_layout.num_entries[storage::DataLayout::BEARING_VALUES]);
auto offsets_ptr =
data_layout.GetBlockPtr<unsigned>(memory_block, storage::DataLayout::BEARING_OFFSETS);
auto blocks_ptr =
data_layout.GetBlockPtr<IndexBlock>(memory_block, storage::DataLayout::BEARING_BLOCKS);
util::vector_view<unsigned> bearing_offsets(
offsets_ptr, data_layout.num_entries[storage::DataLayout::BEARING_OFFSETS]);
util::vector_view<IndexBlock> bearing_blocks(
blocks_ptr, data_layout.num_entries[storage::DataLayout::BEARING_BLOCKS]);
util::RangeTable<16, storage::Ownership::View> bearing_range_table(
bearing_offsets, bearing_blocks, static_cast<unsigned>(bearing_values.size()));
intersection_bearings_view = extractor::IntersectionBearingsView{
std::move(bearing_values), std::move(bearing_class_id), std::move(bearing_range_table)};
auto entry_class_ptr = data_layout.GetBlockPtr<util::guidance::EntryClass>(
memory_block, storage::DataLayout::ENTRY_CLASS);
util::vector_view<util::guidance::EntryClass> entry_class_table(
entry_class_ptr, data_layout.num_entries[storage::DataLayout::ENTRY_CLASS]);
m_entry_class_table = std::move(entry_class_table);
}
void InitializeManeuverOverridePointers(storage::DataLayout &data_layout, char *memory_block)
{
auto maneuver_overrides_ptr = data_layout.GetBlockPtr<extractor::StorageManeuverOverride>(
memory_block, storage::DataLayout::MANEUVER_OVERRIDES);
m_maneuver_overrides = util::vector_view<extractor::StorageManeuverOverride>(
maneuver_overrides_ptr,
data_layout.num_entries[storage::DataLayout::MANEUVER_OVERRIDES]);
auto maneuver_override_node_sequences_ptr = data_layout.GetBlockPtr<NodeID>(
memory_block, storage::DataLayout::MANEUVER_OVERRIDE_NODE_SEQUENCES);
m_maneuver_override_node_sequences = util::vector_view<NodeID>(
maneuver_override_node_sequences_ptr,
data_layout.num_entries[storage::DataLayout::MANEUVER_OVERRIDE_NODE_SEQUENCES]);
}
void InitializeInternalPointers(storage::DataLayout &data_layout,
char *memory_block,
void InitializeInternalPointers(const storage::SharedDataIndex &index,
const std::string &metric_name,
const std::size_t exclude_index)
{
InitializeChecksumPointer(data_layout, memory_block);
InitializeNodeInformationPointers(data_layout, memory_block);
InitializeEdgeBasedNodeDataInformationPointers(data_layout, memory_block);
InitializeEdgeInformationPointers(data_layout, memory_block);
InitializeTurnPenalties(data_layout, memory_block);
InitializeGeometryPointers(data_layout, memory_block);
InitializeTimestampPointer(data_layout, memory_block);
InitializeNamePointers(data_layout, memory_block);
InitializeTurnLaneDescriptionsPointers(data_layout, memory_block);
InitializeProfilePropertiesPointer(data_layout, memory_block, exclude_index);
InitializeRTreePointers(data_layout, memory_block);
InitializeIntersectionClassPointers(data_layout, memory_block);
InitializeManeuverOverridePointers(data_layout, memory_block);
// TODO: For multi-metric support we need to have separate exclude classes per metric
(void)metric_name;
m_profile_properties =
index.GetBlockPtr<extractor::ProfileProperties>("/common/properties");
exclude_mask = m_profile_properties->excludable_classes[exclude_index];
m_check_sum = *index.GetBlockPtr<std::uint32_t>("/common/connectivity_checksum");
std::tie(m_coordinate_list, m_osmnodeid_list) =
make_nbn_data_view(index, "/common/nbn_data");
m_static_rtree = make_search_tree_view(index, "/common/rtree");
m_geospatial_query.reset(
new SharedGeospatialQuery(m_static_rtree, m_coordinate_list, *this));
edge_based_node_data = make_ebn_data_view(index, "/common/ebg_node_data");
turn_data = make_turn_data_view(index, "/common/turn_data");
m_name_table = make_name_table_view(index, "/common/names");
std::tie(m_lane_description_offsets, m_lane_description_masks) =
make_turn_lane_description_views(index, "/common/turn_lanes");
m_lane_tupel_id_pairs = make_lane_data_view(index, "/common/turn_lanes");
m_turn_weight_penalties = make_turn_weight_view(index, "/common/turn_penalty");
m_turn_duration_penalties = make_turn_duration_view(index, "/common/turn_penalty");
segment_data = make_segment_data_view(index, "/common/segment_data");
m_datasources = index.GetBlockPtr<extractor::Datasources>("/common/data_sources_names");
intersection_bearings_view =
make_intersection_bearings_view(index, "/common/intersection_bearings");
m_entry_class_table = make_entry_classes_view(index, "/common/entry_classes");
std::tie(m_maneuver_overrides, m_maneuver_override_node_sequences) =
make_maneuver_overrides_views(index, "/common/maneuver_overrides");
}
public:
// allows switching between process_memory/shared_memory datafacade, based on the type of
// allocator
ContiguousInternalMemoryDataFacadeBase(std::shared_ptr<ContiguousBlockAllocator> allocator_,
const std::string &metric_name,
const std::size_t exclude_index)
: allocator(std::move(allocator_))
{
InitializeInternalPointers(allocator->GetLayout(), allocator->GetMemory(), exclude_index);
InitializeInternalPointers(allocator->GetIndex(), metric_name, exclude_index);
}
// node and edge information access
@@ -558,72 +239,57 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
return m_osmnodeid_list[id];
}
std::vector<NodeID> GetUncompressedForwardGeometry(const EdgeID id) const override final
NodeForwardRange GetUncompressedForwardGeometry(const EdgeID id) const override final
{
auto range = segment_data.GetForwardGeometry(id);
return std::vector<NodeID>{range.begin(), range.end()};
return segment_data.GetForwardGeometry(id);
}
virtual std::vector<NodeID> GetUncompressedReverseGeometry(const EdgeID id) const override final
NodeReverseRange GetUncompressedReverseGeometry(const EdgeID id) const override final
{
auto range = segment_data.GetReverseGeometry(id);
return std::vector<NodeID>{range.begin(), range.end()};
return segment_data.GetReverseGeometry(id);
}
virtual std::vector<EdgeWeight>
GetUncompressedForwardDurations(const EdgeID id) const override final
DurationForwardRange GetUncompressedForwardDurations(const EdgeID id) const override final
{
auto range = segment_data.GetForwardDurations(id);
return std::vector<EdgeWeight>{range.begin(), range.end()};
return segment_data.GetForwardDurations(id);
}
virtual std::vector<EdgeWeight>
GetUncompressedReverseDurations(const EdgeID id) const override final
DurationReverseRange GetUncompressedReverseDurations(const EdgeID id) const override final
{
auto range = segment_data.GetReverseDurations(id);
return std::vector<EdgeWeight>{range.begin(), range.end()};
return segment_data.GetReverseDurations(id);
}
virtual std::vector<EdgeWeight>
GetUncompressedForwardWeights(const EdgeID id) const override final
WeightForwardRange GetUncompressedForwardWeights(const EdgeID id) const override final
{
auto range = segment_data.GetForwardWeights(id);
return std::vector<EdgeWeight>{range.begin(), range.end()};
return segment_data.GetForwardWeights(id);
}
virtual std::vector<EdgeWeight>
GetUncompressedReverseWeights(const EdgeID id) const override final
WeightReverseRange GetUncompressedReverseWeights(const EdgeID id) const override final
{
auto range = segment_data.GetReverseWeights(id);
return std::vector<EdgeWeight>{range.begin(), range.end()};
return segment_data.GetReverseWeights(id);
}
// Returns the data source ids that were used to supply the edge
// weights.
virtual std::vector<DatasourceID>
GetUncompressedForwardDatasources(const EdgeID id) const override final
DatasourceForwardRange GetUncompressedForwardDatasources(const EdgeID id) const override final
{
auto range = segment_data.GetForwardDatasources(id);
return std::vector<DatasourceID>{range.begin(), range.end()};
return segment_data.GetForwardDatasources(id);
}
// Returns the data source ids that were used to supply the edge
// weights.
virtual std::vector<DatasourceID>
GetUncompressedReverseDatasources(const EdgeID id) const override final
DatasourceReverseRange GetUncompressedReverseDatasources(const EdgeID id) const override final
{
auto range = segment_data.GetReverseDatasources(id);
return std::vector<DatasourceID>{range.begin(), range.end()};
return segment_data.GetReverseDatasources(id);
}
virtual TurnPenalty GetWeightPenaltyForEdgeID(const unsigned id) const override final
TurnPenalty GetWeightPenaltyForEdgeID(const unsigned id) const override final
{
BOOST_ASSERT(m_turn_weight_penalties.size() > id);
return m_turn_weight_penalties[id];
}
virtual TurnPenalty GetDurationPenaltyForEdgeID(const unsigned id) const override final
TurnPenalty GetDurationPenaltyForEdgeID(const unsigned id) const override final
{
BOOST_ASSERT(m_turn_duration_penalties.size() > id);
return m_turn_duration_penalties[id];
@@ -763,7 +429,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
input_coordinate, bearing, bearing_range, approach);
}
unsigned GetCheckSum() const override final { return m_check_sum; }
std::uint32_t GetCheckSum() const override final { return m_check_sum; }
GeometryID GetGeometryIndex(const NodeID id) const override final
{
@@ -836,8 +502,6 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
return m_datasources->GetSourceName(id);
}
std::string GetTimestamp() const override final { return m_timestamp; }
bool GetContinueStraightDefault() const override final
{
return m_profile_properties->continue_straight_at_waypoint;
@@ -954,9 +618,10 @@ class ContiguousInternalMemoryDataFacade<CH>
{
public:
ContiguousInternalMemoryDataFacade(std::shared_ptr<ContiguousBlockAllocator> allocator,
const std::string &metric_name,
const std::size_t exclude_index)
: ContiguousInternalMemoryDataFacadeBase(allocator, exclude_index),
ContiguousInternalMemoryAlgorithmDataFacade<CH>(allocator, exclude_index)
: ContiguousInternalMemoryDataFacadeBase(allocator, metric_name, exclude_index),
ContiguousInternalMemoryAlgorithmDataFacade<CH>(allocator, metric_name, exclude_index)
{
}
@@ -974,122 +639,15 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
QueryGraph query_graph;
void InitializeInternalPointers(storage::DataLayout &data_layout,
char *memory_block,
void InitializeInternalPointers(const storage::SharedDataIndex &index,
const std::string &metric_name,
const std::size_t exclude_index)
{
InitializeMLDDataPointers(data_layout, memory_block, exclude_index);
InitializeGraphPointer(data_layout, memory_block);
}
void InitializeMLDDataPointers(storage::DataLayout &data_layout,
char *memory_block,
const std::size_t exclude_index)
{
if (data_layout.GetBlockSize(storage::DataLayout::MLD_PARTITION) > 0)
{
BOOST_ASSERT(data_layout.GetBlockSize(storage::DataLayout::MLD_LEVEL_DATA) > 0);
BOOST_ASSERT(data_layout.GetBlockSize(storage::DataLayout::MLD_CELL_TO_CHILDREN) > 0);
auto level_data =
data_layout.GetBlockPtr<partitioner::MultiLevelPartitionView::LevelData>(
memory_block, storage::DataLayout::MLD_LEVEL_DATA);
auto mld_partition_ptr = data_layout.GetBlockPtr<PartitionID>(
memory_block, storage::DataLayout::MLD_PARTITION);
auto partition_entries_count =
data_layout.GetBlockEntries(storage::DataLayout::MLD_PARTITION);
util::vector_view<PartitionID> partition(mld_partition_ptr, partition_entries_count);
auto mld_chilren_ptr = data_layout.GetBlockPtr<CellID>(
memory_block, storage::DataLayout::MLD_CELL_TO_CHILDREN);
auto children_entries_count =
data_layout.GetBlockEntries(storage::DataLayout::MLD_CELL_TO_CHILDREN);
util::vector_view<CellID> cell_to_children(mld_chilren_ptr, children_entries_count);
mld_partition =
partitioner::MultiLevelPartitionView{level_data, partition, cell_to_children};
}
const auto weights_block_id = static_cast<storage::DataLayout::BlockID>(
storage::DataLayout::MLD_CELL_WEIGHTS_0 + exclude_index);
const auto durations_block_id = static_cast<storage::DataLayout::BlockID>(
storage::DataLayout::MLD_CELL_DURATIONS_0 + exclude_index);
if (data_layout.GetBlockSize(weights_block_id) > 0)
{
auto mld_cell_weights_ptr =
data_layout.GetBlockPtr<EdgeWeight>(memory_block, weights_block_id);
auto mld_cell_durations_ptr =
data_layout.GetBlockPtr<EdgeDuration>(memory_block, durations_block_id);
auto weight_entries_count =
data_layout.GetBlockEntries(storage::DataLayout::MLD_CELL_WEIGHTS_0);
auto duration_entries_count =
data_layout.GetBlockEntries(storage::DataLayout::MLD_CELL_DURATIONS_0);
BOOST_ASSERT(weight_entries_count == duration_entries_count);
util::vector_view<EdgeWeight> weights(mld_cell_weights_ptr, weight_entries_count);
util::vector_view<EdgeDuration> durations(mld_cell_durations_ptr,
duration_entries_count);
mld_cell_metric = customizer::CellMetricView{std::move(weights), std::move(durations)};
}
if (data_layout.GetBlockSize(storage::DataLayout::MLD_CELLS) > 0)
{
auto mld_source_boundary_ptr = data_layout.GetBlockPtr<NodeID>(
memory_block, storage::DataLayout::MLD_CELL_SOURCE_BOUNDARY);
auto mld_destination_boundary_ptr = data_layout.GetBlockPtr<NodeID>(
memory_block, storage::DataLayout::MLD_CELL_DESTINATION_BOUNDARY);
auto mld_cells_ptr = data_layout.GetBlockPtr<partitioner::CellStorageView::CellData>(
memory_block, storage::DataLayout::MLD_CELLS);
auto mld_cell_level_offsets_ptr = data_layout.GetBlockPtr<std::uint64_t>(
memory_block, storage::DataLayout::MLD_CELL_LEVEL_OFFSETS);
auto source_boundary_entries_count =
data_layout.GetBlockEntries(storage::DataLayout::MLD_CELL_SOURCE_BOUNDARY);
auto destination_boundary_entries_count =
data_layout.GetBlockEntries(storage::DataLayout::MLD_CELL_DESTINATION_BOUNDARY);
auto cells_entries_counts = data_layout.GetBlockEntries(storage::DataLayout::MLD_CELLS);
auto cell_level_offsets_entries_count =
data_layout.GetBlockEntries(storage::DataLayout::MLD_CELL_LEVEL_OFFSETS);
util::vector_view<NodeID> source_boundary(mld_source_boundary_ptr,
source_boundary_entries_count);
util::vector_view<NodeID> destination_boundary(mld_destination_boundary_ptr,
destination_boundary_entries_count);
util::vector_view<partitioner::CellStorageView::CellData> cells(mld_cells_ptr,
cells_entries_counts);
util::vector_view<std::uint64_t> level_offsets(mld_cell_level_offsets_ptr,
cell_level_offsets_entries_count);
mld_cell_storage = partitioner::CellStorageView{std::move(source_boundary),
std::move(destination_boundary),
std::move(cells),
std::move(level_offsets)};
}
}
void InitializeGraphPointer(storage::DataLayout &data_layout, char *memory_block)
{
auto graph_nodes_ptr = data_layout.GetBlockPtr<GraphNode>(
memory_block, storage::DataLayout::MLD_GRAPH_NODE_LIST);
auto graph_edges_ptr = data_layout.GetBlockPtr<GraphEdge>(
memory_block, storage::DataLayout::MLD_GRAPH_EDGE_LIST);
auto graph_node_to_offset_ptr = data_layout.GetBlockPtr<QueryGraph::EdgeOffset>(
memory_block, storage::DataLayout::MLD_GRAPH_NODE_TO_OFFSET);
util::vector_view<GraphNode> node_list(
graph_nodes_ptr, data_layout.num_entries[storage::DataLayout::MLD_GRAPH_NODE_LIST]);
util::vector_view<GraphEdge> edge_list(
graph_edges_ptr, data_layout.num_entries[storage::DataLayout::MLD_GRAPH_EDGE_LIST]);
util::vector_view<QueryGraph::EdgeOffset> node_to_offset(
graph_node_to_offset_ptr,
data_layout.num_entries[storage::DataLayout::MLD_GRAPH_NODE_TO_OFFSET]);
query_graph =
QueryGraph(std::move(node_list), std::move(edge_list), std::move(node_to_offset));
mld_partition = make_partition_view(index, "/mld/multilevelpartition");
mld_cell_metric =
make_filtered_cell_metric_view(index, "/mld/metrics/" + metric_name, exclude_index);
mld_cell_storage = make_cell_storage_view(index, "/mld/cellstorage");
query_graph = make_multi_level_graph_view(index, "/mld/multilevelgraph");
}
// allocator that keeps the allocation data
@@ -1097,10 +655,12 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
public:
ContiguousInternalMemoryAlgorithmDataFacade(
std::shared_ptr<ContiguousBlockAllocator> allocator_, const std::size_t exclude_index)
std::shared_ptr<ContiguousBlockAllocator> allocator_,
const std::string &metric_name,
const std::size_t exclude_index)
: allocator(std::move(allocator_))
{
InitializeInternalPointers(allocator->GetLayout(), allocator->GetMemory(), exclude_index);
InitializeInternalPointers(allocator->GetIndex(), metric_name, exclude_index);
}
const partitioner::MultiLevelPartitionView &GetMultiLevelPartition() const override
@@ -1115,6 +675,8 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
// search graph access
unsigned GetNumberOfNodes() const override final { return query_graph.GetNumberOfNodes(); }
unsigned GetMaxBorderNodeID() const override final { return query_graph.GetMaxBorderNodeID(); }
unsigned GetNumberOfEdges() const override final { return query_graph.GetNumberOfEdges(); }
unsigned GetOutDegree(const NodeID n) const override final
@@ -1154,9 +716,10 @@ class ContiguousInternalMemoryDataFacade<MLD> final
private:
public:
ContiguousInternalMemoryDataFacade(std::shared_ptr<ContiguousBlockAllocator> allocator,
const std::string &metric_name,
const std::size_t exclude_index)
: ContiguousInternalMemoryDataFacadeBase(allocator, exclude_index),
ContiguousInternalMemoryAlgorithmDataFacade<MLD>(allocator, exclude_index)
: ContiguousInternalMemoryDataFacadeBase(allocator, metric_name, exclude_index),
ContiguousInternalMemoryAlgorithmDataFacade<MLD>(allocator, metric_name, exclude_index)
{
}
+31 -14
View File
@@ -10,10 +10,9 @@
#include "extractor/class_data.hpp"
#include "extractor/edge_based_node_segment.hpp"
//#include "extractor/guidance/turn_lane_types.hpp"
#include "extractor/maneuver_override.hpp"
//#include "extractor/original_edge_data.hpp"
#include "extractor/query_node.hpp"
#include "extractor/segment_data_container.hpp"
#include "extractor/travel_mode.hpp"
#include "extractor/turn_lane_types.hpp"
@@ -25,12 +24,16 @@
#include "util/guidance/entry_class.hpp"
#include "util/guidance/turn_lanes.hpp"
#include "util/integer_range.hpp"
#include "util/packed_vector.hpp"
#include "util/string_util.hpp"
#include "util/string_view.hpp"
#include "util/typedefs.hpp"
#include "osrm/coordinate.hpp"
#include <boost/range/adaptor/reversed.hpp>
#include <boost/range/any_range.hpp>
#include <cstddef>
#include <string>
@@ -50,10 +53,27 @@ class BaseDataFacade
{
public:
using RTreeLeaf = extractor::EdgeBasedNodeSegment;
using NodeForwardRange =
boost::iterator_range<extractor::SegmentDataView::SegmentNodeVector::const_iterator>;
using NodeReverseRange = boost::reversed_range<const NodeForwardRange>;
using WeightForwardRange =
boost::iterator_range<extractor::SegmentDataView::SegmentWeightVector::const_iterator>;
using WeightReverseRange = boost::reversed_range<const WeightForwardRange>;
using DurationForwardRange =
boost::iterator_range<extractor::SegmentDataView::SegmentDurationVector::const_iterator>;
using DurationReverseRange = boost::reversed_range<const DurationForwardRange>;
using DatasourceForwardRange =
boost::iterator_range<extractor::SegmentDataView::SegmentDatasourceVector::const_iterator>;
using DatasourceReverseRange = boost::reversed_range<const DatasourceForwardRange>;
BaseDataFacade() {}
virtual ~BaseDataFacade() {}
virtual unsigned GetCheckSum() const = 0;
virtual std::uint32_t GetCheckSum() const = 0;
// node and edge information access
virtual util::Coordinate GetCoordinateOfNode(const NodeID id) const = 0;
@@ -64,9 +84,8 @@ class BaseDataFacade
virtual ComponentID GetComponentID(const NodeID id) const = 0;
virtual std::vector<NodeID> GetUncompressedForwardGeometry(const EdgeID id) const = 0;
virtual std::vector<NodeID> GetUncompressedReverseGeometry(const EdgeID id) const = 0;
virtual NodeForwardRange GetUncompressedForwardGeometry(const EdgeID id) const = 0;
virtual NodeReverseRange GetUncompressedReverseGeometry(const EdgeID id) const = 0;
virtual TurnPenalty GetWeightPenaltyForEdgeID(const unsigned id) const = 0;
@@ -74,18 +93,18 @@ class BaseDataFacade
// Gets the weight values for each segment in an uncompressed geometry.
// Should always be 1 shorter than GetUncompressedGeometry
virtual std::vector<EdgeWeight> GetUncompressedForwardWeights(const EdgeID id) const = 0;
virtual std::vector<EdgeWeight> GetUncompressedReverseWeights(const EdgeID id) const = 0;
virtual WeightForwardRange GetUncompressedForwardWeights(const EdgeID id) const = 0;
virtual WeightReverseRange GetUncompressedReverseWeights(const EdgeID id) const = 0;
// Gets the duration values for each segment in an uncompressed geometry.
// Should always be 1 shorter than GetUncompressedGeometry
virtual std::vector<EdgeWeight> GetUncompressedForwardDurations(const EdgeID id) const = 0;
virtual std::vector<EdgeWeight> GetUncompressedReverseDurations(const EdgeID id) const = 0;
virtual DurationForwardRange GetUncompressedForwardDurations(const EdgeID id) const = 0;
virtual DurationReverseRange GetUncompressedReverseDurations(const EdgeID id) const = 0;
// Returns the data source ids that were used to supply the edge
// weights. Will return an empty array when only the base profile is used.
virtual std::vector<DatasourceID> GetUncompressedForwardDatasources(const EdgeID id) const = 0;
virtual std::vector<DatasourceID> GetUncompressedReverseDatasources(const EdgeID id) const = 0;
virtual DatasourceForwardRange GetUncompressedForwardDatasources(const EdgeID id) const = 0;
virtual DatasourceReverseRange GetUncompressedReverseDatasources(const EdgeID id) const = 0;
// Gets the name of a datasource
virtual StringView GetDatasourceName(const DatasourceID id) const = 0;
@@ -173,8 +192,6 @@ class BaseDataFacade
virtual StringView GetExitsForID(const NameID id) const = 0;
virtual std::string GetTimestamp() const = 0;
virtual bool GetContinueStraightDefault() const = 0;
virtual double GetMapMatchingMaxSpeed() const = 0;
@@ -0,0 +1,44 @@
#ifndef OSRM_ENGINE_DATAFACADE_MMAP_MEMORY_ALLOCATOR_HPP_
#define OSRM_ENGINE_DATAFACADE_MMAP_MEMORY_ALLOCATOR_HPP_
#include "engine/datafacade/contiguous_block_allocator.hpp"
#include "storage/storage_config.hpp"
#include "util/vector_view.hpp"
#include <boost/iostreams/device/mapped_file.hpp>
#include <memory>
namespace osrm
{
namespace engine
{
namespace datafacade
{
/**
* This allocator uses file backed mmap memory block as the data location.
*/
class MMapMemoryAllocator : public ContiguousBlockAllocator
{
public:
explicit MMapMemoryAllocator(const storage::StorageConfig &config,
const boost::filesystem::path &memory_file);
~MMapMemoryAllocator() override final;
// interface to give access to the datafacades
const storage::SharedDataIndex &GetIndex() override final;
private:
storage::SharedDataIndex index;
util::vector_view<char> mapped_memory;
boost::iostreams::mapped_file mapped_memory_file;
};
} // namespace datafacade
} // namespace engine
} // namespace osrm
#endif // OSRM_ENGINE_DATAFACADE_SHARED_MEMORY_ALLOCATOR_HPP_
@@ -27,12 +27,11 @@ class ProcessMemoryAllocator : public ContiguousBlockAllocator
~ProcessMemoryAllocator() override final;
// interface to give access to the datafacades
storage::DataLayout &GetLayout() override final;
char *GetMemory() override final;
const storage::SharedDataIndex &GetIndex() override final;
private:
storage::SharedDataIndex index;
std::unique_ptr<char[]> internal_memory;
std::unique_ptr<storage::DataLayout> internal_layout;
};
} // namespace datafacade
@@ -3,7 +3,7 @@
#include "engine/datafacade/contiguous_block_allocator.hpp"
#include "storage/shared_datatype.hpp"
#include "storage/shared_data_index.hpp"
#include "storage/shared_memory.hpp"
#include <memory>
@@ -23,15 +23,16 @@ namespace datafacade
class SharedMemoryAllocator : public ContiguousBlockAllocator
{
public:
explicit SharedMemoryAllocator(storage::SharedDataType data_region);
explicit SharedMemoryAllocator(
const std::vector<storage::SharedRegionRegister::ShmKey> &shm_keys);
~SharedMemoryAllocator() override final;
// interface to give access to the datafacades
storage::DataLayout &GetLayout() override final;
char *GetMemory() override final;
const storage::SharedDataIndex &GetIndex() override final;
private:
std::unique_ptr<storage::SharedMemory> m_large_memory;
storage::SharedDataIndex index;
std::vector<std::unique_ptr<storage::SharedMemory>> memory_regions;
};
} // namespace datafacade
+30 -6
View File
@@ -33,6 +33,7 @@ template <template <typename A> class FacadeT, typename AlgorithmT> class DataFa
DataFacadeFactory(std::shared_ptr<AllocatorT> allocator)
: DataFacadeFactory(allocator, has_exclude_flags)
{
BOOST_ASSERT_MSG(facades.size() >= 1, "At least one datafacade is needed");
}
template <typename ParameterT> std::shared_ptr<const Facade> Get(const ParameterT &params) const
@@ -45,13 +46,33 @@ template <template <typename A> class FacadeT, typename AlgorithmT> class DataFa
template <typename AllocatorT>
DataFacadeFactory(std::shared_ptr<AllocatorT> allocator, std::true_type)
{
for (const auto index : util::irange<std::size_t>(0, facades.size()))
const auto &index = allocator->GetIndex();
properties = index.template GetBlockPtr<extractor::ProfileProperties>("/common/properties");
const auto &metric_name = properties->GetWeightName();
std::vector<std::string> exclude_prefixes;
auto exclude_path = std::string("/") + routing_algorithms::identifier<AlgorithmT>() +
std::string("/metrics/") + metric_name + "/exclude/";
index.List(exclude_path, std::back_inserter(exclude_prefixes));
facades.resize(exclude_prefixes.size());
if (facades.empty())
{
facades[index] = std::make_shared<const Facade>(allocator, index);
throw util::exception(std::string("Could not find any metrics for ") +
routing_algorithms::name<AlgorithmT>() +
" in the data. Did you load the right dataset?");
}
properties = allocator->GetLayout().template GetBlockPtr<extractor::ProfileProperties>(
allocator->GetMemory(), storage::DataLayout::PROPERTIES);
for (const auto &exclude_prefix : exclude_prefixes)
{
auto index_begin = exclude_prefix.find_last_of("/");
BOOST_ASSERT_MSG(index_begin != std::string::npos,
"The exclude prefix needs to be a valid data path.");
std::size_t index =
std::stoi(exclude_prefix.substr(index_begin + 1, exclude_prefix.size()));
BOOST_ASSERT(index >= 0 && index < facades.size());
facades[index] = std::make_shared<const Facade>(allocator, metric_name, index);
}
for (const auto index : util::irange<std::size_t>(0, properties->class_names.size()))
{
@@ -67,7 +88,10 @@ template <template <typename A> class FacadeT, typename AlgorithmT> class DataFa
template <typename AllocatorT>
DataFacadeFactory(std::shared_ptr<AllocatorT> allocator, std::false_type)
{
facades[0] = std::make_shared<const Facade>(allocator, 0);
const auto &index = allocator->GetIndex();
properties = index.template GetBlockPtr<extractor::ProfileProperties>("/common/properties");
const auto &metric_name = properties->GetWeightName();
facades.push_back(std::make_shared<const Facade>(allocator, metric_name, 0));
}
std::shared_ptr<const Facade> Get(const api::TileParameters &, std::false_type) const
@@ -124,7 +148,7 @@ template <template <typename A> class FacadeT, typename AlgorithmT> class DataFa
return {};
}
std::array<std::shared_ptr<const Facade>, extractor::MAX_EXCLUDABLE_CLASSES> facades;
std::vector<std::shared_ptr<const Facade>> facades;
std::unordered_map<std::string, extractor::ClassData> name_to_class;
const extractor::ProfileProperties *properties = nullptr;
};
+30
View File
@@ -4,6 +4,7 @@
#include "engine/data_watchdog.hpp"
#include "engine/datafacade.hpp"
#include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
#include "engine/datafacade/mmap_memory_allocator.hpp"
#include "engine/datafacade/process_memory_allocator.hpp"
#include "engine/datafacade_factory.hpp"
@@ -25,6 +26,31 @@ template <typename AlgorithmT, template <typename A> class FacadeT> class DataFa
virtual std::shared_ptr<const Facade> Get(const api::TileParameters &) const = 0;
};
template <typename AlgorithmT, template <typename A> class FacadeT>
class ExternalProvider final : public DataFacadeProvider<AlgorithmT, FacadeT>
{
public:
using Facade = typename DataFacadeProvider<AlgorithmT, FacadeT>::Facade;
ExternalProvider(const storage::StorageConfig &config,
const boost::filesystem::path &memory_file)
: facade_factory(std::make_shared<datafacade::MMapMemoryAllocator>(config, memory_file))
{
}
std::shared_ptr<const Facade> Get(const api::TileParameters &params) const override final
{
return facade_factory.Get(params);
}
std::shared_ptr<const Facade> Get(const api::BaseParameters &params) const override final
{
return facade_factory.Get(params);
}
private:
DataFacadeFactory<FacadeT, AlgorithmT> facade_factory;
};
template <typename AlgorithmT, template <typename A> class FacadeT>
class ImmutableProvider final : public DataFacadeProvider<AlgorithmT, FacadeT>
{
@@ -57,6 +83,8 @@ class WatchingProvider : public DataFacadeProvider<AlgorithmT, FacadeT>
public:
using Facade = typename DataFacadeProvider<AlgorithmT, FacadeT>::Facade;
WatchingProvider(const std::string &dataset_name) : watchdog(dataset_name) {}
std::shared_ptr<const Facade> Get(const api::TileParameters &params) const override final
{
return watchdog.Get(params);
@@ -74,6 +102,8 @@ template <typename AlgorithmT>
using WatchingProvider = detail::WatchingProvider<AlgorithmT, DataFacade>;
template <typename AlgorithmT>
using ImmutableProvider = detail::ImmutableProvider<AlgorithmT, DataFacade>;
template <typename AlgorithmT>
using ExternalProvider = detail::ExternalProvider<AlgorithmT, DataFacade>;
}
}
+11 -78
View File
@@ -7,8 +7,6 @@
#include "engine/api/table_parameters.hpp"
#include "engine/api/tile_parameters.hpp"
#include "engine/api/trip_parameters.hpp"
#include "engine/data_watchdog.hpp"
#include "engine/datafacade/contiguous_block_allocator.hpp"
#include "engine/datafacade_provider.hpp"
#include "engine/engine_config.hpp"
#include "engine/plugins/match.hpp"
@@ -19,9 +17,7 @@
#include "engine/plugins/viaroute.hpp"
#include "engine/routing_algorithms.hpp"
#include "engine/status.hpp"
#include "util/exception.hpp"
#include "util/exception_utils.hpp"
#include "util/fingerprint.hpp"
#include "util/json_container.hpp"
#include <memory>
@@ -63,9 +59,16 @@ template <typename Algorithm> class Engine final : public EngineInterface
{
if (config.use_shared_memory)
{
util::Log(logDEBUG) << "Using shared memory with algorithm "
<< routing_algorithms::name<Algorithm>();
facade_provider = std::make_unique<WatchingProvider<Algorithm>>();
util::Log(logDEBUG) << "Using shared memory with name \"" << config.dataset_name
<< "\" with algorithm " << routing_algorithms::name<Algorithm>();
facade_provider = std::make_unique<WatchingProvider<Algorithm>>(config.dataset_name);
}
else if (!config.memory_file.empty())
{
util::Log(logDEBUG) << "Using memory mapped filed at " << config.memory_file
<< " with algorithm " << routing_algorithms::name<Algorithm>();
facade_provider = std::make_unique<ExternalProvider<Algorithm>>(config.storage_config,
config.memory_file);
}
else
{
@@ -116,8 +119,6 @@ template <typename Algorithm> class Engine final : public EngineInterface
return tile_plugin.HandleRequest(GetAlgorithms(params), params, result);
}
static bool CheckCompatibility(const EngineConfig &config);
private:
template <typename ParametersT> auto GetAlgorithms(const ParametersT &params) const
{
@@ -133,74 +134,6 @@ template <typename Algorithm> class Engine final : public EngineInterface
const plugins::MatchPlugin match_plugin;
const plugins::TilePlugin tile_plugin;
};
template <>
bool Engine<routing_algorithms::ch::Algorithm>::CheckCompatibility(const EngineConfig &config)
{
if (config.use_shared_memory)
{
storage::SharedMonitor<storage::SharedDataTimestamp> barrier;
using mutex_type = typename decltype(barrier)::mutex_type;
boost::interprocess::scoped_lock<mutex_type> current_region_lock(barrier.get_mutex());
auto mem = storage::makeSharedMemory(barrier.data().region);
auto layout = reinterpret_cast<storage::DataLayout *>(mem->Ptr());
return layout->GetBlockSize(storage::DataLayout::CH_GRAPH_NODE_LIST) > 4 &&
layout->GetBlockSize(storage::DataLayout::CH_GRAPH_EDGE_LIST) > 4;
}
else
{
if (!boost::filesystem::exists(config.storage_config.GetPath(".osrm.hsgr")))
return false;
storage::io::FileReader in(config.storage_config.GetPath(".osrm.hsgr"),
storage::io::FileReader::VerifyFingerprint);
auto size = in.GetSize();
return size > 0;
}
}
template <>
bool Engine<routing_algorithms::mld::Algorithm>::CheckCompatibility(const EngineConfig &config)
{
if (config.use_shared_memory)
{
storage::SharedMonitor<storage::SharedDataTimestamp> barrier;
using mutex_type = typename decltype(barrier)::mutex_type;
boost::interprocess::scoped_lock<mutex_type> current_region_lock(barrier.get_mutex());
auto mem = storage::makeSharedMemory(barrier.data().region);
auto layout = reinterpret_cast<storage::DataLayout *>(mem->Ptr());
// checks that all the needed memory blocks are populated
// DataLayout::MLD_CELL_SOURCE_BOUNDARY and DataLayout::MLD_CELL_DESTINATION_BOUNDARY
// are not checked, because in situations where there are so few nodes in the graph that
// they all fit into one cell, they can be empty.
bool empty_data = layout->GetBlockSize(storage::DataLayout::MLD_LEVEL_DATA) > 0 &&
layout->GetBlockSize(storage::DataLayout::MLD_PARTITION) > 0 &&
layout->GetBlockSize(storage::DataLayout::MLD_CELL_TO_CHILDREN) > 0 &&
layout->GetBlockSize(storage::DataLayout::MLD_CELLS) > 0 &&
layout->GetBlockSize(storage::DataLayout::MLD_CELL_LEVEL_OFFSETS) > 0 &&
layout->GetBlockSize(storage::DataLayout::MLD_GRAPH_NODE_LIST) > 0 &&
layout->GetBlockSize(storage::DataLayout::MLD_GRAPH_EDGE_LIST) > 0 &&
layout->GetBlockSize(storage::DataLayout::MLD_CELL_WEIGHTS_0) > 0 &&
layout->GetBlockSize(storage::DataLayout::MLD_CELL_DURATIONS_0) > 0 &&
layout->GetBlockSize(storage::DataLayout::MLD_GRAPH_NODE_TO_OFFSET) > 0;
return empty_data;
}
else
{
if (!boost::filesystem::exists(config.storage_config.GetPath(".osrm.partition")) ||
!boost::filesystem::exists(config.storage_config.GetPath(".osrm.cells")) ||
!boost::filesystem::exists(config.storage_config.GetPath(".osrm.mldgr")) ||
!boost::filesystem::exists(config.storage_config.GetPath(".osrm.cell_metrics")))
return false;
storage::io::FileReader in(config.storage_config.GetPath(".osrm.partition"),
storage::io::FileReader::VerifyFingerprint);
auto size = in.GetSize();
return size > 0;
}
}
}
}
+2
View File
@@ -88,8 +88,10 @@ struct EngineConfig final
int max_results_nearest = -1;
int max_alternatives = 3; // set an arbitrary upper bound; can be adjusted by user
bool use_shared_memory = true;
boost::filesystem::path memory_file;
Algorithm algorithm = Algorithm::CH;
std::string verbosity;
std::string dataset_name;
};
}
}
+42 -44
View File
@@ -434,11 +434,6 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// Find the node-based-edge that this belongs to, and directly
// calculate the forward_weight, forward_offset, reverse_weight, reverse_offset
EdgeWeight forward_weight_offset = 0, forward_weight = 0;
EdgeWeight reverse_weight_offset = 0, reverse_weight = 0;
EdgeDuration forward_duration_offset = 0, forward_duration = 0;
EdgeDuration reverse_duration_offset = 0, reverse_duration = 0;
BOOST_ASSERT(data.forward_segment_id.enabled || data.reverse_segment_id.enabled);
BOOST_ASSERT(!data.reverse_segment_id.enabled ||
datafacade.GetGeometryIndex(data.forward_segment_id.id).id ==
@@ -446,35 +441,42 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
const auto geometry_id = datafacade.GetGeometryIndex(data.forward_segment_id.id).id;
const auto component_id = datafacade.GetComponentID(data.forward_segment_id.id);
const std::vector<EdgeWeight> forward_weight_vector =
datafacade.GetUncompressedForwardWeights(geometry_id);
const std::vector<EdgeWeight> reverse_weight_vector =
datafacade.GetUncompressedReverseWeights(geometry_id);
const std::vector<EdgeWeight> forward_duration_vector =
datafacade.GetUncompressedForwardDurations(geometry_id);
const std::vector<EdgeWeight> reverse_duration_vector =
datafacade.GetUncompressedReverseDurations(geometry_id);
const auto forward_weights = datafacade.GetUncompressedForwardWeights(geometry_id);
const auto reverse_weights = datafacade.GetUncompressedReverseWeights(geometry_id);
for (std::size_t i = 0; i < data.fwd_segment_position; i++)
{
forward_weight_offset += forward_weight_vector[i];
forward_duration_offset += forward_duration_vector[i];
}
forward_weight = forward_weight_vector[data.fwd_segment_position];
forward_duration = forward_duration_vector[data.fwd_segment_position];
const auto forward_durations = datafacade.GetUncompressedForwardDurations(geometry_id);
const auto reverse_durations = datafacade.GetUncompressedReverseDurations(geometry_id);
BOOST_ASSERT(data.fwd_segment_position < reverse_weight_vector.size());
const auto forward_weight_offset =
std::accumulate(forward_weights.begin(),
forward_weights.begin() + data.fwd_segment_position,
EdgeWeight{0});
for (std::size_t i = 0; i < reverse_weight_vector.size() - data.fwd_segment_position - 1;
i++)
{
reverse_weight_offset += reverse_weight_vector[i];
reverse_duration_offset += reverse_duration_vector[i];
}
reverse_weight =
reverse_weight_vector[reverse_weight_vector.size() - data.fwd_segment_position - 1];
reverse_duration =
reverse_duration_vector[reverse_duration_vector.size() - data.fwd_segment_position - 1];
const auto forward_duration_offset =
std::accumulate(forward_durations.begin(),
forward_durations.begin() + data.fwd_segment_position,
EdgeDuration{0});
EdgeWeight forward_weight = forward_weights[data.fwd_segment_position];
EdgeDuration forward_duration = forward_durations[data.fwd_segment_position];
BOOST_ASSERT(data.fwd_segment_position <
std::distance(forward_durations.begin(), forward_durations.end()));
const auto reverse_weight_offset =
std::accumulate(reverse_weights.begin(),
reverse_weights.end() - data.fwd_segment_position - 1,
EdgeWeight{0});
const auto reverse_duration_offset =
std::accumulate(reverse_durations.begin(),
reverse_durations.end() - data.fwd_segment_position - 1,
EdgeDuration{0});
EdgeWeight reverse_weight =
reverse_weights[reverse_weights.size() - data.fwd_segment_position - 1];
EdgeDuration reverse_duration =
reverse_durations[reverse_durations.size() - data.fwd_segment_position - 1];
ratio = std::min(1.0, std::max(0.0, ratio));
if (data.forward_segment_id.id != SPECIAL_SEGMENTID)
@@ -493,14 +495,13 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
return std::find(first, last, INVALID_SEGMENT_WEIGHT) == last;
};
bool is_forward_valid_source =
areSegmentsValid(forward_weight_vector.begin(), forward_weight_vector.end());
bool is_forward_valid_target =
areSegmentsValid(forward_weight_vector.begin(),
forward_weight_vector.begin() + data.fwd_segment_position + 1);
areSegmentsValid(forward_weights.begin(), forward_weights.end());
bool is_forward_valid_target = areSegmentsValid(
forward_weights.begin(), forward_weights.begin() + data.fwd_segment_position + 1);
bool is_reverse_valid_source =
areSegmentsValid(reverse_weight_vector.begin(), reverse_weight_vector.end());
areSegmentsValid(reverse_weights.begin(), reverse_weights.end());
bool is_reverse_valid_target = areSegmentsValid(
reverse_weight_vector.begin(), reverse_weight_vector.end() - data.fwd_segment_position);
reverse_weights.begin(), reverse_weights.end() - data.fwd_segment_position);
auto transformed = PhantomNodeWithDistance{
PhantomNode{data,
@@ -605,17 +606,14 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
BOOST_ASSERT(data.forward_segment_id.id != SPECIAL_NODEID);
const auto geometry_id = datafacade.GetGeometryIndex(data.forward_segment_id.id).id;
const std::vector<EdgeWeight> forward_weight_vector =
datafacade.GetUncompressedForwardWeights(geometry_id);
if (forward_weight_vector[data.fwd_segment_position] != INVALID_SEGMENT_WEIGHT)
const auto forward_weights = datafacade.GetUncompressedForwardWeights(geometry_id);
if (forward_weights[data.fwd_segment_position] != INVALID_SEGMENT_WEIGHT)
{
forward_edge_valid = data.forward_segment_id.enabled;
}
const std::vector<EdgeWeight> reverse_weight_vector =
datafacade.GetUncompressedReverseWeights(geometry_id);
if (reverse_weight_vector[reverse_weight_vector.size() - data.fwd_segment_position - 1] !=
const auto reverse_weights = datafacade.GetUncompressedReverseWeights(geometry_id);
if (reverse_weights[reverse_weights.size() - data.fwd_segment_position - 1] !=
INVALID_SEGMENT_WEIGHT)
{
reverse_edge_valid = data.reverse_segment_id.enabled;
+42 -17
View File
@@ -12,6 +12,7 @@
#include "util/coordinate_calculation.hpp"
#include <algorithm>
#include <cmath>
#include <utility>
#include <vector>
@@ -54,10 +55,10 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
const auto source_node_id =
reversed_source ? source_node.reverse_segment_id.id : source_node.forward_segment_id.id;
const auto source_geometry_id = facade.GetGeometryIndex(source_node_id).id;
std::vector<NodeID> source_geometry = facade.GetUncompressedForwardGeometry(source_geometry_id);
const auto source_geometry = facade.GetUncompressedForwardGeometry(source_geometry_id);
geometry.osm_node_ids.push_back(
facade.GetOSMNodeIDOfNode(source_geometry[source_segment_start_coordinate]));
facade.GetOSMNodeIDOfNode(source_geometry(source_segment_start_coordinate)));
auto cumulative_distance = 0.;
auto current_distance = 0.;
@@ -80,7 +81,9 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
prev_coordinate = coordinate;
const auto osm_node_id = facade.GetOSMNodeIDOfNode(path_point.turn_via_node);
if (osm_node_id != geometry.osm_node_ids.back())
if (osm_node_id != geometry.osm_node_ids.back() ||
path_point.turn_instruction.type != osrm::guidance::TurnType::NoTurn)
{
geometry.annotations.emplace_back(LegGeometry::Annotation{
current_distance,
@@ -108,18 +111,41 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
const auto target_node_id =
reversed_target ? target_node.reverse_segment_id.id : target_node.forward_segment_id.id;
const auto target_geometry_id = facade.GetGeometryIndex(target_node_id).id;
const std::vector<DatasourceID> forward_datasources =
facade.GetUncompressedForwardDatasources(target_geometry_id);
const auto forward_datasources = facade.GetUncompressedForwardDatasources(target_geometry_id);
// FIXME if source and target phantoms are on the same segment then duration and weight
// will be from one projected point till end of segment
// testbot/weight.feature:Start and target on the same and adjacent edge
geometry.annotations.emplace_back(LegGeometry::Annotation{
current_distance,
(reversed_target ? target_node.reverse_duration : target_node.forward_duration) / 10.,
(reversed_target ? target_node.reverse_weight : target_node.forward_weight) /
facade.GetWeightMultiplier(),
forward_datasources[target_node.fwd_segment_position]});
// This happens when the source/target are on the same edge-based-node
// There will be no entries in the unpacked path, thus no annotations.
// We will need to calculate the lone annotation by looking at the position
// of the source/target nodes, and calculating their differences.
if (geometry.annotations.empty())
{
auto duration =
std::abs(
(reversed_target ? target_node.reverse_duration : target_node.forward_duration) -
(reversed_source ? source_node.reverse_duration : source_node.forward_duration)) /
10.;
BOOST_ASSERT(duration >= 0);
auto weight =
std::abs((reversed_target ? target_node.reverse_weight : target_node.forward_weight) -
(reversed_source ? source_node.reverse_weight : source_node.forward_weight)) /
facade.GetWeightMultiplier();
BOOST_ASSERT(weight >= 0);
geometry.annotations.emplace_back(
LegGeometry::Annotation{current_distance,
duration,
weight,
forward_datasources(target_node.fwd_segment_position)});
}
else
{
geometry.annotations.emplace_back(LegGeometry::Annotation{
current_distance,
(reversed_target ? target_node.reverse_duration : target_node.forward_duration) / 10.,
(reversed_target ? target_node.reverse_weight : target_node.forward_weight) /
facade.GetWeightMultiplier(),
forward_datasources(target_node.fwd_segment_position)});
}
geometry.segment_offsets.push_back(geometry.locations.size());
geometry.locations.push_back(target_node.location);
@@ -131,10 +157,9 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
// target node rev: 1 1 <- 2 <- 3
const auto target_segment_end_coordinate =
target_node.fwd_segment_position + (reversed_target ? 0 : 1);
const std::vector<NodeID> target_geometry =
facade.GetUncompressedForwardGeometry(target_geometry_id);
const auto target_geometry = facade.GetUncompressedForwardGeometry(target_geometry_id);
geometry.osm_node_ids.push_back(
facade.GetOSMNodeIDOfNode(target_geometry[target_segment_end_coordinate]));
facade.GetOSMNodeIDOfNode(target_geometry(target_segment_end_coordinate)));
BOOST_ASSERT(geometry.segment_distances.size() == geometry.segment_offsets.size() - 1);
BOOST_ASSERT(geometry.locations.size() > geometry.segment_distances.size());
+24 -2
View File
@@ -13,13 +13,19 @@ namespace engine
namespace guidance
{
// Multiple possible reasons can result in unnecessary/confusing instructions
// Collapsing such turns into a single turn instruction, we give a clearer
// set of instructions that is not cluttered by unnecessary turns/name changes.
OSRM_ATTR_WARN_UNUSED
std::vector<RouteStep> collapseTurnInstructions(std::vector<RouteStep> steps);
// Multiple possible reasons can result in unnecessary/confusing instructions
// A prime example would be a segregated intersection. Turning around at this
// intersection would result in two instructions to turn left.
// Collapsing such turns into a single turn instruction, we give a clearer
// set of instructionst that is not cluttered by unnecessary turns/name changes.
// set of instructions that is not cluttered by unnecessary turns/name changes.
OSRM_ATTR_WARN_UNUSED
std::vector<RouteStep> collapseTurnInstructions(std::vector<RouteStep> steps);
std::vector<RouteStep> collapseSegregatedTurnInstructions(std::vector<RouteStep> steps);
// A combined turn is a set of two instructions that actually form a single turn, as far as we
// perceive it. A u-turn consisting of two left turns is one such example. But there are also lots
@@ -93,6 +99,22 @@ struct StaggeredTurnStrategy : CombineStrategy
const RouteStep &step_prior_to_intersection;
};
// Handling of consecutive segregated steps
struct CombineSegregatedStepsStrategy : CombineStrategy
{
void operator()(RouteStep &step_at_turn_location, const RouteStep &transfer_from_step) const;
};
// Handling of segregated intersections
struct SegregatedTurnStrategy : CombineStrategy
{
SegregatedTurnStrategy(const RouteStep &step_prior_to_intersection);
void operator()(RouteStep &step_at_turn_location, const RouteStep &transfer_from_step) const;
const RouteStep &step_prior_to_intersection;
};
// Signage Strategies
// Transfer the signage from the next step onto this step
@@ -23,6 +23,7 @@ const constexpr std::size_t MIN_END_OF_ROAD_INTERSECTIONS = std::size_t{2};
const constexpr double MAX_COLLAPSE_DISTANCE = 30.0;
// a bit larger than 100 to avoid oscillation in tests
const constexpr double NAME_SEGMENT_CUTOFF_LENGTH = 105.0;
const double constexpr STRAIGHT_ANGLE = 180.;
// check if a step is completely without turn type
inline bool hasTurnType(const RouteStep &step)
@@ -104,6 +105,12 @@ inline void setInstructionType(RouteStep &step, const osrm::guidance::TurnType::
step.maneuver.instruction.type = type;
}
// alias for readability
inline void setModifier(RouteStep &step, const osrm::guidance::DirectionModifier::Enum modifier)
{
step.maneuver.instruction.direction_modifier = modifier;
}
// alias for readability
inline bool haveSameMode(const RouteStep &lhs, const RouteStep &rhs)
{
@@ -215,6 +222,86 @@ inline double totalTurnAngle(const RouteStep &entry_step, const RouteStep &exit_
return total_angle;
}
// check bearings for u-turns.
// since bearings are wrapped around at 0 (we only support 0,360), we need to do some minor math to
// check if bearings `a` and `b` go in opposite directions. In general we accept some minor
// deviations for u-turns.
inline bool bearingsAreReversed(const double bearing_in, const double bearing_out)
{
// Nearly perfectly reversed angles have a difference close to 180 degrees (straight)
const double left_turn_angle = [&]() {
if (0 <= bearing_out && bearing_out <= bearing_in)
return bearing_in - bearing_out;
return bearing_in + 360 - bearing_out;
}();
return util::angularDeviation(left_turn_angle, 180) <= 35;
}
// Returns true if the specified step has only one intersection
inline bool hasSingleIntersection(const RouteStep &step)
{
return (step.intersections.size() == 1);
}
// Returns true if the specified angle is a wider straight turn
inline bool isWiderStraight(const double angle) { return (angle >= 125 && angle <= 235); }
// Returns the straightest intersecting edge turn for the specified step
inline double getStraightestIntersectingEdgeTurn(const RouteStep &step)
{
const auto &intersection = step.intersections.front();
const double bearing_in = util::bearing::reverse(intersection.bearings[intersection.in]);
double staightest_turn = 360.;
double staightest_delta = 360.;
for (std::size_t i = 0; i < intersection.bearings.size(); ++i)
{
// Skip the in, out, and non-traversable edges
if ((i == intersection.in) || (i == intersection.out) || !intersection.entry.at(i))
continue;
double intersecting_turn =
util::bearing::angleBetween(bearing_in, intersection.bearings.at(i));
double straight_delta = util::angularDeviation(intersecting_turn, STRAIGHT_ANGLE);
if (straight_delta < staightest_delta)
{
staightest_delta = straight_delta;
staightest_turn = intersecting_turn;
}
}
return staightest_turn;
}
// Returns true if the specified step has the straightest turn as compared to
// the intersecting edges
inline bool hasStraightestTurn(const RouteStep &step)
{
const auto &intersection = step.intersections.front();
const double path_turn =
util::bearing::angleBetween(util::bearing::reverse(intersection.bearings[intersection.in]),
intersection.bearings[intersection.out]);
// Path turn must be a wider straight
if (isWiderStraight(path_turn))
{
const double straightest_intersecting_turn = getStraightestIntersectingEdgeTurn(step);
const double path_straight_delta = util::angularDeviation(path_turn, STRAIGHT_ANGLE);
const double intersecting_straight_delta =
util::angularDeviation(straightest_intersecting_turn, STRAIGHT_ANGLE);
const double path_intersecting_delta =
util::angularDeviation(path_turn, straightest_intersecting_turn);
// Add some fuzz - the delta between the path and intersecting turn must be greater
// than 10 in order to consider using the intersecting turn as the straightest
return ((path_intersecting_delta > 10.)
? (path_straight_delta <= intersecting_straight_delta)
: true);
}
return false;
}
} /* namespace guidance */
} /* namespace engine */
} /* namespace osrm */
+24 -8
View File
@@ -139,22 +139,38 @@ inline InternalRouteResult CollapseInternalRouteResult(const InternalRouteResult
{
BOOST_ASSERT(!collapsed.unpacked_path_segments.empty());
auto &last_segment = collapsed.unpacked_path_segments.back();
// deduplicate last segment (needs to be checked for empty for the same node query edge
// case)
if (!last_segment.empty())
last_segment.pop_back();
// update target phantom node of leg
BOOST_ASSERT(!collapsed.segment_end_coordinates.empty());
collapsed.segment_end_coordinates.back().target_phantom =
leggy_result.segment_end_coordinates[i].target_phantom;
collapsed.target_traversed_in_reverse.back() =
leggy_result.target_traversed_in_reverse[i];
// copy path segments into current leg
last_segment.insert(last_segment.end(),
leggy_result.unpacked_path_segments[i].begin(),
leggy_result.unpacked_path_segments[i].end());
if (!leggy_result.unpacked_path_segments[i].empty())
{
auto old_size = last_segment.size();
last_segment.insert(last_segment.end(),
leggy_result.unpacked_path_segments[i].begin(),
leggy_result.unpacked_path_segments[i].end());
// The first segment of the unpacked path is missing the weight of the
// source phantom. We need to add those values back so that the total
// edge weight is correct
last_segment[old_size].weight_until_turn +=
leggy_result.source_traversed_in_reverse[i]
? leggy_result.segment_end_coordinates[i].source_phantom.reverse_weight
: leggy_result.segment_end_coordinates[i].source_phantom.forward_weight;
last_segment[old_size].duration_until_turn +=
leggy_result.source_traversed_in_reverse[i]
? leggy_result.segment_end_coordinates[i].source_phantom.reverse_duration
: leggy_result.segment_end_coordinates[i].source_phantom.forward_duration;
}
}
}
BOOST_ASSERT(collapsed.segment_end_coordinates.size() ==
collapsed.unpacked_path_segments.size());
return collapsed;
}
}
@@ -136,24 +136,29 @@ void annotatePath(const FacadeT &facade,
// datastructures to hold extracted data from geometry
std::vector<NodeID> id_vector;
std::vector<EdgeWeight> weight_vector;
std::vector<EdgeWeight> duration_vector;
std::vector<SegmentWeight> weight_vector;
std::vector<SegmentDuration> duration_vector;
std::vector<DatasourceID> datasource_vector;
const auto get_segment_geometry = [&](const auto geometry_index) {
const auto copy = [](auto &vector, const auto range) {
vector.resize(range.size());
std::copy(range.begin(), range.end(), vector.begin());
};
if (geometry_index.forward)
{
id_vector = facade.GetUncompressedForwardGeometry(geometry_index.id);
weight_vector = facade.GetUncompressedForwardWeights(geometry_index.id);
duration_vector = facade.GetUncompressedForwardDurations(geometry_index.id);
datasource_vector = facade.GetUncompressedForwardDatasources(geometry_index.id);
copy(id_vector, facade.GetUncompressedForwardGeometry(geometry_index.id));
copy(weight_vector, facade.GetUncompressedForwardWeights(geometry_index.id));
copy(duration_vector, facade.GetUncompressedForwardDurations(geometry_index.id));
copy(datasource_vector, facade.GetUncompressedForwardDatasources(geometry_index.id));
}
else
{
id_vector = facade.GetUncompressedReverseGeometry(geometry_index.id);
weight_vector = facade.GetUncompressedReverseWeights(geometry_index.id);
duration_vector = facade.GetUncompressedReverseDurations(geometry_index.id);
datasource_vector = facade.GetUncompressedReverseDatasources(geometry_index.id);
copy(id_vector, facade.GetUncompressedReverseGeometry(geometry_index.id));
copy(weight_vector, facade.GetUncompressedReverseWeights(geometry_index.id));
copy(duration_vector, facade.GetUncompressedReverseDurations(geometry_index.id));
copy(datasource_vector, facade.GetUncompressedReverseDatasources(geometry_index.id));
}
};
@@ -174,8 +179,8 @@ void annotatePath(const FacadeT &facade,
BOOST_ASSERT(id_vector.size() > 0);
BOOST_ASSERT(datasource_vector.size() > 0);
BOOST_ASSERT(weight_vector.size() == id_vector.size() - 1);
BOOST_ASSERT(duration_vector.size() == id_vector.size() - 1);
BOOST_ASSERT(weight_vector.size() + 1 == id_vector.size());
BOOST_ASSERT(duration_vector.size() + 1 == id_vector.size());
const bool is_first_segment = unpacked_path.empty();
const std::size_t start_index =
@@ -192,23 +197,24 @@ void annotatePath(const FacadeT &facade,
BOOST_ASSERT(start_index < end_index);
for (std::size_t segment_idx = start_index; segment_idx < end_index; ++segment_idx)
{
unpacked_path.push_back(PathData{*node_from,
id_vector[segment_idx + 1],
name_index,
is_segregated,
weight_vector[segment_idx],
0,
duration_vector[segment_idx],
0,
guidance::TurnInstruction::NO_TURN(),
{{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID},
travel_mode,
classes,
EMPTY_ENTRY_CLASS,
datasource_vector[segment_idx],
osrm::guidance::TurnBearing(0),
osrm::guidance::TurnBearing(0),
is_left_hand_driving});
unpacked_path.push_back(
PathData{*node_from,
id_vector[segment_idx + 1],
name_index,
is_segregated,
static_cast<EdgeWeight>(weight_vector[segment_idx]),
0,
static_cast<EdgeDuration>(duration_vector[segment_idx]),
0,
guidance::TurnInstruction::NO_TURN(),
{{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID},
travel_mode,
classes,
EMPTY_ENTRY_CLASS,
datasource_vector[segment_idx],
osrm::guidance::TurnBearing(0),
osrm::guidance::TurnBearing(0),
is_left_hand_driving});
}
BOOST_ASSERT(unpacked_path.size() > 0);
if (facade.HasLaneData(turn_id))
@@ -264,16 +270,16 @@ void annotatePath(const FacadeT &facade,
for (std::size_t segment_idx = start_index; segment_idx != end_index;
(start_index < end_index ? ++segment_idx : --segment_idx))
{
BOOST_ASSERT(segment_idx < id_vector.size() - 1);
BOOST_ASSERT(segment_idx < static_cast<std::size_t>(id_vector.size() - 1));
BOOST_ASSERT(facade.GetTravelMode(target_node_id) > 0);
unpacked_path.push_back(
PathData{target_node_id,
id_vector[start_index < end_index ? segment_idx + 1 : segment_idx - 1],
facade.GetNameIndex(target_node_id),
facade.IsSegregated(target_node_id),
weight_vector[segment_idx],
static_cast<EdgeWeight>(weight_vector[segment_idx]),
0,
duration_vector[segment_idx],
static_cast<EdgeDuration>(duration_vector[segment_idx]),
0,
guidance::TurnInstruction::NO_TURN(),
{{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID},
@@ -207,6 +207,25 @@ void unpackLegs(const DataFacade<Algorithm> &facade,
phantom_nodes_vector[current_leg].target_phantom.forward_segment_id.id));
}
}
template <typename Algorithm>
inline void initializeHeap(SearchEngineData<Algorithm> &engine_working_data,
const DataFacade<Algorithm> &facade)
{
const auto nodes_number = facade.GetNumberOfNodes();
engine_working_data.InitializeOrClearFirstThreadLocalStorage(nodes_number);
}
template <>
inline void initializeHeap<mld::Algorithm>(SearchEngineData<mld::Algorithm> &engine_working_data,
const DataFacade<mld::Algorithm> &facade)
{
const auto nodes_number = facade.GetNumberOfNodes();
const auto border_nodes_number = facade.GetMaxBorderNodeID() + 1;
engine_working_data.InitializeOrClearFirstThreadLocalStorage(nodes_number, border_nodes_number);
}
}
template <typename Algorithm>
@@ -221,7 +240,7 @@ InternalRouteResult shortestPathSearch(SearchEngineData<Algorithm> &engine_worki
!(continue_straight_at_waypoint ? *continue_straight_at_waypoint
: facade.GetContinueStraightDefault());
engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade.GetNumberOfNodes());
initializeHeap(engine_working_data, facade);
auto &forward_heap = *engine_working_data.forward_heap_1;
auto &reverse_heap = *engine_working_data.reverse_heap_1;
+6 -4
View File
@@ -91,13 +91,13 @@ template <> struct SearchEngineData<routing_algorithms::mld::Algorithm>
NodeID,
EdgeWeight,
MultiLayerDijkstraHeapData,
util::UnorderedMapStorage<NodeID, int>>;
util::TwoLevelStorage<NodeID, int>>;
using ManyToManyQueryHeap = util::QueryHeap<NodeID,
NodeID,
EdgeWeight,
ManyToManyMultiLayerDijkstraHeapData,
util::UnorderedMapStorage<NodeID, int>>;
util::TwoLevelStorage<NodeID, int>>;
using SearchEngineHeapPtr = boost::thread_specific_ptr<QueryHeap>;
using ManyToManyHeapPtr = boost::thread_specific_ptr<ManyToManyQueryHeap>;
@@ -106,9 +106,11 @@ template <> struct SearchEngineData<routing_algorithms::mld::Algorithm>
static SearchEngineHeapPtr reverse_heap_1;
static ManyToManyHeapPtr many_to_many_heap;
void InitializeOrClearFirstThreadLocalStorage(unsigned number_of_nodes);
void InitializeOrClearFirstThreadLocalStorage(unsigned number_of_nodes,
unsigned number_of_boundary_nodes);
void InitializeOrClearManyToManyThreadLocalStorage(unsigned number_of_nodes);
void InitializeOrClearManyToManyThreadLocalStorage(unsigned number_of_nodes,
unsigned number_of_boundary_nodes);
};
}
}
@@ -0,0 +1,20 @@
#ifndef OSRM_EXTRACTOR_COMPRESSED_NODE_BASED_GRAPH_EDGE_HPP
#define OSRM_EXTRACTOR_COMPRESSED_NODE_BASED_GRAPH_EDGE_HPP
#include "util/typedefs.hpp"
namespace osrm
{
namespace extractor
{
// We encode the cnbg graph only using its topology as edge list
struct CompressedNodeBasedGraphEdge
{
NodeID source;
NodeID target;
};
}
}
#endif // OSRM_EXTRACTOR_COMPRESSED_NODE_BASED_GRAPH_EDGE_HPP
+3 -18
View File
@@ -9,20 +9,16 @@
#include "extractor/edge_based_node_segment.hpp"
#include "extractor/extraction_turn.hpp"
#include "extractor/maneuver_override.hpp"
#include "extractor/name_table.hpp"
#include "extractor/nbg_to_ebg.hpp"
#include "extractor/node_data_container.hpp"
#include "extractor/query_node.hpp"
#include "extractor/restriction_index.hpp"
#include "extractor/turn_lane_types.hpp"
#include "extractor/way_restriction_map.hpp"
#include "guidance/turn_analysis.hpp"
#include "guidance/turn_instruction.hpp"
#include "util/concurrent_id_map.hpp"
#include "util/deallocating_vector.hpp"
#include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp"
#include "util/name_table.hpp"
#include "util/node_based_graph.hpp"
#include "util/typedefs.hpp"
@@ -74,7 +70,7 @@ class EdgeBasedGraphFactory
const std::unordered_set<NodeID> &barrier_nodes,
const std::unordered_set<NodeID> &traffic_lights,
const std::vector<util::Coordinate> &coordinates,
const util::NameTable &name_table,
const NameTable &name_table,
const std::unordered_set<EdgeID> &segregated_edges,
const LaneDescriptionMap &lane_description_map);
@@ -99,17 +95,6 @@ class EdgeBasedGraphFactory
std::uint64_t GetNumberOfEdgeBasedNodes() const;
// Basic analysis of a turn (u --(e1)-- v --(e2)-- w)
// with known angle.
// Handles special cases like u-turns and roundabouts
// For basic turns, the turn based on the angle-classification is returned
guidance::TurnInstruction AnalyzeTurn(const NodeID u,
const EdgeID e1,
const NodeID v,
const EdgeID e2,
const NodeID w,
const double angle) const;
private:
using EdgeData = util::NodeBasedDynamicGraph::EdgeData;
@@ -153,7 +138,7 @@ class EdgeBasedGraphFactory
const std::unordered_set<NodeID> &m_traffic_lights;
const CompressedEdgeContainer &m_compressed_edge_container;
const util::NameTable &name_table;
const NameTable &name_table;
const std::unordered_set<EdgeID> &segregated_edges;
const LaneDescriptionMap &lane_description_map;
+4 -4
View File
@@ -7,7 +7,7 @@
#include "extractor/restriction.hpp"
#include "extractor/scripting_environment.hpp"
#include "storage/io.hpp"
#include "storage/tar_fwd.hpp"
namespace osrm
{
@@ -27,9 +27,9 @@ class ExtractionContainers
void PrepareRestrictions();
void PrepareEdges(ScriptingEnvironment &scripting_environment);
void WriteNodes(storage::io::FileWriter &file_out) const;
void WriteEdges(storage::io::FileWriter &file_out) const;
void WriteMetadata(storage::io::FileWriter &file_out) const;
void WriteNodes(storage::tar::FileWriter &file_out) const;
void WriteEdges(storage::tar::FileWriter &file_out) const;
void WriteMetadata(storage::tar::FileWriter &file_out) const;
void WriteCharData(const std::string &file_name);
public:
+2 -7
View File
@@ -77,7 +77,7 @@ class Extractor
const std::vector<TurnRestriction> &turn_restrictions,
const std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions,
const std::unordered_set<EdgeID> &segregated_edges,
const util::NameTable &name_table,
const NameTable &name_table,
const std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
const LaneDescriptionMap &turn_lane_map,
// for calculating turn penalties
@@ -99,11 +99,6 @@ class Extractor
const std::vector<util::Coordinate> &coordinates);
std::shared_ptr<RestrictionMap> LoadRestrictionMap();
// 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,
const std::vector<util::Coordinate> &coordiantes);
void WriteConditionalRestrictions(
const std::string &path,
std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions);
@@ -116,7 +111,7 @@ class Extractor
const std::unordered_set<NodeID> &barrier_nodes,
const std::vector<TurnRestriction> &turn_restrictions,
const std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions,
const util::NameTable &name_table,
const NameTable &name_table,
LaneDescriptionMap lane_description_map,
ScriptingEnvironment &scripting_environment);
};
-1
View File
@@ -52,7 +52,6 @@ struct ExtractorConfig final : storage::IOConfig
".osrm.names",
".osrm.tls",
".osrm.tld",
".osrm.timestamp",
".osrm.geometry",
".osrm.nbg_nodes",
".osrm.ebg_nodes",
+307 -62
View File
@@ -4,12 +4,14 @@
#include "extractor/edge_based_edge.hpp"
#include "extractor/node_data_container.hpp"
#include "extractor/profile_properties.hpp"
#include "extractor/query_node.hpp"
#include "extractor/serialization.hpp"
#include "extractor/turn_lane_types.hpp"
#include "util/coordinate.hpp"
#include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp"
#include "util/guidance/turn_lanes.hpp"
#include "util/packed_vector.hpp"
#include "util/range_table.hpp"
#include "util/serialization.hpp"
@@ -33,10 +35,10 @@ inline void writeIntersections(const boost::filesystem::path &path,
std::is_same<IntersectionBearingsView, IntersectionBearingsT>::value,
"");
storage::io::FileWriter writer(path, storage::io::FileWriter::GenerateFingerprint);
storage::tar::FileWriter writer(path, storage::tar::FileWriter::GenerateFingerprint);
serialization::write(writer, intersection_bearings);
storage::serialization::write(writer, entry_classes);
serialization::write(writer, "/common/intersection_bearings", intersection_bearings);
storage::serialization::write(writer, "/common/entry_classes", entry_classes);
}
// read the .osrm.icd file
@@ -49,30 +51,30 @@ inline void readIntersections(const boost::filesystem::path &path,
std::is_same<IntersectionBearingsView, IntersectionBearingsT>::value,
"");
storage::io::FileReader reader(path, storage::io::FileReader::VerifyFingerprint);
storage::tar::FileReader reader(path, storage::tar::FileReader::VerifyFingerprint);
serialization::read(reader, intersection_bearings);
storage::serialization::read(reader, entry_classes);
serialization::read(reader, "/common/intersection_bearings", intersection_bearings);
storage::serialization::read(reader, "/common/entry_classes", entry_classes);
}
// reads .osrm.properties
inline void readProfileProperties(const boost::filesystem::path &path,
ProfileProperties &properties)
{
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
storage::io::FileReader reader{path, fingerprint};
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
storage::tar::FileReader reader{path, fingerprint};
serialization::read(reader, properties);
serialization::read(reader, "/common/properties", properties);
}
// writes .osrm.properties
inline void writeProfileProperties(const boost::filesystem::path &path,
const ProfileProperties &properties)
{
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint;
storage::io::FileWriter writer{path, fingerprint};
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
storage::tar::FileWriter writer{path, fingerprint};
serialization::write(writer, properties);
serialization::write(writer, "/common/properties", properties);
}
template <typename EdgeBasedEdgeVector>
@@ -83,13 +85,16 @@ void writeEdgeBasedGraph(const boost::filesystem::path &path,
{
static_assert(std::is_same<typename EdgeBasedEdgeVector::value_type, EdgeBasedEdge>::value, "");
storage::io::FileWriter writer(path, storage::io::FileWriter::GenerateFingerprint);
storage::tar::FileWriter writer(path, storage::tar::FileWriter::GenerateFingerprint);
writer.WriteElementCount64(number_of_edge_based_nodes);
storage::serialization::write(writer, edge_based_edge_list);
writer.WriteOne(connectivity_checksum);
writer.WriteElementCount64("/common/number_of_edge_based_nodes", 1);
writer.WriteFrom("/common/number_of_edge_based_nodes", number_of_edge_based_nodes);
storage::serialization::write(writer, "/common/edge_based_edge_list", edge_based_edge_list);
writer.WriteElementCount64("/common/connectivity_checksum", 1);
writer.WriteFrom("/common/connectivity_checksum", connectivity_checksum);
}
// reads .osrm.ebg file
template <typename EdgeBasedEdgeVector>
void readEdgeBasedGraph(const boost::filesystem::path &path,
EdgeID &number_of_edge_based_nodes,
@@ -98,14 +103,14 @@ void readEdgeBasedGraph(const boost::filesystem::path &path,
{
static_assert(std::is_same<typename EdgeBasedEdgeVector::value_type, EdgeBasedEdge>::value, "");
storage::io::FileReader reader(path, storage::io::FileReader::VerifyFingerprint);
storage::tar::FileReader reader(path, storage::tar::FileReader::VerifyFingerprint);
number_of_edge_based_nodes = reader.ReadElementCount64();
storage::serialization::read(reader, edge_based_edge_list);
reader.ReadInto(connectivity_checksum);
reader.ReadInto("/common/number_of_edge_based_nodes", number_of_edge_based_nodes);
storage::serialization::read(reader, "/common/edge_based_edge_list", edge_based_edge_list);
reader.ReadInto("/common/connectivity_checksum", connectivity_checksum);
}
// reads .osrm.nodes
// reads .osrm.nbg_nodes
template <typename CoordinatesT, typename PackedOSMIDsT>
inline void readNodes(const boost::filesystem::path &path,
CoordinatesT &coordinates,
@@ -114,14 +119,26 @@ inline void readNodes(const boost::filesystem::path &path,
static_assert(std::is_same<typename CoordinatesT::value_type, util::Coordinate>::value, "");
static_assert(std::is_same<typename PackedOSMIDsT::value_type, OSMNodeID>::value, "");
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
storage::io::FileReader reader{path, fingerprint};
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
storage::tar::FileReader reader{path, fingerprint};
storage::serialization::read(reader, coordinates);
util::serialization::read(reader, osm_node_ids);
storage::serialization::read(reader, "/common/nbn_data/coordinates", coordinates);
util::serialization::read(reader, "/common/nbn_data/osm_node_ids", osm_node_ids);
}
// writes .osrm.nodes
// reads only coordinates from .osrm.nbg_nodes
template <typename CoordinatesT>
inline void readNodeCoordinates(const boost::filesystem::path &path, CoordinatesT &coordinates)
{
static_assert(std::is_same<typename CoordinatesT::value_type, util::Coordinate>::value, "");
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
storage::tar::FileReader reader{path, fingerprint};
storage::serialization::read(reader, "/common/nbn_data/coordinates", coordinates);
}
// writes .osrm.nbg_nodes
template <typename CoordinatesT, typename PackedOSMIDsT>
inline void writeNodes(const boost::filesystem::path &path,
const CoordinatesT &coordinates,
@@ -130,48 +147,48 @@ inline void writeNodes(const boost::filesystem::path &path,
static_assert(std::is_same<typename CoordinatesT::value_type, util::Coordinate>::value, "");
static_assert(std::is_same<typename PackedOSMIDsT::value_type, OSMNodeID>::value, "");
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint;
storage::io::FileWriter writer{path, fingerprint};
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
storage::tar::FileWriter writer{path, fingerprint};
storage::serialization::write(writer, coordinates);
util::serialization::write(writer, osm_node_ids);
storage::serialization::write(writer, "/common/nbn_data/coordinates", coordinates);
util::serialization::write(writer, "/common/nbn_data/osm_node_ids", osm_node_ids);
}
// reads .osrm.cnbg_to_ebg
inline void readNBGMapping(const boost::filesystem::path &path, std::vector<NBGToEBG> &mapping)
{
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
storage::io::FileReader reader{path, fingerprint};
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
storage::tar::FileReader reader{path, fingerprint};
storage::serialization::read(reader, mapping);
storage::serialization::read(reader, "/common/cnbg_to_ebg", mapping);
}
// writes .osrm.cnbg_to_ebg
inline void writeNBGMapping(const boost::filesystem::path &path,
const std::vector<NBGToEBG> &mapping)
{
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint;
storage::io::FileWriter writer{path, fingerprint};
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
storage::tar::FileWriter writer{path, fingerprint};
storage::serialization::write(writer, mapping);
storage::serialization::write(writer, "/common/cnbg_to_ebg", mapping);
}
// reads .osrm.datasource_names
inline void readDatasources(const boost::filesystem::path &path, Datasources &sources)
{
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
storage::io::FileReader reader{path, fingerprint};
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
storage::tar::FileReader reader{path, fingerprint};
serialization::read(reader, sources);
serialization::read(reader, "/common/data_sources_names", sources);
}
// writes .osrm.datasource_names
inline void writeDatasources(const boost::filesystem::path &path, Datasources &sources)
{
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint;
storage::io::FileWriter writer{path, fingerprint};
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
storage::tar::FileWriter writer{path, fingerprint};
serialization::write(writer, sources);
serialization::write(writer, "/common/data_sources_names", sources);
}
// reads .osrm.geometry
@@ -181,10 +198,10 @@ inline void readSegmentData(const boost::filesystem::path &path, SegmentDataT &s
static_assert(std::is_same<SegmentDataContainer, SegmentDataT>::value ||
std::is_same<SegmentDataView, SegmentDataT>::value,
"");
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
storage::io::FileReader reader{path, fingerprint};
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
storage::tar::FileReader reader{path, fingerprint};
serialization::read(reader, segment_data);
serialization::read(reader, "/common/segment_data", segment_data);
}
// writes .osrm.geometry
@@ -194,10 +211,10 @@ inline void writeSegmentData(const boost::filesystem::path &path, const SegmentD
static_assert(std::is_same<SegmentDataContainer, SegmentDataT>::value ||
std::is_same<SegmentDataView, SegmentDataT>::value,
"");
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint;
storage::io::FileWriter writer{path, fingerprint};
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
storage::tar::FileWriter writer{path, fingerprint};
serialization::write(writer, segment_data);
serialization::write(writer, "/common/segment_data", segment_data);
}
// reads .osrm.ebg_nodes
@@ -208,10 +225,10 @@ inline void readNodeData(const boost::filesystem::path &path, NodeDataT &node_da
std::is_same<EdgeBasedNodeDataView, NodeDataT>::value ||
std::is_same<EdgeBasedNodeDataExternalContainer, NodeDataT>::value,
"");
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
storage::io::FileReader reader{path, fingerprint};
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
storage::tar::FileReader reader{path, fingerprint};
serialization::read(reader, node_data);
serialization::read(reader, "/common/ebg_node_data", node_data);
}
// writes .osrm.ebg_nodes
@@ -222,10 +239,10 @@ inline void writeNodeData(const boost::filesystem::path &path, const NodeDataT &
std::is_same<EdgeBasedNodeDataView, NodeDataT>::value ||
std::is_same<EdgeBasedNodeDataExternalContainer, NodeDataT>::value,
"");
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint;
storage::io::FileWriter writer{path, fingerprint};
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
storage::tar::FileWriter writer{path, fingerprint};
serialization::write(writer, node_data);
serialization::write(writer, "/common/ebg_node_data", node_data);
}
// reads .osrm.tls
@@ -238,11 +255,11 @@ inline void readTurnLaneDescriptions(const boost::filesystem::path &path,
"");
static_assert(std::is_same<typename OffsetsT::value_type, std::uint32_t>::value, "");
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
storage::io::FileReader reader{path, fingerprint};
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
storage::tar::FileReader reader{path, fingerprint};
storage::serialization::read(reader, turn_offsets);
storage::serialization::read(reader, turn_masks);
storage::serialization::read(reader, "/common/turn_lanes/offsets", turn_offsets);
storage::serialization::read(reader, "/common/turn_lanes/masks", turn_masks);
}
// writes .osrm.tls
@@ -255,11 +272,239 @@ inline void writeTurnLaneDescriptions(const boost::filesystem::path &path,
"");
static_assert(std::is_same<typename OffsetsT::value_type, std::uint32_t>::value, "");
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint;
storage::io::FileWriter writer{path, fingerprint};
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
storage::tar::FileWriter writer{path, fingerprint};
storage::serialization::write(writer, turn_offsets);
storage::serialization::write(writer, turn_masks);
storage::serialization::write(writer, "/common/turn_lanes/offsets", turn_offsets);
storage::serialization::write(writer, "/common/turn_lanes/masks", turn_masks);
}
// reads .osrm.tld
template <typename TurnLaneDataT>
inline void readTurnLaneData(const boost::filesystem::path &path, TurnLaneDataT &turn_lane_data)
{
static_assert(
std::is_same<typename TurnLaneDataT::value_type, util::guidance::LaneTupleIdPair>::value,
"");
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
storage::tar::FileReader reader{path, fingerprint};
storage::serialization::read(reader, "/common/turn_lanes/data", turn_lane_data);
}
// writes .osrm.tld
template <typename TurnLaneDataT>
inline void writeTurnLaneData(const boost::filesystem::path &path,
const TurnLaneDataT &turn_lane_data)
{
static_assert(
std::is_same<typename TurnLaneDataT::value_type, util::guidance::LaneTupleIdPair>::value,
"");
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
storage::tar::FileWriter writer{path, fingerprint};
storage::serialization::write(writer, "/common/turn_lanes/data", turn_lane_data);
}
// reads .osrm.maneuver_overrides
template <typename StorageManeuverOverrideT, typename NodeSequencesT>
inline void readManeuverOverrides(const boost::filesystem::path &path,
StorageManeuverOverrideT &maneuver_overrides,
NodeSequencesT &node_sequences)
{
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
storage::tar::FileReader reader{path, fingerprint};
storage::serialization::read(
reader, "/common/maneuver_overrides/overrides", maneuver_overrides);
storage::serialization::read(
reader, "/common/maneuver_overrides/node_sequences", node_sequences);
}
// writes .osrm.maneuver_overrides
inline void writeManeuverOverrides(const boost::filesystem::path &path,
const std::vector<StorageManeuverOverride> &maneuver_overrides,
const std::vector<NodeID> &node_sequences)
{
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
storage::tar::FileWriter writer{path, fingerprint};
storage::serialization::write(
writer, "/common/maneuver_overrides/overrides", maneuver_overrides);
storage::serialization::write(
writer, "/common/maneuver_overrides/node_sequences", node_sequences);
}
// writes .osrm.turn_weight_penalties
template <typename TurnPenaltyT>
inline void writeTurnWeightPenalty(const boost::filesystem::path &path,
const TurnPenaltyT &turn_penalty)
{
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
storage::tar::FileWriter writer{path, fingerprint};
storage::serialization::write(writer, "/common/turn_penalty/weight", turn_penalty);
}
// read .osrm.turn_weight_penalties
template <typename TurnPenaltyT>
inline void readTurnWeightPenalty(const boost::filesystem::path &path, TurnPenaltyT &turn_penalty)
{
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
storage::tar::FileReader reader{path, fingerprint};
storage::serialization::read(reader, "/common/turn_penalty/weight", turn_penalty);
}
// writes .osrm.turn_duration_penalties
template <typename TurnPenaltyT>
inline void writeTurnDurationPenalty(const boost::filesystem::path &path,
const TurnPenaltyT &turn_penalty)
{
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
storage::tar::FileWriter writer{path, fingerprint};
storage::serialization::write(writer, "/common/turn_penalty/duration", turn_penalty);
}
// read .osrm.turn_weight_penalties
template <typename TurnPenaltyT>
inline void readTurnDurationPenalty(const boost::filesystem::path &path, TurnPenaltyT &turn_penalty)
{
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
storage::tar::FileReader reader{path, fingerprint};
storage::serialization::read(reader, "/common/turn_penalty/duration", turn_penalty);
}
// writes .osrm.restrictions
template <typename ConditionalRestrictionsT>
inline void writeConditionalRestrictions(const boost::filesystem::path &path,
const ConditionalRestrictionsT &conditional_restrictions)
{
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
storage::tar::FileWriter writer{path, fingerprint};
serialization::write(writer, "/common/conditional_restrictions", conditional_restrictions);
}
// read .osrm.restrictions
template <typename ConditionalRestrictionsT>
inline void readConditionalRestrictions(const boost::filesystem::path &path,
ConditionalRestrictionsT &conditional_restrictions)
{
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
storage::tar::FileReader reader{path, fingerprint};
serialization::read(reader, "/common/conditional_restrictions", conditional_restrictions);
}
// reads .osrm file which is a temporary file of osrm-extract
template <typename BarrierOutIter, typename TrafficSignalsOutIter, typename PackedOSMIDsT>
void readRawNBGraph(const boost::filesystem::path &path,
BarrierOutIter barriers,
TrafficSignalsOutIter traffic_signals,
std::vector<util::Coordinate> &coordinates,
PackedOSMIDsT &osm_node_ids,
std::vector<extractor::NodeBasedEdge> &edge_list,
std::vector<extractor::NodeBasedEdgeAnnotation> &annotations)
{
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
storage::tar::FileReader reader{path, fingerprint};
auto number_of_nodes = reader.ReadElementCount64("/extractor/nodes");
coordinates.resize(number_of_nodes);
osm_node_ids.reserve(number_of_nodes);
auto index = 0;
auto decode = [&](const auto &current_node) {
coordinates[index].lon = current_node.lon;
coordinates[index].lat = current_node.lat;
osm_node_ids.push_back(current_node.node_id);
index++;
};
reader.ReadStreaming<extractor::QueryNode>("/extractor/nodes",
boost::make_function_output_iterator(decode));
reader.ReadStreaming<NodeID>("/extractor/barriers", barriers);
reader.ReadStreaming<NodeID>("/extractor/traffic_lights", traffic_signals);
storage::serialization::read(reader, "/extractor/edges", edge_list);
storage::serialization::read(reader, "/extractor/annotations", annotations);
}
template <typename NameTableT>
void readNames(const boost::filesystem::path &path, NameTableT &table)
{
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
storage::tar::FileReader reader{path, fingerprint};
serialization::read(reader, "/common/names", table);
}
template <typename NameTableT>
void writeNames(const boost::filesystem::path &path, const NameTableT &table)
{
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
storage::tar::FileWriter writer{path, fingerprint};
serialization::write(writer, "/common/names", table);
}
template <typename NodeWeigtsVectorT>
void readEdgeBasedNodeWeights(const boost::filesystem::path &path, NodeWeigtsVectorT &weights)
{
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
storage::tar::FileReader reader{path, fingerprint};
storage::serialization::read(reader, "/extractor/edge_based_node_weights", weights);
}
template <typename NodeWeigtsVectorT>
void writeEdgeBasedNodeWeights(const boost::filesystem::path &path,
const NodeWeigtsVectorT &weights)
{
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
storage::tar::FileWriter writer{path, fingerprint};
storage::serialization::write(writer, "/extractor/edge_based_node_weights", weights);
}
template <typename RTreeT>
void writeRamIndex(const boost::filesystem::path &path, const RTreeT &rtree)
{
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
storage::tar::FileWriter writer{path, fingerprint};
util::serialization::write(writer, "/common/rtree", rtree);
}
template <typename RTreeT> void readRamIndex(const boost::filesystem::path &path, RTreeT &rtree)
{
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
storage::tar::FileReader reader{path, fingerprint};
util::serialization::read(reader, "/common/rtree", rtree);
}
template <typename EdgeListT>
void writeCompressedNodeBasedGraph(const boost::filesystem::path &path, const EdgeListT &edge_list)
{
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
storage::tar::FileWriter writer{path, fingerprint};
storage::serialization::write(writer, "/extractor/cnbg", edge_list);
}
template <typename EdgeListT>
void readCompressedNodeBasedGraph(const boost::filesystem::path &path, EdgeListT &edge_list)
{
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
storage::tar::FileReader reader{path, fingerprint};
storage::serialization::read(reader, "/extractor/cnbg", edge_list);
}
}
}
@@ -1,9 +1,9 @@
#ifndef OSRM_EXTRACTOR_INTERSECTION_HAVE_IDENTICAL_NAMES_HPP_
#define OSRM_EXTRACTOR_INTERSECTION_HAVE_IDENTICAL_NAMES_HPP_
#include "extractor/name_table.hpp"
#include "extractor/suffix_table.hpp"
#include "guidance/constants.hpp"
#include "util/name_table.hpp"
namespace osrm
{
@@ -17,7 +17,7 @@ namespace intersection
// rhs->lhs)
bool HaveIdenticalNames(const NameID lhs,
const NameID rhs,
const util::NameTable &name_table,
const NameTable &name_table,
const SuffixTable &street_name_suffix_table);
} // namespace intersection
@@ -26,14 +26,19 @@ struct IntersectionEdge
using IntersectionEdges = std::vector<IntersectionEdge>;
// The extracted geometry of an intersection edge only knows about edge IDs and bearings
// Bearing is the direction in clockwise angle from true north after taking the turn:
// 0 = heading north, 90 = east, 180 = south, 270 = west
// `initial_bearing` is the original OSM edge bearing
// `perceived_bearing` is the edge bearing after line fitting and edges merging
struct IntersectionEdgeGeometry
{
EdgeID edge;
EdgeID eid;
double initial_bearing;
double perceived_bearing;
double length;
double segment_length;
bool operator<(const IntersectionEdgeGeometry &other) const { return edge < other.edge; }
bool operator<(const IntersectionEdgeGeometry &other) const { return eid < other.eid; }
};
using IntersectionEdgeGeometries = std::vector<IntersectionEdgeGeometry>;
@@ -1,6 +1,19 @@
#ifndef OSRM_EXTRACTOR_INTERSECTION_INTERSECTION_VIEW_HPP_
#define OSRM_EXTRACTOR_INTERSECTION_INTERSECTION_VIEW_HPP_
#include "extractor/intersection/intersection_edge.hpp"
#include "guidance/turn_instruction.hpp"
#include "util/bearing.hpp"
#include "util/log.hpp"
#include "util/node_based_graph.hpp"
#include "util/typedefs.hpp" // EdgeID
#include <boost/range/algorithm/count_if.hpp>
#include <boost/range/algorithm/find_if.hpp>
#include <boost/range/algorithm/min_element.hpp>
#include <algorithm>
#include <functional>
#include <limits>
@@ -8,17 +21,6 @@
#include <type_traits>
#include <vector>
#include "util/bearing.hpp"
#include "util/log.hpp"
#include "util/node_based_graph.hpp"
#include "util/typedefs.hpp" // EdgeID
#include "guidance/turn_instruction.hpp"
#include <boost/range/algorithm/count_if.hpp>
#include <boost/range/algorithm/find_if.hpp>
#include <boost/range/algorithm/min_element.hpp>
namespace osrm
{
namespace extractor
@@ -26,24 +28,6 @@ namespace extractor
namespace intersection
{
// the shape of an intersection only knows about edge IDs and bearings
// `bearing` is the direction in clockwise angle from true north after taking the turn:
// 0 = heading north, 90 = east, 180 = south, 270 = west
struct IntersectionShapeData
{
EdgeID eid;
double bearing;
double segment_length;
};
inline auto makeCompareShapeDataByBearing(const double base_bearing)
{
return [base_bearing](const auto &lhs, const auto &rhs) {
return util::angularDeviation(lhs.bearing, base_bearing) <
util::angularDeviation(rhs.bearing, base_bearing);
};
}
inline auto makeCompareAngularDeviation(const double angle)
{
return [angle](const auto &lhs, const auto &rhs) {
@@ -60,12 +44,12 @@ inline auto makeExtractLanesForRoad(const util::NodeBasedDynamicGraph &node_base
// When viewing an intersection from an incoming edge, we can transform a shape into a view which
// gives additional information on angles and whether a turn is allowed
struct IntersectionViewData : IntersectionShapeData
struct IntersectionViewData : IntersectionEdgeGeometry
{
IntersectionViewData(const IntersectionShapeData &shape,
IntersectionViewData(const IntersectionEdgeGeometry &geometry,
const bool entry_allowed,
const double angle)
: IntersectionShapeData(shape), entry_allowed(entry_allowed), angle(angle)
: IntersectionEdgeGeometry(geometry), entry_allowed(entry_allowed), angle(angle)
{
}
@@ -80,10 +64,13 @@ struct IntersectionViewData : IntersectionShapeData
template <typename Self> struct EnableShapeOps
{
// same as closest turn, but for bearings
auto FindClosestBearing(double bearing) const
auto FindClosestBearing(double base_bearing) const
{
auto comp = makeCompareShapeDataByBearing(bearing);
return std::min_element(self()->begin(), self()->end(), comp);
return std::min_element(
self()->begin(), self()->end(), [base_bearing](const auto &lhs, const auto &rhs) {
return util::angularDeviation(lhs.perceived_bearing, base_bearing) <
util::angularDeviation(rhs.perceived_bearing, base_bearing);
});
}
// search a given eid in the intersection
@@ -119,10 +106,10 @@ template <typename Self> struct EnableShapeOps
auto self() const { return static_cast<const Self *>(this); }
};
struct IntersectionShape final : std::vector<IntersectionShapeData>, //
EnableShapeOps<IntersectionShape> //
struct IntersectionShape final : std::vector<IntersectionEdgeGeometry>, //
EnableShapeOps<IntersectionShape> //
{
using Base = std::vector<IntersectionShapeData>;
using Base = std::vector<IntersectionEdgeGeometry>;
};
// Common operations shared among IntersectionView and Intersections.
@@ -4,9 +4,12 @@
#include "extractor/compressed_edge_container.hpp"
#include "extractor/intersection/coordinate_extractor.hpp"
#include "extractor/intersection/have_identical_names.hpp"
#include "extractor/name_table.hpp"
#include "extractor/restriction_index.hpp"
#include "extractor/turn_lane_types.hpp"
#include "guidance/intersection.hpp"
#include "util/coordinate.hpp"
#include "util/node_based_graph.hpp"
#include "util/typedefs.hpp"
@@ -40,7 +43,7 @@ class MergableRoadDetector
{
public:
// in case we have to change the mode we are operating on
using MergableRoadData = IntersectionShapeData;
using MergableRoadData = IntersectionEdgeGeometry;
MergableRoadDetector(const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
@@ -49,7 +52,7 @@ class MergableRoadDetector
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const TurnLanesIndexedArray &turn_lanes_data,
const util::NameTable &name_table,
const extractor::NameTable &name_table,
const SuffixTable &street_name_suffix_table);
// OSM ways tend to be modelled as separate ways for different directions. This is often due to
@@ -168,7 +171,7 @@ class MergableRoadDetector
const TurnLanesIndexedArray &turn_lanes_data;
// name detection
const util::NameTable &name_table;
const extractor::NameTable &name_table;
const SuffixTable &street_name_suffix_table;
const CoordinateExtractor coordinate_extractor;
@@ -2,6 +2,7 @@
#define OSRM_EXTRACTOR_BEARING_CONTAINER_HPP
#include "storage/shared_memory_ownership.hpp"
#include "storage/tar_fwd.hpp"
#include "util/guidance/bearing_class.hpp"
#include "util/range_table.hpp"
@@ -21,11 +22,13 @@ template <storage::Ownership Ownership> class IntersectionBearingsContainer;
namespace serialization
{
template <storage::Ownership Ownership>
void read(storage::io::FileReader &reader,
void read(storage::tar::FileReader &reader,
const std::string &name,
detail::IntersectionBearingsContainer<Ownership> &turn_data);
template <storage::Ownership Ownership>
void write(storage::io::FileWriter &writer,
void write(storage::tar::FileWriter &writer,
const std::string &name,
const detail::IntersectionBearingsContainer<Ownership> &turn_data);
}
@@ -83,10 +86,12 @@ template <storage::Ownership Ownership> class IntersectionBearingsContainer
return result;
}
friend void serialization::read<Ownership>(storage::io::FileReader &reader,
friend void serialization::read<Ownership>(storage::tar::FileReader &reader,
const std::string &name,
IntersectionBearingsContainer &turn_data_container);
friend void
serialization::write<Ownership>(storage::io::FileWriter &writer,
serialization::write<Ownership>(storage::tar::FileWriter &writer,
const std::string &name,
const IntersectionBearingsContainer &turn_data_container);
private:
+121
View File
@@ -0,0 +1,121 @@
#ifndef OSRM_EXTRACTOR_NAME_TABLE_HPP
#define OSRM_EXTRACTOR_NAME_TABLE_HPP
#include "util/indexed_data.hpp"
#include "util/string_view.hpp"
#include "util/typedefs.hpp"
#include <string>
namespace osrm
{
namespace extractor
{
namespace detail
{
template <storage::Ownership Ownership> class NameTableImpl;
}
namespace serialization
{
template <storage::Ownership Ownership>
inline void read(storage::tar::FileReader &reader,
const std::string &name,
detail::NameTableImpl<Ownership> &index_data);
template <storage::Ownership Ownership>
inline void write(storage::tar::FileWriter &writer,
const std::string &name,
const detail::NameTableImpl<Ownership> &index_data);
}
namespace detail
{
// This class provides a limited view over all the string data we serialize out.
// The following functions are a subset of what is available.
// See the data facades for they provide full access to this serialized string data.
// Way string data is stored in blocks based on `id` as follows:
//
// | name | destination | pronunciation | ref | exits
// ^ ^
// [range)
// ^ id + 2
//
// `id + offset` gives us the range of chars.
//
// Offset 0 is name, 1 is destination, 2 is pronunciation, 3 is ref, 4 is exits
// See datafacades and extractor callbacks for details.
template <storage::Ownership Ownership> class NameTableImpl
{
public:
using IndexedData =
util::detail::IndexedDataImpl<util::VariableGroupBlock<16, util::StringView>, Ownership>;
using ResultType = typename IndexedData::ResultType;
using ValueType = typename IndexedData::ValueType;
NameTableImpl() {}
NameTableImpl(IndexedData indexed_data_) : indexed_data{std::move(indexed_data_)} {}
util::StringView GetNameForID(const NameID id) const
{
if (id == INVALID_NAMEID)
return {};
return indexed_data.at(id + 0);
}
util::StringView GetDestinationsForID(const NameID id) const
{
if (id == INVALID_NAMEID)
return {};
return indexed_data.at(id + 1);
}
util::StringView GetExitsForID(const NameID id) const
{
if (id == INVALID_NAMEID)
return {};
return indexed_data.at(id + 4);
}
util::StringView GetRefForID(const NameID id) const
{
if (id == INVALID_NAMEID)
return {};
const constexpr auto OFFSET_REF = 3u;
return indexed_data.at(id + OFFSET_REF);
}
util::StringView GetPronunciationForID(const NameID id) const
{
if (id == INVALID_NAMEID)
return {};
const constexpr auto OFFSET_PRONUNCIATION = 2u;
return indexed_data.at(id + OFFSET_PRONUNCIATION);
}
friend void serialization::read<Ownership>(storage::tar::FileReader &reader,
const std::string &name,
NameTableImpl &index_data);
friend void serialization::write<Ownership>(storage::tar::FileWriter &writer,
const std::string &name,
const NameTableImpl &index_data);
private:
IndexedData indexed_data;
};
}
using NameTable = detail::NameTableImpl<storage::Ownership::Container>;
using NameTableView = detail::NameTableImpl<storage::Ownership::View>;
} // namespace extractor
} // namespace osrm
#endif // OSRM_EXTRACTOR_NAME_TABLE_HPP
+9 -5
View File
@@ -6,8 +6,8 @@
#include "extractor/node_based_edge.hpp"
#include "extractor/travel_mode.hpp"
#include "storage/io_fwd.hpp"
#include "storage/shared_memory_ownership.hpp"
#include "storage/tar_fwd.hpp"
#include "util/permutation.hpp"
#include "util/typedefs.hpp"
@@ -29,11 +29,13 @@ template <storage::Ownership Ownership> class EdgeBasedNodeDataContainerImpl;
namespace serialization
{
template <storage::Ownership Ownership>
void read(storage::io::FileReader &reader,
void read(storage::tar::FileReader &reader,
const std::string &name,
detail::EdgeBasedNodeDataContainerImpl<Ownership> &ebn_data);
template <storage::Ownership Ownership>
void write(storage::io::FileWriter &writer,
void write(storage::tar::FileWriter &writer,
const std::string &name,
const detail::EdgeBasedNodeDataContainerImpl<Ownership> &ebn_data);
}
@@ -89,10 +91,12 @@ template <storage::Ownership Ownership> class EdgeBasedNodeDataContainerImpl
return annotation_data[nodes[node_id].annotation_id].classes;
}
friend void serialization::read<Ownership>(storage::io::FileReader &reader,
friend void serialization::read<Ownership>(storage::tar::FileReader &reader,
const std::string &name,
EdgeBasedNodeDataContainerImpl &ebn_data_container);
friend void
serialization::write<Ownership>(storage::io::FileWriter &writer,
serialization::write<Ownership>(storage::tar::FileWriter &writer,
const std::string &name,
const EdgeBasedNodeDataContainerImpl &ebn_data_container);
template <typename = std::enable_if<Ownership == storage::Ownership::Container>>
+82
View File
@@ -1,6 +1,7 @@
#ifndef OSRM_EXTRACTOR_CLASSIFICATION_DATA_HPP_
#define OSRM_EXTRACTOR_CLASSIFICATION_DATA_HPP_
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <cstdlib>
@@ -22,17 +23,25 @@ namespace RoadPriorityClass
typedef std::uint8_t Enum;
// Top priority Road
const constexpr Enum MOTORWAY = 0;
const constexpr Enum MOTORWAY_LINK = 1;
// Second highest priority
const constexpr Enum TRUNK = 2;
const constexpr Enum TRUNK_LINK = 3;
// Main roads
const constexpr Enum PRIMARY = 4;
const constexpr Enum PRIMARY_LINK = 5;
const constexpr Enum SECONDARY = 6;
const constexpr Enum SECONDARY_LINK = 7;
const constexpr Enum TERTIARY = 8;
const constexpr Enum TERTIARY_LINK = 9;
// Residential Categories
const constexpr Enum MAIN_RESIDENTIAL = 10;
const constexpr Enum SIDE_RESIDENTIAL = 11;
const constexpr Enum ALLEY = 12;
const constexpr Enum PARKING = 13;
// Link Category
const constexpr Enum LINK_ROAD = 14;
const constexpr Enum UNCLASSIFIED = 15;
// Bike Accessible
const constexpr Enum BIKE_PATH = 16;
// Walk Accessible
@@ -125,6 +134,79 @@ inline bool canBeSeenAsFork(const RoadClassification first, const RoadClassifica
static_cast<int>(second.GetPriority())) <= 1;
}
// priority groups are road classes that can be categoriesed as somewhat similar
inline std::uint8_t getRoadGroup(const RoadClassification classification)
{
const constexpr std::uint8_t groups[RoadPriorityClass::CONNECTIVITY + 1] = {
0, // MOTORWAY
0, // MOTORWAY_LINK
1, // TRUNK
1, // TRUNK_LINK
2, // PRIMARY
2, // PRIMARY_LINK
2, // SECONDARY
2, // SECONDARY_LINK
2, // TERTIARY
2, // TERTIARY_LINK
3, // MAIN_RESIDENTIAL
3, // SIDE_RESIDENTIAL
3, // ALLEY
3, // PARKING
4, // LINK_ROAD
4, // UNCLASSIFIED
5, // BIKE_PATH
6, // FOOT_PATH
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7 // CONNECTIVITY
};
BOOST_ASSERT(groups[RoadPriorityClass::CONNECTIVITY] == 7);
return groups[classification.GetPriority()];
}
// LHS road classification is strictly less than RHS, if it belongs to a lower general category
// of roads. E.g. normal city roads are strictly less of a priority than a motorway and alleys
// are strictly less than inner-city roads.
inline bool strictlyLess(const RoadClassification lhs, const RoadClassification rhs)
{
if (!lhs.IsLowPriorityRoadClass() && rhs.IsLowPriorityRoadClass())
return false;
if (lhs.IsLowPriorityRoadClass() && !rhs.IsLowPriorityRoadClass())
return true;
return getRoadGroup(lhs) > getRoadGroup(rhs);
}
// check whether a link class is the fitting link class to a road
inline bool isLinkTo(const RoadClassification link, const RoadClassification road)
{
// needs to be a link/non-link combination
if (!link.IsLinkClass() || road.IsLinkClass())
return false;
switch (link.GetPriority())
{
case RoadPriorityClass::MOTORWAY_LINK:
return road.GetPriority() == RoadPriorityClass::MOTORWAY;
case RoadPriorityClass::TRUNK_LINK:
return road.GetPriority() == RoadPriorityClass::TRUNK;
case RoadPriorityClass::PRIMARY_LINK:
return road.GetPriority() == RoadPriorityClass::PRIMARY;
case RoadPriorityClass::SECONDARY_LINK:
return road.GetPriority() == RoadPriorityClass::SECONDARY;
case RoadPriorityClass::TERTIARY_LINK:
return road.GetPriority() == RoadPriorityClass::TERTIARY;
default:
return false;
}
}
inline bool obviousByRoadClass(const RoadClassification in_classification,
const RoadClassification obvious_candidate,
const RoadClassification compare_candidate)
+13 -8
View File
@@ -5,8 +5,8 @@
#include "util/typedefs.hpp"
#include "util/vector_view.hpp"
#include "storage/io_fwd.hpp"
#include "storage/shared_memory_ownership.hpp"
#include "storage/tar_fwd.hpp"
#include <boost/filesystem/path.hpp>
#include <boost/range/adaptor/reversed.hpp>
@@ -32,10 +32,12 @@ template <storage::Ownership Ownership> class SegmentDataContainerImpl;
namespace serialization
{
template <storage::Ownership Ownership>
inline void read(storage::io::FileReader &reader,
inline void read(storage::tar::FileReader &reader,
const std::string &name,
detail::SegmentDataContainerImpl<Ownership> &segment_data);
template <storage::Ownership Ownership>
inline void write(storage::io::FileWriter &writer,
inline void write(storage::tar::FileWriter &writer,
const std::string &name,
const detail::SegmentDataContainerImpl<Ownership> &segment_data);
}
@@ -53,14 +55,15 @@ template <storage::Ownership Ownership> class SegmentDataContainerImpl
// FIXME We should change the indexing to Edge-Based-Node id
using DirectionalGeometryID = std::uint32_t;
using SegmentOffset = std::uint32_t;
using SegmentNodeVector = Vector<NodeID>;
using SegmentWeightVector = PackedVector<SegmentWeight, SEGMENT_WEIGHT_BITS>;
using SegmentDurationVector = PackedVector<SegmentDuration, SEGMENT_DURAITON_BITS>;
using SegmentDurationVector = PackedVector<SegmentDuration, SEGMENT_DURATION_BITS>;
using SegmentDatasourceVector = Vector<DatasourceID>;
SegmentDataContainerImpl() = default;
SegmentDataContainerImpl(Vector<std::uint32_t> index_,
Vector<NodeID> nodes_,
SegmentNodeVector nodes_,
SegmentWeightVector fwd_weights_,
SegmentWeightVector rev_weights_,
SegmentDurationVector fwd_durations_,
@@ -200,15 +203,17 @@ template <storage::Ownership Ownership> class SegmentDataContainerImpl
auto GetNumberOfSegments() const { return fwd_weights.size(); }
friend void
serialization::read<Ownership>(storage::io::FileReader &reader,
serialization::read<Ownership>(storage::tar::FileReader &reader,
const std::string &name,
detail::SegmentDataContainerImpl<Ownership> &segment_data);
friend void serialization::write<Ownership>(
storage::io::FileWriter &writer,
storage::tar::FileWriter &writer,
const std::string &name,
const detail::SegmentDataContainerImpl<Ownership> &segment_data);
private:
Vector<std::uint32_t> index;
Vector<NodeID> nodes;
SegmentNodeVector nodes;
SegmentWeightVector fwd_weights;
SegmentWeightVector rev_weights;
SegmentDurationVector fwd_durations;
+112 -199
View File
@@ -1,10 +1,11 @@
#ifndef OSRM_EXTRACTOR_IO_HPP
#define OSRM_EXTRACTOR_IO_HPP
#include "conditional_turn_penalty.hpp"
#include "extractor/conditional_turn_penalty.hpp"
#include "extractor/datasources.hpp"
#include "extractor/intersection_bearings_container.hpp"
#include "extractor/maneuver_override.hpp"
#include "extractor/name_table.hpp"
#include "extractor/nbg_to_ebg.hpp"
#include "extractor/node_data_container.hpp"
#include "extractor/profile_properties.hpp"
@@ -25,234 +26,113 @@ namespace serialization
// read/write for bearing data
template <storage::Ownership Ownership>
inline void read(storage::io::FileReader &reader,
inline void read(storage::tar::FileReader &reader,
const std::string &name,
detail::IntersectionBearingsContainer<Ownership> &intersection_bearings)
{
storage::serialization::read(reader, intersection_bearings.values);
storage::serialization::read(reader, intersection_bearings.node_to_class_id);
util::serialization::read(reader, intersection_bearings.class_id_to_ranges_table);
storage::serialization::read(reader, name + "/bearing_values", intersection_bearings.values);
storage::serialization::read(
reader, name + "/node_to_class_id", intersection_bearings.node_to_class_id);
util::serialization::read(
reader, name + "/class_id_to_ranges", intersection_bearings.class_id_to_ranges_table);
}
template <storage::Ownership Ownership>
inline void write(storage::io::FileWriter &writer,
inline void write(storage::tar::FileWriter &writer,
const std::string &name,
const detail::IntersectionBearingsContainer<Ownership> &intersection_bearings)
{
storage::serialization::write(writer, intersection_bearings.values);
storage::serialization::write(writer, intersection_bearings.node_to_class_id);
util::serialization::write(writer, intersection_bearings.class_id_to_ranges_table);
storage::serialization::write(writer, name + "/bearing_values", intersection_bearings.values);
storage::serialization::write(
writer, name + "/node_to_class_id", intersection_bearings.node_to_class_id);
util::serialization::write(
writer, name + "/class_id_to_ranges", intersection_bearings.class_id_to_ranges_table);
}
// read/write for properties file
inline void read(storage::io::FileReader &reader, ProfileProperties &properties)
inline void
read(storage::tar::FileReader &reader, const std::string &name, ProfileProperties &properties)
{
reader.ReadInto(properties);
reader.ReadInto(name, properties);
}
inline void write(storage::io::FileWriter &writer, const ProfileProperties &properties)
inline void write(storage::tar::FileWriter &writer,
const std::string &name,
const ProfileProperties &properties)
{
writer.WriteFrom(properties);
writer.WriteElementCount64(name, 1);
writer.WriteFrom(name, properties);
}
// read/write for datasources file
inline void read(storage::io::FileReader &reader, Datasources &sources)
inline void read(storage::tar::FileReader &reader, const std::string &name, Datasources &sources)
{
reader.ReadInto(sources);
reader.ReadInto(name, sources);
}
inline void write(storage::io::FileWriter &writer, Datasources &sources)
inline void write(storage::tar::FileWriter &writer, const std::string &name, Datasources &sources)
{
writer.WriteFrom(sources);
writer.WriteElementCount64(name, 1);
writer.WriteFrom(name, sources);
}
// read/write for segment data file
template <storage::Ownership Ownership>
inline void read(storage::io::FileReader &reader,
inline void read(storage::tar::FileReader &reader,
const std::string &name,
detail::SegmentDataContainerImpl<Ownership> &segment_data)
{
storage::serialization::read(reader, segment_data.index);
storage::serialization::read(reader, segment_data.nodes);
util::serialization::read(reader, segment_data.fwd_weights);
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.fwd_datasources);
storage::serialization::read(reader, segment_data.rev_datasources);
storage::serialization::read(reader, name + "/index", segment_data.index);
storage::serialization::read(reader, name + "/nodes", segment_data.nodes);
util::serialization::read(reader, name + "/forward_weights", segment_data.fwd_weights);
util::serialization::read(reader, name + "/reverse_weights", segment_data.rev_weights);
util::serialization::read(reader, name + "/forward_durations", segment_data.fwd_durations);
util::serialization::read(reader, name + "/reverse_durations", segment_data.rev_durations);
storage::serialization::read(
reader, name + "/forward_data_sources", segment_data.fwd_datasources);
storage::serialization::read(
reader, name + "/reverse_data_sources", segment_data.rev_datasources);
}
template <storage::Ownership Ownership>
inline void write(storage::io::FileWriter &writer,
inline void write(storage::tar::FileWriter &writer,
const std::string &name,
const detail::SegmentDataContainerImpl<Ownership> &segment_data)
{
storage::serialization::write(writer, segment_data.index);
storage::serialization::write(writer, segment_data.nodes);
util::serialization::write(writer, segment_data.fwd_weights);
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.fwd_datasources);
storage::serialization::write(writer, segment_data.rev_datasources);
storage::serialization::write(writer, name + "/index", segment_data.index);
storage::serialization::write(writer, name + "/nodes", segment_data.nodes);
util::serialization::write(writer, name + "/forward_weights", segment_data.fwd_weights);
util::serialization::write(writer, name + "/reverse_weights", segment_data.rev_weights);
util::serialization::write(writer, name + "/forward_durations", segment_data.fwd_durations);
util::serialization::write(writer, name + "/reverse_durations", segment_data.rev_durations);
storage::serialization::write(
writer, name + "/forward_data_sources", segment_data.fwd_datasources);
storage::serialization::write(
writer, name + "/reverse_data_sources", segment_data.rev_datasources);
}
template <storage::Ownership Ownership>
inline void read(storage::io::FileReader &reader,
inline void read(storage::tar::FileReader &reader,
const std::string &name,
detail::EdgeBasedNodeDataContainerImpl<Ownership> &node_data_container)
{
// read header (separate sizes for both vectors)
reader.ReadElementCount64();
reader.ReadElementCount64();
// read actual data
storage::serialization::read(reader, node_data_container.nodes);
storage::serialization::read(reader, node_data_container.annotation_data);
storage::serialization::read(reader, name + "/nodes", node_data_container.nodes);
storage::serialization::read(
reader, name + "/annotations", node_data_container.annotation_data);
}
template <storage::Ownership Ownership>
inline void write(storage::io::FileWriter &writer,
inline void write(storage::tar::FileWriter &writer,
const std::string &name,
const detail::EdgeBasedNodeDataContainerImpl<Ownership> &node_data_container)
{
writer.WriteElementCount64(node_data_container.NumberOfNodes());
writer.WriteElementCount64(node_data_container.NumberOfAnnotations());
storage::serialization::write(writer, node_data_container.nodes);
storage::serialization::write(writer, node_data_container.annotation_data);
storage::serialization::write(writer, name + "/nodes", node_data_container.nodes);
storage::serialization::write(
writer, name + "/annotations", node_data_container.annotation_data);
}
inline void read(storage::io::FileReader &reader, NodeRestriction &restriction)
{
reader.ReadInto(restriction.from);
reader.ReadInto(restriction.via);
reader.ReadInto(restriction.to);
}
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.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)
{
writer.WriteOne(c.modifier);
storage::serialization::write(writer, c.times);
storage::serialization::write(writer, c.weekdays);
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);
}
inline void read(storage::io::FileReader &reader, ConditionalTurnPenalty &turn_penalty)
inline void read(storage::io::BufferReader &reader, ConditionalTurnPenalty &turn_penalty)
{
reader.ReadInto(turn_penalty.turn_offset);
reader.ReadInto(turn_penalty.location.lat);
@@ -268,46 +148,79 @@ inline void read(storage::io::FileReader &reader, ConditionalTurnPenalty &turn_p
}
}
inline void write(storage::io::FileWriter &writer, const ConditionalTurnPenalty &turn_penalty)
inline void write(storage::io::BufferWriter &writer, const ConditionalTurnPenalty &turn_penalty)
{
writer.WriteOne(turn_penalty.turn_offset);
writer.WriteOne(static_cast<util::FixedLatitude::value_type>(turn_penalty.location.lat));
writer.WriteOne(static_cast<util::FixedLongitude::value_type>(turn_penalty.location.lon));
writer.WriteFrom(turn_penalty.turn_offset);
writer.WriteFrom(static_cast<util::FixedLatitude::value_type>(turn_penalty.location.lat));
writer.WriteFrom(static_cast<util::FixedLongitude::value_type>(turn_penalty.location.lon));
writer.WriteElementCount64(turn_penalty.conditions.size());
for (const auto &c : turn_penalty.conditions)
{
writer.WriteOne(c.modifier);
writer.WriteFrom(c.modifier);
storage::serialization::write(writer, c.times);
storage::serialization::write(writer, c.weekdays);
storage::serialization::write(writer, c.monthdays);
}
}
inline void write(storage::io::FileWriter &writer,
inline void write(storage::io::BufferWriter &writer,
const std::vector<ConditionalTurnPenalty> &conditional_penalties)
{
writer.WriteElementCount64(conditional_penalties.size());
for (const auto &penalty : conditional_penalties)
{
write(writer, penalty);
}
}
inline void read(storage::io::FileReader &reader,
inline void read(storage::io::BufferReader &reader,
std::vector<ConditionalTurnPenalty> &conditional_penalties)
{
auto const num_elements = reader.ReadElementCount64();
auto num_elements = reader.ReadElementCount64();
conditional_penalties.resize(num_elements);
for (auto &penalty : conditional_penalties)
{
read(reader, penalty);
}
}
inline void write(storage::io::FileWriter &writer,
const std::vector<StorageManeuverOverride> &maneuver_overrides,
const std::vector<NodeID> &node_sequences)
inline void write(storage::tar::FileWriter &writer,
const std::string &name,
const std::vector<ConditionalTurnPenalty> &conditional_penalties)
{
writer.WriteElementCount64(maneuver_overrides.size());
writer.WriteElementCount64(node_sequences.size());
writer.WriteFrom(maneuver_overrides);
writer.WriteFrom(node_sequences);
storage::io::BufferWriter buffer_writer;
write(buffer_writer, conditional_penalties);
storage::serialization::write(writer, name, buffer_writer.GetBuffer());
}
inline void read(storage::tar::FileReader &reader,
const std::string &name,
std::vector<ConditionalTurnPenalty> &conditional_penalties)
{
std::string buffer;
storage::serialization::read(reader, name, buffer);
storage::io::BufferReader buffer_reader{buffer};
read(buffer_reader, conditional_penalties);
}
template <storage::Ownership Ownership>
inline void write(storage::tar::FileWriter &writer,
const std::string &name,
const detail::NameTableImpl<Ownership> &name_table)
{
storage::io::BufferWriter buffer_writer;
util::serialization::write(writer, name, name_table.indexed_data);
}
template <storage::Ownership Ownership>
inline void read(storage::tar::FileReader &reader,
const std::string &name,
detail::NameTableImpl<Ownership> &name_table)
{
std::string buffer;
util::serialization::read(reader, name, name_table.indexed_data);
}
}
}
+1 -1
View File
@@ -19,7 +19,7 @@ class DrivewayHandler final : public IntersectionHandler
const extractor::RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const extractor::TurnLanesIndexedArray &turn_lanes_data,
const util::NameTable &name_table,
const extractor::NameTable &name_table,
const extractor::SuffixTable &street_name_suffix_table);
~DrivewayHandler() override final = default;
+9 -6
View File
@@ -27,10 +27,11 @@ inline void readTurnData(const boost::filesystem::path &path,
std::is_same<guidance::TurnDataView, TurnDataT>::value ||
std::is_same<guidance::TurnDataExternalContainer, TurnDataT>::value,
"");
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
storage::io::FileReader reader{path, fingerprint};
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
storage::tar::FileReader reader{path, fingerprint};
serialization::read(reader, turn_data, connectivity_checksum);
reader.ReadInto("/common/connectivity_checksum", connectivity_checksum);
serialization::read(reader, "/common/turn_data", turn_data);
}
// writes .osrm.edges
@@ -43,10 +44,12 @@ inline void writeTurnData(const boost::filesystem::path &path,
std::is_same<guidance::TurnDataView, TurnDataT>::value ||
std::is_same<guidance::TurnDataExternalContainer, TurnDataT>::value,
"");
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint;
storage::io::FileWriter writer{path, fingerprint};
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
storage::tar::FileWriter writer{path, fingerprint};
serialization::write(writer, turn_data, connectivity_checksum);
writer.WriteElementCount64("/common/connectivity_checksum", 1);
writer.WriteFrom("/common/connectivity_checksum", connectivity_checksum);
serialization::write(writer, "/common/turn_data", turn_data);
}
}
}
+2 -2
View File
@@ -4,6 +4,7 @@
#include "guidance/turn_data_container.hpp"
#include "extractor/compressed_edge_container.hpp"
#include "extractor/name_table.hpp"
#include "extractor/node_data_container.hpp"
#include "extractor/suffix_table.hpp"
#include "extractor/turn_lane_types.hpp"
@@ -13,7 +14,6 @@
#include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp"
#include "util/guidance/turn_lanes.hpp"
#include "util/name_table.hpp"
#include "util/node_based_graph.hpp"
#include <unordered_set>
@@ -33,7 +33,7 @@ void annotateTurns(const util::NodeBasedDynamicGraph &node_based_graph,
const std::unordered_set<NodeID> &barrier_nodes,
const extractor::RestrictionMap &node_restriction_map,
const extractor::WayRestrictionMap &way_restriction_map,
const util::NameTable &name_table,
const extractor::NameTable &name_table,
const extractor::SuffixTable &suffix_table,
const extractor::TurnLanesIndexedArray &turn_lanes_data,
extractor::LaneDescriptionMap &lane_description_map,
+1 -1
View File
@@ -114,7 +114,7 @@ inline std::string toString(const ConnectedRoad &road)
result += " angle: ";
result += std::to_string(road.angle);
result += " bearing: ";
result += std::to_string(road.bearing);
result += std::to_string(road.perceived_bearing);
result += " instruction: ";
result += std::to_string(static_cast<std::int32_t>(road.instruction.type)) + " " +
std::to_string(static_cast<std::int32_t>(road.instruction.direction_modifier)) + " " +
File diff suppressed because it is too large Load Diff
+4 -1
View File
@@ -7,6 +7,9 @@
#include "extractor/node_data_container.hpp"
#include "extractor/suffix_table.hpp"
#include "util/bearing.hpp"
#include "util/node_based_graph.hpp"
#include "util/guidance/name_announcements.hpp"
namespace osrm
@@ -19,7 +22,7 @@ inline bool isThroughStreet(const std::size_t index,
const IntersectionType &intersection,
const util::NodeBasedDynamicGraph &node_based_graph,
const extractor::EdgeBasedNodeDataContainer &node_data_container,
const util::NameTable &name_table,
const extractor::NameTable &name_table,
const extractor::SuffixTable &street_name_suffix_table)
{
using osrm::util::angularDeviation;
+3 -2
View File
@@ -1,12 +1,13 @@
#ifndef OSRM_GUIDANCE_MOTORWAY_HANDLER_HPP_
#define OSRM_GUIDANCE_MOTORWAY_HANDLER_HPP_
#include "extractor/name_table.hpp"
#include "guidance/intersection.hpp"
#include "guidance/intersection_handler.hpp"
#include "guidance/is_through_street.hpp"
#include "util/attributes.hpp"
#include "util/name_table.hpp"
#include "util/node_based_graph.hpp"
#include <vector>
@@ -27,7 +28,7 @@ class MotorwayHandler : public IntersectionHandler
const extractor::RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const extractor::TurnLanesIndexedArray &turn_lanes_data,
const util::NameTable &name_table,
const extractor::NameTable &name_table,
const extractor::SuffixTable &street_name_suffix_table);
~MotorwayHandler() override final = default;

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