Compare commits

..

261 Commits

Author SHA1 Message Date
Daniel J. Hofmann fe491bf92c Allow Travis builds for this branch 2016-08-04 15:22:51 +02:00
Daniel J. Hofmann 7b432b34bb Update CMakeLists.txt version to 5.3.1 2016-08-04 15:12:48 +02:00
Daniel J. Hofmann 6983cd0de2 Adapt Changelog for v5.3.1 2016-08-04 15:06:44 +02:00
Daniel J. Hofmann fe8177077c Disable our added failing cucumber tests for now 2016-08-04 14:58:06 +02:00
Daniel J. Hofmann 5f339f4ed6 Fall back to generic match finding if not a reverse-lane 2016-08-04 14:57:59 +02:00
Daniel J. Hofmann 3c0b52c637 Skip handling none values for our edge cases for now..
Conflicts:
	src/extractor/guidance/turn_lane_augmentation.cpp
2016-08-04 14:57:53 +02:00
Daniel Patterson 877fc5b42c Add a minimal version of the failing test case. 2016-08-04 14:57:47 +02:00
Daniel J. Hofmann e28785e399 Reproducing breaking intersection in cucumber scenario
Conflicts:
	src/extractor/guidance/turn_lane_augmentation.cpp
2016-08-04 14:57:39 +02:00
Daniel J. Hofmann 2c4a54ce05 Try to come up with a small test case 2016-08-04 14:57:32 +02:00
Michael Krasnyk a8afc74590 Fix #2706 by using correct fallback u-turn
Regression is due to a combination of 08248e3853
and http://www.openstreetmap.org/changeset/40938983
where in ways http://www.openstreetmap.org/way/27292481
and http://www.openstreetmap.org/way/432488408
nodes
4315134884 (part of way 432488408)
4315134891 (part of way 432488408)
4315134886 (part of way 432488408)
form a u-turn that has index 0 after sorting and used as an allowed one
with a reversed edge.
A u-turn that corresponds to the condition uturn_could_be_valid == true has index 1
and ignored.
2016-07-31 22:46:10 +02:00
Daniel J. Hofmann d195eee7c4 Lane Handling for multiple indications per lane as in left;left|, fixes #2694
Before we asserted on unique lane indications per lane. Turns out the
OSM data contains lane strings such as:

    left;left|right

Which represents two lanes as in:

    <<     >
     ||    |

The two left indications _on a single lane_ look like data issue.
And we can't represent this with our enum-approach at the moment.

We don't want to crash there, so silently swallow this and
generate a single left|right for it.
2016-07-26 12:18:15 +02:00
Patrick Niklaus 9b737230d6 Reenable ARM builds 2016-07-22 13:57:57 +02:00
Patrick Niklaus ecbd709535 Update the changelog for 5.3.0 2016-07-22 13:57:28 +02:00
Patrick Niklaus 060ec99678 Fix devide by zero when updating speeds 2016-07-21 18:57:21 +02:00
Dane Springmeyer 3601d1d262 increase travis cacher timeout to ensure large caches are able to be uploaded and downloaded 2016-07-21 17:58:57 +02:00
Moritz Kobitzsch 41ba20ca9a switch api format to new structure 2016-07-21 17:42:10 +02:00
Patrick Niklaus 57e3f173d3 [skip ci] Update docker files to gcc 5 2016-07-21 17:19:35 +02:00
Patrick Niklaus 92c298c7cf [skip ci] Fix example URLs in readme 2016-07-21 17:08:39 +02:00
Moritz Kobitzsch b25011ee60 fix use-lane handling 2016-07-21 16:37:54 +02:00
Moritz Kobitzsch 0e017a6ce5 collapse use-lane instructions if possible 2016-07-20 10:23:26 +02:00
Moritz Kobitzsch 2431e15ffa mark second case as todo, see https://github.com/Project-OSRM/osrm-backend/issues/2661 2016-07-20 09:55:30 +02:00
Moritz Kobitzsch 396add1e9d make roundabout maneuvers continuous with respect to lane changes 2016-07-20 09:55:30 +02:00
Patrick Niklaus 86241a2793 [skip ci] Add docs for contributing 2016-07-19 17:38:03 +02:00
Moritz Kobitzsch ee47afbe17 fix 2672 2016-07-19 17:06:47 +02:00
Moritz Kobitzsch 8831ca2f32 fix roundabouts with traffic lights 2016-07-19 14:49:09 +02:00
Daniel J. Hofmann abde215bc3 Remove semantically wrong ordering for LaneTupel 2016-07-18 12:33:56 +02:00
Daniel J. Hofmann 130d5298fc Fixes Undefined Behavior in LaneTupel (Strict Aliasing), resolves 2665
It's complicated :sigh: read this please:
http://dbp-consulting.com/tutorials/StrictAliasing.html

tl;dr: has to go through a memcpy (in C++) as in:
https://github.com/WebAssembly/binaryen/blob/184cc11cee2a65d30c7696eb3284e132099e4acb/src/support/utilities.h#L29-L40
2016-07-18 12:32:25 +02:00
Moritz Kobitzsch 50cbba1620 adding a todo testscase / regression test-case 2016-07-15 10:35:25 +02:00
Patrick Niklaus 2cc293ad16 [skip ci] Update changelog for RC3 2016-07-13 21:57:07 +02:00
Patrick Niklaus 6ac65a922f Disable ARM builds until sourceforge comes up again 2016-07-13 14:19:33 +02:00
Patrick Niklaus 3d80f989d0 Fix tests after cucumber update and changed escaping. 2016-07-13 11:48:53 +02:00
Patrick Niklaus 4fcb5d28a4 Merge pull request #2624 from oxidase/issues/2617
Fix ambiguous data issues
2016-07-13 11:20:40 +02:00
Patrick Niklaus 3ebdacf369 Merge pull request #2629 from ssuluh/master
Fix windows compilation with regard to struct/class packing
2016-07-13 11:08:34 +02:00
Moritz Kobitzsch 2ddc00c21e update cucumber to 1.2.1 and remove hack 2016-07-13 11:04:35 +02:00
Daniel J. Hofmann e76e39a398 Improves Lane Handling for Multi-Hop Roundabout Instruction
This changeset implements Lane Anticipation on roundabouts, delimited
by enter / leave step pairs. It does not handle lane anticipation
within a roundabout.

Lane anticipation happens on the granularity of a valid roundbaout:

We discard partial roundabout (enter without exit or exit without
enter) or data issues (no roundabout, exit before enter).

Related:

- https://github.com/Project-OSRM/osrm-backend/issues/2626 for lanes
  within a roundabout

- https://github.com/Project-OSRM/osrm-backend/issues/2625 for handling
  going straight in lane anticipation
2016-07-13 10:44:12 +02:00
Patrick Niklaus 04667f1ed8 Log incoming requests before they are processed 2016-07-11 16:50:09 +02:00
Surya Suluh 2091c3443b Fix windows compilation with regard to struct/class packing 2016-07-11 09:47:04 -04:00
Michael Krasnyk 2b466b2fb2 Fix ambiguity in edges by using names lexicographical order 2016-07-11 05:54:30 +02:00
Michael Krasnyk e17b306265 Fix ambiguity in edge weights by using minimal weight 2016-07-08 18:20:55 +02:00
Daniel J. Hofmann b00b15ab98 Manual modernize run with LLVM 3.8
More is blocked by:
- https://github.com/Project-OSRM/osrm-backend/issues/2631
2016-07-07 12:45:24 +02:00
Moritz Kobitzsch f4db79fe9b fix obvious turn collapsing for straight turns 2016-07-06 10:50:47 +02:00
Moritz Kobitzsch 0e4061f858 deduplicate code for roundabout handling 2016-07-01 11:34:44 +02:00
Moritz Kobitzsch 043a1446e1 adjust changelog (mention both files) and update a typo 2016-06-30 10:39:05 +02:00
Moritz Kobitzsch 49221995e8 add documentation on use lane type 2016-06-28 17:53:31 +02:00
Moritz Kobitzsch 247a7488b8 Adjusting Changelog 5.3.0-rc.2 to follow scheme 2016-06-28 13:25:35 +02:00
Moritz Kobitzsch 1806198971 Prepare Update to 5.3.0 RC2 2016-06-28 13:22:33 +02:00
Moritz Kobitzsch 375331b80c fixing lua issue in profile 2016-06-28 12:59:02 +02:00
Patrick Niklaus 8fdbe965cc [skip ci] Fix documentation 2016-06-28 11:08:37 +02:00
Patrick Niklaus dc77d02e8a Change OSRM version to 5.3.0 2016-06-28 10:35:45 +02:00
Moritz Kobitzsch 6265b8fa77 fix broken assertion 2016-06-28 10:30:02 +02:00
Moritz Kobitzsch 311b348d09 handle sliproads at traffic lights 2016-06-28 10:23:22 +02:00
Daniel Patterson ec02cdc4cc Use mmap instead of read - it's a lot faster here.
Also clean up construction of STRONG_TYPEDEF so that it can be
packed properly in structs (this explains all the () -> {}) changes
here.
2016-06-27 17:24:30 -07:00
Moritz Kobitzsch 5905708111 expose lanes as enums, adjusted for comments 2016-06-27 11:12:02 +02:00
Moritz Kobitzsch 5d91b759d1 Implement Turn Lane Api 2016-06-27 10:07:48 +02:00
Daniel J. Hofmann ec0a1a4ab1 Anticipate Lane Changes 2016-06-27 10:07:43 +02:00
Moritz Kobitzsch efa29edf09 basic turn lane handling 2016-06-27 10:07:41 +02:00
Moritz Kobitzsch 2a05b70dfc reduce number of end-of-road instructions in unnecessary cases 2016-06-26 16:40:15 +02:00
Patrick Niklaus 8693e68271 Merge pull request #2588 from Project-OSRM/fix/bike_surface_speeds
bike: surface should never increase speed
2016-06-26 16:37:12 +02:00
Emil Tin d21a9a514d bike: surface should never increase speed 2016-06-25 12:52:54 +02:00
Moritz Kobitzsch e03d132823 fix invalid circle centers 2016-06-24 15:12:51 +02:00
Daniel J. Hofmann 61ba985bc9 Prevent linker from discarding TBB symbols we need, fixes #2557
We build `osrm_contract` (the library) linking in libtbb. We then
build `osrm-contract` (the binary) linking in `osrm_contract` (the
library).

Because we're only using TBB's `parallel_invoke` in the code for the
binary, it seems like the linker discards some symbols in the library.

Therefore we have to link libtbb for the binary again. Even worse, the
order now matters: if we first link in `osrm_contract` and then libtbb,
we're still hitting the issue re. discarded symbols.

Therefore we first link in all dependencies (libtbb, libboost*), and
only then `osrm_contract`.

Strictly speaking, we probably have to do this for all of our binary
targets, or we will hit similar issues in the future.
2016-06-24 12:06:28 +02:00
Moritz Kobitzsch 4629a20fe4 improve handling of obvious for end-of-road situations 2016-06-24 12:05:42 +02:00
Patrick Niklaus a28125ee9a Merge pull request #2577 from noblige/noblige/compile-armv7
option to disable LTO
2016-06-24 12:04:02 +02:00
Daniel J. Hofmann df877aca1b Hard-abort on assertion and show detailed information, solves #2579
From

> [warn} oops

to

> [assert] /tmp/osrm-backend/src/extractor/extractor.cpp:79
> in: int osrm::extractor::Extractor::run(): false
> terminate called without an active exception
2016-06-23 18:57:35 +02:00
Aleksei Potov 05dc415aba option to disable LTO 2016-06-23 09:44:02 -07:00
Daniel Patterson 6dedd9cb72 Fix segfault when route includes very short segments. 2016-06-22 14:48:57 -07:00
Daniel J. Hofmann 256d39b572 Sync OSRM version in CMakeLists, fixes #2576 2016-06-22 17:03:31 +02:00
Patrick Niklaus d186ae1863 Fix semi-colon warnings 2016-06-22 13:20:55 +02:00
Patrick Niklaus fddc19e98d Fix regressed formating 2016-06-21 22:25:48 +02:00
Lauren Budorick 2592cd2e58 Update tests to catch 0-subtraction error 2016-06-21 19:31:46 +02:00
Patrick Niklaus 93b6438cea Fix fromTop and fromLeft calculation 2016-06-21 19:31:46 +02:00
Daniel J. Hofmann f6746d88b7 Removes unused -s from osrm-datastore, use osrm-springclean tool, closes #2561 2016-06-21 18:09:11 +02:00
Daniel J. Hofmann 34ace4dd4b Let Travis fail fast if CMake/Clang download fails, fixes #2433 2016-06-21 18:08:19 +02:00
Daniel J. Hofmann 41d0f42ddf Show user hint on wrong Node.js version, fixes #2435.
This is more of a hack but looks like the best we can do.

The reason for this is the following:

1/ we require strict mode for our v4 script

2/ v0.10 in strict mode marks 'let' as a reserved keyword,
   aborting before execution any code in the script. Thus,
   we can't assert e.g. on process.versions['node'] !== '4'.
2016-06-21 18:07:35 +02:00
Moritz Kobitzsch 2868f702a5 fix issues with roundabouts and intersections and sliproads 2016-06-21 16:56:57 +02:00
Patrick Niklaus ec4dcee8bd Merge pull request #2549 from oxidase/issue/2546
Fix omitting the last point's coordinates in the geometry field
2016-06-21 16:41:35 +02:00
Michael Krasnyk 8c378191df Fix omitting the last point's coordinates in the geometry field 2016-06-21 07:06:43 +02:00
Daniel J. Hofmann b98431e8e6 Use BaseDataFacades in guidance and prevent ODR violations with inline 2016-06-21 00:49:06 +02:00
Moritz Kobitzsch 3c8781855e handle steep off-ramps 2016-06-21 00:47:43 +02:00
Patrick Niklaus 27a94f3ca6 Merge pull request #2504 from oxidase/issue/2502
Fixes for i686 and armhf platforms
2016-06-20 22:01:09 +00:00
Michael Krasnyk 04e334e3e2 Make storage blocks aligned to 4 bytes for ARM NEON/VFP instructions
Aligned blocks prevent bus errors in NEON/VFP instructions.

Block pointers are aligned to 4 bytes, that is guaranteed
by aligned mmaped-pointers, the 4 bytes size of the CANARY block and
aligned sizes of blocks.
2016-06-20 22:45:40 +02:00
Michael Krasnyk 12d4832037 Fix platform-independent data in data files 2016-06-20 22:45:40 +02:00
Michael Krasnyk 6e4f6fec91 Added armhf Travis build 2016-06-20 22:45:40 +02:00
Michael Krasnyk 57c9525e5c Added i686 Travis build 2016-06-20 22:45:40 +02:00
Michael Krasnyk 543e4fb57d Fix rounding issue in query coordinates by using toFixed
that internally uses boost::numeric_cast<std::int32_t>
instead of static_cast<std::int32_t>
2016-06-20 22:45:40 +02:00
Michael Krasnyk 3881ead8e5 Fix rounding issue due to non-associative floating arithmetic
Failing test
features/car/traffic_turn_penalties.feature:33

Tables were not identical:
    from |     to |     route |     speed |     time
|     a |     h |     ad,dhk,dhk |     63 km/h |     11.5s +-1 |
|     i |     g |     fim,fg,fg |     59 km/h |     12s  +-1 |
| (-) a | (-) e | (-) ad,de,de | (-) 57 km/h | (-) 12.5s +-1 |
| (+) a | (+) e | (+) ad,de,de | (+) 58 km/h | (+) 12.5s +-1 |
|     c |     g |     cd,de,ef,fg,fg |     63 km/h |     23s +-1 |
|     p |     g |     mp,fim,fg,fg |     61 km/h |     23.5s +-1 |
|     a |     l |     ad,dhk,kl,kl |     60 km/h |     24s +-1 |
|     l |     e |     kl,dhk,de,de |     59 km/h |     24.5s +-1 |
|     g |     n |     fg,fim,mn,mn |     57 km/h |     25s +-1 |
2016-06-20 22:45:40 +02:00
Michael Krasnyk 911d1e81b6 Make explicit promotion to int64_t
to avoid incorrect promotions for 32 bit size_t
2016-06-20 22:45:40 +02:00
Michael Krasnyk ae06300c17 Fix unused variables warnings in crc32 2016-06-20 22:43:28 +02:00
Michael Krasnyk 26879ca91a Make build directory configurable via OSRM_BUILD_DIR in tests 2016-06-20 22:43:28 +02:00
Moritz Kobitzsch 306744e5cb fix roundabout-handling when name changes 2016-06-17 11:02:14 +02:00
Moritz Kobitzsch 3ca32898a1 move guidance decision into debug header 2016-06-15 11:30:30 +02:00
Patrick Niklaus 532fda267f [skip ci] Update changelog for 5.2.1
Conflicts:
	CHANGELOG.md
2016-06-14 14:32:33 +02:00
Daniel Patterson 494845b160 Copy data to beginning of buffer, not end. (#2542)
Copy data to beginning of buffer, not end.
2016-06-13 12:59:42 -07:00
Patrick Niklaus 0fc823041e Removed debug code 2016-06-13 17:57:33 +02:00
Patrick Niklaus 71eae4137d [skip ci] Update changelog 2016-06-13 17:27:53 +02:00
Moritz Kobitzsch 47b19f209b prefer obvious turn assignment over forks 2016-06-13 15:00:18 +02:00
Moritz Kobitzsch 2b5355edca improve slipway handling to allow multiple styles of turn lanes / turn roads 2016-06-13 11:56:50 +02:00
Patrick Niklaus e9a0beb4e8 Fix shared memory encoding for node-ids 2016-06-12 20:50:57 +02:00
Vladimir Kurchatkin 6bdfe68897 Add feature name to vector tiles (#2488) 2016-06-10 11:15:14 -07:00
Daniel J. Hofmann cf2d2b6763 Boost.Test Testing Docs 2016-06-10 19:03:44 +02:00
Moritz Kobitzsch 95cd44f34f add directions guide 2016-06-10 19:03:44 +02:00
Moritz Kobitzsch d330e60d40 added a guide on writing good cucumber tests for osrm 2016-06-10 19:03:44 +02:00
Moritz Kobitzsch 99004bbec8 add testcase 2016-06-10 10:20:39 +02:00
Emil Tin bbcc728a07 Update http.md
clarify "new name" instruction
2016-06-10 09:42:13 +02:00
Daniel J. Hofmann 033dc0a72d Pre-allocate up-front whenever possible 2016-06-09 16:06:27 +02:00
Patrick Niklaus 1c140a112a Make sure we also reserve space for destination and pronunciation 2016-06-08 10:58:11 +02:00
Moritz Kobitzsch 312e86eb58 handle merge on collapsed instructions 2016-06-06 11:55:14 +02:00
Moritz Kobitzsch 1dfdb38d4a improve collapse-handling 2016-06-06 10:05:18 +02:00
Dane Springmeyer dfafe7dc5f Install clang-3.8 via mason binary 2016-06-04 12:15:29 +02:00
Dane Springmeyer 6ecc123d15 Fix various issues with pkg-config 2016-06-04 12:08:54 +02:00
Daniel J. Hofmann 6f322d2140 Silence multiline comment warning 2016-06-03 14:47:45 +02:00
Daniel J. Hofmann dfa762bccc Pronunciation.
Spelling is hard. Maybe this time. /cc @themarex @systemed
2016-06-02 16:35:21 +02:00
Daniel J. Hofmann 87f00d2c4c Restrict CMake version to 2.8.11+ for target_include_directories 2016-06-02 16:07:29 +02:00
Daniel J. Hofmann 6f94e0dfb8 Update the Changelog for v5.2.0-rc2 2016-06-02 15:22:56 +02:00
Daniel J. Hofmann ad70759f91 Revert "Handle small roundabouts, fixes #516."
This reverts commit 7641b12b08.

Conflicts:
	profiles/bicycle.lua
	profiles/car.lua
2016-06-02 15:08:24 +02:00
Daniel J. Hofmann 27c4e8ddd0 Revert "Adds tag to taginfo"
This reverts commit 14fdf861ca.
2016-06-02 15:00:50 +02:00
Daniel J. Hofmann 805d74b6ae Revert "Fixes roundabout spelling in existing cucumber test"
This reverts commit ef7b36da32.
2016-06-02 15:00:49 +02:00
Daniel J. Hofmann 4ad78309e2 Revert "Set speeds for mini roundabouts in car and bike profile"
This reverts commit a85f39c140.
2016-06-02 15:00:47 +02:00
Daniel J. Hofmann b78207ddd8 Revert "Add implied oneway cucumber tests for mini roundabouts"
This reverts commit bd707b0cfc.

Conflicts:
	features/bicycle/oneway.feature
	features/car/oneway.feature
2016-06-02 15:00:44 +02:00
Daniel J. Hofmann b6834da9a4 Revert "Test guidance instructions for entering and leaving mini roundabouts"
This reverts commit 9cdc9008aa.
2016-06-02 14:57:48 +02:00
Daniel J. Hofmann 801cc72691 Sync with Clang38 Format 2016-06-02 14:43:27 +02:00
Patrick Niklaus e198709643 Add documentation about nodes property 2016-06-02 14:28:33 +02:00
Patrick Niklaus ed8d5e0b0a Add missing semicolon 2016-06-02 14:27:25 +02:00
Lauren Budorick e8fb312703 Update OSM node IDs annotation cucumber code per d6de2ca71c 2016-06-02 14:27:25 +02:00
Lauren Budorick 058b8c3b31 Template vector 2016-06-02 14:27:25 +02:00
Lauren Budorick ae3ccb009e Formatting [ci skip] 2016-06-02 14:27:25 +02:00
Lauren Budorick 0c60a2aef8 Minor cleanups + comments 2016-06-02 14:27:25 +02:00
Lauren Budorick 44fdf86702 IT WORKS 2016-06-02 14:27:25 +02:00
Lauren Budorick 1659bbf7b1 Refining packed_vector.hpp
* Rename to std::vector-like APIs (push_back, at)
* Add size, reserve, capacity methods
2016-06-02 14:27:25 +02:00
Lauren Budorick 46b58fba83 Packed vector cleanups and unit test 2016-06-02 14:27:25 +02:00
Lauren Budorick 84da86ba4a Add packed vector sketch 2016-06-02 14:27:25 +02:00
Lauren Budorick 6777127497 Add cucumber tests for node IDs 2016-06-02 14:27:25 +02:00
Lauren Budorick a4ac07866a Recreate feature/expose_node_ids 2016-06-02 14:27:25 +02:00
Daniel J. Hofmann 448f8377fb Sync with Clang38 Format 2016-06-02 13:14:33 +02:00
Daniel J. Hofmann c490752ca7 highway=motorway_link does not imply oneway, fixes #1662
References:
- http://wiki.openstreetmap.org/wiki/Tag:highway%3Dmotorway_link#Tagging_oneway
- http://wiki.openstreetmap.org/wiki/Tag:highway%3Dmotorway_link
- http://wiki.openstreetmap.org/wiki/Tag:highway%3Dmotorway
2016-06-02 13:05:50 +02:00
Daniel J. Hofmann 6edc565c01 Add destinations API feature 2016-06-02 12:00:23 +02:00
Daniel J. Hofmann bb0c2754d3 With empty summaries no longer the case, update library tests accordingly 2016-06-02 00:26:04 +02:00
Moritz Kobitzsch 58d6e8f4d0 handle short summaries correctly 2016-06-02 00:26:04 +02:00
Moritz Kobitzsch bdc66049a5 fix INVALID_NAME_ID vs INVALID_NAMEID -> EMPTY_NAMEID 2016-06-01 23:19:26 +02:00
Patrick Niklaus 0a53775fb3 Expose pronunciation in RouteStep
Uses name:pronunciation by default for cars.
2016-06-01 23:17:57 +02:00
Daniel J. Hofmann 9cdc9008aa Test guidance instructions for entering and leaving mini roundabouts 2016-06-01 20:17:48 +02:00
Daniel J. Hofmann bd707b0cfc Add implied oneway cucumber tests for mini roundabouts 2016-06-01 20:17:48 +02:00
Daniel J. Hofmann a85f39c140 Set speeds for mini roundabouts in car and bike profile 2016-06-01 20:17:48 +02:00
Daniel J. Hofmann ef7b36da32 Fixes roundabout spelling in existing cucumber test 2016-06-01 20:17:48 +02:00
Daniel J. Hofmann 14fdf861ca Adds tag to taginfo 2016-06-01 20:17:48 +02:00
Daniel J. Hofmann 7641b12b08 Handle small roundabouts, fixes #516.
This gives us ~51k additional roundabout instructions.
Guidance handes sizes internally.

Note: it is highway=mini_roundabout but junction=roundabout

References:
- http://wiki.openstreetmap.org/wiki/Tag:highway%3Dmini_roundabout
- http://wiki.openstreetmap.org/wiki/Tag:junction=roundabout
- http://taginfo.openstreetmap.org/tags/highway=mini_roundabout
2016-06-01 20:17:48 +02:00
Daniel J. Hofmann e7159adf59 Switching off any LLVM APT references as servers are no longer available
References:
- http://lists.llvm.org/pipermail/llvm-foundation/2016-June/000025.html
2016-06-01 20:04:52 +02:00
Daniel J. Hofmann 51f08f2994 Let's still show the badge although we dropped support for Windows
This reverts commit a03eac8e48.
2016-06-01 19:22:31 +02:00
Daniel J. Hofmann a03eac8e48 Remove Windows Build Badge from Readme 2016-06-01 15:37:16 +02:00
Daniel J. Hofmann 503137221d Let osrm-routed log status code, fixes #512.
Disclaimer: osrm-routed is not recommended for production usage.
Use node-osrm instead: https://github.com/Project-OSRM/node-osrm
2016-05-31 14:44:50 +02:00
Patrick Niklaus fb9205bf81 Merge pull request #2476 from oxidase/refactor/2472
Refactor ramIndex #2472
2016-05-31 03:00:47 -04:00
Michael Krasnyk bfbb313088 Conditional hashing of osrm libraries 2016-05-29 07:39:49 +02:00
Michael Krasnyk 25d3c4b843 Updated change log and adjusted format 2016-05-29 07:39:49 +02:00
Michael Krasnyk 371c06d66d Change size of QueryCandidate from 32 to 24 bytes 2016-05-29 07:39:49 +02:00
Michael Krasnyk 3e5c978719 Reduce ramIndex file size
PR #2472: the bottom-most node of the r-tree contains
only a single index to a leaf node, so out of 532 bytes
only 4 are used.
2016-05-29 07:39:49 +02:00
Michael Krasnyk 843f1a6356 Set LeafNode alignment to LEAF_PAGE_SIZE bytes
References:
- https://github.com/Project-OSRM/osrm-backend/pull/2348#issuecomment-219804408
- http://stackoverflow.com/questions/15523537/alignas-specifier-vs-attribute-aligned-c11
- http://stackoverflow.com/questions/7895869/cross-platform-alignx-macro
2016-05-29 07:39:49 +02:00
Dane Springmeyer a5c5faa21d drop support for using DYLD_LIBRARY_PATH on OS X 2016-05-29 06:01:16 +02:00
Patrick Niklaus 6a1e17c6fa Print TBB version in FindTBB 2016-05-29 00:06:45 +02:00
Patrick Niklaus cd30f370b8 Remove the use of atomics and use thread-local accumulation instead 2016-05-29 00:06:18 +02:00
Dane Springmeyer 4ae8abe6a3 run clang-format [skip ci] 2016-05-27 22:35:17 +02:00
Dane Springmeyer 82bfd4ee40 fix compile with clang-3.5 2016-05-27 22:35:17 +02:00
Patrick Niklaus e08c4cff13 Make PRs fail if they don't adhere to our style format 2016-05-27 21:05:43 +02:00
Patrick Niklaus 6e16eab6ec Format with clang-format 3.8 2016-05-27 21:05:04 +02:00
Patrick Niklaus 21c47514da Update clang-format to 3.8 2016-05-27 17:45:00 +02:00
Patrick Niklaus d6de2ca71c Really place annotations in RouteLeg and not Route 2016-05-27 16:46:28 +02:00
Dane Springmeyer 451a0d9090 try caching test data on travis 2016-05-27 00:40:49 +02:00
Patrick Niklaus 262354f733 Rename annotate to annotations 2016-05-26 23:35:11 +02:00
Daniel J. Hofmann 498370330d String bulk insertion 2016-05-26 22:50:17 +02:00
Daniel J. Hofmann 6865853776 Not everything is a NodeID! 2016-05-26 22:50:17 +02:00
Daniel J. Hofmann 1418c0dbbc Move ExtractionWays and ExtractionNodes into container to avoid copying 2016-05-26 22:50:17 +02:00
Daniel J. Hofmann bbc79dd49f ExtractionContainers already owns its data 2016-05-26 22:50:17 +02:00
Daniel J. Hofmann 8036320d94 Do not bind primitives per ref 2016-05-26 22:50:17 +02:00
Patrick Niklaus c30f69d6e9 Fix breaking test uncovered by this fix 2016-05-26 22:34:39 +02:00
Patrick Niklaus 2e2f34f241 Fix retry code launch classes 2016-05-26 22:34:39 +02:00
Lauren Budorick cbbeef5c46 Prune unnecessary cucumber code 2016-05-26 22:34:39 +02:00
Moritz Kobitzsch 823ee54f22 add turn restrictions to test-cases 2016-05-26 21:31:04 +02:00
Daniel Patterson 3d03797e53 Distinguish between offramps and sliproads. 2016-05-26 21:31:04 +02:00
Patrick Niklaus 089e60fa1e Remove obsolete timer code 2016-05-26 20:25:33 +02:00
Patrick Niklaus baf8e4784b Transfer match benchmark to own binary 2016-05-26 20:25:33 +02:00
Moritz Kobitzsch d53350b263 be more verbose on broken configs 2016-05-26 20:04:24 +02:00
Patrick Niklaus 824afdceca use 5 seconds as cucumber timeout 2016-05-26 20:02:21 +02:00
Patrick Niklaus a8230e976f Merge pull request #2454 from oxidase/reset-force-flags
Remove force flags and update extract/contract hashes with arguments
2016-05-26 13:16:29 -04:00
Michael Krasnyk 6af7e6866c Sort file extensions in rename lists 2016-05-26 17:05:11 +02:00
Michael Krasnyk aaa27333ba Remove force flags and update extractor/contractor hashes
with command line arguments and argument files data.
2016-05-26 16:36:26 +02:00
Moritz Kobitzsch 797f2a196b handle intersection-access for roundabout correctly 2016-05-26 16:25:26 +02:00
Moritz Kobitzsch 51066ff18f fix options in step-definitions 2016-05-26 15:38:55 +02:00
Dane Springmeyer 4de64a92cb fix zlib linking order 2016-05-25 09:32:27 -04:00
Freenerd a21fd2ea18 Contractor: log stats for loaded speed files 2016-05-24 14:35:16 -04:00
Patrick Niklaus 0df0b4305d Merge pull request #2453 from Project-OSRM/cmake-from-mason
[Travis] Install cmake from more reliable s3 endpoint
2016-05-24 14:32:45 -04:00
Dane Springmeyer a5ed53e7aa install cmake from mason / simplify install 2016-05-24 13:35:13 -04:00
Daniel Patterson 0587c5f5c4 Trim datasource names before writing to datafile. 2016-05-24 15:20:14 +02:00
Patrick Niklaus 57dbb18c4c Merge pull request #2451 from Project-OSRM/disable-osx-spotlight
[Travis] Disable spotlight indexing on osx to speed up 'npm test'
2016-05-24 09:10:35 -04:00
Dane Springmeyer 4d92f08424 disable spotlight indexing on osx to speed up 'npm test' 2016-05-23 19:35:22 -04:00
Patrick Niklaus 254ee07942 Add new sanity check assertions to UnpackPath 2016-05-23 23:15:15 +02:00
Patrick Niklaus 0bf8bd2230 Remove invalid assertion.
This ports the matching change from RoutingBase.
2016-05-23 23:15:15 +02:00
Michael Krasnyk b5225f07cb Fix #2413 by converting enums to unsigned char constants 2016-05-23 18:33:24 +02:00
Moritz Kobitzsch abed7690d0 fix continue on obvious 2016-05-23 17:55:30 +02:00
Patrick Niklaus f96174ddbe Merge pull request #2428 from zimathias/disable-access-logging-option
Disable access logging option
2016-05-23 10:12:42 -04:00
Mathias Gug e5b713841a Fix style. 2016-05-20 12:47:47 -07:00
Mathias Gug 3b1b12069f Add changelog entry. 2016-05-20 12:47:47 -07:00
Mathias Gug 1635f7351d Support environment variable to disable http requests logging. 2016-05-20 12:47:47 -07:00
Daniel J. Hofmann ce5ae411c1 Resurrect Flat Map + Binary Search commit from PR 2412 2016-05-20 20:43:45 +02:00
Patrick Niklaus d1bc32fb31 Add comments and debug code 2016-05-20 18:52:29 +02:00
Patrick Niklaus f9f87f25d4 Use elogate() to fixup geometry when merging steps, fixes #2424 2016-05-20 18:52:29 +02:00
Patrick Niklaus 89aa6b7881 Add regression test for #2424 2016-05-20 18:52:29 +02:00
Patrick Niklaus edf9e0c1ed [skip ci] Update changelog and OSRM version 2016-05-20 18:52:00 +02:00
Dane Springmeyer c2e520ad9d Fix linking of osrm-example to boost_iostreams
Fixes linking error seen on OS X:

```
[ 50%] Linking CXX executable osrm-example
/Users/dane/.homebrew/Cellar/cmake/3.5.0/bin/cmake -E cmake_link_script CMakeFiles/osrm-example.dir/link.txt --verbose=1
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++    -std=c++11  -Wl,-search_paths_first -Wl,-headerpad_max_install_names  CMakeFiles/osrm-example.dir/example.cpp.o  -o osrm-example  /Users/dane/projects/osrm-backend/here/lib/libOSRM.a /Users/dane/.homebrew/lib/libboost_filesystem-mt.dylib /Users/dane/.homebrew/lib/libboost_system-mt.dylib /Users/dane/.homebrew/lib/libboost_thread-mt.dylib /Users/dane/.homebrew/lib/libboost_chrono-mt.dylib /Users/dane/.homebrew/lib/libboost_date_time-mt.dylib /Users/dane/.homebrew/lib/libboost_atomic-mt.dylib 
undef: __ZN5boost9iostreams18mapped_file_source9open_implERKNS0_24basic_mapped_file_paramsINS0_6detail4pathEEE
undef: __ZN5boost9iostreams18mapped_file_sourceC1Ev
undef: __ZNK5boost9iostreams18mapped_file_source4sizeEv
undef: __ZNK5boost9iostreams18mapped_file_source4dataEv
Undefined symbols for architecture x86_64:
  "boost::iostreams::mapped_file_source::open_impl(boost::iostreams::basic_mapped_file_params<boost::iostreams::detail::path> const&)", referenced from:
      void boost::iostreams::mapped_file_source::open<boost::filesystem::path>(boost::filesystem::path const&, unsigned long, long) in libOSRM.a(engine.cpp.o)
  "boost::iostreams::mapped_file_source::mapped_file_source()", referenced from:
      osrm::engine::datafacade::SharedDataFacade::CheckAndReloadFacade() in libOSRM.a(engine.cpp.o)
      osrm::engine::datafacade::InternalDataFacade::InternalDataFacade(osrm::storage::StorageConfig const&) in libOSRM.a(engine.cpp.o)
  "boost::iostreams::mapped_file_source::size() const", referenced from:
      osrm::engine::datafacade::SharedDataFacade::CheckAndReloadFacade() in libOSRM.a(engine.cpp.o)
      osrm::engine::datafacade::InternalDataFacade::InternalDataFacade(osrm::storage::StorageConfig const&) in libOSRM.a(engine.cpp.o)
  "boost::iostreams::mapped_file_source::data() const", referenced from:
      osrm::engine::datafacade::SharedDataFacade::CheckAndReloadFacade() in libOSRM.a(engine.cpp.o)
      osrm::engine::datafacade::InternalDataFacade::InternalDataFacade(osrm::storage::StorageConfig const&) in libOSRM.a(engine.cpp.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
```
2016-05-20 16:04:18 +02:00
Dane Springmeyer 7649187095 workaround boostorg/numeric_conversion#4 2016-05-20 16:03:19 +02:00
Dane Springmeyer fe39d0fd10 disable BOOST_TEST_DYN_LINK if Boost_USE_STATIC_LIBS 2016-05-20 00:03:37 -04:00
Patrick Niklaus 98b83b7208 Fix library test 2016-05-19 16:44:31 +02:00
Patrick Niklaus 57321979ae Remove leftover debugging code 2016-05-19 16:44:31 +02:00
Patrick Niklaus e3ce0c5887 Add fuzzy matching for bearings and intersections list 2016-05-19 16:44:31 +02:00
Patrick Niklaus 95af72c70c Make intersection backwards compatible
For `depart` and `arrive` `step.intersections[0].{bearings|entry}` will have
only one entry.
2016-05-19 16:44:31 +02:00
Patrick Niklaus 3b37769624 Use bearing_before and bearing_after in the bearings field 2016-05-19 16:44:31 +02:00
Moritz Kobitzsch d150df1c5c format 2016-05-19 16:44:31 +02:00
Moritz Kobitzsch a322e27e05 update changelog/docs 2016-05-19 16:44:31 +02:00
Moritz Kobitzsch 98fe0badbe fix loading in storage 2016-05-19 16:44:31 +02:00
Moritz Kobitzsch 44b841a25d fix storage 2016-05-19 16:44:31 +02:00
Moritz Kobitzsch 9c8bf820de adjusted to in/out. only emit one of them for depart/arrive 2016-05-19 16:44:31 +02:00
Moritz Kobitzsch 4d9aa65e78 intersection classes with variable degree of discretization 2016-05-19 16:44:31 +02:00
Moritz Kobitzsch 0f3942558f version using discrete values stored directly at intersection 2016-05-19 16:43:46 +02:00
Moritz Kobitzsch ba074b0116 initial version of intersection classification 2016-05-19 16:43:46 +02:00
Daniel J. Hofmann 6aa97048df Rip out custom CSV parser code and its third_party dependency 2016-05-19 00:01:54 +02:00
Daniel J. Hofmann d9a5c79ea6 Map leaf nodes to RAM and iterate over them potentially in parallel 2016-05-19 00:01:54 +02:00
Daniel J. Hofmann 9d7714c714 Make looping through all leaf nodes less confusing 2016-05-19 00:01:54 +02:00
Daniel J. Hofmann 8291be375a Expose concurrency in saving files 2016-05-19 00:01:54 +02:00
Daniel J. Hofmann 0a73737f69 Fold parsing and data loading in concurrently executing action 2016-05-19 00:01:54 +02:00
Daniel J. Hofmann 2fd1b6c913 Expose concurrency between intern/external node map and geometries 2016-05-19 00:01:54 +02:00
Daniel J. Hofmann ea38a1d880 Parse multiple files concurrently 2016-05-19 00:01:54 +02:00
Daniel J. Hofmann f576e13c51 Concurrent lookup hashtables 2016-05-19 00:01:54 +02:00
Daniel J. Hofmann ee7bb8731a Expose concurrency between segment speeds and turn penalties 2016-05-19 00:01:54 +02:00
Daniel J. Hofmann da0c3ff394 Refactor edge weight parsing code 2016-05-19 00:01:54 +02:00
Daniel J. Hofmann 6ae559b42b Throw error if edge based graph file could not be loaded 2016-05-19 00:01:54 +02:00
Mathias Gug 95ca6ebdaa Update CHANGELOG entry. 2016-05-18 23:59:52 +02:00
Mathias Gug 0d6964d9c8 Add CHANGELOG entry. 2016-05-18 23:59:52 +02:00
Mathias Gug ba386d4b2c Document environment variable. 2016-05-18 23:59:52 +02:00
Mathias Gug b5ffb51e18 Signal the parent process when we're ready to serve requests.
This can be used for a hot reload of the process binary. The supervising
process can be told when the new process is ready to serve requests.
2016-05-18 23:59:52 +02:00
Moritz Kobitzsch a9f674497a emit turn-straight for obvious turns where the main road continues 2016-05-18 19:54:53 +02:00
Patrick Niklaus 1e8a92ccb4 Add changelog entry 2016-05-18 19:16:44 +02:00
Mathias Gug b9178bb8c7 Fix build on windows. 2016-05-18 19:13:18 +02:00
Mathias Gug 520b29d0d5 Use const for option. Include proper header files. 2016-05-18 19:13:18 +02:00
Mathias Gug fe397e6953 Support SO_REUSEPORT option
so that multiple osrm-routed processes can bind to the same port.
2016-05-18 19:13:18 +02:00
Patrick Niklaus dcb741d827 Merge pull request #2403 from oxidase/refactor/duration-parser
Refactoring of iso_8601_grammar
2016-05-17 12:26:28 -04:00
Michael Krasnyk 508c205d35 Refactoring of iso_8601_grammar
* formats 'hh:mm:ss' and ISO 8601 are merged into one grammar.
* iso_8601_grammar is changed to static const.
* iso_8601_grammar supports formats P[n]DT[n]H[n]M[n]S, P[n]W,
  and part of alternative PTHHMMSS and extended PTHH:MM:SS formats.
2016-05-17 00:39:32 +02:00
Daniel J. Hofmann d5294bb5d0 Silences warnings when running npm test 2016-05-16 14:43:54 -04:00
Patrick Niklaus 6ed9be31ca Merge pull request #2408 from oxidase/master
Remove latitude rounding in yToLat
2016-05-16 17:04:49 +02:00
Michael Krasnyk 3bbd3a8a65 Remove latitude rounding in yToLat 2016-05-16 00:53:33 +02:00
Daniel Patterson 73a608895a Merge pull request #2402 from Project-OSRM/fix_docker
Remove Ruby from docker setup, use Node.
2016-05-13 13:38:10 -07:00
Daniel Patterson 96c73baeb3 Remove Ruby from docker setup, use Node. 2016-05-13 12:32:36 -07:00
Patrick Niklaus 73113f5eb8 Fix codecov.yml 2016-05-12 17:56:40 +02:00
Patrick Niklaus 7b74b86891 Add codecov file 2016-05-12 01:17:16 +02:00
Daniel Patterson 0903b8227f Example of the annotation response value. 2016-05-12 01:11:09 +02:00
Daniel Patterson fa525ad610 Return an array with meta-data for each coordinate.
Currently supports duration and distance for each coordinate.

This is particularly useful in map-matching, comparing how
a trip progresses compared to a real GPS trace that is
map-matched.
2016-05-12 01:11:09 +02:00
Daniel J. Hofmann 0f2bb5dde5 Disable builing components tool by default until GDAL 2 compatibility #1738 lands 2016-05-12 00:25:18 +02:00
Patrick Niklaus 84dc1b6845 [skip ci] Use codecov badge 2016-05-11 22:45:07 +02:00
Patrick Niklaus 4ce1a37772 Limit osrm-extact to 3 jobs because OOM 2016-05-11 22:43:26 +02:00
Patrick Niklaus 8dd4cc5c40 Integrate codecov 2016-05-11 22:43:18 +02:00
Patrick Niklaus 6aed145dae [skip ci] Rephrased the API docs in terms of adding new types 2016-05-09 18:39:30 +02:00
Patrick Niklaus d15cc77b0b Merge pull request #2386 from oxidase/rtree-optimize-addition
Missing two commits in StaticRTree changes
2016-05-08 14:20:59 +02:00
Michael Krasnyk 24a75d37fb Approximate inverse Gudermannian function by a Padé approximant 2016-05-08 06:00:21 +02:00
Michael Krasnyk 7e80dae59b Fix MSVS build. 2016-05-08 06:00:21 +02:00
340 changed files with 14685 additions and 5754 deletions
+59 -23
View File
@@ -2,53 +2,89 @@
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
ConstructorInitializerIndentWidth: 4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: false
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: true
AlwaysBreakTemplateDeclarations: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterClass: true
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
BeforeCatch: true
BeforeElse: true
IndentBraces: true
BreakBeforeBinaryOperators: false
BreakBeforeBraces: Allman
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BinPackParameters: false
ColumnLimit: 100
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: false
DerivePointerBinding: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IncludeCategories:
- Regex: '^<'
Priority: 3
- Regex: '^"(osrm|util|engine|extract|contract)/'
Priority: 2
- Regex: '.*'
Priority: 1
IndentCaseLabels: false
MaxEmptyLinesToKeep: 1
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakString: 1000
PenaltyBreakFirstLessLess: 120
PenaltyExcessCharacter: 1000
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerBindsToType: false
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
Cpp11BracedListStyle: true
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
IndentWidth: 4
TabWidth: 8
UseTab: Never
BreakBeforeBraces: Allman
IndentFunctionDeclarationAfterType: false
SpacesInParentheses: false
SpacesInAngles: false
SpaceInEmptyParentheses: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: true
SpaceBeforeAssignmentOperators: true
ContinuationIndentWidth: 4
CommentPragmas: '^ IWYU pragma:'
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
SpaceBeforeParens: ControlStatements
...
+35 -15
View File
@@ -13,15 +13,19 @@ notifications:
branches:
only:
- master
- "5.3"
cache:
ccache: true
apt: true
directories:
- test/cache
env:
global:
- CCACHE_TEMPDIR=/tmp/.ccache-temp
- CCACHE_COMPRESS=1
- CASHER_TIME_OUT=1000
- JOBS=4
matrix:
@@ -37,7 +41,7 @@ matrix:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-5', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev', 'ccache']
env: CCOMPILER='gcc-5' CXXCOMPILER='g++-5' BUILD_TYPE='Debug'
env: CCOMPILER='gcc-5' CXXCOMPILER='g++-5' BUILD_TYPE='Debug' COVERAGE=ON
- os: linux
compiler: "gcc-4.8-debug"
@@ -51,9 +55,9 @@ matrix:
compiler: "clang-3.8-debug"
addons: &clang38
apt:
sources: ['llvm-toolchain-precise-3.8', 'ubuntu-toolchain-r-test']
packages: ['clang-3.8', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev', 'ccache']
env: CCOMPILER='clang-3.8' CXXCOMPILER='clang++-3.8' BUILD_TYPE='Debug' RUN_CLANG_FORMAT=ON
sources: ['ubuntu-toolchain-r-test']
packages: ['libstdc++-5-dev', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev', 'ccache']
env: CLANG_VERSION='3.8.0' BUILD_TYPE='Debug' RUN_CLANG_FORMAT=ON
- os: osx
osx_image: xcode7.3
@@ -69,6 +73,14 @@ matrix:
packages: ['g++-5', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev', 'ccache']
env: CCOMPILER='gcc-5' CXXCOMPILER='g++-5' BUILD_TYPE='Release'
- os: linux
compiler: "gcc-5-release-i686"
env: TARGET_ARCH='i686' CCOMPILER='gcc-5' CXXCOMPILER='g++-5' BUILD_TYPE='Release'
- os: linux
compiler: "gcc-4.8-release-armhf"
env: TARGET_ARCH='armhf' CCOMPILER='arm-linux-gnueabihf-gcc-4.8' CXXCOMPILER='arm-linux-gnueabihf-g++-4.8' BUILD_TYPE='Release'
# Disabled because of CI slowness
#- os: linux
#- compiler: gcc
@@ -112,22 +124,28 @@ matrix:
#- env: CCOMPILER='clang-3.8' CXXCOMPILER='clang++-3.8' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
before_install:
- if [[ ! -z $TARGET_ARCH ]] ; then source ./scripts/travis/before_install.$TARGET_ARCH.sh ; fi
- if [[ $(uname -s) == 'Darwin' ]]; then sudo mdutil -i off /; fi;
- source ./scripts/install_node.sh 4
- npm install
- DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
- mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR}
- export PATH=${DEPS_DIR}/bin:${PATH} && mkdir -p ${DEPS_DIR}
- CMAKE_URL="https://mason-binaries.s3.amazonaws.com/${TRAVIS_OS_NAME}-x86_64/cmake/3.5.2.tar.gz"
- travis_retry wget --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C ${DEPS_DIR} || exit 1
- |
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
CMAKE_URL="http://www.cmake.org/files/v3.5/cmake-3.5.1-Linux-x86_64.tar.gz"
mkdir cmake && travis_retry wget --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake
export PATH=${DEPS_DIR}/cmake/bin:${PATH}
elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
if [[ ${CLANG_VERSION:-false} != false ]]; then
export CCOMPILER='clang'
export CXXCOMPILER='clang++'
CLANG_URL="https://mason-binaries.s3.amazonaws.com/${TRAVIS_OS_NAME}-x86_64/clang/${CLANG_VERSION}.tar.gz"
travis_retry wget --quiet -O - ${CLANG_URL} | tar --strip-components=1 -xz -C ${DEPS_DIR} || exit 1
fi
- |
if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
# implicit deps, but seem to be installed by default with recent images: libxml2 GDAL boost
brew install cmake libzip libstxxl lua51 luabind tbb md5sha1sum ccache
brew install libzip libstxxl lua51 luabind tbb md5sha1sum ccache
fi
install:
- cd ${TRAVIS_BUILD_DIR}
- |
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
./scripts/check_taginfo.py taginfo.json profiles/car.lua
@@ -136,6 +154,7 @@ install:
- export CC=${CCOMPILER} CXX=${CXXCOMPILER}
- cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS:-OFF} -DCOVERAGE=${COVERAGE:-OFF} -DBUILD_TOOLS=1 -DENABLE_CCACHE=ON
- echo "travis_fold:start:MAKE"
- make osrm-extract --jobs=3
- make --jobs=${JOBS}
- make tests --jobs=${JOBS}
- make benchmarks --jobs=${JOBS}
@@ -148,11 +167,12 @@ install:
fi
- popd
- mkdir example/build && pushd example/build
- cmake ..
- cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
- make
- popd
script:
- if [[ $TARGET_ARCH == armhf ]] ; then echo "Skip tests for $TARGET_ARCH" && exit 0 ; fi
- echo "travis_fold:start:BENCHMARK"
- make -C test/data benchmark
- echo "travis_fold:end:BENCHMARK"
@@ -170,9 +190,9 @@ script:
after_success:
- |
if [ -n "${RUN_CLANG_FORMAT}" ]; then
./scripts/format.sh || true # we don't want to fail just yet
./scripts/format.sh # we don't want to fail just yet
fi
- |
if [ -n "${COVERAGE}" ]; then
coveralls --build-root build --exclude unit_tests --exclude third_party --exclude node_modules --gcov-options '\-lp'
bash <(curl -s https://codecov.io/bash)
fi
+176
View File
@@ -1,3 +1,179 @@
# 5.3.1
Changes from 5.3.1
- Bugfixes:
- Disabled broken lane handling for complex uturn/oneway combinations for now (190 intersections affected on the planet)
- Fixed a bug with overlaping geometries, which broke OSRM on recent Egypt extracts with data-modelling issues
# 5.3.0
Changes from 5.3.0-rc.3
- Guidance
- Only announce `use lane` on required turns (not using all lanes to go straight)
- Moved `lanes` to the intersection objects. This is BREAKING in relation to other Release Candidates but not with respect to other releases.
- Bugfixes
- Fix BREAKING: bug that could result in failure to load 'osrm.icd' files. This breaks the dataformat
- Fix: bug that results in segfaults when `use lane` instructions are suppressed
Changes form 5.2.7
- API
- Introduces new `TurnType` in the form of `use lane`. The type indicates that you have to stick to a lane without turning
- Introduces `lanes` to the `Intersection` object. The lane data contains both the markings at the intersection and a flag indicating if they can be chosen for the next turn
- Removed unused `-s` from `osrm-datastore`
- Guidance
- Only announce `use lane` on required turns (not using all lanes to go straight)
- Improved detection of obvious turns
- Improved turn lane detection
- Reduce the number of end-of-road instructions in obvious cases
- Profile:
- bicycle.lua: Surface speeds never increase the actual speed
- Infrastructure
- Add 32bit support
- Add ARM NEON/VFP support
- Fix Windows builds
- Optimize speed file updates using mmap
- Add option to disable LTO for older compilers
- BREAKING: The new turn type changes the turn-type order. This breaks the **data format**.
- BREAKING: Turn lane data introduces two new files (osrm.tld,osrm.tls). This breaks the fileformat for older versions.
- Bugfixes:
- Fix devide by zero on updating speed data using osrm-contract
# 5.3.0 RC3
Changes from 5.3.0-rc.2
- Guidance
- Improved detection of obvious turns
- Improved turn lane detection
- Bugfixes
- Fix bug that didn't chose minimal weights on overlapping edges
# 5.3.0 RC2
Changes from 5.3.0-rc.1
- Bugfixes
- Fixes invalid checks in the lane-extraction part of the car profile
# 5.3.0 RC1
- API
- Introduces new `TurnType` in the form of `use lane`. The type indicates that you have to stick to a lane without turning
- Introduces lanes to the route response. The lane data contains both the markings at the intersection and a flag indicating their involvement in the turn
- Infrastructure
- BREAKING: The new turn type changes the turn-type order. This breaks the **data format**.
- BREAKING: Turn lane data introduces two new files (osrm.tld,osrm.tls). This breaks the fileformat for older versions.
# 5.2.5
- Bugfixes
- Fixes a segfault caused by incorrect trimming logic for very short steps.
# 5.2.4
- Bugfixes:
- Fixed in issue that arised on roundabouts in combination with intermediate intersections and sliproads
# 5.2.3
- Bugfixes:
- Fixed an issue with name changes in roundabouts that could result in crashes
# 5.2.2
Changes from 5.2.1
- Bugfixes:
- Buffer overrun in tile plugin response handling
# 5.2.1
Changes from 5.2.0
- Bugfixes:
- Removed debug statement that was spamming the console
# 5.2.0
Changes from 5.2.0 RC2
- Bugfixes:
- Fixed crash when loading shared memory caused by invalid OSM IDs segment size.
- Various small instructions handling fixes
Changes from 5.1.0
- API:
- new parameter `annotations` for `route`, `trip` and `match` requests. Returns additional data about each
coordinate along the selected/matched route line per `RouteLeg`:
- duration of each segment
- distance of each segment
- OSM node ids of all segment endpoints
- Introducing Intersections for Route Steps. This changes the API format in multiple ways.
- `bearing_before`/`bearing_after` of `StepManeuver` are now deprecated and will be removed in the next major release
- `location` of `StepManeuvers` is now deprecated and will be removed in the next major release
- every `RouteStep` now has property `intersections` containing a list of `Intersection` objects.
- Support for destination signs. New member `destinations` in `RouteStep`, based on `destination` and `destination:ref`
- Support for name pronunciations. New member `pronunciation` in `RouteStep`, based on `name:pronunciation`
- Profile changes:
- duration parser now accepts P[n]DT[n]H[n]M[n]S, P[n]W, PTHHMMSS and PTHH:MM:SS ISO8601 formats.
- `result.destinations` allows you to set a way's destinations
- `result.pronunciation` allows you to set way name pronunciations
- `highway=motorway_link` no longer implies `oneway` as per the OSM Wiki
- Infrastructure:
- BREAKING: Changed the on-disk encoding of the StaticRTree to reduce ramIndex file size. This breaks the **data format**
- BREAKING: Intersection Classification adds a new file to the mix (osrm.icd). This breaks the fileformat for older versions.
- Better support for osrm-routed binary upgrade on the fly [UNIX specific]:
- Open sockets with SO_REUSEPORT to allow multiple osrm-routed processes serving requests from the same port.
- Add SIGNAL_PARENT_WHEN_READY environment variable to enable osrm-routed signal its parent with USR1 when it's running and waiting for requests.
- Disable http access logging via DISABLE_ACCESS_LOGGING environment variable.
- Guidance:
- BREAKING: modifies the file format with new internal identifiers
- improved detection of turning streets, not reporting new-name in wrong situations
- improved handling of sliproads (emit turns instead of 'take the ramp')
- improved collapsing of instructions. Some 'new name' instructions will be suppressed if they are without alternative and the segment is short
- Bugfixes
- fixed broken summaries for very short routes
# 5.2.0 RC2
Changes from 5.2.0 RC1
- Guidance:
- improved handling of sliproads (emit turns instead of 'take the ramp')
- improved collapsing of instructions. Some 'new name' instructions will be suppressed if they are without alternative and the segment is short
- BREAKING: modifies the file format with new internal identifiers
- API:
- paramater `annotate` was renamed to `annotations`.
- `annotation` as accidentally placed in `Route` instead of `RouteLeg`
- Support for destination signs. New member `destinations` in `RouteStep`, based on `destination` and `destination:ref`
- Support for name pronunciations. New member `pronunciation` in `RouteStep`, based on `name:pronunciation`
- Add `nodes` property to `annotation` in `RouteLeg` containing the ids of nodes covered by the route
- Profile changes:
- `result.destinations` allows you to set a way's destinations
- `result.pronunciation` allows you to set way name pronunciations
- `highway=motorway_link` no longer implies `oneway` as per the OSM Wiki
- Infrastructure
- BREAKING: Changed the on-disk encoding of the StaticRTree to reduce ramIndex file size. This breaks the **data format**
- Bugfixes
- fixed broken summaries for very short routes
# 5.2.0 RC1
Changes from 5.1.0
- API:
- new parameter `annotate` for `route` and `match` requests. Returns additional data about each
coordinate along the selected/matched route line.
- Introducing Intersections for Route Steps. This changes the API format in multiple ways.
- `bearing_before`/`bearing_after` of `StepManeuver` are now deprecated and will be removed in the next major release
- `location` of `StepManeuvers` is now deprecated and will be removed in the next major release
- every `RouteStep` now has property `intersections` containing a list of `Intersection` objects.
- Profile changes:
- duration parser now accepts P[n]DT[n]H[n]M[n]S, P[n]W, PTHHMMSS and PTHH:MM:SS ISO8601 formats.
- Infrastructure:
- Better support for osrm-routed binary upgrade on the fly [UNIX specific]:
- Open sockets with SO_REUSEPORT to allow multiple osrm-routed processes serving requests from the same port.
- Add SIGNAL_PARENT_WHEN_READY environment variable to enable osrm-routed signal its parent with USR1 when it's running and waiting for requests.
- BREAKING: Intersection Classification adds a new file to the mix (osrm.icd). This breaks the fileformat for older versions.
- Disable http access logging via DISABLE_ACCESS_LOGGING environment
variable.
- Guidance:
- improved detection of turning streets, not reporting new-name in wrong situations
# 5.1.0
Changes with regard to 5.0.0
+80 -37
View File
@@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 2.8.8)
cmake_minimum_required(VERSION 2.8.11)
# we depend on 2.8.11 introducing target_include_directories
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR AND NOT MSVC_IDE)
message(FATAL_ERROR "In-source builds are not allowed.
@@ -8,8 +9,24 @@ endif()
project(OSRM C CXX)
set(OSRM_VERSION_MAJOR 5)
set(OSRM_VERSION_MINOR 1)
set(OSRM_VERSION_PATCH 0)
set(OSRM_VERSION_MINOR 3)
set(OSRM_VERSION_PATCH 1)
# these two functions build up custom variables:
# OSRM_INCLUDE_PATHS and OSRM_DEFINES
# These variables we want to pass to
# include_directories and add_definitions for both
# this build and for sharing externally via pkg-config
function(add_dependency_includes includes)
list(APPEND OSRM_INCLUDE_PATHS "${includes}")
set(OSRM_INCLUDE_PATHS "${OSRM_INCLUDE_PATHS}" PARENT_SCOPE)
endfunction(add_dependency_includes)
function(add_dependency_defines defines)
list(APPEND OSRM_DEFINES "${defines}")
set(OSRM_DEFINES "${OSRM_DEFINES}" PARENT_SCOPE)
endfunction(add_dependency_defines)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include(CheckCXXCompilerFlag)
@@ -22,7 +39,7 @@ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(bitness 64)
message(STATUS "Building on a 64 bit system")
else()
message(WARNING "Building on a 32 bit system is unsupported")
message(STATUS "Building on a 32 bit system")
endif()
if(WIN32 AND MSVC_VERSION LESS 1900)
@@ -32,10 +49,11 @@ endif()
option(ENABLE_CCACHE "Speed up incremental rebuilds via ccache" ON)
option(ENABLE_JSON_LOGGING "Adds additional JSON debug logging to the response" OFF)
option(BUILD_TOOLS "Build OSRM tools" OFF)
option(BUILD_COMPONENTS "Build osrm-components" ON)
option(BUILD_COMPONENTS "Build osrm-components" OFF)
option(ENABLE_ASSERTIONS OFF)
option(COVERAGE OFF)
option(SANITIZER OFF)
option(ENABLE_LTO "Use LTO if available" ON)
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/include/)
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/include/)
@@ -54,7 +72,7 @@ configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/include/util/version.hpp.in
${CMAKE_CURRENT_BINARY_DIR}/include/util/version.hpp
)
file(GLOB UtilGlob src/util/*.cpp)
file(GLOB UtilGlob src/util/*.cpp src/util/*/*.cpp)
file(GLOB ExtractorGlob src/extractor/*.cpp src/extractor/*/*.cpp)
file(GLOB ContractorGlob src/contractor/*.cpp)
file(GLOB StorageGlob src/storage/*.cpp)
@@ -101,7 +119,7 @@ if(CMAKE_BUILD_TYPE MATCHES Release)
message(STATUS "Configuring OSRM in release mode")
# Check if LTO is available
check_cxx_compiler_flag("-flto" LTO_AVAILABLE)
if(LTO_AVAILABLE)
if(ENABLE_LTO AND LTO_AVAILABLE)
set(OLD_CXX_FLAGS ${CMAKE_CXX_FLAGS})
# GCC in addition allows parallelizing LTO
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
@@ -163,7 +181,7 @@ elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
# using GCC
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wuninitialized -Wunreachable-code -Wstrict-overflow=1 -D_FORTIFY_SOURCE=2 ${COLOR_FLAG} -fPIC")
if(WIN32) # using mingw
add_definitions(-DWIN32)
add_dependency_defines(-DWIN32)
set(OPTIONAL_SOCKET_LIBS ws2_32 wsock32)
endif()
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")
@@ -172,12 +190,12 @@ elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC")
# using Visual Studio C++
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} date_time chrono zlib)
add_definitions(-DBOOST_LIB_DIAGNOSTIC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
add_definitions(-DNOMINMAX) # avoid min and max macros that can break compilation
add_definitions(-D_USE_MATH_DEFINES) #needed for M_PI with cmath.h
add_definitions(-D_WIN32_WINNT=0x0501)
add_definitions(-DXML_STATIC)
add_dependency_defines(-DBOOST_LIB_DIAGNOSTIC)
add_dependency_defines(-D_CRT_SECURE_NO_WARNINGS)
add_dependency_defines(-DNOMINMAX) # avoid min and max macros that can break compilation
add_dependency_defines(-D_USE_MATH_DEFINES) #needed for M_PI with cmath.h
add_dependency_defines(-D_WIN32_WINNT=0x0501)
add_dependency_defines(-DXML_STATIC)
find_library(ws2_32_LIBRARY_PATH ws2_32)
target_link_libraries(osrm-extract wsock32 ws2_32)
endif()
@@ -204,7 +222,7 @@ set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${LINKER_FLAGS}")
# Activate C++11
if(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif()
# Configuring other platform dependencies
@@ -229,41 +247,54 @@ endif()
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/third_party/libosmium/cmake")
set(OSMIUM_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/libosmium/include")
find_package(Osmium REQUIRED COMPONENTS io)
include_directories(SYSTEM ${OSMIUM_INCLUDE_DIRS})
add_dependency_includes(${OSMIUM_INCLUDE_DIR})
find_package(Boost 1.49.0 REQUIRED COMPONENTS ${BOOST_COMPONENTS})
if(NOT WIN32)
add_definitions(-DBOOST_TEST_DYN_LINK)
# collect a subset of the boost libraries needed
# by libosrm
foreach(lib ${Boost_LIBRARIES})
if(NOT WIN32)
if(lib MATCHES filesystem OR lib MATCHES thread OR lib MATCHES iostreams OR lib MATCHES system)
list(APPEND BOOST_ENGINE_LIBRARIES "${lib}")
endif()
else()
list(APPEND BOOST_ENGINE_LIBRARIES "${lib}")
endif()
endforeach(lib)
if(NOT WIN32 AND NOT Boost_USE_STATIC_LIBS)
add_dependency_defines(-DBOOST_TEST_DYN_LINK)
endif()
add_definitions(-DBOOST_SPIRIT_USE_PHOENIX_V3)
add_definitions(-DBOOST_RESULT_OF_USE_DECLTYPE)
add_definitions(-DBOOST_FILESYSTEM_NO_DEPRECATED)
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
add_dependency_defines(-DBOOST_SPIRIT_USE_PHOENIX_V3)
add_dependency_defines(-DBOOST_RESULT_OF_USE_DECLTYPE)
add_dependency_defines(-DBOOST_FILESYSTEM_NO_DEPRECATED)
add_dependency_includes(${Boost_INCLUDE_DIRS})
find_package(Threads REQUIRED)
find_package(TBB REQUIRED)
include_directories(SYSTEM ${TBB_INCLUDE_DIR})
add_dependency_includes(${TBB_INCLUDE_DIR})
if(WIN32 AND CMAKE_BUILD_TYPE MATCHES Debug)
set(TBB_LIBRARIES ${TBB_DEBUG_LIBRARIES})
endif()
find_package(Luabind REQUIRED)
include(check_luabind)
include_directories(SYSTEM ${LUABIND_INCLUDE_DIR})
add_dependency_includes(${LUABIND_INCLUDE_DIR})
set(USED_LUA_LIBRARIES ${LUA_LIBRARY})
if(LUAJIT_FOUND)
set(USED_LUA_LIBRARIES, LUAJIT_LIBRARIES)
endif()
include_directories(SYSTEM ${LUA_INCLUDE_DIR})
add_dependency_includes(${LUA_INCLUDE_DIR})
find_package(EXPAT REQUIRED)
include_directories(SYSTEM ${EXPAT_INCLUDE_DIRS})
add_dependency_includes(${EXPAT_INCLUDE_DIRS})
find_package(STXXL REQUIRED)
include_directories(SYSTEM ${STXXL_INCLUDE_DIR})
add_dependency_includes(${STXXL_INCLUDE_DIR})
set(OpenMP_FIND_QUIETLY ON)
find_package(OpenMP)
@@ -273,20 +304,23 @@ if(OPENMP_FOUND)
endif()
find_package(BZip2 REQUIRED)
include_directories(SYSTEM ${BZIP_INCLUDE_DIRS})
add_dependency_includes(${BZIP2_INCLUDE_DIR})
find_package(ZLIB REQUIRED)
include_directories(SYSTEM ${ZLIB_INCLUDE_DIRS})
add_dependency_includes(${ZLIB_INCLUDE_DIRS})
if (ENABLE_JSON_LOGGING)
message(STATUS "Enabling json logging")
add_definitions(-DENABLE_JSON_LOGGING)
add_dependency_defines(-DENABLE_JSON_LOGGING)
endif()
add_definitions(${OSRM_DEFINES})
include_directories(SYSTEM ${OSRM_INCLUDE_PATHS})
# Binaries
target_link_libraries(osrm-datastore osrm_store ${Boost_LIBRARIES})
target_link_libraries(osrm-extract osrm_extract ${Boost_LIBRARIES})
target_link_libraries(osrm-contract osrm_contract ${Boost_LIBRARIES})
target_link_libraries(osrm-contract ${Boost_LIBRARIES} ${TBB_LIBRARIES} osrm_contract)
target_link_libraries(osrm-routed osrm ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} ${ZLIB_LIBRARY})
set(EXTRACTOR_LIBRARIES
@@ -311,12 +345,12 @@ set(CONTRACTOR_LIBRARIES
${MAYBE_RT_LIBRARY}
${MAYBE_COVERAGE_LIBRARIES})
set(ENGINE_LIBRARIES
${Boost_LIBRARIES}
${BOOST_ENGINE_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
${STXXL_LIBRARY}
${TBB_LIBRARIES}
${MAYBE_RT_LIBRARY}
${MAYBE_COVERAGE_LIBRARIES})
${MAYBE_COVERAGE_LIBRARIES}
${ZLIB_LIBRARY})
set(STORAGE_LIBRARIES
${Boost_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
@@ -412,14 +446,23 @@ foreach(lib ${ENGINE_LIBRARIES})
set(ENGINE_LIBRARY_LISTING "${ENGINE_LIBRARY_LISTING} -L${ENGINE_LIBRARY_PATH} -l${ENGINE_LIBRARY_NAME}")
endforeach()
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/pkgconfig.in libosrm.pc @ONLY)
install(FILES ${PROJECT_BINARY_DIR}/libosrm.pc DESTINATION lib/pkgconfig)
if(BUILD_DEBIAN_PACKAGE)
include(CPackDebianConfig)
include(CPack)
endif()
function(JOIN VALUES GLUE OUTPUT)
string (REPLACE ";" "${GLUE}" _TMP_STR "${VALUES}")
set (${OUTPUT} "${_TMP_STR}" PARENT_SCOPE)
endfunction()
# Set up variables, then write to pkgconfig file
JOIN("${OSRM_DEFINES}" " " OSRM_DEFINES_STRING)
JOIN("-I${OSRM_INCLUDE_PATHS}" " -I" OSRM_INCLUDE_PATHS_STRING)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/pkgconfig.in libosrm.pc @ONLY)
install(FILES ${PROJECT_BINARY_DIR}/libosrm.pc DESTINATION lib/pkgconfig)
# add a target to generate API documentation with Doxygen
find_package(Doxygen)
if(DOXYGEN_FOUND)
+55
View File
@@ -0,0 +1,55 @@
# User
Before you open a new issue, please search for older ones that cover the same issue.
In general "me too" comments/issues are frowned upon.
You can add a :+1: emoji to the issue if you want to express interest in this.
# Developer
We use `clang-format` version `3.8` to consistently format the code base. There is a helper script under `scripts/format.sh`.
In general changes that affect the API and/or increase the memory consumption need to be discussed first.
Often we don't include changes that would increase the memory consumption a lot if they are not generally usable (e.g. elevation data is a good example).
## Pull Request
Every pull-request that changes the API needs to update the docs in `docs/http.md` and add an entry to `CHANGELOG.md`.
Breaking changes need to have a BREAKING prefix. See the [releasing documentation](docs/releasing.md) on how this affects the version.
Early feedback is also important.
You will see that a lot of the PR have tags like `[not ready]` or `[wip]`.
We like to open PRs as soon as we are starting to work on something to make it visible to the rest of the team.
If your work is going in entirely the wrong direction, there is a good chance someone will pick up on this before it is too late.
Everyone is encouraged to read PRs of other people and give feedback.
For every significant code change we require a pull request review before it is merged.
If your pull request modifies the API this need to be signed of by a team discussion.
This means you will need to find another member of the team with commit access and request a review of your pull request.
Once your pull request is reviewed you can merge it! If you don't have commit access, ping someone that has commit access.
If you do have commit access there are in general two accepted styles to merging:
1. Make sure the branch is up to date with `master`. Run `git rebase master` to find out.
2. Once that is ensured you can either:
- Click the nice green merge button (for a non-fast-forward merge)
- Merge by hand using a fast-forward merge
Which merge you prefer is up to personal preference. In general it is recommended to use fast-forward merges because it creates a history that is sequential and easier to understand.
# Maintainer
## Doing a release
There is an in-depth guide around how to push out a release once it is ready [here](docs/releasing.md).
## The API
Changes to the API need to be discussed and signed off by the team. Breaking changes even more so than additive changes.
## Milestones
If a pull request or an issue is applicable for the current or next milestone, depends on the target version number.
Since we use semantic versioning we restrict breaking changes to major releases.
After a Release Candidate is released we usually don't change the API anymore if it is not critical.
Bigger code changes after a RC was released should also be avoided.
+3 -3
View File
@@ -8,7 +8,7 @@ The Open Source Routing Machine is a high performance routing engine written in
|:-------------|:-------|
| Linux | [![Build Status](https://travis-ci.org/Project-OSRM/osrm-backend.png?branch=master)](https://travis-ci.org/Project-OSRM/osrm-backend) |
| Windows | [![Build status](https://ci.appveyor.com/api/projects/status/4iuo3s9gxprmcjjh)](https://ci.appveyor.com/project/DennisOSRM/osrm-backend) |
| Coverage | [![Coverage Status](https://coveralls.io/repos/github/Project-OSRM/osrm-backend/badge.svg?branch=master)](https://coveralls.io/github/Project-OSRM/osrm-backend?branch=master) |
| Coverage | [![codecov](https://codecov.io/gh/Project-OSRM/osrm-backend/branch/master/graph/badge.svg)](https://codecov.io/gh/Project-OSRM/osrm-backend) |
## Building
@@ -46,7 +46,7 @@ osrm-routed data.osrm
Running a query on your local server:
```
curl http://127.0.0.1:5000/13.388860,52.517037;13.385983,52.496891?steps=true&alternatives=true
curl http://127.0.0.1:5000/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true&alternatives=true
```
### Running a request against the Demo Server
@@ -56,7 +56,7 @@ First read the [API usage policy](https://github.com/Project-OSRM/osrm-backend/w
Then run simple query with instructions and alternatives on Berlin:
```
curl https://router.project-osrm.org/13.388860,52.517037;13.385983,52.496891?steps=true&alternatives=true
curl https://router.project-osrm.org/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true&alternatives=true
```
## References in publications
+1
View File
@@ -280,4 +280,5 @@ if (TBB_FOUND)
FILE(READ "${TBB_INCLUDE_DIRS}/tbb/tbb_stddef.h" _TBB_VERSION_CONTENTS)
STRING(REGEX REPLACE ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1" TBB_INTERFACE_VERSION "${_TBB_VERSION_CONTENTS}")
set(TBB_INTERFACE_VERSION "${TBB_INTERFACE_VERSION}")
message(STATUS "TBB interface version: ${TBB_INTERFACE_VERSION}")
endif (TBB_FOUND)
+1 -1
View File
@@ -8,4 +8,4 @@ Version: v@OSRM_VERSION_MAJOR@.@OSRM_VERSION_MINOR@.@OSRM_VERSION_PATCH@
Requires:
Libs: -L${libdir} -losrm
Libs.private: @ENGINE_LIBRARY_LISTING@
Cflags: -I${includedir} -I${includedir}/osrm
Cflags: -I${includedir} -I${includedir}/osrm @OSRM_INCLUDE_PATHS_STRING@ @OSRM_DEFINES_STRING@ @CMAKE_CXX_FLAGS@
+7
View File
@@ -0,0 +1,7 @@
coverage:
ignore:
- unit_tests/.*
- third_party/.*
comment: off
+10 -11
View File
@@ -1,19 +1,18 @@
FROM ubuntu:14.04
RUN apt-get update -y
RUN apt-get install -y build-essential git-core python-pip python-software-properties software-properties-common
RUN apt-get update -y && apt-get install -y software-properties-common
RUN add-apt-repository ppa:ubuntu-toolchain-r/test
RUN apt-get update -y && apt-get install -y g++-5 libbz2-dev libstxxl-dev libstxxl1 libxml2-dev libzip-dev lua5.1 liblua5.1-0-dev libtbb-dev libgdal-dev libluabind-dev libboost-all-dev ccache
RUN apt-get -y install curl cmake cmake-curses-gui git
RUN apt-get -y install gcc-4.8 g++-4.8 libboost1.55-all-dev llvm-3.4
RUN apt-get -y install libbz2-dev libstxxl-dev libstxxl1 libxml2-dev
RUN apt-get -y install libzip-dev lua5.1 liblua5.1-0-dev libtbb-dev libgdal-dev ruby1.9
RUN apt-get -y install curl cmake cmake-curses-gui
RUN pip install awscli
# luabind
RUN curl https://gist.githubusercontent.com/DennisOSRM/f2eb7b948e6fe1ae319e/raw/install-luabind.sh | sudo bash
WORKDIR /opt
RUN git clone --depth 1 --branch v0.31.0 https://github.com/creationix/nvm.git
RUN /bin/bash -c "source /opt/nvm/nvm.sh && nvm install v4"
RUN useradd -ms /bin/bash mapbox
USER mapbox
ENV HOME /home/mapbox
WORKDIR /home/mapbox
RUN echo "source /opt/nvm/nvm.sh" > .bashrc
RUN echo "source /home/mapbox/.bashrc" > .profile
+1 -1
View File
@@ -8,4 +8,4 @@ docker run \
-e "CXX=clang++" \
-v `pwd`:/home/mapbox/osrm-backend \
-t mapbox/osrm:linux \
osrm-backend/docker/test.sh
/bin/bash -lc "osrm-backend/docker/test.sh"
+3 -2
View File
@@ -5,7 +5,8 @@ set -o pipefail
docker run \
-i \
-e "CXX=g++" \
-e "CXX=g++-5" \
-e "CC=gcc-5" \
-v `pwd`:/home/mapbox/osrm-backend \
-t mapbox/osrm:linux \
osrm-backend/docker/test.sh
/bin/bash -lc "osrm-backend/docker/test.sh"
+5 -6
View File
@@ -4,11 +4,8 @@ set -e
set -o pipefail
export CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Release"
export PATH=$PATH:/home/mapbox/.gem/ruby/1.9.1/bin:/home/mapbox/osrm-backend/vendor/bundle/ruby/1.9.1/bin
cd /home/mapbox/osrm-backend
gem install --user-install bundler
bundle install --path vendor/bundle
[ -d build ] && rm -rf build
mkdir -p build
cd build
@@ -16,7 +13,9 @@ cmake .. $CMAKEOPTIONS -DBUILD_TOOLS=1
make -j`nproc`
make tests -j`nproc`
./datastructure-tests
./algorithm-tests
#./unit_tests/server-tests
#./unit_tests/library-tests
#./unit_tests/extractor-tests
#./unit_tests/util-tests
cd ..
bundle exec cucumber -p verify
npm test
+173 -42
View File
@@ -1,3 +1,18 @@
## Environent Variables
### SIGNAL_PARENT_WHEN_READY
If the SIGNAL_PARENT_WHEN_READY environment variable is set osrm-routed will
send the USR1 signal to its parent when it will be running and waiting for
requests. This could be used to upgrade osrm-routed to a new binary on the fly
without any service downtime - no incoming requests will be lost.
### DISABLE_ACCESS_LOGGING
If the DISABLE_ACCESS_LOGGING environment variable is set osrm-routed will
**not** log any http requests to standard output. This can be useful in high
traffic setup.
## HTTP API
`osrm-routed` supports only `GET` requests of the form. If you your response size
@@ -136,7 +151,7 @@ http://router.project-osrm.org/nearest/v1/driving/13.388860,52.517037?number=3&b
### Request
```
http://{server}/route/v1/{profile}/{coordinates}?alternatives={true|false}&steps={true|false}&geometries={polyline|geojson}&overview={full|simplified|false}
http://{server}/route/v1/{profile}/{coordinates}?alternatives={true|false}&steps={true|false}&geometries={polyline|geojson}&overview={full|simplified|false}&annotations={true|false}
```
In addition to the [general options](#general-options) the following options are supported for this service:
@@ -145,6 +160,7 @@ In addition to the [general options](#general-options) the following options are
|------------|------------------------------------------|-------------------------------------------------------------------------------|
|alternatives|`true`, `false` (default) |Search for alternative routes and return as well.\* |
|steps |`true`, `false` (default) |Return route steps for each route leg |
|annotations |`true`, `false` (default) |Returns additional metadata for each coordinate along the route geometry. |
|geometries |`polyline` (default), `geojson` |Returned route geometry format (influences overview and per step) |
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
|continue_straight |`default` (default), `true`, `false`|Forces the route to keep going straight at waypoints and don't do a uturn even if it would be faster. Default value depends on the profile. |
@@ -237,7 +253,7 @@ The algorithm might not be able to match all points. Outliers are removed if the
### Request
```
http://{server}/match/v1/{profile}/{coordinates}?steps={true|false}&geometries={polyline|geojson}&overview={simplified|full|false}
http://{server}/match/v1/{profile}/{coordinates}?steps={true|false}&geometries={polyline|geojson}&overview={simplified|full|false}&annotations={true|false}
```
In addition to the [general options](#general-options) the following options are supported for this service:
@@ -247,6 +263,7 @@ In addition to the [general options](#general-options) the following options are
|------------|------------------------------------------------|------------------------------------------------------------------------------------------|
|steps |`true`, `false` (default) |Return route steps for each route |
|geometries |`polyline` (default), `geojson` |Returned route geometry format (influences overview and per step) |
|annotations |`true`, `false` (default) |Returns additional metadata for each coordinate along the route geometry. |
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
|timestamps |`{timestamp};{timestamp}[;{timestamp} ...]` |Timestamp of the input location. |
|radiuses |`{radius};{radius}[;{radius} ...]` |Standard deviation of GPS precision used for map matching. If applicable use GPS accuracy.|
@@ -284,7 +301,7 @@ multiple trips for each connected component are returned.
### Request
```
http://{server}/trip/v1/{profile}/{coordinates}?steps={true|false}&geometries={polyline|geojson}&overview={simplified|full|false}
http://{server}/trip/v1/{profile}/{coordinates}?steps={true|false}&geometries={polyline|geojson}&overview={simplified|full|false}&annotations={true|false}
```
In addition to the [general options](#general-options) the following options are supported for this service:
@@ -292,6 +309,7 @@ In addition to the [general options](#general-options) the following options are
|Option |Values |Description |
|------------|------------------------------------------------|---------------------------------------------------------------------------|
|steps |`true`, `false` (default) |Return route instructions for each trip |
|annotations |`true`, `false` (default) |Returns additional metadata for each coordinate along the route geometry. |
|geometries |`polyline` (default), `geojson` |Returned route geometry format (influences overview and per step) |
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
@@ -339,7 +357,7 @@ Three input coordinates, `geometry=geojson`, `steps=false`:
{
"distance": 90.0,
"duration": 300.0,
"geometry": {"type": "LineString", "coordinates": [[120., 10.], [120.1, 10.], [120.2, 10.], [120.3, 10.]]},
"geometry": {"type": "LineString", "coordinates": [[120.0, 10.0], [120.1, 10.0], [120.2, 10.0], [120.3, 10.0]]},
"legs": [
{
"distance": 30.0,
@@ -377,15 +395,27 @@ Represents a route between two waypoints.
| true | array of `RouteStep` objects describing the turn-by-turn instructions |
| false | empty array |
- `annotation`: Additional details about each coordinate along the route geometry:
| annotations | |
|--------------|-----------------------------------------------------------------------|
| true | returns distance and durations of each coordinate along the route |
| false | will not exist |
#### Example
With `steps=false`:
With `steps=false` and `annotations=true`:
```json
{
"distance": 30.0,
"duration": 100.0,
"steps": []
"steps": [],
"annotation": {
"distance": [5,5,10,5,5],
"duration": [15,15,40,15,15],
"nodes": [49772551,49772552,49786799,49786800,49786801,49786802]
}
}
```
@@ -407,11 +437,47 @@ step.
| geojson | [GeoJSON `LineString`](http://geojson.org/geojson-spec.html#linestring) or [GeoJSON `Point`](http://geojson.org/geojson-spec.html#point) if it is only one coordinate (not wrapped by a GeoJSON feature)|
- `name`: The name of the way along which travel proceeds.
- `pronunciation`: The pronunciation hint of the way name. Will be `undefined` if there is no pronunciation hit.
- `destinations`: The destinations of the way. Will be `undefined` if there are no destinations.
- `mode`: A string signifying the mode of transportation.
- `maneuver`: A `StepManeuver` object representing the maneuver.
- `intersections`: A list of `Intersection` objects that are passed along the segment, the very first belonging to the StepManeuver
#### Example
```
{
"distance":152.3,
"duration":15.6,
"name":"Lortzingstraße",
"maneuver":{
"type":"turn",
"modifier":"right",
},
"geometry":"{lu_IypwpAVrAvAdI",
"mode":"driving",
"intersections":[
{"location":[13.39677,52.54366],
"in":3,
"out":2,
"bearings":[10,92,184,270],
"entry":["true","true","true","false"],
"lanes":[
{"indications":["left","straight"], "valid":"false"},
{"indications":["right"], "valid":"true"}
]},
{"location":[13.394718,52.543096],
"in":0,
"out":1,
"bearings":[60,240,330],
"entry":["false","true","true"]
"lanes":[
{"indications":["straight"], "valid":"true"},
{"indications":["right"], "valid":"false"}
]}
]}
```
### StepManeuver
#### Properties
@@ -421,62 +487,127 @@ step.
direction of travel immediately before the maneuver.
- `bearing_after`: The clockwise angle from true north to the
direction of travel immediately after the maneuver.
- `type` A string indicating the type of maneuver
- `type` A string indicating the type of maneuver. **new identifiers might be introduced without API change**
Types unknown to the client should be handled like the `turn` type, the existance of correct `modifier` values is guranteed.
| `type` | Description |
|-------------------|--------------------------------------------------------------|
| turn | a basic turn into direction of the `modifier` |
| new name | no turn is taken, but the road name changes. The Road can take a turn itself, following `modifier` |
| depart | indicates the departure of the leg |
| arrive | indicates the destination of the leg |
| merge | merge onto a street (e.g. getting on the highway from a ramp, the `modifier specifies the direction of the merge`) |
| ramp | **Deprecated**. Replaced by `on_ramp` and `off_ramp`. |
| on ramp | take a ramp to enter a highway (direction given my `modifier`) |
| off ramp | take a ramp to exit a highway (direction given my `modifier`) |
| fork | take the left/right side at a fork depending on `modifier` |
| end of road | road ends in a T intersection turn in direction of `modifier`|
| continue | Turn in direction of `modifier` to stay on the same road |
| roundabout | traverse roundabout, has additional field `exit` with NR if the roundabout is left. `the modifier specifies the direction of entering the roundabout` |
| rotary | a larger version of a roundabout, can offer `rotary_name` in addition to the `exit` parameter. |
| roundabout turn | Describes a turn at a small roundabout that should be treated as normal turn. The `modifier` indicates the turn direciton. Example instruction: `At the roundabout turn left`. |
| notification | not an actual turn but a change in the driving conditions. For example the travel mode. If the road takes a turn itself, the `modifier` describes the direction |
| `type` | Description |
|------------------|--------------------------------------------------------------|
| `turn` | a basic turn into direction of the `modifier` |
| `new name` | no turn is taken/possible, but the road name changes. The road can take a turn itself, following `modifier`. |
| `depart` | indicates the departure of the leg |
| `arrive` | indicates the destination of the leg |
| `merge` | merge onto a street (e.g. getting on the highway from a ramp, the `modifier specifies the direction of the merge`) |
| `ramp` | **Deprecated**. Replaced by `on_ramp` and `off_ramp`. |
| `on ramp` | take a ramp to enter a highway (direction given my `modifier`) |
| `off ramp` | take a ramp to exit a highway (direction given my `modifier`) |
| `fork` | take the left/right side at a fork depending on `modifier` |
| `end of road` | road ends in a T intersection turn in direction of `modifier`|
| `use lane` | going straight on a specific lane |
| `continue` | Turn in direction of `modifier` to stay on the same road |
| `roundabout` | traverse roundabout, has additional field `exit` with NR if the roundabout is left. `the modifier specifies the direction of entering the roundabout` |
| `rotary` | a larger version of a roundabout, can offer `rotary_name` in addition to the `exit` parameter. |
| `roundabout turn`| Describes a turn at a small roundabout that should be treated as normal turn. The `modifier` indicates the turn direciton. Example instruction: `At the roundabout turn left`. |
| `notification` | not an actual turn but a change in the driving conditions. For example the travel mode. If the road takes a turn itself, the `modifier` describes the direction |
Please note that even though there are `new name` and `notification` instructions, the `mode` and `name` can change
between all instructions. They only offer a fallback in case nothing else is to report.
- `modifier` An optional `string` indicating the direction change of the maneuver.
| `modifier` | Description |
|-------------------|-------------------------------------------|
| uturn | indicates reversal of direction |
| sharp right | a sharp right turn |
| right | a normal turn to the right |
| slight right | a slight turn to the right |
| straight | no relevant change in direction |
| slight left | a slight turn to the left |
| left | a normal turn to the left |
| sharp left | a sharp turn to the left |
The list of turns without a modifier is limited to: `depart/arrive`. If the source/target location is close enough to the `depart/arrive` location, no modifier will be given.
| `uturn` | indicates reversal of direction |
| `sharp right` | a sharp right turn |
| `right` | a normal turn to the right |
| `slight right` | a slight turn to the right |
| `straight` | no relevant change in direction |
| `slight left` | a slight turn to the left |
| `left` | a normal turn to the left |
| `sharp left` | a sharp turn to the left |
The list of turns without a modifier is limited to: `depart/arrive`. If the source/target location is close enough to the `depart/arrive` location, no modifier will be given.
The meaning depends on the `type` field.
| `type` | Description |
|------------------------|---------------------------------------------------------------------------------------------------------------------------|
| `turn` | `modifier` indicates the change in direction accomplished through the turn |
| `depart`/`arrive` | `modifier` indicates the position of departure point and arrival point in relation to the current direction of travel |
- `exit` An optional `integer` indicating number of the exit to take. The field exists for the following `type` field:
| `type` | Description |
|------------------------|---------------------------------------------------------------------------------------------------------------------------|
| `roundabout` | Number of the roundabout exit to take. If exit is `undefined` the destination is on the roundabout. |
| `turn` or `end of road`| Indicates the number of intersections passed until the turn. Example instruction: `at the fourth intersection, turn left` |
| else | Indicates the number of intersections passed until the turn. Example instruction: `at the fourth intersection, turn left` |
New maneuver `type` and `modifier` and new properties (potentially depending on `type`) may be introduced in the future without an API version change.
New properties (potentially depending on `type`) may be introduced in the future without an API version change.
### Lane
A `Lane` represents a turn lane at the corresponding turn location.
#### Properties
- `indications`: a indication (e.g. marking on the road) specifying the turn lane. A road can have multiple indications (e.g. an arrow pointing straight and left). The indications are given in an array, each containing one of the following types. Further indications might be added on without an API version change.
| `value` | Description |
|------------------------|---------------------------------------------------------------------------------------------------------------------------|
| `none` | No dedicated indication is shown. |
| `uturn` | An indication signaling the possibility to reverse (i.e. fully bend arrow). |
| `sharp right` | An indication indicating a sharp right turn (i.e. strongly bend arrow). |
| `right` | An indication indicating a right turn (i.e. bend arrow). |
| `slight right` | An indication indicating a slight right turn (i.e. slightly bend arrow). |
| `straight` | No dedicated indication is shown (i.e. straight arrow). |
| `slight left` | An indication indicating a slight left turn (i.e. slightly bend arrow). |
| `left` | An indication indicating a left turn (i.e. bend arrow). |
| `sharp left` | An indication indicating a sharp left turn (i.e. strongly bend arrow). |
- `valid`: a boolean flag indicating whether the lane is a valid choice in the current maneuver
#### Example
```json
{
"indications": ["left", "straight"],
"valid": "false"
}
```
### Intersection
An intersection gives a full representation of any cross-way the path passes bay. For every step, the very first intersection (`intersections[0]`) corresponds to the
location of the StepManeuver. Further intersections are listed for every cross-way until the next turn instruction.
#### Properties
- `location`: A `[longitude, latitude]` pair describing the location of the turn.
- `bearings`: A list of bearing values (e.g. [0,90,180,270]) that are available at the intersection. The bearings describe all available roads at the intersection.
- `entry`: A list of entry flags, corresponding in a 1:1 relationship to the bearings. A value of `true` indicates that the respective road could be entered on a valid route.
`false` indicates that the turn onto the respective road would violate a restriction.
- `in`: index into bearings/entry array. Used to calculate the bearing just before the turn. Namely, the clockwise angle from true north to the
direction of travel immediately before the maneuver/passing the intersection. Bearings are given relative to the intersection. To get the bearing
in the direction of driving, the bearing has to be rotated by a value of 180. The value is not supplied for `depart` maneuvers.
- `out`: index into the bearings/entry array. Used to extract the bearing just after the turn. Namely, The clockwise angle from true north to the
direction of travel immediately after the maneuver/passing the intersection. The value is not supplied for `arrive` maneuvers.
- `lanes`: Array of `Lane` objects that denote the available turn lanes at the turn location
#### Example
```
{
"location":[13.394718,52.543096],
"in":0,
"out":2,
"bearings":[60,150,240,330],
"entry":["false","true","true","true"]
"lanes":{
"indications": ["left", "straight"],
"valid": "false"
}
]}
}
```
### Waypoint
+239
View File
@@ -0,0 +1,239 @@
# Testsuite
OSRM comes with a testsuite containing both unit-tests using the Boost library and cucucmber.js for scenario driven testing.
## Unit Tests
For a general introduction on Boost.Test have a look at [its docs](http://www.boost.org/doc/libs/1_60_0/libs/test/doc/html/index.html).
### Separate Test Binaries
Unit tests should be registered according to the sub-project they're in.
If you want to write tests for utility functions, add them to the utility test binary.
See `CMakeLists.txt` in the unit test directory for how to register new unit tests.
### Using Boost.Test Primitives
There is a difference between only reporting a failed condition and aborting the test right at a failed condition.
Have a look at [`BOOST_CHECK` vs `BOOST_REQUIRE`](http://www.boost.org/doc/libs/1_60_0/libs/test/doc/html/boost_test/utf_reference/testing_tool_ref/assertion_boost_level.html).
Instead of manually checking e.g. for equality, less than, if a function throws etc. use their [corresponding Boost.Test primitives](http://www.boost.org/doc/libs/1_60_0/libs/test/doc/html/boost_test/utf_reference/testing_tool_ref.html).
If you use `BOOST_CHECK_EQUAL` you have to implement `operator<<` for your type so that Boost.Test can print mismatches.
If you do not want to do this, define `BOOST_TEST_DONT_PRINT_LOG_VALUE` (and undef it after the check call) or sidestep it with `BOOST_CHECK(fst == snd);`.
### Test Fixture
If you need to test features on a real dataset (think about this twice: prefer cucumber and dataset-independent tests for their reproducibility and minimality), there is a fixed dataset in `test/data`.
This dataset is a small extract and may not even contain all tags or edge cases.
Furthermore this dataset is not in sync with what you see in up-to-date OSM maps or on the demo server.
See the library tests for how to add new dataset dependent tests.
## Cucumber
For a general introduction on cucumber in our testsuite, have a look at [the wiki](https://github.com/Project-OSRM/osrm-backend/wiki/Cucumber-Test-Suite).
This documentation aims to supply a guideline on how to write cucumber tests that test new features introduced into osrm.
### Test the feature
It is often tempting to reduce the test to a path and accompanying instructions. Instructions can and will change over the course of improving guidance.
Instructions should only be used when writing a feature located in `features/guidance`. All other features should avoid using instructions at all.
### Write Tests to Scale
OSRM is a navigation engine. Tests should always consider this background.
An important implication is the grid size. If tests use a very small grid size, you run into the chance of instructions being omitted.
For example:
```
Background:
Given the profile "car"
Given a grid size of 10 meters
Scenario: Testbot - Straight Road
Given the node map
| a | b | c | d |
And the ways
| nodes | highway |
| ab | primary |
| bc | primary |
| cd | primary |
When I route I should get
| from | to | route |
| a | d | ab,bc,cd,cd |
```
In a navigation engine, the instructions
- depart east on ab
- in 10 meters the road name changes to bc
- in 10 meters the road name changes to cd
- you arrived at cd
would be impossible to announce and not helpful at all.
Since no actual choices exist, the route you get could result in `ab,cd` and simply say `depart` and `arrive`.
To prevent such surprises, always consider the availability of other roads and use grid sizes/road lengths that correspond to actually reasonable scenarios in a road network.
### Use names
If you specify many nodes in close succession to present a specific road geometry, consider using `name` to indicate to OSRM that the segment is a single road.
```
Background:
Given the profile "car"
Given a grid size of 10 meters
Scenario: Testbot - Straight Road
Given the node map
| a | b | c | d |
And the ways
| nodes | highway | name |
| ab | primary | road |
| bc | primary | road |
| cd | primary | road |
When I route I should get
| from | to | route | turns |
| a | d | road,road | depart,arrive |
```
Guidance guarantees only essential maneuvers. You will always see `depart` and `arrive` as well as all turns that are not obvious.
So the following scenario does not change the instructions
```
Background:
Given the profile "car"
Given a grid size of 10 meters
Scenario: Testbot - Straight Road
Given the node map
| a | b |
| d | c |
And the ways
| nodes | highway | name |
| ab | primary | road |
| bc | primary | road |
| cd | primary | road |
When I route I should get
| from | to | route | turns |
| a | d | road,road | depart,arrive |
```
but if we modify it to
```
Background:
Given the profile "car"
Given a grid size of 10 meters
Scenario: Testbot - Straight Road
Given the node map
| a | b | e |
| d | c | |
And the ways
| nodes | highway | name |
| ab | primary | road |
| bc | primary | road |
| cd | primary | road |
| be | primary | turn |
When I route I should get
| from | to | route | turns |
| a | d | road,road,road | depart,continue right,arrive |
```
### Test all directions
Modelling a road as roundabout has an implied oneway tag associated with it. In the following case, we can route from `a` to `d` but not from `d` to `a`.
To discover those errors, make sure to check for all allowed directions.
```
Scenario: Enter and Exit mini roundabout with sharp angle # features/guidance/mini-roundabout.feature:37
Given the profile "car" # features/step_definitions/data.js:8
Given a grid size of 10 meters # features/step_definitions/data.js:20
Given the node map # features/step_definitions/data.js:45
| a | b | |
| | c | d |
And the ways # features/step_definitions/data.js:128
| nodes | highway | name |
| ab | tertiary | MySt |
| bc | roundabout | |
| cd | tertiary | MySt |
When I route I should get # features/step_definitions/routing.js:4
| from | to | route | turns | # |
| a | d | MySt,MySt | depart,arrive | # suppress multiple enter/exit mini roundabouts |
| d | a | MySt,MySt | depart,arrive | # suppress multiple enter/exit mini roundabouts |
Tables were not identical:
| from | to | route | turns | #
| a | d | MySt,MySt | depart,arrive | # suppress multiple enter/exit mini roundabouts |
| (-) d | (-) a | (-) MySt,MySt | (-) depart,arrive | (-) # suppress multiple enter/exit mini roundabouts |
| (+) d | (+) a | (+) | (+) | (+) # suppress multiple enter/exit mini roundabouts |
```
### Prevent Randomness
Some features in OSRM can result in strange experiences during testcases. To prevent some of these issues, follow the guidelines below.
#### Use Waypoints
Using grid nodes as waypoints offers the chance of unwanted side effects.
OSRM converts the grid into a so called edge-based graph.
```
Scenario: Testbot - Intersection
Given the node map
| | e | |
| b | a | d |
| | c | |
And the ways
| nodes | highway | oneway |
| ab | primary | yes |
| ac | primary | yes |
| ad | primary | yes |
| ae | primary | yes |
```
Selecting `a` as a `waypoint` results in four possible starting locations. Which one of the routes `a,b`, `a,c`, `a,d`, or `a,e` is found is pure chance and depends on the order in the static `r-tree`.
To guarantee discovery, use:
```
Scenario: Testbot - Intersection
Given the node map
| | | e | | |
| | | 4 | | |
| b | 1 | a | 3 | d |
| | | 2 | | |
| | | c | | |
And the ways
| nodes | highway | oneway |
| ab | primary | yes |
| ac | primary | yes |
| ad | primary | yes |
| ae | primary | yes |
```
And use `1`,`2`,`3`, and `4` as starting waypoints. The routes `1,b`, `2,c`, `3,d`, and `4,e` can all be discovered.
#### Allow For Small Offsets
Whenever you are independent of the start location (see use waypoints), the waypoint chosen as start/end location can still influence distances/durations.
If you are testing for a duration metric, allow for a tiny offset to ensure a passing test in the presence of rounding/snapping issues.
#### Don't Rely on Alternatives
Alternative route discovery is a random feature in itself. The discovery of routes depends on the contraction order of roads and cannot be assumed successful, ever.
+8 -5
View File
@@ -6,10 +6,13 @@ Please create a directory and run cmake from there, passing the path to this sou
This process created the file `CMakeCache.txt' and the directory `CMakeFiles'. Please delete them.")
endif()
if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
set(CMAKE_BUILD_TYPE Release)
endif()
project(osrm-example C CXX)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ")
set(bitness 32)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
@@ -23,11 +26,11 @@ if(WIN32 AND MSVC_VERSION LESS 1900)
message(FATAL_ERROR "Building with Microsoft compiler needs Latest Visual Studio 2015 (Community or better)")
endif()
link_directories(${LibOSRM_LIBRARY_DIRS})
add_executable(osrm-example example.cpp)
find_package(LibOSRM REQUIRED)
find_package(Boost 1.49.0 COMPONENTS filesystem system thread REQUIRED)
target_link_libraries(osrm-example ${LibOSRM_LIBRARIES} ${Boost_LIBRARIES})
include_directories(SYSTEM ${LibOSRM_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
target_link_libraries(osrm-example ${LibOSRM_LIBRARIES} ${LibOSRM_DEPENDENT_LIBRARIES})
include_directories(SYSTEM ${LibOSRM_INCLUDE_DIRS})
set(CMAKE_CXX_FLAGS ${LibOSRM_CXXFLAGS})
+24 -26
View File
@@ -1,13 +1,24 @@
# - Try to find LibOSRM
# Once done this will define
# LibOSRM_FOUND - System has LibOSRM
# LibOSRM_INCLUDE_DIRS - The LibOSRM include directories
# LibOSRM_LIBRARIES - The libraries needed to use LibOSRM
# LibOSRM_DEFINITIONS - Compiler switches required for using LibOSRM
# LibOSRM_LIBRARIES - The libraries and ldflags needed to use LibOSRM
# LibOSRM_DEPENDENT_LIBRARIES - The libraries and ldflags need to link LibOSRM dependencies
# LibOSRM_LIBRARY_DIRS - The libraries paths needed to find LibOSRM
# LibOSRM_CXXFLAGS - Compiler switches required for using LibOSRM
find_package(PkgConfig)
pkg_check_modules(PC_LibOSRM QUIET libosrm)
set(LibOSRM_DEFINITIONS ${PC_LibOSRM_CFLAGS_OTHER})
pkg_search_module(PC_LibOSRM QUIET libosrm)
function(JOIN VALUES GLUE OUTPUT)
string (REPLACE ";" "${GLUE}" _TMP_STR "${VALUES}")
set (${OUTPUT} "${_TMP_STR}" PARENT_SCOPE)
endfunction()
list(REMOVE_ITEM PC_LibOSRM_CFLAGS " ")
JOIN("${PC_LibOSRM_CFLAGS}" " " output)
set(LibOSRM_CXXFLAGS ${output})
set(LibOSRM_LIBRARY_DIRS ${PC_LibOSRM_LIBRARY_DIRS})
find_path(LibOSRM_INCLUDE_DIR osrm/osrm.hpp
PATH_SUFFIXES osrm include/osrm include
@@ -19,8 +30,6 @@ find_path(LibOSRM_INCLUDE_DIR osrm/osrm.hpp
/opt/local
/opt)
set(LibOSRM_INCLUDE_DIRS ${LibOSRM_INCLUDE_DIR} ${LibOSRM_INCLUDE_DIR}/osrm)
find_library(TEST_LibOSRM_STATIC_LIBRARY Names osrm.lib libosrm.a
PATH_SUFFIXES osrm lib/osrm lib
HINTS ${PC_LibOSRM_LIBDIR} ${PC_LibOSRM_LIBRARY_DIRS}
@@ -30,7 +39,7 @@ find_library(TEST_LibOSRM_STATIC_LIBRARY Names osrm.lib libosrm.a
/usr
/opt/local
/opt)
find_library(TEST_LibOSRM_DYNAMIC_LIBRARY Names osrm.dynlib libosrm.so
find_library(TEST_LibOSRM_DYNAMIC_LIBRARY Names libosrm.dylib libosrm.so
PATH_SUFFIXES osrm lib/osrm lib
HINTS ${PC_LibOSRM_LIBDIR} ${PC_LibOSRM_LIBRARY_DIRS}
~/Library/Frameworks
@@ -40,26 +49,15 @@ find_library(TEST_LibOSRM_DYNAMIC_LIBRARY Names osrm.dynlib libosrm.so
/opt/local
/opt)
if (NOT ("${TEST_LibOSRM_STATIC_LIBRARY}" STREQUAL "TEST_LibOSRM_STATIC_LIBRARY-NOTFOUND"))
if ("${PC_LibOSRM_STATIC_LIBRARIES}" STREQUAL "")
set(LibOSRM_STATIC_LIBRARIES ${TEST_LibOSRM_STATIC_LIBRARY})
else()
set(LibOSRM_STATIC_LIBRARIES ${PC_LibOSRM_STATIC_LIBRARIES})
endif()
set(LibOSRM_LIBRARIES ${LibOSRM_STATIC_LIBRARIES})
endif()
if (NOT ("${TEST_LibOSRM_DYNAMIC_LIBRARY}" STREQUAL "TEST_LibOSRM_DYNAMIC_LIBRARY-NOTFOUND"))
if ("${PC_LibOSRM_LIBRARIES}" STREQUAL "")
set(LibOSRM_DYNAMIC_LIBRARIES ${TEST_LibOSRM_DYNAMIC_LIBRARY})
else()
set(LibOSRM_DYNAMIC_LIBRARIES ${PC_LibOSRM_LIBRARIES})
endif()
set(LibOSRM_LIBRARIES ${LibOSRM_DYNAMIC_LIBRARIES})
endif()
set(LibOSRM_DEPENDENT_LIBRARIES ${PC_LibOSRM_STATIC_LDFLAGS})
set(LibOSRM_LIBRARIES ${PC_LibOSRM_LDFLAGS})
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LIBOSRM_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(LibOSRM DEFAULT_MSG
LibOSRM_LIBRARIES LibOSRM_INCLUDE_DIR)
LibOSRM_LIBRARY_DIRS
LibOSRM_CXXFLAGS
LibOSRM_LIBRARIES
LibOSRM_DEPENDENT_LIBRARIES
LibOSRM_INCLUDE_DIR)
+7 -7
View File
@@ -1,20 +1,20 @@
#include "osrm/match_parameters.hpp"
#include "osrm/nearest_parameters.hpp"
#include "osrm/route_parameters.hpp"
#include "osrm/table_parameters.hpp"
#include "osrm/nearest_parameters.hpp"
#include "osrm/trip_parameters.hpp"
#include "osrm/match_parameters.hpp"
#include "osrm/coordinate.hpp"
#include "osrm/engine_config.hpp"
#include "osrm/json_container.hpp"
#include "osrm/status.hpp"
#include "osrm/osrm.hpp"
#include "osrm/status.hpp"
#include <exception>
#include <iostream>
#include <string>
#include <utility>
#include <iostream>
#include <exception>
#include <cstdlib>
@@ -40,8 +40,8 @@ int main(int argc, const char *argv[]) try
RouteParameters params;
// Route in monaco
params.coordinates.push_back({util::FloatLongitude(7.419758), util::FloatLatitude(43.731142)});
params.coordinates.push_back({util::FloatLongitude(7.419505), util::FloatLatitude(43.736825)});
params.coordinates.push_back({util::FloatLongitude{7.419758}, util::FloatLatitude{43.731142}});
params.coordinates.push_back({util::FloatLongitude{7.419505}, util::FloatLatitude{43.736825}});
// Response is in JSON format
json::Object result;
+5 -2
View File
@@ -46,14 +46,17 @@ Feature: Bike - Mode flag
Scenario: Bike - Mode when pushing bike against oneways
Given the node map
| a | b | |
| | c | d |
| a | b | e |
| f | c | d |
And the ways
| nodes | highway | oneway |
| ab | primary | |
| bc | primary | yes |
| cd | primary | |
| be | primary | |
| cf | primary | |
When I route I should get
| from | to | route | modes |
+18 -16
View File
@@ -18,8 +18,8 @@ Feature: Bike - Oneway streets
Scenario: Bike - Around the Block
Given the node map
| a | b |
| d | c |
| | a | b | |
| f | d | c | e |
And the ways
| nodes | oneway | foot |
@@ -27,6 +27,8 @@ Feature: Bike - Oneway streets
| bc | | no |
| cd | | no |
| da | | no |
| df | | no |
| ce | | no |
When I route I should get
| from | to | route |
@@ -48,22 +50,22 @@ Feature: Bike - Oneway streets
Scenario: Bike - Implied oneways
Then routability should be
| highway | foot | bicycle | junction | forw | backw |
| | no | | | x | x |
| | no | | roundabout | x | |
| motorway | no | yes | | x | |
| motorway_link | no | yes | | x | |
| motorway | no | yes | roundabout | x | |
| motorway_link | no | yes | roundabout | x | |
| highway | foot | bicycle | junction | forw | backw | # |
| | no | | | x | x | |
| | no | | roundabout | x | | |
| motorway | no | yes | | x | | |
| motorway_link | no | yes | | x | x | does not imply oneway |
| motorway | no | yes | roundabout | x | | |
| motorway_link | no | yes | roundabout | x | | |
Scenario: Bike - Overriding implied oneways
Then routability should be
| highway | foot | junction | oneway | forw | backw |
| primary | no | roundabout | no | x | x |
| primary | no | roundabout | yes | x | |
| motorway_link | no | | -1 | | |
| trunk_link | no | | -1 | | |
| primary | no | roundabout | -1 | | x |
| highway | foot | junction | oneway | forw | backw |
| primary | no | roundabout | no | x | x |
| primary | no | roundabout | yes | x | |
| motorway_link | no | | -1 | | |
| trunk_link | no | | -1 | | |
| primary | no | roundabout | -1 | | x |
Scenario: Bike - Oneway:bicycle should override normal oneways tags
Then routability should be
@@ -115,7 +117,7 @@ Feature: Bike - Oneway streets
Scenario: Bike - Two consecutive oneways
Given the node map
| a | b | c |
| a | b | | c |
And the ways
| nodes | oneway |
+4 -2
View File
@@ -87,14 +87,16 @@ Feature: Bike - Accessability of different way types
Scenario: Bike - Instructions when pushing bike on oneways
Given the node map
| a | b | |
| | c | d |
| a | b | e |
| f | c | d |
And the ways
| nodes | highway | oneway |
| ab | primary | |
| bc | primary | yes |
| cd | primary | |
| be | primary | |
| cf | primary | |
When I route I should get
| from | to | route | modes |
+17
View File
@@ -38,3 +38,20 @@ Feature: Bike - Surfaces
| cycleway | | 48s |
| nosense | | |
| nosense | asphalt | |
Scenario: Bicycle - Surfaces should not increase speed when pushing bikes
Given the node map
| a | b |
| c | d |
And the ways
| nodes | highway | oneway | surface |
| ab | primary | yes | asphalt |
| cd | footway | | asphalt |
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 |
+17
View File
@@ -18,6 +18,23 @@ Feature: Car - Street names in instructions
| from | to | route |
| a | c | My Way,Your Way (A1),Your Way (A1) |
Scenario: Car - A named street with pronunciation
Given the node map
| a | b | d |
| | 1 | |
| | c | |
And the ways
| nodes | name |name:pronunciation | ref |
| ab | My Way | | |
| bd | My Way | meyeway | A1 |
| cd | Your Way | yourewaye | |
When I route I should get
| from | to | route | pronunciations |
| a | d | My Way,My Way (A1) | ,meyeway |
| 1 | c | Your Way,Your Way | yourewaye,yourewaye |
@todo
Scenario: Car - Use way type to describe unnamed ways
Given the node map
+17 -13
View File
@@ -17,24 +17,26 @@ Feature: Car - Oneway streets
Scenario: Car - Implied oneways
Then routability should be
| highway | junction | forw | backw |
| motorway | | x | |
| motorway_link | | x | |
| primary | | x | x |
| motorway | roundabout | x | |
| motorway_link | roundabout | x | |
| primary | roundabout | x | |
| highway | junction | forw | backw | # |
| motorway | | x | | |
| motorway_link | | x | x | does not imply oneway |
| primary | | x | x | |
| motorway | roundabout | x | | |
| motorway_link | roundabout | x | | |
| primary | roundabout | x | | |
Scenario: Car - Overrule implied oneway
Then routability should be
| highway | oneway | forw | backw |
| motorway | no | x | x |
| motorway_link | no | x | x |
| highway | oneway | forw | backw | # |
| motorway | no | x | x | |
| motorway_link | no | x | x | |
| motorway_link | yes | x | | |
| motorway_link | | x | x | does not imply onway |
Scenario: Car - Around the Block
Given the node map
| a | b |
| d | c |
| | a | b | |
| f | d | c | e |
And the ways
| nodes | oneway |
@@ -42,6 +44,8 @@ Feature: Car - Oneway streets
| bc | |
| cd | |
| da | |
| ce | |
| df | |
When I route I should get
| from | to | route |
@@ -66,7 +70,7 @@ Feature: Car - Oneway streets
Scenario: Car - Two consecutive oneways
Given the node map
| a | b | c |
| a | b | | c |
And the ways
| nodes | oneway |
+1
View File
@@ -5,6 +5,7 @@ Feature: Car - Turn restrictions
Background: Use car routing
Given the profile "car"
Given a grid size of 200 meters
@no_turning
Scenario: Car - No left turn
+26 -28
View File
@@ -12,19 +12,17 @@ Feature: Traffic - turn penalties
| nodes | highway |
| ad | primary |
| cd | primary |
| de | primary |
| def | primary |
| dhk | primary |
| bf | primary |
| ef | primary |
| fg | primary |
| fim | primary |
| jk | primary |
| kl | primary |
| klm | primary |
| ko | primary |
| lm | primary |
| mn | primary |
| mp | primary |
And the profile "car"
@@ -32,22 +30,22 @@ Feature: Traffic - turn penalties
Scenario: Weighting not based on turn penalty file
When I route I should get
| from | to | route | speed | time |
| a | h | ad,dhk,dhk | 63 km/h | 11.5s +-1 |
| from | to | route | speed | time |
| a | h | ad,dhk,dhk | 63 km/h | 11.5s +-1 |
# straight
| i | g | fim,fg,fg | 59 km/h | 12s +-1 |
| i | g | fim,fg,fg | 59 km/h | 12s +-1 |
# right
| a | e | ad,de,de | 57 km/h | 12.5s +-1 |
| a | e | ad,def,def | 57 km/h | 12.5s +-1 |
# left
| c | g | cd,de,ef,fg,fg | 63 km/h | 23s +-1 |
| c | g | cd,def,fg,fg | 63 km/h | 23s +-1 |
# double straight
| p | g | mp,fim,fg,fg | 61 km/h | 23.5s +-1 |
| p | g | mp,fim,fg,fg | 61 km/h | 23.5s +-1 |
# straight-right
| a | l | ad,dhk,kl,kl | 60 km/h | 24s +-1 |
| a | l | ad,dhk,klm,klm | 60 km/h | 24s +-1 |
# straight-left
| l | e | kl,dhk,de,de | 59 km/h | 24.5s +-1 |
| l | e | klm,dhk,def,def | 59 km/h | 24.5s +-1 |
# double right
| g | n | fg,fim,mn,mn | 57 km/h | 25s +-1 |
| g | n | fg,fim,mn,mn | 57 km/h | 25s +-1 |
# double left
Scenario: Weighting based on turn penalty file
@@ -62,24 +60,24 @@ Feature: Traffic - turn penalties
"""
And the contract extra arguments "--turn-penalty-file penalties.csv"
When I route I should get
| from | to | route | speed | time |
| a | h | ad,dhk,dhk | 63 km/h | 11.5s +-1 |
| from | to | route | speed | time |
| a | h | ad,dhk,dhk | 63 km/h | 11.5s +-1 |
# straight
| i | g | fim,fg,fg | 55 km/h | 13s +-1 |
| i | g | fim,fg,fg | 55 km/h | 13s +-1 |
# right - ifg penalty
| a | e | ad,de,de | 64 km/h | 11s +-1 |
| a | e | ad,def,def | 64 km/h | 11s +-1 |
# left - faster because of negative ade penalty
| c | g | cd,de,ef,fg,fg | 63 km/h | 23s +-1 |
| c | g | cd,def,fg,fg | 63 km/h | 23s +-1 |
# double straight
| p | g | mp,fim,fg,fg | 59 km/h | 24.5s +-1 |
| p | g | mp,fim,fg,fg | 59 km/h | 24.5s +-1 |
# straight-right - ifg penalty
| a | l | ad,de,ef,fim,lm,lm | 61 km/h | 35.5s +-1 |
| a | l | ad,def,fim,klm,klm | 61 km/h | 35.5s +-1 |
# was straight-left - forced around by hkl penalty
| l | e | lm,fim,ef,ef | 57 km/h | 25s +-1 |
| l | e | klm,fim,def,def | 57 km/h | 25s +-1 |
# double right - forced left by lkh penalty
| g | n | fg,fim,mn,mn | 30 km/h | 47.5s +-1 |
| g | n | fg,fim,mn,mn | 30 km/h | 47.5s +-1 |
# double left - imn penalty
| j | c | jk,kl,lm,fim,ef,de,cd,cd | 60 km/h | 48s +-1 |
| j | c | jk,klm,fim,def,cd,cd | 60 km/h | 48s +-1 |
# double left - hdc penalty ever so slightly higher than imn; forces all the way around
Scenario: Too-negative penalty clamps, but does not fail
@@ -90,8 +88,8 @@ Feature: Traffic - turn penalties
1,4,5,-10
"""
When I route I should get
| from | to | route | time |
| a | d | ad,ad | 10s +-1 |
| a | e | ad,de,de | 10s +-1 |
| b | f | bf,bf | 10s +-1 |
| b | g | bf,fg,fg | 20s +-1 |
| from | to | route | time |
| a | d | ad,ad | 10s +-1 |
| a | e | ad,def,def | 10s +-1 |
| b | f | bf,bf | 10s +-1 |
| b | g | bf,fg,fg | 20s +-1 |
+500
View File
@@ -0,0 +1,500 @@
@routing @guidance @turn-lanes
Feature: Turn Lane Guidance
Background:
Given the profile "car"
Given a grid size of 20 meters
@anticipate
Scenario: Anticipate Lane Change for subsequent multi-lane intersections
Given the node map
| a | | b | | x | | |
| | | | | | | |
| | | c | | d | | z |
| | | | | | | |
| | | y | | e | | |
And the ways
| nodes | turn:lanes:forward |
| ab | through\|right\|right\|right |
| bx | |
| bc | left\|left\|through |
| cd | through\|right |
| cy | |
| dz | |
| de | |
When I route I should get
| waypoints | route | turns | lanes | # |
| a,d | ab,bc,cd,cd | depart,turn right,turn left,arrive | ,straight:false right:true right:true right:false,left:true left:true straight:false, | 2 hops |
| a,e | ab,bc,cd,de,de | depart,turn right,turn left,turn right,arrive | ,straight:false right:false right:true right:false,left:false left:true straight:false,straight:false right:true, | 3 hops |
@anticipate
Scenario: Anticipate Lane Change for quick same direction turns, staying on the same street
Given the node map
| a | | b | x |
| | | | |
| | | c | |
| | | | |
| e | | d | y |
And the ways
| nodes | turn:lanes:forward | turn:lanes:backward | name |
| ab | through\|right\|right | | MySt |
| bx | | | XSt |
| bc | | left\|right | MySt |
| cd | left\|right | through\|through | MySt |
| de | | left\|left\|through | MySt |
| dy | | | YSt |
When I route I should get
| waypoints | route | turns | lanes |
| a,e | MySt,MySt,MySt,MySt | depart,continue right,turn right,arrive | ,straight:false right:false right:true,left:false right:true, |
| e,a | MySt,MySt,MySt,MySt | depart,continue left,turn left,arrive | ,left:true left:false straight:false,left:true right:false, |
@anticipate
Scenario: Anticipate Lane Change for quick same direction turns, changing between streets
Given the node map
| a | | b | x |
| | | | |
| | | c | |
| | | | |
| e | | d | y |
And the ways
| nodes | turn:lanes:forward | turn:lanes:backward | name |
| ab | through\|right\|right | | AXSt |
| bx | | | AXSt |
| bc | | left\|right | BDSt |
| cd | left\|right | through\|through | BDSt |
| de | | left\|left\|through | EYSt |
| dy | | | EYSt |
When I route I should get
| waypoints | route | turns | lanes |
| a,e | AXSt,BDSt,EYSt,EYSt | depart,turn right,turn right,arrive | ,straight:false right:false right:true,left:false right:true, |
| e,a | EYSt,BDSt,AXSt,AXSt | depart,turn left,turn left,arrive | ,left:true left:false straight:false,left:true right:false, |
@anticipate
Scenario: Anticipate Lane Change for quick turns during a merge
Given the node map
| a | | | | |
| x | b | | c | y |
| | | | | d |
And the ways
| nodes | turn:lanes:forward | name | highway | oneway |
| ab | slight_left\|slight_left | On | motorway_link | yes |
| xb | | Hwy | motorway | |
| bc | through\|slight_right | Hwy | motorway | |
| cd | | Off | motorway_link | yes |
| cy | | Hwy | motorway | |
When I route I should get
| waypoints | route | turns | lanes |
| a,d | On,Hwy,Off,Off | depart,merge slight right,off ramp right,arrive | ,slight left:false slight left:true,straight:false slight right:true, |
@anticipate
Scenario: Schoenefelder Kreuz
# https://www.openstreetmap.org/way/264306388#map=16/52.3202/13.5568
Given the node map
| a | b | x | | | i |
| | | c | d | | |
| | | | | | j |
And the ways
| nodes | turn:lanes:forward | lanes | highway | oneway | name |
| ab | none\|none\|none\|slight_right\|slight_right | 5 | motorway | | abx |
| bx | | 3 | motorway | | abx |
| bc | | 2 | motorway_link | yes | bcd |
| cd | slight_left\|slight_left;slight_right\|slight_right | 3 | motorway_link | yes | bcd |
| di | slight_left\|slight_right | 2 | motorway_link | yes | di |
| dj | | 2 | motorway_link | yes | dj |
When I route I should get
| waypoints | route | turns | lanes |
| a,i | abx,bcd,di,di | depart,off ramp right,fork slight left,arrive | ,none:false none:false none:false slight right:true slight right:true,slight left:true slight left;slight right:true slight right:false, |
| a,j | abx,bcd,dj,dj | depart,off ramp right,fork slight right,arrive | ,none:false none:false none:false slight right:true slight right:true,slight left:false slight left;slight right:true slight right:true, |
@anticipate
Scenario: Kreuz Oranienburg
# https://www.openstreetmap.org/way/4484007#map=18/52.70439/13.20269
Given the node map
| i | | | | | a |
| j | | c | b | | x |
And the ways
| nodes | turn:lanes:forward | lanes | highway | oneway | name |
| ab | | 1 | motorway_link | yes | ab |
| xb | | 1 | motorway_link | yes | xbcj |
| bc | none\|slight_right | 2 | motorway_link | yes | xbcj |
| ci | | 1 | motorway_link | yes | ci |
| cj | | 1 | motorway_link | yes | xbcj |
When I route I should get
| waypoints | route | turns | lanes |
| a,i | ab,xbcj,ci,ci | depart,merge slight left,turn slight right,arrive | ,,none:false slight right:true, |
| a,j | ab,xbcj,xbcj | depart,merge slight left,arrive | ,, |
@anticipate
Scenario: Lane anticipation for fan-in
Given the node map
| a | | b | | x | | |
| | | | | | | |
| | | c | | d | | z |
| | | | | | | |
| | | y | | e | | |
And the ways
| nodes | turn:lanes:forward | name |
| ab | through\|right\|right\|right | abx |
| bx | | abx |
| bc | left\|left\|through | bcy |
| cy | | bcy |
| cd | through\|right | cdz |
| dz | | cdz |
| de | | de |
When I route I should get
| waypoints | route | turns | lanes |
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,straight:false right:false right:true right:false,left:false left:true straight:false,straight:false right:true, |
@anticipate
Scenario: Lane anticipation for fan-out
Given the node map
| a | | b | | x | | |
| | | | | | | |
| | | c | | d | | z |
| | | | | | | |
| | | y | | e | | |
And the ways
| nodes | turn:lanes:forward | name |
| ab | through\|right | abx |
| bx | | abx |
| bc | left\|left\|through | bcy |
| cy | | bcy |
| cd | through\|right\|right\|right | cdz |
| dz | | cdz |
| de | | de |
When I route I should get
| waypoints | route | turns | lanes |
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,straight:false right:true,left:true left:true straight:false,straight:false right:true right:true right:true, |
@anticipate
Scenario: Lane anticipation for fan-in followed by fan-out
Given the node map
| a | | b | | x | | |
| | | | | | | |
| | | c | | d | | z |
| | | | | | | |
| | | y | | e | | |
And the ways
| nodes | turn:lanes:forward | name |
| ab | through\|right\|right\|right | abx |
| bx | | abx |
| bc | left\|left\|through | bcy |
| cy | | bcy |
| cd | through\|right\|right\|right | cdz |
| dz | | cdz |
| de | | de |
When I route I should get
| waypoints | route | turns | lanes |
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,straight:false right:true right:true right:false,left:true left:true straight:false,straight:false right:true right:true right:true, |
@anticipate
Scenario: Lane anticipation for fan-out followed by fan-in
Given the node map
| a | | b | | x | | |
| | | | | | | |
| | | c | | d | | z |
| | | | | | | |
| | | y | | e | | |
And the ways
| nodes | turn:lanes:forward | name |
| ab | through\|right | abx |
| bx | | abx |
| bc | left\|left\|through | bcy |
| cy | | bcy |
| cd | through\|right | cdz |
| dz | | cdz |
| de | | de |
When I route I should get
| waypoints | route | turns | lanes |
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,straight:false right:true,left:false left:true straight:false,straight:false right:true, |
@anticipate
Scenario: Lane anticipation for multiple hops with same number of lanes
Given the node map
| a | | b | | x | | |
| | | | | | | |
| | | c | | d | | z |
| | | | | | | |
| | | y | | e | | f |
| | | | | | | |
| | | | | w | | |
And the ways
| nodes | turn:lanes:forward | name |
| ab | through\|right\|right\|right | abx |
| bx | | abx |
| bc | left\|left\|through | bcy |
| cy | | bcy |
| cd | through\|right\|right | cdz |
| dz | | cdz |
| de | left\|through | dew |
| ew | | dew |
| ef | | ef |
When I route I should get
| waypoints | route | turns | lanes |
| a,f | abx,bcy,cdz,dew,ef,ef | depart,turn right,turn left,turn right,turn left,arrive | ,straight:false right:false right:true right:false,left:false left:true straight:false,straight:false right:true right:false,left:true straight:false, |
@anticipate @todo @bug @2661
Scenario: Anticipate with lanes in roundabout: roundabouts as the unit of anticipation
Given the node map
| | | e | | |
| a | b | | d | f |
| | | c | | |
| | | | | |
| | | g | | |
| k | h | | j | l |
| | | i | | |
And the ways
| nodes | turn:lanes:forward | highway | junction | # |
| ab | slight_right\|slight_right\|slight_right | primary | | |
| bc | slight_left\|slight_right\|slight_right | primary | roundabout | top |
| cd | | primary | roundabout | top |
| de | | primary | roundabout | top |
| eb | | primary | roundabout | top |
| df | | primary | | |
| cg | slight_right\|slight_right | primary | | |
| gh | slight_left\|slight_right | primary | roundabout | bot |
| hi | | primary | roundabout | bot |
| ij | slight_left\|slight_right | primary | roundabout | bot |
| jg | | primary | roundabout | bot |
| hk | | primary | | |
| jl | | primary | | |
When I route I should get
| # | waypoints | route | turns | lanes |
| right-right | a,k | ab,cg,hk,hk | depart,roundabout-exit-1,roundabout-exit-1,arrive | ,slight right:false slight right:false slight right:true,slight right:false slight right:true, |
| right-left | a,l | ab,cg,jl,jl | depart,roundabout-exit-1,roundabout-exit-2,arrive | ,slight right:false slight right:false slight right:true,slight right:false slight right:true, |
| todo exits | a,f | ab,df,df | depart,roundabout-exit-2,arrive | ,slight right:false slight right:false slight right:true, |
| todo exits | a,e | ab,bc,eb | depart,roundabout-exit-undefined,arrive | ,slight right:true slight right:true slight right:true, |
@anticipate @todo
Scenario: Roundabout with lanes only tagged on exit
Given the node map
| | | e | | |
| a | b | | d | f |
| | | c | | |
And the ways
| nodes | turn:lanes:forward | highway | junction |
| ab | | primary | |
| bc | | primary | roundabout |
| cd | slight_left\|slight_left\|slight_right | primary | roundabout |
| de | | primary | roundabout |
| eb | | primary | roundabout |
| df | | primary | |
When I route I should get
| waypoints | route | turns | lanes |
| a,f | ab,df,df | depart,roundabout-exit-1,use lane slight right,arrive | ,,slight left:false slight left:false slight right:true, |
@anticipate
Scenario: Anticipate with lanes in roundabout where we stay on the roundabout for multiple exits
Given the node map
| | | a | | |
| | | b | | |
| | c | | g | h |
| | | | | |
| | d | | f | |
| | | e | | |
| x | | | | y |
And the ways
| nodes | turn:lanes:forward | highway | junction |
| ab | slight_right\|slight_right | primary | |
| bc | | primary | roundabout |
| cd | | primary | roundabout |
| de | | primary | roundabout |
| ef | | primary | roundabout |
| fg | slight_right | primary | roundabout |
| gb | | primary | roundabout |
| gh | | primary | |
| cx | | primary | |
| dx | | primary | |
| ey | | primary | |
| fy | | primary | |
When I route I should get
| waypoints | route | turns | lanes |
| a,h | ab,gh,gh | depart,roundabout-exit-5,arrive | ,slight right:false slight right:true, |
@anticipate
Scenario: Departing or arriving inside a roundabout does not yet anticipate lanes
Given the node map
| | | a | | |
| x | b | | d | y |
| | | c | | |
And the ways
| nodes | turn:lanes:forward | highway | junction | name |
| xb | slight_right\|slight_right | primary | | xb |
| dy | | primary | | dy |
| ab | | primary | roundabout | roundabout |
| bc | | primary | roundabout | roundabout |
| cd | left\|slight_right | primary | roundabout | roundabout |
| da | | primary | roundabout | roundabout |
When I route I should get
| waypoints | route | turns | lanes |
| x,y | xb,dy,dy | depart,roundabout-exit-1,arrive | ,slight right:false slight right:true, |
| x,c | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,slight right:true slight right:true, |
| x,a | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,slight right:true slight right:true, |
@anticipate
Scenario: Departing or arriving inside a roundabout does not yet anticipate lanes (BIG version)
Given the node map
| | | a | | |
| x | b | | d | y |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | c | | |
And the ways
| nodes | turn:lanes:forward | highway | junction | name |
| xb | slight_right\|slight_right | primary | | xb |
| dy | | primary | | dy |
| ab | | primary | roundabout | roundabout |
| bc | | primary | roundabout | roundabout |
| cd | left\|slight_right | primary | roundabout | roundabout |
| da | | primary | roundabout | roundabout |
When I route I should get
| waypoints | route | turns | lanes |
| x,y | xb,dy,dy | depart,roundabout-exit-1,arrive | ,slight right:false slight right:true, |
| x,c | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,slight right:true slight right:true, |
| x,a | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,slight right:true slight right:true, |
@anticipate
Scenario: Anticipate Lanes for turns before and / or after roundabout
Given the node map
| a | b | | | x |
| | c | | | |
| d | | f | g | z |
| | e | | h | |
| | | | | |
| | y | | | |
And the ways
| nodes | turn:lanes:forward | highway | junction | name |
| ab | through\|right\|right\|right\|right | primary | | abx |
| bx | | primary | | abx |
| bc | right\|right\|right\|right | primary | | bc |
| cd | | primary | roundabout | cdefc |
| de | slight_left\|slight_left&slight_left\|slight_right | primary | roundabout | cdefc |
| ef | left\|slight_right\|slight_right | primary | roundabout | cdefc |
| fc | | primary | roundabout | cdefc |
| ey | | primary | | ey |
| fg | through\|right | primary | | fg |
| gz | | primary | | gz |
| gh | | primary | | gh |
When I route I should get
| waypoints | route | turns | lanes |
| a,h | abx,bc,fg,gh,gh | depart,turn right,cdefc-exit-2,turn right,arrive | ,straight:false right:false right:false right:false right:true,right:false right:false right:false right:true,straight:false right:true, |
@anticipate @bug @todo
Scenario: Tripple Right keeping Left
Given the node map
| a | | | | b | | i |
| | | | | | | |
| | | | | | | |
| f | | e | | | | g |
| | | | | | | |
| | | | | | | |
| | j | d | | c | | |
| | | | | h | | |
And the ways
| nodes | turn:lanes:forward | highway | name |
| abi | \|\|right\|right | primary | start |
| bch | \|\|right\|right | primary | first |
| cdj | \|\|right\|right | primary | second |
| de | left\|right\|right | secondary | third |
| feg | | tertiary | fourth |
When I route I should get
| waypoints | route | turns | lanes |
| a,f | start,first,second,third,fourth,fourth | depart,turn right,turn right,turn right,end of road left,arrive | ,none:false none:true right:false right:false,none:false none:true right:false right:false,none:false none:true right:false right:false,left:true right:false right:false, |
| a,g | start,first,second,third,fourth,fourth | depart,turn right,turn right,turn right,end of road right,arrive | ,none:false none:false right:true right:true,none:false none:false right:true right:true,none:false none:false right:true right:true,left:false right:true right:true, |
@anticipate @bug @todo
Scenario: Tripple Left keeping Right
Given the node map
| i | | b | | | | a |
| | | | | | | |
| | | | | | | |
| g | | | | e | | f |
| | | | | | | |
| | | | | | | |
| | | c | | d | j | |
| | | h | | | | |
And the ways
| nodes | turn:lanes:forward | highway | name |
| abi | left\|left\|\| | primary | start |
| bch | left\|left\|\| | primary | first |
| cdj | left\|left\|\| | primary | second |
| de | left\|left\|right | secondary | third |
| feg | | tertiary | fourth |
When I route I should get
| waypoints | route | turns | lanes |
| a,f | start,first,second,third,fourth,fourth | depart,turn left,turn left,turn left,end of road right,arrive | ,left:false left:false none:true none:false,left:false left:false none:true none:false,left:false left:false none:true none:false,left:false left:false right:true, |
| a,g | start,first,second,third,fourth,fourth | depart,turn left,turn left,turn left,end of road left,arrive | ,left:true left:true none:false none:false,left:true left:true none:false none:false,left:true left:true none:false none:false,left:true left:true right:false, |
+286 -1
View File
@@ -344,4 +344,289 @@ Feature: Collapse
| waypoints | route | turns |
| a,d | first,first,first,first | depart,continue left,continue right,arrive |
| a,e | first,second,second | depart,turn left,arrive |
| a,f | first,third,third | depart,new name straight,arrive |
| a,f | first,third,third | depart,turn straight,arrive |
Scenario: Bridge on unnamed road
Given the node map
| a | b | | | | c | d |
And the ways
| nodes | highway | name |
| ab | primary | |
| bc | primary | Bridge |
| cd | primary | |
When I route I should get
| waypoints | route | turns |
| a,d | , | depart,arrive |
Scenario: Crossing Bridge into Segregated Turn
Given the node map
| | | | | | f |
| i | h | | | g | e |
| a | b | | | c | d |
And the ways
| nodes | highway | oneway | name |
| ab | primary | yes | to_bridge |
| bc | primary | yes | bridge |
| cd | primary | yes | off_bridge |
| de | primary | yes | |
| ef | primary | no | target_road |
| eg | primary | yes | off_bridge |
| gh | primary | yes | bridge |
| hi | primary | yes | to_bridge |
When I route I should get
| waypoints | route | turns |
| a,f | to_bridge,target_road,target_road | depart,turn left,arrive |
Scenario: Pankenbruecke
Given the node map
| h | | | | | | i | | | | | | |
| | | b | c | d | e | f | | | | | | g |
| a | | | | | | | | | | | | |
And the ways
| nodes | highway | name | oneway |
| abh | primary | inroad | yes |
| bc | primary | inroad | no |
| cd | primary | bridge | no |
| defg | primary | outroad | no |
| fi | primary | cross | no |
When I route I should get
| waypoints | route | turns |
| a,g | inroad,outroad,outroad | depart,new name straight,arrive |
| a,i | inroad,cross,cross | depart,turn left,arrive |
Scenario: Close Turns - Don't Collapse
Given the node map
| | g | d | |
| | | | |
| e | b | c | f |
| | | | |
| | a | h | |
And the ways
| nodes | highway | name |
| ab | primary | in |
| ebcf | primary | cross |
| cd | primary | out |
| bg | primary | straight |
| ch | primary | reverse |
When I route I should get
| waypoints | route | turns |
| a,d | in,cross,out,out | depart,turn right,turn left,arrive |
| a,h | in,cross,reverse,reverse | depart,turn right,turn right,arrive |
| g,d | straight,cross,out,out | depart,turn left,turn left,arrive |
Scenario: No Name During Turns
Given the node map
| a | b | |
| | c | d |
And the ways
| nodes | highway | name |
| ab | tertiary | road |
| bc | tertiary | |
| cd | tertiary | road |
When I route I should get
| waypoints | route | turns |
| a,d | road,road | depart,arrive |
Scenario: No Name During Turns, Random Oneway
Given the node map
| a | b | |
| | c | d |
And the ways
| nodes | highway | name | oneway |
| ab | tertiary | road | no |
| bc | tertiary | | yes |
| cd | tertiary | road | no |
When I route I should get
| waypoints | route | turns |
| a,d | road,road | depart,arrive |
Scenario: Pulled Back Turn
Given the node map
| | | d |
| a | b | c |
| | e | |
And the ways
| nodes | highway | name |
| abc | tertiary | road |
| cd | tertiary | left |
| be | tertiary | right |
When I route I should get
| waypoints | route | turns |
| a,d | road,left,left | depart,turn left,arrive |
| a,e | road,right,right | depart,turn right,arrive |
Scenario: No Name During Turns, keep important turns
Given the node map
| a | b | e |
| | c | d |
And the ways
| nodes | highway | name |
| ab | tertiary | road |
| bc | tertiary | |
| cd | tertiary | road |
| be | tertiary | other |
When I route I should get
| waypoints | route | turns |
| a,d | road,road,road | depart,continue right,arrive |
Scenario: Segregated Intersection into Slight Turn
Given the node map
| h | | | | | | |
| a | | | | | | |
| | | | | | | |
| | | g | | | | |
| | | b | f | | | |
| | | | c | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | e |
| | | | | | | d |
| | | j | i | | | |
And the ways
| nodes | highway | name | oneway |
| abcd | primary | road | yes |
| efgh | primary | road | yes |
| icf | secondary | in | yes |
| gbj | secondary | out | yes |
When I route I should get
| waypoints | route | turns |
| i,h | in,road,road | depart,turn slight left,arrive |
| a,d | road,road | depart,arrive |
| a,j | road,out,out | depart,turn slight right,arrive |
Scenario: Don't collapse everything to u-turn / too wide
Given the node map
| a | | b | | e |
| | | | | |
| d | | c | | f |
And the ways
| nodes | highway | name |
| abcd | primary | road |
| be | secondary | top |
| cf | secondary | bottom |
When I route I should get
| waypoints | turns | route |
| a,d | depart,continue right,turn right,arrive | road,road,road,road |
| d,a | depart,continue left,turn left,arrive | road,road,road,road |
Scenario: Forking before a turn
Given the node map
| | | | g | |
| | | | | |
| | | | c | |
| a | | b | d | e |
| | | | | |
| | | | f | |
And the ways
| nodes | name | oneway | highway |
| ab | road | yes | primary |
| bd | road | yes | primary |
| bc | road | yes | primary |
| de | road | yes | primary |
| fdcg | cross | no | secondary |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | bd | fdcg | d | no_left_turn |
| restriction | bc | fdcg | c | no_right_turn |
When I route I should get
| waypoints | route | turns |
| a,g | road,cross,cross | depart,turn left,arrive |
| a,e | road,road | depart,arrive |
Scenario: Forking before a turn (narrow)
Given the node map
| | | | g | |
| | | | | |
| | | | c | |
| a | b | | d | e |
| | | | | |
| | | | f | |
And the ways
| nodes | name | oneway | highway |
| ab | road | yes | primary |
| bd | road | yes | primary |
| bc | road | yes | primary |
| de | road | yes | primary |
| fdcg | cross | no | secondary |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | bd | fdcg | d | no_left_turn |
| restriction | bc | fdcg | c | no_right_turn |
When I route I should get
| waypoints | route | turns |
| a,g | road,cross,cross | depart,turn left,arrive |
| a,e | road,road | depart,arrive |
Scenario: Forking before a turn (forky)
Given the node map
| | | | g | | |
| | | | | | |
| | | | c | | |
| a | b | | | | |
| | | | | d | |
| | | | | f | e |
And the ways
| nodes | name | oneway | highway |
| ab | road | yes | primary |
| bd | road | yes | primary |
| bc | road | yes | primary |
| de | road | yes | primary |
| fdcg | cross | no | secondary |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | bd | fdcg | d | no_left_turn |
| restriction | bc | fdcg | c | no_right_turn |
When I route I should get
| waypoints | route | turns |
| a,g | road,cross,cross | depart,turn left,arrive |
| a,e | road,road,road | depart,continue slight right,arrive |
# We should discuss whether the next item should be collapsed to depart,turn right,arrive.
| a,f | road,road,cross,cross | depart,continue slight right,turn right,arrive |
Scenario: On-Off on Highway
Given the node map
| f | | | |
| a | b | c | d |
| | | | e |
And the ways
| nodes | name | highway | oneway |
| abcd | Hwy | motorway | yes |
| fb | on | motorway_link | yes |
| ce | off | motorway_link | yes |
When I route I should get
| waypoints | route | turns |
| a,d | Hwy,Hwy | depart,arrive |
| f,d | on,Hwy,Hwy | depart,merge slight right,arrive |
| f,e | on,Hwy,off,off | depart,merge slight right,off ramp right,arrive |
| a,e | Hwy,off,off | depart,off ramp right,arrive |
+39 -6
View File
@@ -16,9 +16,42 @@ Feature: Continue Instructions
| bd | primary |
When I route I should get
| waypoints | route | turns |
| a,c | abc,abc,abc | depart,continue left,arrive |
| a,d | abc,bd,bd | depart,new name straight,arrive |
| waypoints | route | turns |
| a,c | abc,abc,abc | depart,continue left,arrive |
| a,d | abc,bd,bd | depart,turn straight,arrive |
Scenario: Road turning left and straight
Given the node map
| | | c | |
| a | | b | d |
And the ways
| nodes | highway | name |
| abc | primary | road |
| bd | primary | road |
When I route I should get
| waypoints | route | turns |
| a,c | road,road,road | depart,continue left,arrive |
| a,d | road,road | depart,arrive |
Scenario: Road turning left and straight
Given the node map
| | | c | |
| a | | b | d |
| | | e | |
And the ways
| nodes | highway | name |
| abc | primary | road |
| bd | primary | road |
| be | primary | road |
When I route I should get
| waypoints | route | turns |
| a,c | road,road,road | depart,continue left,arrive |
| a,d | road,road | depart,arrive |
| a,e | road,road,road | depart,continue right,arrive |
Scenario: Road turning right
Given the node map
@@ -31,9 +64,9 @@ Feature: Continue Instructions
| bd | primary |
When I route I should get
| waypoints | route | turns |
| a,c | abc,abc,abc | depart,continue right,arrive |
| a,d | abc,bd,bd | depart,new name straight,arrive |
| waypoints | route | turns |
| a,c | abc,abc,abc | depart,continue right,arrive |
| a,d | abc,bd,bd | depart,turn straight,arrive |
Scenario: Road turning slight left
Given the node map
@@ -0,0 +1,169 @@
@routing @guidance
Feature: Slipways and Dedicated Turn Lanes
Background:
Given the profile "car"
Given a grid size of 5 meters
Scenario: Turn Instead of Ramp
Given the node map
| | | | | e | |
| a | b | | | c | d |
| | | | h | | |
| | | | | | |
| | | | 1 | | |
| | | | | | |
| | | | | f | |
| | | | | | |
| | | | | g | |
And the ways
| nodes | highway | name |
| abcd | trunk | first |
| bhf | trunk_link | |
| ecfg | primary | second |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | abcd | ecfg | c | no_right_turn |
When I route I should get
| waypoints | route | turns |
| a,g | first,second,second | depart,turn right,arrive |
| a,1 | first,, | depart,turn slight right,arrive |
Scenario: Turn Instead of Ramp
Given the node map
| | | | | e | |
| a | b | | | c | d |
| | | | h | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | f | |
| | | | | | |
| | | | | | |
| | | | | g | |
And the ways
| nodes | highway | name |
| abcd | motorway | first |
| bhf | motorway_link | |
| efg | primary | second |
When I route I should get
| waypoints | route | turns |
| a,g | first,,second,second | depart,off ramp slight right,merge slight left,arrive |
Scenario: Inner city expressway with on road
Given the node map
| a | b | | | | c | g |
| | | | | f | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | d | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | e | |
And the ways
| nodes | highway | name |
| abc | primary | road |
| cg | primary | road |
| bfd | trunk_link | |
| cde | trunk | trunk |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | abc | cde | c | no_right_turn |
When I route I should get
| waypoints | route | turns |
| a,e | road,trunk,trunk | depart,turn right,arrive |
Scenario: Slipway Round U-Turn
Given the node map
| a | | f |
| | | |
| b | | e |
| | | |
| | | |
| | g | |
| | | |
| c | | d |
And the ways
| nodes | highway | name | oneway |
| abc | primary | road | yes |
| bge | primary_link | | yes |
| def | primary | road | yes |
When I route I should get
| waypoints | route | turns |
| a,f | road,road,road | depart,continue uturn,arrive |
Scenario: Slipway Steep U-Turn
Given the node map
| a | | f |
| | | |
| b | | e |
| | g | |
| | | |
| | | |
| c | | d |
And the ways
| nodes | highway | name | oneway |
| abc | primary | road | yes |
| bge | primary_link | | yes |
| def | primary | road | yes |
When I route I should get
| waypoints | route | turns |
| a,f | road,road,road | depart,continue uturn,arrive |
Scenario: Schwarzwaldstrasse Autobahn
Given the node map
| | | | | i | | | | | | h | | | | | g |
| | | j | | | | | | | | | | | | | |
| a | | | | | | | k | | | | | | | | |
| | | | b | | r | c | | d | | e | | | | | f |
| | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | |
| | | | | | l | | | | | | | | | | |
| | | | | | m | | | | | | | | | | |
| | | | | | | n | | q | | | | | | | |
| | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | |
| | | | | | | o | | p | | | | | | | |
And the nodes
# the traffic light at `l` is not actually in the data, but necessary for the test to check everything
# http://www.openstreetmap.org/#map=19/48.99211/8.40336
| node | highway |
| r | traffic_signals |
| l | traffic_signals |
And the ways
| nodes | highway | name | ref | oneway |
| abrcd | secondary | Schwarzwaldstrasse | L561 | yes |
| hija | secondary | Schwarzwaldstrasse | L561 | yes |
| def | secondary | Ettlinger Strasse | | yes |
| gh | secondary | Ettlinger Strasse | | yes |
| blmn | secondary_link | | L561 | yes |
| hkc | secondary_link | Ettlinger Strasse | | yes |
| qdki | secondary_link | Ettlinger Allee | | yes |
| cn | secondary_link | Ettlinger Allee | | yes |
| no | primary | Ettlinger Allee | | yes |
| pq | primary | Ettlinger Allee | | yes |
| qe | secondary_link | Ettlinger Allee | | yes |
When I route I should get
| waypoints | route | turns |
| a,o | Schwarzwaldstrasse (L561),Ettlinger Allee,Ettlinger Allee | depart,turn right,arrive |
+10 -10
View File
@@ -29,13 +29,13 @@ Feature: Destination Signs
| qr | QR | | | A1;A2 | yes | |
When I route I should get
| from | to | route | # |
| a | b | AB (E1),AB (E1) | |
| c | d | CD (Berlin),CD (Berlin) | |
| e | f | EF (A1: Berlin),EF (A1: Berlin) | |
| g | h | , | |
| i | j | , | |
| k | l | KL (E1),KL (E1) | |
| m | n | MN (A1, A2: Berlin, Hamburg),MN (A1, A2: Berlin, Hamburg) | |
| o | p | OP,OP | guard against mis-tagging |
| q | r | QR (A1, A2),QR (A1, A2) | |
| from | to | route | destinations | # |
| a | b | AB (E1),AB (E1) | , | |
| c | d | CD (Berlin),CD (Berlin) | Berlin,Berlin | |
| e | f | EF (A1: Berlin),EF (A1: Berlin) | A1: Berlin,A1: Berlin | |
| g | h | , | A1: Berlin,A1: Berlin | |
| i | j | , | Berlin,Berlin | |
| k | l | KL (E1),KL (E1) | A1: Berlin,A1: Berlin | |
| m | n | MN (A1, A2: Berlin, Hamburg),MN (A1, A2: Berlin, Hamburg) | A1, A2: Berlin, Hamburg,A1, A2: Berlin, Hamburg | |
| o | p | OP,OP | , | guard against mis-tagging |
| q | r | QR (A1, A2),QR (A1, A2) | A1, A2,A1, A2 | |
+82 -42
View File
@@ -8,116 +8,156 @@ Feature: End Of Road Instructions
Scenario: End of Road with through street
Given the node map
| | | c |
| a | | b |
| | | d |
| a | e | b |
| | f | d |
And the ways
| nodes | highway |
| ab | primary |
| aeb | primary |
| cbd | primary |
| ef | primary |
When I route I should get
| waypoints | route | turns |
| a,c | ab,cbd,cbd | depart,end of road left,arrive |
| a,d | ab,cbd,cbd | depart,end of road right,arrive |
| waypoints | route | turns |
| a,c | aeb,cbd,cbd | depart,end of road left,arrive |
| a,d | aeb,cbd,cbd | depart,end of road right,arrive |
Scenario: End of Road with three streets
Given the node map
| | | c |
| a | | b |
| | | d |
| a | e | b |
| | f | d |
And the ways
| nodes | highway |
| ab | primary |
| aeb | primary |
| cb | primary |
| bd | primary |
| ef | primary |
When I route I should get
| waypoints | route | turns |
| a,c | ab,cb,cb | depart,end of road left,arrive |
| a,d | ab,bd,bd | depart,end of road right,arrive |
| waypoints | route | turns |
| a,c | aeb,cb,cb | depart,end of road left,arrive |
| a,d | aeb,bd,bd | depart,end of road right,arrive |
Scenario: End of Road with three streets, slightly angled
Given the node map
| a | | | | | c |
| | | | | | b |
| a | e | | | | c |
| | f | | | | b |
| | | | | | d |
And the ways
| nodes | highway |
| ab | primary |
| aeb | primary |
| cb | primary |
| bd | primary |
| ef | primary |
When I route I should get
| waypoints | route | turns |
| a,c | ab,cb,cb | depart,end of road left,arrive |
| a,d | ab,bd,bd | depart,end of road right,arrive |
| waypoints | route | turns |
| a,c | aeb,cb,cb | depart,end of road left,arrive |
| a,d | aeb,bd,bd | depart,end of road right,arrive |
Scenario: End of Road with three streets, slightly angled
Given the node map
| | | | | | c |
| | | | | | b |
| a | | | | | d |
| | f | | | | b |
| a | e | | | | d |
And the ways
| nodes | highway |
| ab | primary |
| aeb | primary |
| ef | primary |
| cb | primary |
| bd | primary |
When I route I should get
| waypoints | route | turns |
| a,c | ab,cb,cb | depart,end of road left,arrive |
| a,d | ab,bd,bd | depart,end of road right,arrive |
| waypoints | route | turns |
| a,c | aeb,cb,cb | depart,end of road left,arrive |
| a,d | aeb,bd,bd | depart,end of road right,arrive |
Scenario: End of Road with through street, slightly angled
Given the node map
| a | | | | | c |
| | | | | | b |
| a | e | | | | c |
| | f | | | | b |
| | | | | | d |
And the ways
| nodes | highway |
| ab | primary |
| aeb | primary |
| ef | primary |
| cbd | primary |
When I route I should get
| waypoints | route | turns |
| a,c | ab,cbd,cbd | depart,end of road left,arrive |
| a,d | ab,cbd,cbd | depart,end of road right,arrive |
| waypoints | route | turns |
| a,c | aeb,cbd,cbd | depart,end of road left,arrive |
| a,d | aeb,cbd,cbd | depart,end of road right,arrive |
Scenario: End of Road with through street, slightly angled
Given the node map
| | | | | | c |
| | | | | | b |
| a | | | | | d |
| | f | | | | b |
| a | e | | | | d |
And the ways
| nodes | highway |
| ab | primary |
| aeb | primary |
| ef | primary |
| cbd | primary |
When I route I should get
| waypoints | route | turns |
| a,c | ab,cbd,cbd | depart,end of road left,arrive |
| a,d | ab,cbd,cbd | depart,end of road right,arrive |
| waypoints | route | turns |
| a,c | aeb,cbd,cbd | depart,end of road left,arrive |
| a,d | aeb,cbd,cbd | depart,end of road right,arrive |
Scenario: End of Road with two ramps - prefer ramp over end of road
Given the node map
| | | c |
| a | | b |
| | | d |
| a | e | b |
| | f | d |
And the ways
| nodes | highway |
| ab | primary |
| aeb | primary |
| ef | primary |
| bc | motorway_link |
| bd | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,c | ab,bc,bc | depart,on ramp left,arrive |
| a,d | ab,bd,bd | depart,on ramp right,arrive |
| waypoints | route | turns |
| a,c | aeb,bc,bc | depart,on ramp left,arrive |
| a,d | aeb,bd,bd | depart,on ramp right,arrive |
# http://www.openstreetmap.org/#map=19/52.49907/13.41836
@end-of-road @negative
Scenario: Don't Handle Circles as End-Of-Road
Given the node map
| | r | | | | q | | | | | | |
| | | | | | a | s | | | | | |
| | | | b | | | | | | | | |
| | | | | | | | j | | | | |
| | | | | | | | | | | | |
| l | | c | | | | | i | | | | k |
| | | | | | | | | | | | |
| | | | | | | | h | | | | |
| m | | | | | | | | | | | |
| | | d | | | | | | | | | n |
| | | | e | | | g | | | | | |
| | | | | f | | | | | | | |
| | | | | o | | p | | | | | |
And the ways
| nodes | highway | name | oneway |
| abcdefghijsa | secondary | kotti | yes |
| ki | secondary | skal | yes |
| cl | secondary | skal | yes |
| md | secondary | skal | yes |
| gn | secondary | skal | yes |
| qa | tertiary | adal | no |
| br | residential | rei | yes |
| fo | secondary | kstr | yes |
| pg | secondary | kstr | yes |
When I route I should get
| waypoints | route | turns | # |
| k,l | skal,kotti,skal,skal | depart,turn right,turn right,arrive | # could be a case to find better turn instructions for |
+33
View File
@@ -281,3 +281,36 @@ Feature: Fork Instructions
| a,c | abd,bc,bc | depart,turn slight left,arrive |
| a,d | abd,abd | depart,arrive |
| a,e | abd,be,be | depart,turn slight right,arrive |
Scenario: Don't Fork when leaving Road
Given the node map
| a | | b | | c |
| | | | | d |
And the ways
| nodes | highway |
| abc | secondary |
| bd | secondary |
When I route I should get
| waypoints | route | turns |
| a,c | abc,abc | depart,arrive |
| a,d | abc,bd,bd | depart,turn slight right,arrive |
Scenario: Fork on motorway links - don't fork on through
Given the node map
| i | | | | | a |
| j | | c | b | | x |
And the ways
| nodes | name | highway |
| xb | xbcj | motorway_link |
| bc | xbcj | motorway_link |
| cj | xbcj | motorway_link |
| ci | off | motorway_link |
| ab | on | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,j | on,xbcj,xbcj | depart,merge slight left,arrive |
| a,i | on,xbcj,off,off | depart,merge slight left,turn slight right,arrive |
+134
View File
@@ -0,0 +1,134 @@
@routing @guidance @intersections
Feature: Intersections Data
Background:
Given the profile "car"
Given a grid size of 10 meters
Scenario: Passing Three Way South
Given the node map
| a | | b | | c |
| | | d | | |
And the ways
| nodes | name |
| ab | through |
| bc | through |
| bd | corner |
When I route I should get
| waypoints | route | intersections |
| a,c | through,through | true:90,true:90 true:180 false:270;true:270 |
Scenario: Passing Three Way North
Given the node map
| | | d | | |
| a | | b | | c |
And the ways
| nodes | name |
| ab | through |
| bc | through |
| bd | corner |
When I route I should get
| waypoints | route | intersections |
| a,c | through,through | true:90,true:0 true:90 false:270;true:270 |
Scenario: Passing Oneway Street In
Given the node map
| | | d | | |
| a | | b | | c |
And the ways
| nodes | name | oneway |
| ab | through | no |
| bc | through | no |
| db | corner | yes |
When I route I should get
| waypoints | route | intersections |
| a,c | through,through | true:90,false:0 true:90 false:270;true:270 |
Scenario: Passing Oneway Street Out
Given the node map
| | | d | | |
| a | | b | | c |
And the ways
| nodes | name | oneway |
| ab | through | no |
| bc | through | no |
| bd | corner | yes |
When I route I should get
| waypoints | route | intersections |
| a,c | through,through | true:90,true:0 true:90 false:270;true:270 |
Scenario: Passing Two Intersections
Given the node map
| | | e | | | | |
| a | | b | | c | | d |
| | | | | f | | |
And the ways
| nodes | name |
| ab | through |
| bc | through |
| cd | through |
| be | corner |
| cf | corner |
When I route I should get
| waypoints | route | intersections |
| a,d | through,through | true:90,true:0 true:90 false:270,true:90 true:180 false:270;true:270 |
Scenario: Passing Two Intersections, Collapsing
Given the node map
| | | e | | | | |
| a | | b | | c | | d |
| | | | | f | | |
And the ways
| nodes | name |
| ab | through |
| bc | throughbridge |
| cd | through |
| be | corner |
| cf | corner |
When I route I should get
| waypoints | route | intersections |
| a,d | through,through | true:90,true:0 true:90 false:270,true:90 true:180 false:270;true:270 |
| f,a | corner,through,through | true:0;true:90 false:180 true:270,true:0 false:90 true:270;true:90 |
Scenario: Roundabouts
Given the node map
| | | | | e | | | | |
| | | | | | | | | |
| | | | | a | | | | |
| | | | 1 | | 4 | | | |
| | | | | | | | | |
| f | | b | | | | d | | h |
| | | | | | | | | |
| | | | 2 | | 3 | | | |
| | | | | c | | | | |
| | | | | | | | | |
| | | | | g | | | | |
And the ways
| nodes | junction |
| abcda | roundabout |
| ea | |
| fb | |
| gc | |
| hd | |
When I route I should get
| waypoints | route | intersections |
| e,f | ea,fb,fb | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:90 |
| e,g | ea,gc,gc | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330;true:0 |
| e,h | ea,hd,hd | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330,true:90 false:210 true:330;true:270 |
| e,2 | ea,abcda,abcda | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:327 +-1 |
| 1,g | abcda,gc,gc | true:214;false:30 true:150 true:270,true:30 true:180 false:330;true:0 |
| 1,3 | abcda,abcda | true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:214 |
+24
View File
@@ -50,3 +50,27 @@ Feature: Merging
| waypoints | route | turns |
| d,c | db,abc,abc | depart,merge slight left,arrive |
Scenario: Merge onto a turning road
Given the node map
| | | | | | | e |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | d | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | c | | |
| | | | b | | | |
| a | | | | | | f |
And the ways
| nodes | highway | name |
| abcde | primary | road |
| fd | residential | in |
When I route I should get
| waypoints | turns | route |
| f,e | depart,merge slight left,arrive | in,road,road |
| f,a | depart,turn sharp left,arrive | in,road,road |
+62 -44
View File
@@ -11,9 +11,9 @@ Feature: Motorway Guidance
| | | | f | g |
And the ways
| nodes | highway |
| abcde | motorway |
| bfg | motorway_link |
| nodes | highway | oneway |
| abcde | motorway | |
| bfg | motorway_link | yes |
When I route I should get
| waypoints | route | turns |
@@ -27,9 +27,9 @@ Feature: Motorway Guidance
| | | | g | e |
And the ways
| nodes | highway |
| abcde | motorway |
| bfg | motorway_link |
| nodes | highway | oneway |
| abcde | motorway | |
| bfg | motorway_link | yes |
When I route I should get
| waypoints | route | turns |
@@ -44,9 +44,9 @@ Feature: Motorway Guidance
And the ways
| nodes | highway |
| abcde | motorway |
| cfg | motorway_link |
| nodes | highway | oneway |
| abcde | motorway | |
| cfg | motorway_link | yes |
When I route I should get
| waypoints | route | turns |
@@ -60,9 +60,9 @@ Feature: Motorway Guidance
| a | b | c | d | e |
And the ways
| nodes | highway |
| abcde | motorway |
| bfg | motorway_link |
| nodes | highway | oneway |
| abcde | motorway | |
| bfg | motorway_link | yes |
When I route I should get
| waypoints | route | turns |
@@ -76,9 +76,9 @@ Feature: Motorway Guidance
| a | b | c | | |
And the ways
| nodes | highway |
| abcde | motorway |
| bfg | motorway_link |
| nodes | highway | oneway |
| abcde | motorway | |
| bfg | motorway_link | yes |
When I route I should get
| waypoints | route | turns |
@@ -92,9 +92,9 @@ Feature: Motorway Guidance
| | | | | e |
And the ways
| nodes | highway |
| abcde | motorway |
| cfg | motorway_link |
| nodes | highway | oneway |
| abcde | motorway | |
| cfg | motorway_link | yes |
When I route I should get
| waypoints | route | turns |
@@ -107,9 +107,9 @@ Feature: Motorway Guidance
| f | g | | | |
And the ways
| nodes | highway |
| abcde | motorway |
| fgd | motorway_link |
| nodes | highway | oneway |
| abcde | motorway | |
| fgd | motorway_link | yes |
When I route I should get
| waypoints | route | turns |
@@ -122,9 +122,9 @@ Feature: Motorway Guidance
| a | b | c | d | e |
And the ways
| nodes | highway |
| abcde | motorway |
| fgd | motorway_link |
| nodes | highway | oneway |
| abcde | motorway | |
| fgd | motorway_link | yes |
When I route I should get
| waypoints | route | turns |
@@ -154,10 +154,10 @@ Feature: Motorway Guidance
| | | | | f | g |
And the ways
| nodes | highway |
| abc | motorway_link |
| cde | motorway |
| cfg | motorway |
| nodes | highway | oneway |
| abc | motorway_link | yes |
| cde | motorway | |
| cfg | motorway | |
When I route I should get
| waypoints | route | turns |
@@ -170,17 +170,17 @@ Feature: Motorway Guidance
| f | g | | | | h | i |
And the ways
| nodes | highway |
| abcde | motorway |
| fgc | motorway_link |
| chi | motorway_link |
| nodes | highway | oneway |
| abcde | motorway | |
| fgc | motorway_link | yes |
| chi | motorway_link | yes |
When I route I should get
| waypoints | route | turns |
| a,e | abcde,abcde | depart,arrive |
| f,e | fgc,abcde,abcde | depart,merge slight left,arrive |
| waypoints | route | turns |
| 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 right,arrive |
Scenario: On And Off Ramp Left
Given the node map
@@ -188,17 +188,17 @@ Feature: Motorway Guidance
| a | b | | c | | d | e |
And the ways
| nodes | highway |
| abcde | motorway |
| fgc | motorway_link |
| chi | motorway_link |
| nodes | highway | oneway |
| abcde | motorway | |
| fgc | motorway_link | yes |
| chi | motorway_link | yes |
When I route I should get
| waypoints | route | turns |
| a,e | abcde,abcde | depart,arrive |
| f,e | fgc,abcde,abcde | depart,merge slight right,arrive |
| waypoints | route | turns |
| 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 left,arrive |
Scenario: Merging Motorways
Given the node map
@@ -216,3 +216,21 @@ Feature: Motorway Guidance
| waypoints | route | turns |
| d,c | db,abc,abc | depart,merge slight left,arrive |
| e,c | eb,abc,abc | depart,merge slight right,arrive |
Scenario: Handle 90 degree off ramps correctly
Given the node map
| a | | | | |
| x | b | | c | y |
| | | | d | |
And the ways
| nodes | name | highway | oneway |
| ab | On | motorway_link | yes |
| xb | Hwy | motorway | |
| bc | Hwy | motorway | |
| cd | Off | motorway_link | yes |
| cy | Hwy | motorway | |
When I route I should get
| waypoints | route | turns |
| a,d | On,Hwy,Off,Off | depart,merge slight right,off ramp right,arrive |
+3 -3
View File
@@ -3,7 +3,7 @@ Feature: New-Name Instructions
Background:
Given the profile "car"
Given a grid size of 10 meters
Given a grid size of 100 meters
Scenario: Undisturbed name Change
Given the node map
@@ -136,7 +136,7 @@ Feature: New-Name Instructions
Scenario: Empty road names - Announce Change From, suppress Change To
Given the node map
| a | | b | | c | | d |
| a | | b | 1 | c | | d |
And the ways
| nodes | name |
@@ -147,7 +147,7 @@ Feature: New-Name Instructions
When I route I should get
| waypoints | route | turns |
| a,d | ab,cd,cd | depart,new name straight,arrive |
| a,c | ab, | depart,arrive |
| a,1 | ab, | depart,arrive |
Scenario: Empty road names - Loose name shortly
Given the node map
+22
View File
@@ -0,0 +1,22 @@
@routing @guidance @post-processing
Feature: General Post-Processing related features
Background:
Given the profile "car"
Given a grid size of 10 meters
# this testcase used to crash geometry generation (at that time handled during intersection generation)
Scenario: Regression test #2424
Given the node map
| | | e | | | | | | i | | | | |
| a | | b | | c | | d | | h | | k | | m |
| | | | | f | | | | | | l | | |
And the ways
| nodes | name |
| abcd | Fritz-Elsas-Straße |
| hkm | Fritz-Elsas-Straße |
| dhi | Martin-Luther-Straße |
| be | corner |
| kl | corner |
| cf | corner |
+22
View File
@@ -367,3 +367,25 @@ Feature: Basic Roundabout
| h,d | gh,cd,cd | depart,roundabout-exit-2,arrive |
| h,f | gh,ef,ef | depart,roundabout-exit-1,arrive |
Scenario: Enter and Exit -- Bearing
Given the node map
| | | a | | |
| | | b | | |
| h | g | | c | d |
| | | e | | |
| | | f | | |
And the ways
| nodes | junction |
| ab | |
| cd | |
| ef | |
| gh | |
| bgecb | roundabout |
When I route I should get
| waypoints | route | turns | bearing |
| a,d | ab,cd,cd | depart,roundabout turn left exit-3,arrive | 0->180,180->224,90->0 |
| a,f | ab,ef,ef | depart,roundabout turn straight exit-2,arrive | 0->180,180->224,180->0 |
| a,h | ab,gh,gh | depart,roundabout turn right exit-1,arrive | 0->180,180->224,270->0 |
+139
View File
@@ -337,3 +337,142 @@ Feature: Basic Roundabout
| a,e | ac,de,de | depart,roundabout-exit-1,arrive |
| a,f | ac,bf,bf | depart,roundabout-exit-2,arrive |
Scenario: Enter and Exit - Bearings
Given the node map
| | | | a | | | |
| | | | | | | |
| | | i | b | l | | |
| h | | g | | c | | d |
| | | j | e | k | | |
| | | | | | | |
| | | | f | | | |
And the ways
| nodes | junction |
| ab | |
| cd | |
| ef | |
| gh | |
| bigjekclb | roundabout |
When I route I should get
| waypoints | route | turns | bearing |
| a,d | ab,cd,cd | depart,roundabout-exit-3,arrive | 0->180,180->270,90->0 |
| a,f | ab,ef,ef | depart,roundabout-exit-2,arrive | 0->180,180->270,180->0 |
| a,h | ab,gh,gh | depart,roundabout-exit-1,arrive | 0->180,180->270,270->0 |
Scenario: Motorway Roundabout
#See 39.933742 -75.082345
Given the node map
| | | | | l | | | | a | | i |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | b | | | | |
| | | | c | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | h | | |
| n | | | | | | | | | | |
| | | | | | | | | | | |
| | | d | | | | | | | | j |
| | | | | | | | | | | |
| | | | | m | | | g | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | e | | f | | | | | | |
And the ways
| nodes | junction | name | highway | oneway | ref |
| ab | | crescent | trunk | yes | US 130 |
| bcd | roundabout | crescent | trunk | yes | US 130 |
| de | | crescent | trunk | yes | US 130 |
| fg | | crescent | trunk | yes | US 130 |
| gh | roundabout | crescent | trunk | yes | US 130 |
| hi | | crescent | trunk | yes | US 130 |
| jh | | | trunk_link | yes | NJ 38 |
| hb | roundabout | | trunk_link | yes | NJ 38 |
| bl | | | trunk_link | yes | NJ 38 |
| cnd | | kaighns | trunk_link | yes | |
| dmg | roundabout | | trunk_link | yes | |
When I route I should get
| waypoints | route | turns |
| a,e | crescent (US 130),crescent (US 130),crescent (US 130) | depart,roundabout-exit-3,arrive |
| j,l | NJ 38,NJ 38,NJ 38 | depart,roundabout-exit-2,arrive |
Scenario: Double Roundabout with through-lane
#http://map.project-osrm.org/?z=18&center=38.911752%2C-77.048667&loc=38.912003%2C-77.050831&loc=38.909277%2C-77.042516&hl=en&alt=0
Given the node map
| | | | | o | | | | | | | | | | | | n | | | | |
| | | | | e | | | | | | | | | | | | j | | | | |
| | | | | | | | | | | | | | | | | | | | | |
| | | | | | | q | | | | | | | | | | | | | | |
| a | | b | | | | | | s | | f | | | | g | | | | i | | k |
| | | | | | | r | | | | | | | | | | | p | | | |
| | | | | | | | | | | t | | | | | | | | | | |
| | | | | c | | d | | | | | | | | | | h | | | | |
| | | | | l | | | | | | | | | | | | m | | | | |
And the nodes
| node | highway |
| i | traffic_signals |
And the ways
| nodes | junction | name | oneway |
| bcdrqeb | roundabout | sheridan circle | yes |
| ghi | roundabout | dupont circle | yes |
| ijg | roundabout | dupont circle | yes |
| ab | | massachusetts | no |
| sfgpik | | massachusetts | no |
| cl | | 23rd street | no |
| oe | | r street | no |
| jn | | new hampshire | no |
| mh | | new hampshire | yes |
| rsq | | massachusetts | yes |
| ft | | suppressed | no |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | sfgpik | ijg | i | no_left_turn |
When I route I should get
| waypoints | route | turns |
| a,k | massachusetts,massachusetts,massachusetts,massachusetts | depart,sheridan circle-exit-2,dupont circle-exit-1,arrive |
Scenario: Enter and Exit - Traffic Signals
Given the node map
| | | a | | |
| | i | b | l | |
| h | g | | c | d |
| | j | e | k | |
| | | f | | |
And the nodes
| node | highway |
| i | traffic_signals |
| j | traffic_signals |
| k | traffic_signals |
| l | traffic_signals |
And the ways
| nodes | junction |
| ab | |
| cd | |
| ef | |
| gh | |
| bigjekclb | roundabout |
When I route I should get
| waypoints | route | turns |
| a,d | ab,cd,cd | depart,roundabout-exit-3,arrive |
| a,f | ab,ef,ef | depart,roundabout-exit-2,arrive |
| a,h | ab,gh,gh | depart,roundabout-exit-1,arrive |
| d,f | cd,ef,ef | depart,roundabout-exit-3,arrive |
| d,h | cd,gh,gh | depart,roundabout-exit-2,arrive |
| d,a | cd,ab,ab | depart,roundabout-exit-1,arrive |
| f,h | ef,gh,gh | depart,roundabout-exit-3,arrive |
| f,a | ef,ab,ab | depart,roundabout-exit-2,arrive |
| f,d | ef,cd,cd | depart,roundabout-exit-1,arrive |
| h,a | gh,ab,ab | depart,roundabout-exit-3,arrive |
| h,d | gh,cd,cd | depart,roundabout-exit-2,arrive |
| h,f | gh,ef,ef | depart,roundabout-exit-1,arrive |
+848
View File
@@ -0,0 +1,848 @@
@routing @guidance @turn-lanes
Feature: Turn Lane Guidance
Background:
Given the profile "car"
Given a grid size of 20 meters
@bug
Scenario: Basic Turn Lane 3-way Turn with empty lanes
Given the node map
| a | | b | | c |
| | | d | | |
And the ways
| nodes | turn:lanes | turn:lanes:forward | turn:lanes:backward | name |
| ab | | through\|right | | in |
| bc | | | left\|through\|\| | straight |
| bd | | | left\|right | right |
When I route I should get
| waypoints | route | turns | lanes |
| a,c | in,straight,straight | depart,new name straight,arrive | ,straight:true right:false, |
| a,d | in,right,right | depart,turn right,arrive | ,straight:false right:true, |
| c,a | straight,in,in | depart,new name straight,arrive | ,left:false straight:true none:true none:true, |
| c,d | straight,right,right | depart,turn left,arrive | ,left:true straight:false none:false none:false, |
Scenario: Basic Turn Lane 4-Way Turn
Given the node map
| | | e | | |
| a | | b | | c |
| | | d | | |
And the ways
| nodes | turn:lanes | turn:lanes:forward | turn:lanes:backward | name |
| ab | | \|right | | in |
| bc | | | | straight |
| bd | | | left\| | right |
| be | | | | left |
When I route I should get
| waypoints | route | turns | lanes |
| a,c | in,straight,straight | depart,new name straight,arrive | ,none:true right:false, |
| a,d | in,right,right | depart,turn right,arrive | ,none:false right:true, |
| a,e | in,left,left | depart,turn left,arrive | ,none:true right:false, |
| d,a | right,in,in | depart,turn left,arrive | ,left:true none:false, |
| d,e | right,left,left | depart,new name straight,arrive | ,left:false none:true, |
| d,c | right,straight,straight | depart,turn right,arrive | ,left:false none:true, |
Scenario: Basic Turn Lane 4-Way Turn using none
Given the node map
| | | e | | |
| a | | b | | c |
| | | d | | |
And the ways
| nodes | turn:lanes | turn:lanes:forward | turn:lanes:backward | name |
| ab | | none\|right | | in |
| bc | | | | straight |
| bd | | | left\|none | right |
| be | | | | left |
When I route I should get
| waypoints | route | turns | lanes |
| a,c | in,straight,straight | depart,new name straight,arrive | ,none:true right:false, |
| a,d | in,right,right | depart,turn right,arrive | ,none:false right:true, |
| a,e | in,left,left | depart,turn left,arrive | ,none:true right:false, |
Scenario: Basic Turn Lane 4-Way With U-Turn Lane
Given the node map
| | | e | | |
| a | 1 | b | | c |
| | | d | | |
And the ways
| nodes | turn:lanes | turn:lanes:forward | name |
| ab | | reverse;left\|through;right | in |
| bc | | | straight |
| bd | | | right |
| be | | | left |
When I route I should get
| from | to | bearings | route | turns | lanes |
| a | c | 180,180 180,180 | in,straight,straight | depart,new name straight,arrive | ,left;uturn:false straight;right:true, |
| a | d | 180,180 180,180 | in,right,right | depart,turn right,arrive | ,left;uturn:false straight;right:true, |
| a | e | 180,180 180,180 | in,left,left | depart,turn left,arrive | ,left;uturn:true straight;right:false, |
| 1 | a | 90,2 270,2 | in,in,in | depart,turn uturn,arrive | ,left;uturn:true straight;right:false, |
#this next test requires decision on how to announce lanes for going straight if there is no turn
Scenario: Turn with Bus-Lane
Given the node map
| a | | b | | c |
| | | | | |
| | | d | | |
And the ways
| nodes | name | turn:lanes:forward | lanes:psv:forward |
| ab | road | through\|right\| | 1 |
| bc | road | | |
| bd | turn | | |
When I route I should get
| waypoints | route | turns | lanes |
| a,d | road,turn,turn | depart,turn right,arrive | ,straight:false right:true, |
| a,c | road,road | depart,arrive | , |
@PROFILE @LANES
Scenario: Turn with Bus-Lane but without lanes
Given the node map
| a | | b | | c |
| | | | | |
| | | d | | |
And the ways
| nodes | name | lanes:psv |
| ab | road | 1 |
| bc | road | yes |
| bd | turn | |
When I route I should get
| waypoints | route | turns |
| a,d | road,turn,turn | depart,turn right,arrive |
| a,c | road,road | depart,arrive |
#turn lanes are often drawn at the incoming road, even though the actual turn requires crossing the intersection first
@todo @bug
Scenario: Turn Lanes at Segregated Road
Given the node map
| | | i | l | | |
| | | | | | |
| h | | g | f | | e |
| a | | b | c | | d |
| | | | | | |
| | | j | k | | |
And the ways
| nodes | name | turn:lanes:forward | oneway |
| ab | road | left\|through\|right | yes |
| bc | road | left\|through | yes |
| cd | road | | yes |
| ef | road | \|through\|through;right | yes |
| fg | road | left;through\|through\| | yes |
| gh | road | | yes |
| ig | cross | | yes |
| gb | cross | left\|through | yes |
| bj | cross | | yes |
| kc | cross | left\|through;right | yes |
| cf | cross | left\|through | yes |
| fl | cross | | yes |
When I route I should get
| waypoints | route | turns | lanes |
| a,j | road,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true |
| a,d | road,road,road | depart,use lane straight,arrive | ,left:false straight:true right:false, |
| a,l | road,cross,cross | depart,turn left,arrive | ,left:true straight:false right:false, |
| a,h | road,road,road | depart,continue uturn,arrive | ,left:true straight:false right:false, |
| k,d | cross,road,road | depart,turn right,arrive | ,left:false straight;right:true, |
| k,l | cross,cross,cross | depart,use lane straight,arrive | ,left:false straight;right:true, |
| k,h | cross,road,road | depart,turn left,arrive | ,left:true straight;right:false, |
| k,j | cross,cross,cross | depart,continue uturn,arrive | ,left:true straight;right:false, |
| e,l | road,cross,cross | depart,turn right,arrive | ,none:false straight:false straight;right:true, |
| e,h | road,road | depart,arrive | ,none:false straight:true straight;right:true |
| e,j | road,cross,cross | depart,turn left,arrive | ,none:true straight:false straight;right:false, |
| e,d | road,road,road | depart,continue uturn,arrive | ,none:true straight:false straight;right:false, |
| i,h | cross,road,road | depart,turn right,arrive | ,, |
| i,j | cross,cross,cross | depart,use lane straight,arrive | ,left:false straight:true, |
| i,d | cross,road,road | depart,turn left,arrive | ,left:true straight:false, |
| i,l | cross,cross,cross | depart,continue uturn,arrive | ,left:true straight:false, |
#copy of former case to prevent further regression
Scenario: Turn Lanes at Segregated Road
Given the node map
| | | i | l | | |
| | | | | | |
| h | | g | f | | e |
| a | | b | c | | d |
| | | | | | |
| | | j | k | | |
And the ways
| nodes | name | turn:lanes:forward | oneway |
| ab | road | left\|through\|right | yes |
| bc | road | left\|through | yes |
| cd | road | | yes |
| ef | road | \|through\|through;right | yes |
| fg | road | left;through\|through\| | yes |
| gh | road | | yes |
| ig | cross | | yes |
| gb | cross | left\|through | yes |
| bj | cross | | yes |
| kc | cross | left\|through;right | yes |
| cf | cross | left\|through | yes |
| fl | cross | | yes |
When I route I should get
| waypoints | route | turns | lanes |
| a,j | road,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true, |
| k,d | cross,road,road | depart,turn right,arrive | ,left:false straight;right:true, |
| 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 | , |
| i,l | cross,cross,cross | depart,continue uturn,arrive | ,left:true straight:false, |
Scenario: Turn Lanes at Segregated Road
Given the node map
| | | g | f | | |
| a | | b | c | | d |
| | | | | | |
| | | j | k | | |
And the ways
| nodes | name | turn:lanes:forward | oneway |
| ab | road | left\|through\|right | yes |
| bc | road | | yes |
| cd | road | | yes |
| gb | cross | | yes |
| bj | cross | | yes |
| kc | cross | | yes |
| cf | cross | | yes |
When I route I should get
| waypoints | route | turns | lanes |
| a,j | road,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true, |
#this can happen due to traffic lights / lanes not drawn up to the intersection itself
Scenario: Turn Lanes Given earlier than actual turn
Given the node map
| a | | b | c | | d |
| | | | | | |
| | | | e | | |
And the ways
| nodes | name | turn:lanes:forward |
| ab | road | \|right |
| bc | road | |
| cd | road | |
| ce | turn | |
When I route I should get
| waypoints | route | turns | lanes |
| a,e | road,turn,turn | depart,turn right,arrive | ,none:false right:true, |
| a,d | road,road | depart,arrive | , |
Scenario: Turn Lanes Given earlier than actual turn
Given the node map
| a | | b | c | d | | e | | f | g | h | | i |
| | | j | | | | | | | | k | | |
And the ways
| nodes | name | turn:lanes:forward | turn:lanes:backward |
| abc | road | | |
| cd | road | | left\| |
| def | road | | |
| fg | road | \|right | |
| ghi | road | | |
| bj | first-turn | | |
| hk | second-turn | | |
When I route I should get
| waypoints | route | turns | lanes |
| a,k | road,second-turn,second-turn | depart,turn right,arrive | ,none:false right:true, |
| a,i | road,road | depart,arrive | , |
| i,j | road,first-turn,first-turn | depart,turn left,arrive | ,left:true none:false, |
| i,a | road,road | depart,arrive | , |
Scenario: Passing a one-way street
Given the node map
| e | | | f | |
| a | | b | c | d |
And the ways
| nodes | name | turn:lanes:forward | oneway |
| ab | road | left\|through | no |
| bcd | road | | no |
| eb | owi | | yes |
| cf | turn | | |
When I route I should get
| waypoints | route | turns | lanes |
| a,f | road,turn,turn | depart,turn left,arrive | ,left:true straight:false, |
Scenario: Passing a one-way street, partly pulled back lanes
Given the node map
| e | | | f | |
| a | | b | c | d |
| | | g | | |
And the ways
| nodes | name | turn:lanes:forward | oneway |
| ab | road | left\|through;right | no |
| bcd | road | | no |
| eb | owi | | yes |
| cf | turn | | no |
| bg | right | | no |
When I route I should get
| waypoints | route | turns | lanes |
| a,f | road,turn,turn | depart,turn left,arrive | ,left:true straight;right:false, |
| a,g | road,right,right | depart,turn right,arrive | ,left:false straight;right:true, |
Scenario: Passing a one-way street, partly pulled back lanes, no through
Given the node map
| e | | | f |
| a | | b | c |
| | | g | |
And the ways
| nodes | name | turn:lanes:forward | oneway |
| ab | road | left\|right | no |
| bc | road | | no |
| eb | owi | | yes |
| cf | turn | | no |
| bg | right | | no |
When I route I should get
| waypoints | route | turns | lanes |
| a,f | road,turn,turn | depart,turn left,arrive | ,left:true right:false, |
| a,g | road,right,right | depart,turn right,arrive | ,left:false right:true, |
@todo @bug
Scenario: Narrowing Turn Lanes
Given the node map
| | | | | g | |
| | | | | | |
| a | | b | c | d | e |
| | | | f | | |
And the ways
| nodes | name | turn:lanes:forward |
| ab | road | left\|through\|right |
| bc | road | |
| cd | road | left\|through |
| de | through | |
| dg | left | |
| cf | right | |
When I route I should get
| waypoints | route | turns | lanes |
| a,g | road,left,left | depart,turn left,arrive | ,left:true straight:false right:false, |
| a,e | road,through,through | depart,new name straight,arrive | ,left:false straight:true right:false, |
| a,f | road,right,right | depart,turn right,arrive | ,left:false straight:false right:true, |
Scenario: Turn at a traffic light
Given the node map
| a | b | c | d |
| | | e | |
And the nodes
| node | highway |
| b | traffic_signals |
And the ways
| nodes | name | turn:lanes:forward |
| ab | road | through\|right |
| bc | road | |
| cd | road | |
| ce | turn | |
When I route I should get
| waypoints | route | turns | lanes |
| a,d | road,road | depart,arrive | , |
| a,e | road,turn,turn | depart,turn right,arrive | ,straight:false right:true, |
@bug @todo
Scenario: Theodor Heuss Platz
Given the node map
| | | | i | o | | | l | |
| | | b | | | | a | | m |
| | c | | | | | | | |
| | | | | | | | h | |
| | | | | | | | | |
| j | | | | | | | | |
| | | | | | | | g | |
| | | | | | | | | |
| | d | | | | | | | |
| | | e | | | | f | | |
| | | | | k | | | | n |
And the nodes
| node | highway |
| g | traffic_signals |
And the ways
| nodes | name | turn:lanes:forward | junction | oneway | highway |
| abcdef | roundabout | | roundabout | yes | primary |
| gha | roundabout | | roundabout | yes | primary |
| fg | roundabout | slight_left\|slight_left;slight_right\|slight_right\|slight_right | roundabout | yes | primary |
| aoib | top | | | yes | primary |
| cjd | left | | | yes | primary |
| ekf | bottom | | | yes | primary |
| fng | bottom-right | | | yes | primary |
| hma | top-right | | | yes | primary |
| hl | top-right-out | | | yes | secondary |
When I route I should get
| waypoints | route | turns | lanes |
| i,m | top,top-right,top-right | depart,roundabout-exit-4,arrive | ,slight left:false slight left;slight right:true slight right:true slight right:true, |
| i,l | top,top-right-out,top-right-out | depart,roundabout-exit-4,arrive | ,slight left:true slight left;slight right:true slight right:false slight right:false, |
| i,o | top,top,top | depart,roundabout-exit-5,arrive | ,, |
Scenario: Turn Lanes Breaking up
Given the node map
| | | | g | |
| | | | | |
| | | | c | |
| a | b | | d | e |
| | | | | |
| | | | f | |
And the ways
| nodes | name | turn:lanes:forward | oneway | highway |
| ab | road | left\|left\|through\|through | yes | primary |
| bd | road | through\|through | yes | primary |
| bc | road | left\|left | yes | primary |
| de | road | | yes | primary |
| fdcg | cross | | | secondary |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | bd | fdcg | d | no_left_turn |
| restriction | bc | fdcg | c | no_right_turn |
When I route I should get
| waypoints | route | turns | lanes |
| a,g | road,cross,cross | depart,turn left,arrive | ,left:true left:true straight:false straight:false, |
| a,e | road,road | depart,arrive | , |
Scenario: U-Turn Road at Intersection
Given the node map
| | | | | | h | |
| | | | | f | e | j |
| a | b | | | | | |
| | | | | c | d | i |
| | | | | | g | |
And the ways
| nodes | name | turn:lanes:forward | oneway | highway |
| ab | road | | no | primary |
| di | road | | yes | primary |
| bc | road | \|through\|right | yes | primary |
| cd | road | \|through\|right | yes | primary |
| fc | road | | no | tertiary |
| jefb | road | | yes | primary |
| gdeh | cross | | no | primary |
When I route I should get
| from | to | bearings | route | turns | lanes |
| a | g | 180,180 180,180 | road,cross,cross | depart,turn right,arrive | ,none:false straight:false right:true, |
| a | h | 180,180 180,180 | road,cross,cross | depart,turn left,arrive | ,none:true straight:false right:false, |
| a | i | 180,180 180,180 | road,road | depart,arrive | , |
| b | a | 90,2 270,2 | road,road,road | depart,continue uturn,arrive | ,none:true straight:false right:false, |
Scenario: Segregated Intersection Merges With Lanes
Given the node map
| | | | | | | f |
| | | | | | | |
| e | | | d | | | |
| | | | | | c | g |
| a | | | b | | | |
| | | | | | | |
| | | | | | h | |
And the ways
| nodes | name | turn:lanes:forward | oneway | highway |
| abc | road | left\|left\|left\|through\|through | yes | primary |
| cde | road | | yes | primary |
| hc | cross | | yes | secondary |
| cg | straight | | no | tertiary |
| cf | left | | yes | primary |
When I route I should get
| waypoints | route | turns | lanes |
| a,f | road,left,left | depart,turn left,arrive | ,left:true left:true left:true straight:false straight:false, |
| a,e | road,road,road | depart,turn uturn,arrive | ,left:true left:false left:false straight:false straight:false, |
| a,g | road,straight,straight | depart,new name straight,arrive | ,left:false left:false left:false straight:true straight:true, |
@bug @todo
Scenario: Passing Through a Roundabout
Given the node map
| | | h | | g | | |
| | a | | | | f | k |
| i | | | | | | |
| | | | | | | |
| | b | | | | e | |
| | | c | | d | | |
| | | | | j | | |
And the ways
| nodes | name | turn:lanes:forward | oneway | highway | junction |
| efgha | round | | yes | primary | roundabout |
| ab | round | | yes | primary | roundabout |
| bc | round | slight_left\|slight_left\|slight_right | yes | primary | roundabout |
| cd | round | | yes | primary | roundabout |
| de | round | slight_left\|slight_right | yes | primary | roundabout |
| ib | left | slight_left\|slight_left\|slight_right | yes | primary | |
| cj | bottom | | yes | primary | |
| ek | right | | yes | primary | |
When I route I should get
| waypoints | route | turns | lanes |
| i,j | left,bottom,bottom | depart,round-exit-1,arrive | ,0, |
| i,k | left,right,right | depart,round-exit-2,arrive | ,1, |
Scenario: Crossing Traffic Light
Given the node map
| a | | b | | c | | d |
| | | | | | | e |
And the nodes
| node | highway |
| b | traffic_signals |
And the ways
| nodes | name | turn:lanes:forward | highway |
| abc | road | through\|through\|through;slight_right\|slight_right | primary |
| cd | road | | primary |
| ce | cross | | primary |
When I route I should get
| waypoints | route | turns | lanes |
| a,d | road,road | depart,arrive | , |
| a,e | road,cross,cross | depart,turn slight right,arrive | ,straight:false straight:false straight;slight right:true slight right:true, |
Scenario: Highway Ramp
Given the node map
| a | | b | | c | | d |
| | | | | | | e |
And the ways
| nodes | name | turn:lanes:forward | highway |
| abc | hwy | through\|through\|through;slight_right\|slight_right | motorway |
| cd | hwy | | motorway |
| ce | ramp | | motorway_link |
When I route I should get
| waypoints | route | turns | lanes |
| a,d | hwy,hwy | depart,arrive | , |
| a,e | hwy,ramp,ramp | depart,off ramp slight right,arrive | ,straight:false straight:false straight;slight right:true slight right:true, |
@bug @todo
Scenario: Turning Off Ramp
Given the node map
| | a | |
| d | c | b |
| e | f | g |
| | h | |
And the ways
| nodes | name | turn:lanes:forward | highway | oneway |
| ac | off | left\|right | motorway_link | yes |
| bcd | road | | primary | yes |
| cf | road | | primary | |
| efg | road | | primary | yes |
| fh | on | | motorway_link | yes |
When I route I should get
| waypoints | route | turns | lanes |
| a,d | off,road,road | depart,turn_right,arrive | ,left:false right:true, |
| a,g | off,road,road | depart,turn_left,arrive | ,left:true right:false, |
| a,h | | | |
Scenario: Off Ramp In a Turn
Given the node map
| a | | | | | | | | | | | |
| | | | | | | | | | | | |
| | | | | | b | | | | | | c |
| | | | | | | | | | | d | |
And the ways
| nodes | name | turn:lanes:forward | highway | oneway |
| ab | hwy | through\|through\|slight_right | motorway | yes |
| bc | hwy | | motorway | yes |
| bd | ramp | | motorway_link | yes |
When I route I should get
| waypoints | route | turns | lanes |
| a,c | hwy,hwy | depart,arrive | , |
| a,d | hwy,ramp,ramp | depart,off ramp slight right,arrive | ,straight:false straight:false slight right:true, |
Scenario: Reverse Lane in Segregated Road
Given the node map
| h | | | | | g | | | | | | f |
| | | | | | | | e | | | | |
| | | | | | | | d | | | | |
| a | | | | | b | | | | | | c |
And the ways
| nodes | name | turn:lanes:forward | highway | oneway |
| ab | road | reverse\|through\|through | primary | yes |
| bc | road | | primary | yes |
| bdeg | road | | primary_link | yes |
| fgh | road | | primary | yes |
When I route I should get
| waypoints | route | turns | lanes |
| a,h | road,road,road | depart,continue uturn,arrive | ,uturn:true straight:false straight:false,|
Scenario: Reverse Lane in Segregated Road with none
Given the node map
| h | | | | | g | | | | | | f |
| | | | | | | | e | | | | |
| | | | | | | | d | | | | |
| a | | | | | b | | | | | | c |
And the ways
| nodes | name | turn:lanes:forward | highway | oneway |
| ab | road | reverse\|through\|none | primary | yes |
| bc | road | | primary | yes |
| bdeg | road | | primary_link | yes |
| fgh | road | | primary | yes |
When I route I should get
| waypoints | route | turns | lanes |
| a,h | road,road,road | depart,continue uturn,arrive | ,uturn:true straight:false none:false, |
Scenario: Reverse Lane in Segregated Road with none, Service Turn Prior
Given the node map
| h | | | | | g | | | | | | f |
| | | | | | | | e | | | | |
| | | | | | | | d | | | | |
| a | | j | | | b | | | | | | c |
| | | i | | | | | | | | | |
And the ways
| nodes | name | turn:lanes:forward | highway | oneway |
| ajb | road | reverse\|through\|none | primary | yes |
| bc | road | | primary | yes |
| bdeg | road | | primary_link | yes |
| fgh | road | | primary | yes |
| ji | park | | service | no |
When I route I should get
| waypoints | route | turns | lanes |
| a,h | road,road,road | depart,continue uturn,arrive | ,uturn:true straight:false none:false, |
Scenario: Don't collapse everything to u-turn / too wide
Given the node map
| a | | b | | e |
| | | | | |
| d | | c | | f |
And the ways
| nodes | highway | name | turn:lanes:forward |
| ab | primary | road | through\|right |
| bc | primary | road | |
| dc | primary | road | left\|through |
| be | secondary | top | |
| cf | secondary | bottom | |
When I route I should get
| waypoints | turns | route | lanes |
| a,d | depart,continue right,turn right,arrive | road,road,road,road | ,straight:false right:true,, |
| d,a | depart,continue left,turn left,arrive | road,road,road,road | ,left:true straight:false,, |
Scenario: Merge Lanes Onto Freeway
Given the node map
| a | | | b | c |
| | d | | | |
And the ways
| nodes | highway | name | turn:lanes:forward |
| abc | motorway | Hwy | |
| db | motorway_link | ramp | slight_right\|slight_right |
When I route I should get
| waypoints | turns | route | lanes |
| d,c | depart,merge slight left,arrive | ramp,Hwy,Hwy | ,slight right:true slight right:true, |
Scenario: Fork on motorway links - don't fork on through but use lane
Given the node map
| i | | | | | a |
| j | | c | b | | x |
And the ways
| nodes | name | highway | turn:lanes:forward |
| xb | xbcj | motorway_link | |
| bc | xbcj | motorway_link | none\|slight_right |
| cj | xbcj | motorway_link | |
| ci | off | motorway_link | |
| ab | on | motorway_link | |
When I route I should get
| waypoints | route | turns | lanes |
| a,j | on,xbcj,xbcj | depart,merge slight left,arrive | ,, |
| a,i | on,xbcj,off,off | depart,merge slight left,turn slight right,arrive | ,,none:false slight right:true, |
#http://www.openstreetmap.org/#map=17/52.47414/13.35712
@todo @ramp @2645
Scenario: Kreuz Schoeneberg - Continue on ramp, don't merge
Given the node map
| i | | | | | j | | | | | | | | | | | |
| | | | | k | | | | | | | | | | | | |
| h | g | | l | | | f | | | | | | | | | | e |
| d | | | | | | | | c | | | | | b | | | a |
And the ways
| nodes | highway | name | oneway | lanes | turn:lanes |
| ab | motorway | A 100 | yes | 3 | |
| bc | motorway | A 100 | yes | 4 | \|\|\|slight_right |
| cd | motorway | A 100 | yes | 3 | |
| eb | motorway_link | | yes | 1 | |
| cf | motorway_link | | yes | 1 | |
| fj | motorway_link | | yes | 1 | |
| fl | motorway_link | | yes | 1 | |
| kl | motorway_link | | yes | 1 | |
| lg | motorway_link | | yes | 2 | through\|slight_right |
| gi | motorway_link | | yes | 1 | |
| gh | motorway_link | | yes | 1 | |
When I route I should get
| waypoints | route | turns | lanes |
| a,d | A 100,A 100 | depart,arrive | |
| a,i | A 100,,,, | depart,off ramp slight right,fork slight left,turn right,arrive | ,none:false none:false none:false slight right:true,,straight:false slight right:true, |
| e,j | ,,, | depart,off ramp slight right,fork slight right,arrive | ,none:false none:false none:false slight right:true,,, |
| e,i | ,,,, | depart,off ramp right,fork slight left,use lane straight,arrive | ,none:false none:false none:false slight right:true,,straight:false slight right:true, |
| e,d | ,A 100,A 100 | depart,merge slight left,arrive | ,, |
| e,h | ,,,, | depart,off ramp right,fork left,use lane straight,arrive | ,none:false none:false none:false slight right:true,,straight:true slight right:false, |
@collapse @use-lane
Scenario: Collapse Multiple Use Lanes
Given the node map
| x | a | | b | | | c | | | d |
| | | | e | | | f | | | |
And the ways
| nodes | name | highway | turn:lanes:forward |
| ab | road | primary | through,right |
| bc | road | primary | through,right |
| cd | road | primary | |
| xa | road | primary | |
| be | turn | primary | |
| cf | turn | primary | |
When I route I should get
| waypoints | route | turns | lanes |
| x,d | road,road | depart,arrive | , |
Scenario: Lane Parsing Issue #2694
Given the node map
| | c |
| a | b |
| | d |
And the ways
| nodes | highway | turn:lanes:forward |
| ab | primary | left;left\|right |
| bc | primary | |
| bd | primary | |
When I route I should get
| waypoints | route | turns | lanes |
| a,c | ab,bc,bc | depart,turn left,arrive | ,left:true right:false, |
# http://www.openstreetmap.org/#map=19/47.97685/7.82933&layers=D
@bug @todo
Scenario: Lane Parsing Issue #2706: None Assignments I
Given the node map
| | f | | | j | |
| | | | | | |
| a | b | c | | d | e |
| | | | | | |
| | | | | i | |
| | g | | | h | |
And the nodes
| node | highway |
| a | traffic_signals |
| i | traffic_signals |
And the ways
| nodes | highway | name | oneway | turn:lanes:forward |
| ab | secondary | Wiesentalstr | | through;left\|right |
| bc | secondary | Wiesentalstr | | none\|left;through |
| cd | secondary | Wiesentalstr | | none\|left;through |
| de | residential | Wippertstr | | |
| fb | secondary | Merzhauser Str | yes | through\|through\|right |
| bg | secondary | Merzhauser Str | yes | |
| hi | secondary | Merzhauser Str | yes | left;reverse\|none\|none |
| ic | secondary_link | Merzhauser Str | yes | |
| id | secondary | Merzhauser Str | yes | through;right\|none |
| dj | secondary | Merzhauser Str | yes | |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | fb | fb | b | no_left_turn |
| restriction | ic | cb | c | only_left_turn |
| restriction | id | dc | d | no_left_turn |
When I route I should get
| waypoints | route | turns | lanes |
| h,a ||||
# Note: at the moment we don't care about routes, we care about the extract process triggering assertions
# https://www.openstreetmap.org/#map=19/47.99257/7.83276&layers=D
@bug @todo
Scenario: Lane Parsing Issue #2706: None Assignments II
Given the node map
| | k | l | |
| j | a | b | f |
| i | c | d | e |
| | h | g | |
And the ways
| nodes | highway | name | oneway | turn:lanes |
| ka | secondary | Eschholzstr | yes | left;reverse\|through\|through\|none |
| kj | unclassified | kj | yes | |
| ac | secondary | Eschholzstr | yes | left;reverse\|none\|none\|none |
| ch | secondary | Eschholzstr | yes | |
| gd | secondary | Eschholzstr | yes | left;reverse\|through\|through\|none |
| db | secondary | Eschholzstr | yes | left;reverse\|through\|through\|none |
| bl | secondary | Eschholzstr | yes | |
| fb | residential | Haslacher Str | yes | left;reverse\|left;through\|right |
| ba | secondary_link | Haslacher Str | yes | left;reverse\|left;through |
| aj | unclassified | Haslacher Str | yes | |
| ic | unclassified | Haslacher Str | yes | left;reverse\|left\|through |
| cd | secondary_link | Haslacher Str | yes | left;reverse\|left\|through |
| de | residential | Haslacher Str | yes | |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | ka | ac | a | only_straight_on |
| restriction | ic | cd | c | only_straight_on |
| restriction | gd | db | d | only_straight_on |
When I route I should get
| waypoints | route | turns | lanes |
| i,e ||||
# Note: at the moment we don't care about routes, we care about the extract process triggering assertions
@bug @todo
Scenario: Lane Parsing Issue #2706: None Assignments III - Minimal reproduction recipe
Given the node map
| | | l | |
| | a | b | |
| | | d | |
| | | | |
And the ways
| nodes | highway | name | oneway | turn:lanes |
| db | secondary | Eschholzstr | yes | left;reverse\|through\|through\|none |
| bl | secondary | Eschholzstr | yes | |
| ba | secondary_link | Haslacher Str | yes | |
When I route I should get
| waypoints | route | turns | lanes |
| d,a ||||
# Note: at the moment we don't care about routes, we care about the extract process triggering assertions
+73
View File
@@ -806,3 +806,76 @@ Feature: Simple Turns
| a,e | abc,be,be | depart,turn right,arrive |
| a,f | abc,bf,bf | depart,turn slight right,arrive |
Scenario: Turn Lane on Splitting up Road
Given the node map
| | | | | | | | | | | | | | | |
| g | | | | f | | | | | | | | | | |
| | | | | | | | | | | | | | | |
| | | | | | h | | | e | | | c | | | d |
| a | | | b | | | | | | | | | | | |
| | | | i | | | | | | | | | | | |
And the ways
| nodes | highway | oneway | name |
| ab | secondary | yes | road |
| be | secondary | yes | road |
| ecd | secondary | no | road |
| efg | secondary | yes | road |
| ehb | secondary_link | yes | road |
| bi | tertiary | no | cross |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | ehb | be | b | no_left_turn |
When I route I should get
| waypoints | route | turns |
| a,d | road,road | depart,arrive |
| d,i | road,cross,cross | depart,turn left,arrive |
| d,g | road,road | depart,arrive |
Scenario: Go onto turning major road
Given the node map
| | | | c |
| | | | |
| | | | |
| a | | | b |
| | | | |
| | | | d |
And the ways
| nodes | highway | name |
| abc | primary | road |
| bd | residential | in |
When I route I should get
| waypoints | turns | route |
| a,c | depart,arrive | road,road |
| d,a | depart,turn left,arrive | in,road,road |
| d,c | depart,new name straight,arrive | in,road,road |
Scenario: Channing Street
Given the node map
| | | g | f | |
| | | | | |
| d | | c | b | a |
| | | | | |
| | | | | |
| | | h | e | |
And the nodes
| node | highway |
| c | traffic_signals |
| b | traffic_signals |
And the ways
| nodes | name | highway | oneway |
| ab | Channing Street Northeast | residential | no |
| bcd | Channing Street Northwest | residential | yes |
| ebf | North Capitol Street Northeast | primary | yes |
| gch | North Capitol Street Northeast | primary | yes |
When I route I should get
| waypoints | turns | route |
| a,d | depart,arrive | Channing Street Northeast,Channing Street Northwest |
| a,h | depart,turn left,arrive | Channing Street Northeast,North Capitol Street Northeast,North Capitol Street Northeast |
@@ -0,0 +1,30 @@
@prepare @options @files
Feature: osrm-contract command line options: datasources
# expansions:
# {extracted_base} => path to current extracted input file
# {profile} => path to current profile script
Background:
Given the profile "testbot"
Given the extract extra arguments "--generate-edge-lookup"
And the node map
| a | b |
And the ways
| nodes |
| ab |
And the speed file
"""
1,2,27
2,1,27
2,3,27
3,2,27
1,4,27
4,1,27
"""
And the data has been extracted
Scenario: osrm-contract - Passing base file
When I run "osrm-contract --segment-speed-file speeds.csv {extracted_base}.osrm"
Then stderr should be empty
And datasource names should contain "lua profile,speeds"
And it should exit with code 0
+9 -4
View File
@@ -17,7 +17,7 @@ module.exports = function () {
this.setContractArgs(args, callback);
});
this.Given(/^a grid size of (\d+) meters$/, (meters, callback) => {
this.Given(/^a grid size of ([0-9.]+) meters$/, (meters, callback) => {
this.setGridSize(meters);
callback();
});
@@ -228,14 +228,17 @@ module.exports = function () {
});
this.Given(/^the raster source$/, (data, callback) => {
this.updateFingerprintExtract(data);
fs.writeFile(path.resolve(this.TEST_FOLDER, 'rastersource.asc'), data, callback);
});
this.Given(/^the speed file$/, (data, callback) => {
this.updateFingerprintContract(data);
fs.writeFile(path.resolve(this.TEST_FOLDER, 'speeds.csv'), data, callback);
});
this.Given(/^the turn penalty file$/, (data, callback) => {
this.updateFingerprintContract(data);
fs.writeFile(path.resolve(this.TEST_FOLDER, 'penalties.csv'), data, callback);
});
@@ -249,9 +252,11 @@ module.exports = function () {
});
this.Given(/^the data has been extracted$/, (callback) => {
this.writeAndExtract((err) => {
if (err) this.processError = err;
callback();
this.osmData.populate(() => {
this.writeAndExtract((err) => {
if (err) this.processError = err;
callback();
});
});
});
-12
View File
@@ -15,16 +15,4 @@ module.exports = function () {
this.setOrigin(this.DEFAULT_ORIGIN);
callback();
});
this.Before('@ignore-platform-windows', () => {
this.skipThisScenario();
});
this.Before('@ignore-platform-unix', () => {
this.skipThisScenario();
});
this.Before('@ignore-platform-mac', () => {
this.skipThisScenario();
});
};
+36 -1
View File
@@ -1,5 +1,6 @@
var util = require('util');
var d3 = require('d3-queue');
var polyline = require('polyline');
module.exports = function () {
this.When(/^I match I should get$/, (table, callback) => {
@@ -33,7 +34,11 @@ module.exports = function () {
var subMatchings = [],
turns = '',
route = '',
duration = '';
duration = '',
annotation = '',
geometry = '',
OSMIDs = '';
if (res.statusCode === 200) {
if (headers.has('matchings')) {
@@ -54,6 +59,21 @@ module.exports = function () {
if (json.matchings.length != 1) throw new Error('*** Checking duration only supported for matchings with one subtrace');
duration = json.matchings[0].duration;
}
if (headers.has('annotation')) {
if (json.matchings.length != 1) throw new Error('*** Checking annotation only supported for matchings with one subtrace');
annotation = this.annotationList(json.matchings[0]);
}
if (headers.has('geometry')) {
if (json.matchings.length != 1) throw new Error('*** Checking geometry only supported for matchings with one subtrace');
geometry = json.matchings[0].geometry;
}
if (headers.has('OSM IDs')) {
if (json.matchings.length != 1) throw new Error('*** CHecking annotation only supported for matchings with one subtrace');
OSMIDs = this.OSMIDList(json.matchings[0]);
}
}
if (headers.has('turns')) {
@@ -68,6 +88,21 @@ module.exports = function () {
got.duration = duration.toString();
}
if (headers.has('annotation')) {
got.annotation = annotation.toString();
}
if (headers.has('geometry')) {
if (this.queryParams['geometries'] === 'polyline')
got.geometry = polyline.decode(geometry).toString();
else
got.geometry = geometry;
}
if (headers.has('OSM IDs')) {
got['OSM IDs'] = OSMIDs;
}
var ok = true;
var encodedResult = '',
extendedTarget = '';
+6
View File
@@ -1,4 +1,5 @@
var assert = require('assert');
var fs = require('fs');
module.exports = function () {
this.When(/^I run "osrm\-routed\s?(.*?)"$/, { timeout: this.TIMEOUT }, (options, callback) => {
@@ -59,6 +60,11 @@ module.exports = function () {
assert.equal(this.stdout.split('\n').length - 1, parseInt(lines));
});
this.Then(/^datasource names should contain "(.+)"$/, (expectedData) => {
var actualData = fs.readFileSync(this.osmData.extractedFile + '.osrm.datasource_names', {encoding:'UTF-8'}).trim().split('\n').join(',');
assert.equal(actualData, expectedData);
});
this.Given(/^the query options$/, (table, callback) => {
table.raw().forEach(tuple => {
this.queryParams[tuple[0]] = tuple[1];
+2 -1
View File
@@ -12,7 +12,8 @@ module.exports = function () {
throw new Error('*** routability table must contain either "forw", "backw" or "bothw" column');
}
this.reprocessAndLoadData(() => {
this.reprocessAndLoadData((e) => {
if (e) callback(e);
var testRow = (row, i, cb) => {
var outputRow = row;
+2 -2
View File
@@ -46,8 +46,8 @@ module.exports = function () {
if (headers.has('trips')) {
subTrips = json.trips.filter(t => !!t).map(t => t.legs).map(tl => Array.prototype.concat.apply([], tl.map((sl, i) => {
var toAdd = [];
if (i === 0) toAdd.push(sl.steps[0].maneuver.location);
toAdd.push(sl.steps[sl.steps.length-1].maneuver.location);
if (i === 0) toAdd.push(sl.steps[0].intersections[0].location);
toAdd.push(sl.steps[sl.steps.length-1].intersections[0].location);
return toAdd;
})));
}
+22 -13
View File
@@ -50,22 +50,27 @@ module.exports = function () {
};
var hashExtract = (cb) => {
this.hashOfFiles(util.format('%s/osrm-extract%s', this.BIN_PATH, this.EXE), (hash) => {
var files = [ util.format('%s/osrm-extract%s', this.BIN_PATH, this.EXE),
util.format('%s/libosrm_extract%s', this.BIN_PATH, this.LIB) ];
this.hashOfFiles(files, (hash) => {
this.binExtractHash = hash;
cb();
});
};
var hashContract = (cb) => {
this.hashOfFiles(util.format('%s/osrm-contract%s', this.BIN_PATH, this.EXE), (hash) => {
var files = [ util.format('%s/osrm-contract%s', this.BIN_PATH, this.EXE),
util.format('%s/libosrm_contract%s', this.BIN_PATH, this.LIB) ];
this.hashOfFiles(files, (hash) => {
this.binContractHash = hash;
this.fingerprintContract = this.hashString(this.binContractHash);
cb();
});
};
var hashRouted = (cb) => {
this.hashOfFiles(util.format('%s/osrm-routed%s', this.BIN_PATH, this.EXE), (hash) => {
var files = [ util.format('%s/osrm-routed%s', this.BIN_PATH, this.EXE),
util.format('%s/libosrm%s', this.BIN_PATH, this.LIB) ];
this.hashOfFiles(files, (hash) => {
this.binRoutedHash = hash;
this.fingerprintRoute = this.hashString(this.binRoutedHash);
cb();
@@ -79,16 +84,18 @@ module.exports = function () {
.defer(hashContract)
.defer(hashRouted)
.awaitAll(() => {
this.fingerprintExtract = this.hashString([this.profileHash, this.luaLibHash, this.binExtractHash].join('-'));
this.AfterConfiguration(() => {
callback();
});
});
};
this.setProfileBasedHashes = () => {
this.fingerprintExtract = this.hashString([this.profileHash, this.luaLibHash, this.binExtractHash].join('-'));
this.fingerprintContract = this.hashString(this.binContractHash);
this.updateFingerprintExtract = (str) => {
this.fingerprintExtract = this.hashString([this.fingerprintExtract, str].join('-'));
};
this.updateFingerprintContract = (str) => {
this.fingerprintContract = this.hashString([this.fingerprintContract, str].join('-'));
};
this.setProfile = (profile, cb) => {
@@ -97,22 +104,24 @@ module.exports = function () {
this.profile = profile;
this.hashProfile((hash) => {
this.profileHash = hash;
this.setProfileBasedHashes();
this.updateFingerprintExtract(this.profileHash);
cb();
});
} else cb();
} else {
this.updateFingerprintExtract(this.profileHash);
cb();
}
};
this.setExtractArgs = (args, callback) => {
this.extractArgs = args;
this.forceExtract = true;
this.forceContract = true;
this.updateFingerprintExtract(args);
callback();
};
this.setContractArgs = (args, callback) => {
this.contractArgs = args;
this.forceContract = true;
this.updateFingerprintContract(args);
callback();
};
};
+45 -30
View File
@@ -194,8 +194,8 @@ module.exports = function () {
this.extractData = (callback) => {
this.logPreprocessInfo();
this.log(util.format('== Extracting %s.osm...', this.osmData.osmFile), 'preprocess');
var cmd = util.format('%s%s/osrm-extract %s.osm %s --profile %s/%s.lua >>%s 2>&1',
this.LOAD_LIBRARIES, this.BIN_PATH, this.osmData.osmFile, this.extractArgs || '', this.PROFILES_PATH, this.profile, this.PREPROCESS_LOG_FILE);
var cmd = util.format('%s/osrm-extract %s.osm %s --profile %s/%s.lua >>%s 2>&1',
this.BIN_PATH, this.osmData.osmFile, this.extractArgs || '', this.PROFILES_PATH, this.profile, this.PREPROCESS_LOG_FILE);
this.log(cmd);
process.chdir(this.TEST_FOLDER);
exec(cmd, (err) => {
@@ -222,11 +222,12 @@ module.exports = function () {
});
};
['osrm','osrm.names','osrm.restrictions','osrm.ebg','osrm.enw','osrm.edges','osrm.fileIndex','osrm.geometry','osrm.nodes','osrm.ramIndex','osrm.properties'].forEach(file => {
q.defer(rename, file);
});
['osrm', 'osrm.ebg', 'osrm.edges', 'osrm.enw', 'osrm.fileIndex', 'osrm.geometry', 'osrm.icd',
'osrm.names', 'osrm.nodes', 'osrm.properties', 'osrm.ramIndex', 'osrm.restrictions', 'osrm.tld', 'osrm.tls'].forEach(file => {
q.defer(rename, file);
});
['osrm.edge_segment_lookup','osrm.edge_penalties'].forEach(file => {
['osrm.edge_penalties', 'osrm.edge_segment_lookup'].forEach(file => {
q.defer(renameIfExists, file);
});
@@ -241,8 +242,8 @@ module.exports = function () {
this.contractData = (callback) => {
this.logPreprocessInfo();
this.log(util.format('== Contracting %s.osm...', this.osmData.extractedFile), 'preprocess');
var cmd = util.format('%s%s/osrm-contract %s %s.osrm >>%s 2>&1',
this.LOAD_LIBRARIES, this.BIN_PATH, this.contractArgs || '', this.osmData.extractedFile, this.PREPROCESS_LOG_FILE);
var cmd = util.format('%s/osrm-contract %s %s.osrm >>%s 2>&1',
this.BIN_PATH, this.contractArgs || '', this.osmData.extractedFile, this.PREPROCESS_LOG_FILE);
this.log(cmd);
process.chdir(this.TEST_FOLDER);
exec(cmd, (err) => {
@@ -260,6 +261,13 @@ module.exports = function () {
});
};
var renameIfExists = (file, cb) => {
fs.stat([this.osmData.extractedFile, file].join('.'), (doesNotExistErr, exists) => {
if (exists) rename(file, cb);
else cb();
});
};
var copy = (file, cb) => {
this.log(util.format('Copying %s.%s to %s.%s', this.osmData.extractedFile, file, this.osmData.contractedFile, file), 'preprocess');
fs.createReadStream([this.osmData.extractedFile, file].join('.'))
@@ -273,11 +281,17 @@ module.exports = function () {
var q = d3.queue();
['osrm.hsgr','osrm.fileIndex','osrm.geometry','osrm.nodes','osrm.ramIndex','osrm.core','osrm.edges','osrm.datasource_indexes','osrm.datasource_names','osrm.level'].forEach((file) => {
q.defer(rename, file);
['osrm', 'osrm.core', 'osrm.datasource_indexes', 'osrm.datasource_names', 'osrm.ebg','osrm.edges',
'osrm.enw', 'osrm.fileIndex', 'osrm.geometry', 'osrm.hsgr', 'osrm.icd','osrm.level', 'osrm.names',
'osrm.nodes', 'osrm.properties', 'osrm.ramIndex', 'osrm.restrictions', 'osrm.tld', 'osrm.tls'].forEach((file) => {
q.defer(rename, file);
});
['osrm.edge_penalties', 'osrm.edge_segment_lookup'].forEach(file => {
q.defer(renameIfExists, file);
});
['osrm.names','osrm.restrictions','osrm.properties','osrm'].forEach((file) => {
[].forEach((file) => {
q.defer(copy, file);
});
@@ -292,32 +306,33 @@ module.exports = function () {
var noop = (cb) => cb();
this.reprocess = (callback) => {
this.writeAndExtract((e) => {
if (e) return callback(e);
this.osmData.populate(() => {
this.isContracted((isContracted) => {
var contractFn = (isContracted && !this.forceContract) ? noop : this.contractData;
if (isContracted) this.log('Already contracted ' + this.osmData.contractedFile, 'preprocess');
contractFn((e) => {
this.forceContract = false;
if (e) return callback(e);
this.logPreprocessDone();
if (!isContracted) {
this.writeAndExtract((e) => {
if (e) return callback(e);
this.contractData((e) => {
if (e) return callback(e);
this.logPreprocessDone();
callback();
});
});
} else {
this.log('Already contracted ' + this.osmData.contractedFile, 'preprocess');
callback();
});
}
});
});
};
this.writeAndExtract = (callback) => {
this.osmData.populate(() => {
this.writeInputData((e) => {
if (e) return callback(e);
this.isExtracted((isExtracted) => {
var extractFn = (isExtracted && !this.forceExtract) ? noop : this.extractData;
if (isExtracted) this.log('Already extracted ' + this.osmData.extractedFile, 'preprocess');
extractFn((e) => {
this.forceExtract = false;
callback(e);
});
this.writeInputData((e) => {
if (e) return callback(e);
this.isExtracted((isExtracted) => {
var extractFn = isExtracted ? noop : this.extractData;
if (isExtracted) this.log('Already extracted ' + this.osmData.extractedFile, 'preprocess');
extractFn((e) => {
callback(e);
});
});
});
+73 -6
View File
@@ -52,24 +52,91 @@ module.exports = {
match (got, want) {
var matchPercent = want.match(/(.*)\s+~(.+)%$/),
matchAbs = want.match(/(.*)\s+\+\-(.+)$/),
matchRe = want.match(/^\/(.*)\/$/);
matchRe = want.match(/^\/(.*)\/$/),
// we use this for matching before/after bearing
matchBearingListAbs = want.match(/^((\d+)->(\d+))(,(\d+)->(\d+))*\s+\+\-(.+)$/),
matchIntersectionListAbs = want.match(/^(((((true|false):\d+)\s{0,1})+,{0,1})+;{0,1})+\s+\+\-(.+)$/);
function inRange(margin, got, want) {
var fromR = parseFloat(want) - margin,
toR = parseFloat(want) + margin;
return parseFloat(got) >= fromR && parseFloat(got) <= toR;
}
function parseIntersectionString(str) {
return str.split(';')
.map((turn_intersections) => turn_intersections
.split(',')
.map((intersection) => intersection
.split(' ')
.map((entry_bearing_pair) => entry_bearing_pair
.split(':'))));
}
if (got === want) {
return true;
} else if (matchBearingListAbs) {
let want_and_margin = want.split('+-'),
margin = parseFloat(want_and_margin[1].trim()),
want_pairs = want_and_margin[0].trim().split(',').map((pair) => pair.split('->')),
got_pairs = got.split(',').map((pair) => pair.split('->'));
if (want_pairs.length != got_pairs.length)
{
return false;
}
for (var i = 0; i < want_pairs.length; ++i)
{
if (!inRange(margin, got_pairs[i][0], want_pairs[i][0]) ||
!inRange(margin, got_pairs[i][1], want_pairs[i][1]))
{
return false;
}
}
return true;
} else if (matchIntersectionListAbs) {
let margin = parseFloat(want.split('+-')[1]),
want_intersections = parseIntersectionString(want.split('+-')[0].trim()),
got_intersections = parseIntersectionString(got);
if (want_intersections.length != got_intersections.length)
{
return false;
}
for (let step_idx = 0; step_idx < want_intersections.length; ++step_idx)
{
if (want_intersections[step_idx].length != got_intersections[step_idx].length)
{
return false;
}
for (let intersection_idx = 0; intersection_idx < want_intersections[step_idx].length; ++intersection_idx)
{
if (want_intersections[step_idx][intersection_idx].length != got_intersections[step_idx][intersection_idx].length)
{
return false;
}
for (let pair_idx = 0; pair_idx < want_intersections[step_idx][intersection_idx].length; ++pair_idx)
{
let want_pair = want_intersections[step_idx][intersection_idx][pair_idx],
got_pair = got_intersections[step_idx][intersection_idx][pair_idx];
if (got_pair[0] != want_pair[0] ||
!inRange(margin, got_pair[1], want_pair[1]))
{
return false;
}
}
}
}
return true;
} else if (matchPercent) { // percentage range: 100 ~ 5%
var target = parseFloat(matchPercent[1]),
percentage = parseFloat(matchPercent[2]);
if (target === 0) {
return true;
} else {
var ratio = Math.abs(1 - parseFloat(got) / target);
let ratio = Math.abs(1 - parseFloat(got) / target);
return 100 * ratio < percentage;
}
} else if (matchAbs) { // absolute range: 100 +-5
var margin = parseFloat(matchAbs[2]),
fromR = parseFloat(matchAbs[1]) - margin,
toR = parseFloat(matchAbs[1]) + margin;
return parseFloat(got) >= fromR && parseFloat(got) <= toR;
let margin = parseFloat(matchAbs[2]);
return inRange(margin, got, matchAbs[1]);
} else if (matchRe) { // regex: /a,b,.*/
return got.match(matchRe[1]);
} else {
+5 -8
View File
@@ -7,7 +7,7 @@ var d3 = require('d3-queue');
module.exports = function () {
this.initializeEnv = (callback) => {
this.OSRM_PORT = process.env.OSRM_PORT && parseInt(process.env.OSRM_PORT) || 5000;
this.TIMEOUT = process.env.CUCUMBER_TIMEOUT && parseInt(process.env.CUCUMBER_TIMEOUT) || 3000;
this.TIMEOUT = process.env.CUCUMBER_TIMEOUT && parseInt(process.env.CUCUMBER_TIMEOUT) || 5000;
this.setDefaultTimeout(this.TIMEOUT);
this.ROOT_FOLDER = process.cwd();
this.OSM_USER = 'osrm';
@@ -21,26 +21,23 @@ module.exports = function () {
this.DEFAULT_GRID_SIZE = 100; // meters
this.PROFILES_PATH = path.resolve(this.ROOT_FOLDER, 'profiles');
this.FIXTURES_PATH = path.resolve(this.ROOT_FOLDER, 'unit_tests/fixtures');
this.BIN_PATH = path.resolve(this.ROOT_FOLDER, 'build');
this.BIN_PATH = process.env.OSRM_BUILD_DIR && process.env.OSRM_BUILD_DIR || path.resolve(this.ROOT_FOLDER, 'build');
this.DEFAULT_INPUT_FORMAT = 'osm';
this.DEFAULT_ORIGIN = [1,1];
this.DEFAULT_LOAD_METHOD = 'datastore';
this.OSRM_ROUTED_LOG_FILE = path.resolve(this.TEST_FOLDER, 'osrm-routed.log');
this.ERROR_LOG_FILE = path.resolve(this.TEST_FOLDER, 'error.log');
// OS X shim to ensure shared libraries from custom locations can be loaded
// This is needed in OS X >= 10.11 because DYLD_LIBRARY_PATH is blocked
// https://forums.developer.apple.com/thread/9233
this.LOAD_LIBRARIES = process.env.OSRM_SHARED_LIBRARY_PATH ? util.format('DYLD_LIBRARY_PATH=%s ', process.env.OSRM_SHARED_LIBRARY_PATH) : '';
// TODO make sure this works on win
if (process.platform.match(/indows.*/)) {
this.TERMSIGNAL = 9;
this.EXE = '.exe';
this.LIB = '.dll';
this.QQ = '"';
} else {
this.TERMSIGNAL = 'SIGTERM';
this.EXE = '';
this.LIB = '.so';
this.QQ = '';
}
@@ -65,7 +62,7 @@ module.exports = function () {
var binPath = path.resolve(util.format('%s/%s%s', this.BIN_PATH, bin, this.EXE));
fs.exists(binPath, (exists) => {
if (!exists) throw new Error(util.format('%s is missing. Build failed?', binPath));
var helpPath = util.format('%s%s --help > /dev/null 2>&1', this.LOAD_LIBRARIES, binPath);
var helpPath = util.format('%s --help > /dev/null 2>&1', binPath);
exec(helpPath, (err) => {
if (err) {
this.log(util.format('*** Exited with code %d', err.code), 'preprocess');
+9 -3
View File
@@ -6,14 +6,19 @@ var d3 = require('d3-queue');
module.exports = function () {
this.hashOfFiles = (paths, cb) => {
paths = Array.isArray(paths) ? paths : [paths];
var shasum = crypto.createHash('sha1');
var shasum = crypto.createHash('sha1'), hashedFiles = false;
var q = d3.queue(1);
var addFile = (path, cb) => {
fs.readFile(path, (err, data) => {
shasum.update(data);
cb(err);
if (err && err.code === 'ENOENT') cb(); // ignore non-existing files
else if (err) cb(err);
else {
shasum.update(data);
hashedFiles = true;
cb();
}
});
};
@@ -21,6 +26,7 @@ module.exports = function () {
q.awaitAll(err => {
if (err) throw new Error('*** Error reading files:', err);
if (!hashedFiles) throw new Error('*** No files found: [' + paths.join(', ') + ']');
cb(shasum.digest('hex'));
});
};
+2 -5
View File
@@ -20,6 +20,8 @@ module.exports = function () {
this.hasLoggedScenarioInfo = false;
this.setGridSize(this.DEFAULT_GRID_SIZE);
this.setOrigin(this.DEFAULT_ORIGIN);
this.fingerprintExtract = this.hashString([this.luaLibHash, this.binExtractHash].join('-'));
this.fingerprintContract = this.hashString(this.binContractHash);
callback();
});
@@ -31,9 +33,4 @@ module.exports = function () {
});
});
});
this.Around('@stress', (scenario, callback) => {
// TODO implement stress timeout? Around support is being dropped in cucumber-js anyway
callback();
});
};
+20 -19
View File
@@ -1,9 +1,9 @@
'use strict';
var fs = require('fs');
var net = require('net');
var spawn = require('child_process').spawn;
var util = require('util');
var net = require('net');
var Timeout = require('node-timeout');
var OSRMBaseLoader = class {
@@ -15,9 +15,7 @@ var OSRMBaseLoader = class {
var limit = Timeout(this.scope.TIMEOUT, { err: this.scope.RoutedError('Launching osrm-routed timed out.') });
var runLaunch = (cb) => {
this.osrmUp(() => {
this.waitForConnection(cb);
});
this.osrmUp(() => { this.waitForConnection(cb); });
};
runLaunch(limit((e) => { if (e) callback(e); else callback(); }));
@@ -46,18 +44,21 @@ var OSRMBaseLoader = class {
}
waitForConnection (callback) {
net.connect({
port: this.scope.OSRM_PORT,
host: '127.0.0.1'
})
.on('connect', () => {
callback();
})
.on('error', (e) => {
setTimeout(() => {
callback(e);
}, 100);
});
var retryCount = 0;
var connectWithRetry = () => {
net.connect({ port: this.scope.OSRM_PORT, host: '127.0.0.1' })
.on('connect', () => { callback(); })
.on('error', () => {
if (retryCount < 2) {
retryCount++;
setTimeout(connectWithRetry, 100);
} else {
callback(new Error('Could not connect to osrm-routed after three retires'));
}
});
};
connectWithRetry();
}
waitForShutdown (callback) {
@@ -86,7 +87,7 @@ var OSRMDirectLoader = class extends OSRMBaseLoader {
fs.appendFile(this.scope.OSRM_ROUTED_LOG_FILE, data, (err) => { if (err) throw err; });
};
var child = spawn(util.format('%s%s/osrm-routed', this.scope.LOAD_LIBRARIES, this.scope.BIN_PATH), [this.inputFile, util.format('-p%d', this.scope.OSRM_PORT)]);
var child = spawn(util.format('%s/osrm-routed', this.scope.BIN_PATH), [this.inputFile, util.format('-p%d', this.scope.OSRM_PORT)]);
this.scope.pid = child.pid;
child.stdout.on('data', writeToLog);
child.stderr.on('data', writeToLog);
@@ -122,7 +123,7 @@ var OSRMDatastoreLoader = class extends OSRMBaseLoader {
fs.appendFile(this.scope.OSRM_ROUTED_LOG_FILE, data, (err) => { if (err) throw err; });
};
var child = spawn(util.format('%s%s/osrm-routed', this.scope.LOAD_LIBRARIES, this.scope.BIN_PATH), ['--shared-memory=1', util.format('-p%d', this.scope.OSRM_PORT)]);
var child = spawn(util.format('%s/osrm-routed', this.scope.BIN_PATH), ['--shared-memory=1', util.format('-p%d', this.scope.OSRM_PORT)]);
this.child = child;
this.scope.pid = child.pid;
child.stdout.on('data', writeToLog);
@@ -148,7 +149,7 @@ module.exports = {
this.loader = new OSRMDirectLoader(this.scope);
this.loader.load(inputFile, callback);
} else {
throw new Error('*** Unknown load method ' + method);
callback(new Error('*** Unknown load method ' + method));
}
}
+52 -1
View File
@@ -1,3 +1,5 @@
'use strict';
var Timeout = require('node-timeout');
var request = require('request');
@@ -137,8 +139,44 @@ module.exports = function () {
return this.extractInstructionList(instructions, s => s.name);
};
this.pronunciationList = (instructions) => {
return this.extractInstructionList(instructions, s => s.pronunciation || '');
};
this.destinationsList = (instructions) => {
return this.extractInstructionList(instructions, s => s.destinations || '');
};
this.bearingList = (instructions) => {
return this.extractInstructionList(instructions, s => s.maneuver.bearing_after);
return this.extractInstructionList(instructions, s => s.maneuver.bearing_before + '->' + s.maneuver.bearing_after);
};
this.annotationList = (instructions) => {
function zip(list_1, list_2)
{
let pairs = [];
for (let i = 0; i < list_1.length; ++i) {
pairs.push([list_1[i], list_2[i]]);
}
return pairs;
}
return instructions.legs.map(l => {return zip(l.annotation.duration, l.annotation.distance).map(p => { return p.join(':'); }).join(','); }).join(',');
};
this.OSMIDList = (instructions) => {
// OSM node IDs also come from the annotation list
return instructions.legs.map(l => l.annotation.nodes.map(n => n.toString()).join(',')).join(',');
};
this.lanesList = (instructions) => {
return this.extractInstructionList(instructions, instruction => {
if( 'lanes' in instruction.intersections[0] )
{
return instruction.intersections[0].lanes.map( p => { return (p.indications).join(';') + ':' + p.valid; } ).join(' ');
} else
{
return '';
}});
};
this.turnList = (instructions) => {
@@ -168,6 +206,19 @@ module.exports = function () {
.join(',');
};
this.intersectionList = (instructions) => {
return instructions.legs.reduce((m, v) => m.concat(v.steps), [])
.map( v => {
return v.intersections
.map( intersection => {
var string = intersection.entry[0]+':'+intersection.bearings[0], i;
for( i = 1; i < intersection.bearings.length; ++i )
string = string + ' ' + intersection.entry[i]+':'+intersection.bearings[i];
return string;
}).join(',');
}).join(';');
};
this.modeList = (instructions) => {
return this.extractInstructionList(instructions, s => s.mode);
};
+1 -1
View File
@@ -25,7 +25,7 @@ module.exports = function () {
opts = opts.replace('{profile}', [this.PROFILES_PATH, this.profile + '.lua'].join('/'));
}
var cmd = util.format('%s%s%s/%s%s%s %s 2>%s', this.QQ, this.LOAD_LIBRARIES, this.BIN_PATH, bin, this.EXE, this.QQ, opts, this.ERROR_LOG_FILE);
var cmd = util.format('%s%s/%s%s%s %s 2>%s', this.QQ, this.BIN_PATH, bin, this.EXE, this.QQ, opts, this.ERROR_LOG_FILE);
process.chdir(this.TEST_FOLDER);
exec(cmd, (err, stdout, stderr) => {
this.stdout = stdout.toString();
+20 -3
View File
@@ -1,3 +1,5 @@
'use strict';
var util = require('util');
var assert = require('assert');
@@ -31,19 +33,24 @@ module.exports = function () {
var afterRequest = (err, res, body) => {
if (err) return cb(err);
if (body && body.length) {
var instructions, bearings, turns, modes, times, distances, summary;
let destinations, pronunciations, instructions, bearings, turns, modes, times,
distances, summary, intersections, lanes;
var json = JSON.parse(body);
let json = JSON.parse(body);
var hasRoute = json.code === 'Ok';
let hasRoute = json.code === 'Ok';
if (hasRoute) {
instructions = this.wayList(json.routes[0]);
pronunciations = this.pronunciationList(json.routes[0]);
destinations = this.destinationsList(json.routes[0]);
bearings = this.bearingList(json.routes[0]);
turns = this.turnList(json.routes[0]);
intersections = this.intersectionList(json.routes[0]);
modes = this.modeList(json.routes[0]);
times = this.timeList(json.routes[0]);
distances = this.distanceList(json.routes[0]);
lanes = this.lanesList(json.routes[0]);
summary = this.summary(json.routes[0]);
}
@@ -97,6 +104,10 @@ module.exports = function () {
got.time = instructions ? util.format('%ds', time) : '';
}
if (headers.has('lanes')) {
got.lanes = (lanes || '').trim();
}
if (headers.has('speed')) {
if (row.speed !== '' && instructions) {
if (!row.speed.match(/\d+ km\/h/))
@@ -108,6 +119,10 @@ module.exports = function () {
}
}
if (headers.has('intersections')) {
got.intersections = (intersections || '').trim();
}
var putValue = (key, value) => {
if (headers.has(key)) got[key] = instructions ? value : '';
};
@@ -117,6 +132,8 @@ module.exports = function () {
putValue('modes', modes);
putValue('times', times);
putValue('distances', distances);
putValue('pronunciations', pronunciations);
putValue('destinations', destinations);
}
var ok = true;
+3 -2
View File
@@ -3,6 +3,7 @@ Feature: Alternative route
Background:
Given the profile "testbot"
And a grid size of 200 meters
And the node map
| | b | c | d | | |
@@ -17,11 +18,11 @@ Feature: Alternative route
| dz |
| ag |
| gh |
| ck |
| kh |
| hi |
| ij |
| jz |
| ck |
| kh |
Scenario: Enabled alternative
Given the query options
+38 -2
View File
@@ -56,7 +56,7 @@ Feature: Basic Routing
Scenario: Two ways connected in a straight line
Given the node map
| a | b | c |
| a | | b | | c |
And the ways
| nodes |
@@ -233,7 +233,7 @@ Feature: Basic Routing
| d | a | abcd,abcd |
| a | m | aeim,aeim |
| m | a | aeim,aeim |
Scenario: Testbot - Triangle challenge
Given the node map
| | | | d |
@@ -251,3 +251,39 @@ Feature: Basic Routing
| from | to | route |
| d | c | de,ce,ce |
| e | d | de,de |
Scenario: Ambiguous edge weights - Use minimal edge weight
Given the node map
| a | b |
And the ways
| nodes | highway | name |
| ab | tertiary | |
| ab | primary | |
| ab | secondary | |
When I route I should get
| from | to | route | time |
| a | b | , | 10s |
| b | a | , | 10s |
Scenario: Ambiguous edge names - Use lexicographically smallest name
Given the node map
| a | b | c |
And the ways
| nodes | highway | name |
| ab | primary | |
| ab | primary | Αβγ |
| ab | primary | |
| ab | primary | Abc |
| ab | primary | |
| ab | primary | Абв |
| bc | primary | Ηθι |
| bc | primary | Δεζ |
| bc | primary | Где |
When I route I should get
| from | to | route |
| a | c | Abc,Δεζ,Δεζ |
| c | a | Δεζ,Abc,Abc |
+91 -75
View File
@@ -14,8 +14,8 @@ Feature: Compass bearing
| ab |
When I route I should get
| from | to | route | bearing |
| a | b | ab,ab | 315,0 |
| from | to | route | bearing |
| a | b | ab,ab | 0->315,315->0|
Scenario: Bearing when going west
Given the node map
@@ -26,8 +26,8 @@ Feature: Compass bearing
| ab |
When I route I should get
| from | to | route | bearing |
| a | b | ab,ab | 270,0 |
| from | to | route | bearing |
| a | b | ab,ab | 0->270,270->0|
Scenario: Bearing af 45 degree intervals
Given the node map
@@ -48,21 +48,21 @@ Feature: Compass bearing
When I route I should get
| from | to | route | bearing |
| x | a | xa,xa | 0,0 |
| x | b | xb,xb | 315,0 |
| x | c | xc,xc | 270,0 |
| x | d | xd,xd | 225,0 |
| x | e | xe,xe | 180,0 |
| x | f | xf,xf | 135,0 |
| x | g | xg,xg | 90,0 |
| x | h | xh,xh | 45,0 |
| x | a | xa,xa | 0->0,0->0|
| x | b | xb,xb | 0->315,315->0|
| x | c | xc,xc | 0->270,270->0|
| x | d | xd,xd | 0->225,225->0|
| x | e | xe,xe | 0->180,180->0|
| x | f | xf,xf | 0->135,135->0|
| x | g | xg,xg | 0->90,90->0|
| x | h | xh,xh | 0->45,45->0|
Scenario: Bearing in a roundabout
Given the node map
| | d | c | |
| k | d | c | j |
| e | | | b |
| f | | | a |
| | g | h | |
| l | g | h | i |
And the ways
| nodes | oneway |
@@ -74,16 +74,26 @@ Feature: Compass bearing
| fg | yes |
| gh | yes |
| ha | yes |
| dk | no |
| ke | no |
| fl | no |
| lg | no |
| hi | no |
| ia | no |
| bj | no |
| cj | no |
When I route I should get
| from | to | route | bearing |
| c | b | cd,de,ef,fg,gh,ha,ab,ab | 270,225,180,135,90,45,0,0 |
| g | f | gh,ha,ab,bc,cd,de,ef,ef | 90,45,0,315,270,225,180,0 |
| from | to | route | bearing |
| c | b | cd,de,ef,fg,gh,ha,ab,ab | 0->270,270->225,225->180,180->135,135->90,90->45,45->0,0->0 |
| g | f | gh,ha,ab,bc,cd,de,ef,ef | 0->90,90->45,45->0,0->315,315->270,270->225,225->180,180->0 |
Scenario: Bearing should stay constant when zig-zagging
Given the node map
| i | j | k | |
| b | d | f | h |
| a | c | e | g |
| | m | n | o |
And the ways
| nodes |
@@ -94,10 +104,16 @@ Feature: Compass bearing
| ef |
| fg |
| gh |
| bi |
| cm |
| dj |
| en |
| fk |
| go |
When I route I should get
| from | to | route | bearing |
| a | h | ab,bc,cd,de,ef,fg,gh,gh | 0,135,0,135,0,135,0,0 |
| a | h | ab,bc,cd,de,ef,fg,gh,gh | 0->0,0->135,135->0,0->135,135->0,0->135,135->0,0->0 |
Scenario: Bearings on an east-west way.
Given the node map
@@ -108,37 +124,37 @@ Feature: Compass bearing
| abcdef |
When I route I should get
| from | to | route | bearing |
| a | b | abcdef,abcdef | 90,0 |
| a | c | abcdef,abcdef | 90,0 |
| a | d | abcdef,abcdef | 90,0 |
| a | e | abcdef,abcdef | 90,0 |
| a | f | abcdef,abcdef | 90,0 |
| b | a | abcdef,abcdef | 270,0 |
| b | c | abcdef,abcdef | 90,0 |
| b | d | abcdef,abcdef | 90,0 |
| b | e | abcdef,abcdef | 90,0 |
| b | f | abcdef,abcdef | 90,0 |
| c | a | abcdef,abcdef | 270,0 |
| c | b | abcdef,abcdef | 270,0 |
| c | d | abcdef,abcdef | 90,0 |
| c | e | abcdef,abcdef | 90,0 |
| c | f | abcdef,abcdef | 90,0 |
| d | a | abcdef,abcdef | 270,0 |
| d | b | abcdef,abcdef | 270,0 |
| d | c | abcdef,abcdef | 270,0 |
| d | e | abcdef,abcdef | 90,0 |
| d | f | abcdef,abcdef | 90,0 |
| e | a | abcdef,abcdef | 270,0 |
| e | b | abcdef,abcdef | 270,0 |
| e | c | abcdef,abcdef | 270,0 |
| e | d | abcdef,abcdef | 270,0 |
| e | f | abcdef,abcdef | 90,0 |
| f | a | abcdef,abcdef | 270,0 |
| f | b | abcdef,abcdef | 270,0 |
| f | c | abcdef,abcdef | 270,0 |
| f | d | abcdef,abcdef | 270,0 |
| f | e | abcdef,abcdef | 270,0 |
| from | to | route | bearing |
| a | b | abcdef,abcdef | 0->90,90->0 |
| a | c | abcdef,abcdef | 0->90,90->0 |
| a | d | abcdef,abcdef | 0->90,90->0 |
| a | e | abcdef,abcdef | 0->90,90->0 |
| a | f | abcdef,abcdef | 0->90,90->0 |
| b | a | abcdef,abcdef | 0->270,270->0 |
| b | c | abcdef,abcdef | 0->90,90->0 |
| b | d | abcdef,abcdef | 0->90,90->0 |
| b | e | abcdef,abcdef | 0->90,90->0 |
| b | f | abcdef,abcdef | 0->90,90->0 |
| c | a | abcdef,abcdef | 0->270,270->0 |
| c | b | abcdef,abcdef | 0->270,270->0 |
| c | d | abcdef,abcdef | 0->90,90->0 |
| c | e | abcdef,abcdef | 0->90,90->0 |
| c | f | abcdef,abcdef | 0->90,90->0 |
| d | a | abcdef,abcdef | 0->270,270->0 |
| d | b | abcdef,abcdef | 0->270,270->0 |
| d | c | abcdef,abcdef | 0->270,270->0 |
| d | e | abcdef,abcdef | 0->90,90->0 |
| d | f | abcdef,abcdef | 0->90,90->0 |
| e | a | abcdef,abcdef | 0->270,270->0 |
| e | b | abcdef,abcdef | 0->270,270->0 |
| e | c | abcdef,abcdef | 0->270,270->0 |
| e | d | abcdef,abcdef | 0->270,270->0 |
| e | f | abcdef,abcdef | 0->90,90->0 |
| f | a | abcdef,abcdef | 0->270,270->0 |
| f | b | abcdef,abcdef | 0->270,270->0 |
| f | c | abcdef,abcdef | 0->270,270->0 |
| f | d | abcdef,abcdef | 0->270,270->0 |
| f | e | abcdef,abcdef | 0->270,270->0 |
Scenario: Bearings at high latitudes
# The coordinas below was calculated using http://www.movable-type.co.uk/scripts/latlong.html,
@@ -161,19 +177,19 @@ Feature: Compass bearing
| bd |
When I route I should get
| from | to | route | bearing |
| a | b | ab,ab | 0,0 |
| b | c | bc,bc | 90,0 |
| c | d | cd,cd | 180,0 |
| d | a | da,da | 270,0 |
| b | a | ab,ab | 180,0 |
| c | b | bc,bc | 270,0 |
| d | c | cd,cd | 0,0 |
| a | d | da,da | 90,0 |
| a | c | ac,ac | 45,0 |
| c | a | ac,ac | 225,0 |
| b | d | bd,bd | 135,0 |
| d | b | bd,bd | 315,0 |
| from | to | route | bearing |
| a | b | ab,ab | 0->0,0->0 |
| b | c | bc,bc | 0->90,90->0 |
| c | d | cd,cd | 0->180,180->0 |
| d | a | da,da | 0->270,270->0 |
| b | a | ab,ab | 0->180,180->0 |
| c | b | bc,bc | 0->270,270->0 |
| d | c | cd,cd | 0->0,0->0 |
| a | d | da,da | 0->90,90->0 |
| a | c | ac,ac | 0->45,45->0 |
| c | a | ac,ac | 0->225,225->0 |
| b | d | bd,bd | 0->135,135->0 |
| d | b | bd,bd | 0->315,315->0 |
Scenario: Bearings at high negative latitudes
# The coordinas below was calculated using http://www.movable-type.co.uk/scripts/latlong.html,
@@ -196,16 +212,16 @@ Feature: Compass bearing
| bd |
When I route I should get
| from | to | route | bearing |
| a | b | ab,ab | 180,0 |
| b | c | bc,bc | 90,0 |
| c | d | cd,cd | 0,0 |
| d | a | da,da | 270,0 |
| b | a | ab,ab | 0,0 |
| c | b | bc,bc | 270,0 |
| d | c | cd,cd | 180,0 |
| a | d | da,da | 90,0 |
| a | c | ac,ac | 135,0 |
| c | a | ac,ac | 315,0 |
| b | d | bd,bd | 45,0 |
| d | b | bd,bd | 225,0 |
| from | to | route | bearing |
| a | b | ab,ab | 0->180,180->0 |
| b | c | bc,bc | 0->90,90->0 |
| c | d | cd,cd | 0->0,0->0 |
| d | a | da,da | 0->270,270->0 |
| b | a | ab,ab | 0->0,0->0 |
| c | b | bc,bc | 0->270,270->0 |
| d | c | cd,cd | 0->180,180->0 |
| a | d | da,da | 0->90,90->0 |
| a | c | ac,ac | 0->135,135->0 |
| c | a | ac,ac | 0->315,315->0 |
| b | d | bd,bd | 0->45,45->0 |
| d | b | bd,bd | 0->225,225->0 |
+56 -52
View File
@@ -14,12 +14,12 @@ Feature: Bearing parameter
| ad |
When I route I should get
| from | to | bearings | route | bearing |
| b | c | 90 90 | ad,ad | 90,0 |
| b | c | 180 90 | | |
| b | c | 80 100 | ad,ad | 90,0 |
| b | c | 79 100 | | |
| b | c | 79,11 100 | ad,ad | 90,0 |
| from | to | bearings | route | bearing |
| b | c | 90 90 | ad,ad | 0->90,90->0|
| b | c | 180 90 | | |
| b | c | 80 100 | ad,ad | 0->90,90->0|
| b | c | 79 100 | | |
| b | c | 79,11 100 | ad,ad | 0->90,90->0|
Scenario: Testbot - Intial bearing in simple case
Given the node map
@@ -33,18 +33,18 @@ Feature: Bearing parameter
| bc |
When I route I should get
| from | to | bearings | route | bearing |
| 0 | c | 0 0 | | |
| 0 | c | 45 45 | bc,bc | 45 ~3% |
| 0 | c | 85 85 | | |
| 0 | c | 95 95 | | |
| 0 | c | 135 135 | ac,ac | 135 ~1% |
| 0 | c | 180 180 | | |
| from | to | bearings | route | bearing |
| 0 | c | 0 0 | | |
| 0 | c | 45 45 | bc,bc | 0->44,44->0 +- 1 |
| 0 | c | 85 85 | | |
| 0 | c | 95 95 | | |
| 0 | c | 135 135 | ac,ac | 0->135,135->0 +- 1|
| 0 | c | 180 180 | | |
Scenario: Testbot - Initial bearing on split way
Given the node map
| d | | | | | 1 | | | | | c |
| a | | | | | 0 | | | | | b |
| g | d | | | | | 1 | | | | | c | f |
| h | a | | | | | 0 | | | | | b | e |
And the ways
| nodes | oneway |
@@ -52,23 +52,27 @@ Feature: Bearing parameter
| bc | yes |
| cd | yes |
| da | yes |
| be | yes |
| fc | yes |
| dg | yes |
| ha | yes |
When I route I should get
| from | to | bearings | route | bearing |
| 0 | b | 10 10 | bc,bc | 0,0 |
| 0 | b | 90 90 | ab,ab | 90,0 |
| from | to | bearings | route | bearing |
| 0 | b | 10 10 | bc,bc | 0->0,0->0 |
| 0 | b | 90 90 | ab,ab | 0->90,90->0 |
# The returned bearing is wrong here, it's based on the snapped
# coordinates, not the acutal edge bearing. This should be
# fixed one day, but it's only a problem when we snap two vias
# to the same point - DP
#| 0 | b | 170 170 | da | 180 |
#| 0 | b | 189 189 | da | 180 |
| 0 | 1 | 90 270 | ab,bc,cd,cd | 90,0,270,0 |
| 1 | d | 10 10 | bc,bc | 0,0 |
| 1 | d | 90 90 | ab,bc,cd,da,da | 90,0,270,180,0 |
| 1 | 0 | 189 189 | da,da | 180,0 |
| 1 | d | 270 270 | cd,cd | 270,0 |
| 1 | d | 349 349 | | |
#| 0 | b | 170 170 | da | 180 |
#| 0 | b | 189 189 | da | 180 |
| 0 | 1 | 90 270 | ab,bc,cd,cd | 0->90,90->0,0->270,270->0 |
| 1 | d | 10 10 | bc,bc | 0->0,0->0 |
| 1 | d | 90 90 | ab,bc,cd,da,da | 0->90,90->0,0->270,270->180,180->0 |
| 1 | 0 | 189 189 | da,da | 0->180,180->0 |
| 1 | d | 270 270 | cd,cd | 0->270,270->0 |
| 1 | d | 349 349 | | |
Scenario: Testbot - Initial bearing in all direction
Given the node map
@@ -81,31 +85,31 @@ Feature: Bearing parameter
| f | | | e | | | d |
And the ways
| nodes | oneway |
| ia | yes |
| jb | yes |
| kc | yes |
| ld | yes |
| me | yes |
| nf | yes |
| og | yes |
| ph | yes |
| ab | yes |
| bc | yes |
| cd | yes |
| de | yes |
| ef | yes |
| fg | yes |
| gh | yes |
| ha | yes |
| nodes | oneway | name |
| ia | yes | ia |
| jb | yes | jb |
| kc | yes | kc |
| ld | yes | ld |
| me | yes | me |
| nf | yes | nf |
| og | yes | og |
| ph | yes | ph |
| ab | yes | ring |
| bc | yes | ring |
| cd | yes | ring |
| de | yes | ring |
| ef | yes | ring |
| fg | yes | ring |
| gh | yes | ring |
| ha | yes | ring |
When I route I should get
| from | to | bearings | route | bearing |
| 0 | q | 0 90 | ia,ab,bc,cd,de,ef,fg,gh,ha,ha | 0,90,180,180,270,270,0,0,90,0 |
| 0 | a | 45 90 | jb,bc,cd,de,ef,fg,gh,ha,ha | 45,180,180,270,270,0,0,90,0 |
| 0 | q | 90 90 | kc,cd,de,ef,fg,gh,ha,ha | 90,180,270,270,0,0,90,0 |
| 0 | a | 135 90 | ld,de,ef,fg,gh,ha,ha | 135,270,270,0,0,90,0 |
| 0 | a | 180 90 | me,ef,fg,gh,ha,ha | 180,270,0,0,90,0 |
| 0 | a | 225 90 | nf,fg,gh,ha,ha | 225,0,0,90,0 |
| 0 | a | 270 90 | og,gh,ha,ha | 270,0,90,0 |
| 0 | a | 315 90 | ph,ha,ha | 315,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 | 0->180,180->270,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 | 0->270,270->0,90->0 |
| 0 | a | 315 90 | ph,ring,ring | 0->315,315->90,90->0 |
+2 -2
View File
@@ -18,5 +18,5 @@ Feature: Geometry Compression
When I route I should get
| from | to | route | distance | speed |
| b | e | abcdef,abcdef | 589m | 36 km/h |
| e | b | abcdef,abcdef | 589m | 36 km/h |
| b | e | abcdef,abcdef | 588.8m | 36 km/h |
| e | b | abcdef,abcdef | 588.8m | 36 km/h |
@@ -3,6 +3,7 @@ Feature: U-turns at via points
Background:
Given the profile "testbot"
Given a grid size of 250 meters
Scenario: Continue straight at waypoints enabled by default
Given the node map
+15
View File
@@ -24,3 +24,18 @@ Feature: Fixed bugs, kept to check for regressions
When I route I should get
| from | to | route |
| x | y | abc,abc |
Scenario: Step trimming with very short segments
Given a grid size of 0.1 meters
Given the node map
| a | 1 | b | c | d | 2 | e |
Given the ways
| nodes | oneway |
| ab | yes |
| bcd | yes |
| de | yes |
When I route I should get
| from | to | route |
| 1 | 2 | bcd,bcd |
+5 -3
View File
@@ -75,12 +75,12 @@ Feature: Avoid weird loops caused by rounding errors
And the node map
| a | | |
| b | e | |
| | | 1 |
| h | | 1 |
| | | |
| | | 2 |
| | | |
| g | | |
| | c | f |
| | d | |
| d | | |
And the ways
| nodes | highway |
@@ -90,6 +90,8 @@ Feature: Avoid weird loops caused by rounding errors
| be | primary |
| ef | primary |
| cf | primary |
| cg | primary |
| bh | primary |
When I route I should get
| waypoints | route |
+42
View File
@@ -104,3 +104,45 @@ Feature: Basic Map Matching
| trace | matchings |
| dcba | hg,gf,fe |
| efgh | ab,bc,cd |
Scenario: Testbot - Duration details
Given the query options
| annotations | true |
Given the node map
| a | b | c | d | e | | g | h |
| | | i | | | | | |
And the ways
| nodes | oneway |
| abcdegh | no |
| ci | no |
When I match I should get
| trace | matchings | annotation |
| abeh | abcedgh | 1:9.897633,0:0,1:10.008842,1:10.008842,1:10.008842,0:0,2:20.017685,1:10.008842 |
| abci | abc,ci | 1:9.897633,0:0,1:10.008842,0:0.111209,1:10.010367 |
# The following is the same as the above, but separated for readability (line length)
When I match I should get
| trace | matchings | OSM IDs |
| abeh | abcedgh | 1,2,3,2,3,4,5,4,5,6,7 |
| abci | abc,ci | 1,2,3,2,3,8,3,8 |
Scenario: Testbot - Geometry details
Given the query options
| overview | full |
| geometries | polyline |
Given the node map
| a | b | c |
| | d | |
And the ways
| nodes | oneway |
| abc | no |
| bd | no |
When I match I should get
| trace | matchings | geometry |
| abd | abd | 1,1,1,1.00009,1,1.00009,0.99991,1.00009 |
+4 -3
View File
@@ -11,6 +11,7 @@ Feature: Testbot - Travel mode
Background:
Given the profile "testbot"
Given a grid size of 200 meters
Scenario: Testbot - Always announce mode change
Given the node map
@@ -72,9 +73,9 @@ Feature: Testbot - Travel mode
| ab | steps |
When I route I should get
| from | to | route | modes | time |
| 0 | 1 | ab,ab | steps down,steps down | 60s +-1 |
| 1 | 0 | ab,ab | steps up,steps up | 60s +-1 |
| from | to | route | modes | time |
| 0 | 1 | ab,ab | steps down,steps down | 120s +-1 |
| 1 | 0 | ab,ab | steps up,steps up | 120s +-1 |
@oneway
Scenario: Testbot - Modes for oneway, different forward/backward speeds
+5 -2
View File
@@ -3,6 +3,7 @@ Feature: Testbot - oneways
Background:
Given the profile "testbot"
Given a grid size of 250 meters
Scenario: Routing on a oneway roundabout
Given the node map
@@ -59,8 +60,8 @@ Feature: Testbot - oneways
Scenario: Testbot - Around the Block
Given the node map
| a | b |
| d | c |
| | a | b | |
| e | d | c | f |
And the ways
| nodes | oneway | foot |
@@ -68,6 +69,8 @@ Feature: Testbot - oneways
| bc | | no |
| cd | | no |
| da | | no |
| de | | no |
| cf | | no |
When I route I should get
| from | to | route |
+6 -6
View File
@@ -24,12 +24,12 @@ Feature: Projection to nearest point on road
Scenario: Projection onto way at high latitudes, 1km distance
When I route I should get
| from | to | route | bearing | distance |
| b | a | abc,abc | 225,0 +-1 | 1000m +- 7 |
| b | c | abc,abc | 45,0 +-1 | 1000m +- 7 |
| a | d | abc,abc | 45,0 +-1 | 1000m +- 7 |
| d | a | abc,abc | 225,0 +-1 | 1000m +- 7 |
| c | d | abc,abc | 225,0 +-1 | 1000m +- 8 |
| d | c | abc,abc | 45 +-1 | 1000m +- 8 |
| b | a | abc,abc | 0->225,225->0 | 1000m +- 7 |
| b | c | abc,abc | 0->45,45->0 | 1000m +- 7 |
| a | d | abc,abc | 0->45,45->0 | 1000m +- 7 |
| d | a | abc,abc | 0->225,225->0 | 1000m +- 7 |
| c | d | abc,abc | 0->225,224->0 | 1000m +- 8 |
| d | c | abc,abc | 0->44,45->0 | 1000m +- 8 |
Scenario: Projection onto way at high latitudes, no distance
When I route I should get
+5 -3
View File
@@ -3,11 +3,12 @@ Feature: Basic Routing
Background:
Given the profile "testbot"
Given a grid size of 200 meters
@smallest
Scenario: Checking
Scenario: Checking
Given the node map
| a | b | | c | d | e |
| a | b | 1 | c | d | e |
And the ways
| nodes |
@@ -22,12 +23,13 @@ Feature: Basic Routing
| e | a | de,cd,bc,ab,ab | de, bc |
| a | b | ab,ab | ab |
| b | d | bc,cd,cd | bc, cd |
| 1 | c | bc,bc | bc |
@smallest
Scenario: Check handling empty values
Given the node map
| a | b | | c | | d | f |
| | | | | | e |
| | | | | | e | |
And the ways
| nodes | name |
+4 -2
View File
@@ -145,14 +145,16 @@ Feature: Estimation of travel time
Scenario: Time of travel on a series of ways
Given the node map
| a | b | |
| | c | d |
| a | b | e |
| f | c | d |
And the ways
| nodes | highway |
| ab | primary |
| bc | primary |
| cd | primary |
| be | primary |
| cf | primary |
When I route I should get
| from | to | route | time |
+12 -6
View File
@@ -85,13 +85,16 @@ Feature: Via points
Scenario: Via points on ring of oneways
# xa it to avoid only having a single ring, which cna trigger edge cases
Given the node map
| x | | | | | | |
| a | 1 | b | 2 | c | 3 | d |
| f | | | | | | e |
| | x | | | | | | g | |
| | a | 1 | b | 2 | c | 3 | d | |
| i | f | | | | | | e | h |
And the ways
| nodes | oneway |
| xa | |
| if | |
| gd | |
| eh | |
| ab | yes |
| bc | yes |
| cd | yes |
@@ -110,13 +113,16 @@ Feature: Via points
Scenario: Via points on ring on the same oneway
# xa it to avoid only having a single ring, which cna trigger edge cases
Given the node map
| x | | | | |
| a | 1 | 2 | 3 | b |
| d | | | | c |
| | x | | | | e | |
| | a | 1 | 2 | 3 | b | |
| g | d | | | | c | f |
And the ways
| nodes | oneway |
| xa | |
| eb | |
| cf | |
| dg | |
| ab | yes |
| bc | yes |
| cd | yes |
+3 -3
View File
@@ -32,11 +32,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "contractor/query_edge.hpp"
#include "extractor/edge_based_edge.hpp"
#include "extractor/edge_based_node.hpp"
#include "util/typedefs.hpp"
#include "util/deallocating_vector.hpp"
#include "util/typedefs.hpp"
#include <vector>
#include <string>
#include <vector>
#include <cstddef>
@@ -78,7 +78,7 @@ class Contractor
private:
ContractorConfig config;
std::size_t
EdgeID
LoadEdgeExpandedGraph(const std::string &edge_based_graph_path,
util::DeallocatingVector<extractor::EdgeBasedEdge> &edge_based_edge_list,
const std::string &edge_segment_lookup_path,
+8 -2
View File
@@ -82,6 +82,9 @@ class IteratorbasedCRC32
: "0"(crc), "c"(*str));
++str;
}
#else
(void)str;
(void)len;
#endif
return crc;
}
@@ -95,8 +98,11 @@ class IteratorbasedCRC32
}
#if defined(__MINGW64__) || defined(_MSC_VER) || !defined(__x86_64__)
inline void
__get_cpuid(int param, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) const
inline void __get_cpuid(int /*param*/,
unsigned * /*eax*/,
unsigned * /*ebx*/,
unsigned *ecx,
unsigned * /*edx*/) const
{
*ecx = 0;
}
+89 -70
View File
@@ -1,17 +1,17 @@
#ifndef GRAPH_CONTRACTOR_HPP
#define GRAPH_CONTRACTOR_HPP
#include "contractor/query_edge.hpp"
#include "util/binary_heap.hpp"
#include "util/deallocating_vector.hpp"
#include "util/dynamic_graph.hpp"
#include "util/percent.hpp"
#include "contractor/query_edge.hpp"
#include "util/xor_fast_hash.hpp"
#include "util/xor_fast_hash_storage.hpp"
#include "util/integer_range.hpp"
#include "util/percent.hpp"
#include "util/simple_logger.hpp"
#include "util/timing_util.hpp"
#include "util/typedefs.hpp"
#include "util/xor_fast_hash.hpp"
#include "util/xor_fast_hash_storage.hpp"
#include <boost/assert.hpp>
@@ -165,14 +165,22 @@ class GraphContractor
<< static_cast<unsigned int>(diter->target);
}
#endif
edges.emplace_back(diter->source, diter->target,
static_cast<unsigned int>(std::max(diter->weight, 1)), 1,
diter->edge_id, false, diter->forward ? true : false,
edges.emplace_back(diter->source,
diter->target,
static_cast<unsigned int>(std::max(diter->weight, 1)),
1,
diter->edge_id,
false,
diter->forward ? true : false,
diter->backward ? true : false);
edges.emplace_back(diter->target, diter->source,
static_cast<unsigned int>(std::max(diter->weight, 1)), 1,
diter->edge_id, false, diter->backward ? true : false,
edges.emplace_back(diter->target,
diter->source,
static_cast<unsigned int>(std::max(diter->weight, 1)),
1,
diter->edge_id,
false,
diter->backward ? true : false,
diter->forward ? true : false);
}
// clear input vector
@@ -276,8 +284,7 @@ class GraphContractor
std::vector<RemainingNodeData> remaining_nodes(number_of_nodes);
// initialize priorities in parallel
tbb::parallel_for(tbb::blocked_range<int>(0, number_of_nodes, InitGrainSize),
[this, &remaining_nodes](const tbb::blocked_range<int> &range)
{
[this, &remaining_nodes](const tbb::blocked_range<int> &range) {
for (int x = range.begin(), end = range.end(); x != end; ++x)
{
remaining_nodes[x].id = x;
@@ -299,9 +306,8 @@ class GraphContractor
std::cout << "initializing elimination PQ ..." << std::flush;
tbb::parallel_for(tbb::blocked_range<int>(0, number_of_nodes, PQGrainSize),
[this, &node_priorities, &node_depth,
&thread_data_list](const tbb::blocked_range<int> &range)
{
[this, &node_priorities, &node_depth, &thread_data_list](
const tbb::blocked_range<int> &range) {
ContractorThreadData *data = thread_data_list.GetThreadData();
for (int x = range.begin(), end = range.end(); x != end; ++x)
{
@@ -342,7 +348,8 @@ class GraphContractor
// remaining graph
std::vector<NodeID> new_node_id_from_orig_id_map(number_of_nodes, SPECIAL_NODEID);
for (const auto new_node_id : util::irange<std::size_t>(0UL, remaining_nodes.size()))
for (const auto new_node_id :
util::irange<std::size_t>(0UL, remaining_nodes.size()))
{
auto &node = remaining_nodes[new_node_id];
BOOST_ASSERT(node_priorities.size() > node.id);
@@ -352,7 +359,8 @@ class GraphContractor
}
// build forward and backward renumbering map and remap ids in remaining_nodes
for (const auto new_node_id : util::irange<std::size_t>(0UL, remaining_nodes.size()))
for (const auto new_node_id :
util::irange<std::size_t>(0UL, remaining_nodes.size()))
{
auto &node = remaining_nodes[new_node_id];
// create renumbering maps in both directions
@@ -378,7 +386,8 @@ class GraphContractor
// node is not yet contracted.
// add (renumbered) outgoing edges to new util::DynamicGraph.
ContractorEdge new_edge = {new_node_id_from_orig_id_map[source],
new_node_id_from_orig_id_map[target], data};
new_node_id_from_orig_id_map[target],
data};
new_edge.data.is_original_via_node_ID = true;
BOOST_ASSERT_MSG(SPECIAL_NODEID != new_node_id_from_orig_id_map[source],
@@ -421,9 +430,8 @@ class GraphContractor
tbb::parallel_for(
tbb::blocked_range<std::size_t>(0, remaining_nodes.size(), IndependentGrainSize),
[this, &node_priorities, &remaining_nodes,
&thread_data_list](const tbb::blocked_range<std::size_t> &range)
{
[this, &node_priorities, &remaining_nodes, &thread_data_list](
const tbb::blocked_range<std::size_t> &range) {
ContractorThreadData *data = thread_data_list.GetThreadData();
// determine independent node set
for (auto i = range.begin(), end = range.end(); i != end; ++i)
@@ -436,8 +444,7 @@ class GraphContractor
// sort all remaining nodes to the beginning of the sequence
const auto begin_independent_nodes = stable_partition(
remaining_nodes.begin(), remaining_nodes.end(), [](RemainingNodeData node_data)
{
remaining_nodes.begin(), remaining_nodes.end(), [](RemainingNodeData node_data) {
return !node_data.is_independent;
});
auto begin_independent_nodes_idx =
@@ -448,11 +455,10 @@ class GraphContractor
{
// write out contraction level
tbb::parallel_for(
tbb::blocked_range<std::size_t>(begin_independent_nodes_idx,
end_independent_nodes_idx, ContractGrainSize),
[this, remaining_nodes, flushed_contractor,
current_level](const tbb::blocked_range<std::size_t> &range)
{
tbb::blocked_range<std::size_t>(
begin_independent_nodes_idx, end_independent_nodes_idx, ContractGrainSize),
[this, remaining_nodes, flushed_contractor, current_level](
const tbb::blocked_range<std::size_t> &range) {
if (flushed_contractor)
{
for (int position = range.begin(), end = range.end(); position != end;
@@ -475,26 +481,24 @@ class GraphContractor
}
// contract independent nodes
tbb::parallel_for(tbb::blocked_range<std::size_t>(begin_independent_nodes_idx,
end_independent_nodes_idx,
ContractGrainSize),
[this, &remaining_nodes,
&thread_data_list](const tbb::blocked_range<std::size_t> &range)
{
ContractorThreadData *data = thread_data_list.GetThreadData();
for (int position = range.begin(), end = range.end();
position != end; ++position)
{
const NodeID x = remaining_nodes[position].id;
this->ContractNode<false>(data, x);
}
});
tbb::parallel_for(
tbb::blocked_range<std::size_t>(
begin_independent_nodes_idx, end_independent_nodes_idx, ContractGrainSize),
[this, &remaining_nodes, &thread_data_list](
const tbb::blocked_range<std::size_t> &range) {
ContractorThreadData *data = thread_data_list.GetThreadData();
for (int position = range.begin(), end = range.end(); position != end;
++position)
{
const NodeID x = remaining_nodes[position].id;
this->ContractNode<false>(data, x);
}
});
tbb::parallel_for(
tbb::blocked_range<int>(begin_independent_nodes_idx, end_independent_nodes_idx,
DeleteGrainSize),
[this, &remaining_nodes, &thread_data_list](const tbb::blocked_range<int> &range)
{
tbb::blocked_range<int>(
begin_independent_nodes_idx, end_independent_nodes_idx, DeleteGrainSize),
[this, &remaining_nodes, &thread_data_list](const tbb::blocked_range<int> &range) {
ContractorThreadData *data = thread_data_list.GetThreadData();
for (int position = range.begin(), end = range.end(); position != end;
++position)
@@ -507,8 +511,7 @@ class GraphContractor
// make sure we really sort each block
tbb::parallel_for(
thread_data_list.data.range(),
[&](const ThreadDataContainer::EnumerableThreadData::range_type &range)
{
[&](const ThreadDataContainer::EnumerableThreadData::range_type &range) {
for (auto &data : range)
tbb::parallel_sort(data->inserted_edges.begin(),
data->inserted_edges.end());
@@ -542,11 +545,11 @@ class GraphContractor
if (!use_cached_node_priorities)
{
tbb::parallel_for(
tbb::blocked_range<int>(begin_independent_nodes_idx, end_independent_nodes_idx,
tbb::blocked_range<int>(begin_independent_nodes_idx,
end_independent_nodes_idx,
NeighboursGrainSize),
[this, &node_priorities, &remaining_nodes, &node_depth,
&thread_data_list](const tbb::blocked_range<int> &range)
{
[this, &node_priorities, &remaining_nodes, &node_depth, &thread_data_list](
const tbb::blocked_range<int> &range) {
ContractorThreadData *data = thread_data_list.GetThreadData();
for (int position = range.begin(), end = range.end(); position != end;
++position)
@@ -570,8 +573,7 @@ class GraphContractor
if (orig_node_id_from_new_node_id_map.size() > 0)
{
tbb::parallel_for(tbb::blocked_range<int>(0, remaining_nodes.size(), InitGrainSize),
[this, &remaining_nodes](const tbb::blocked_range<int> &range)
{
[this, &remaining_nodes](const tbb::blocked_range<int> &range) {
for (int x = range.begin(), end = range.end(); x != end; ++x)
{
const auto orig_id = remaining_nodes[x].id;
@@ -583,8 +585,7 @@ class GraphContractor
else
{
tbb::parallel_for(tbb::blocked_range<int>(0, remaining_nodes.size(), InitGrainSize),
[this, &remaining_nodes](const tbb::blocked_range<int> &range)
{
[this, &remaining_nodes](const tbb::blocked_range<int> &range) {
for (int x = range.begin(), end = range.end(); x != end; ++x)
{
const auto orig_id = remaining_nodes[x].id;
@@ -843,15 +844,25 @@ class GraphContractor
// guarantees that source is not connected to another node that is
// contracted
node_weights[source] = path_distance; // make sure to prune better
inserted_edges.emplace_back(
source, target, path_distance,
out_data.originalEdges + in_data.originalEdges, node, SHORTCUT_ARC,
FORWARD_DIRECTION_ENABLED, REVERSE_DIRECTION_DISABLED);
inserted_edges.emplace_back(source,
target,
path_distance,
out_data.originalEdges +
in_data.originalEdges,
node,
SHORTCUT_ARC,
FORWARD_DIRECTION_ENABLED,
REVERSE_DIRECTION_DISABLED);
inserted_edges.emplace_back(
target, source, path_distance,
out_data.originalEdges + in_data.originalEdges, node, SHORTCUT_ARC,
FORWARD_DIRECTION_DISABLED, REVERSE_DIRECTION_ENABLED);
inserted_edges.emplace_back(target,
source,
path_distance,
out_data.originalEdges +
in_data.originalEdges,
node,
SHORTCUT_ARC,
FORWARD_DIRECTION_DISABLED,
REVERSE_DIRECTION_ENABLED);
}
}
continue;
@@ -867,8 +878,8 @@ class GraphContractor
if (RUNSIMULATION)
{
const int constexpr SIMULATION_SEARCH_SPACE_SIZE = 1000;
Dijkstra(max_distance, number_of_targets, SIMULATION_SEARCH_SPACE_SIZE, *data,
node);
Dijkstra(
max_distance, number_of_targets, SIMULATION_SEARCH_SPACE_SIZE, *data, node);
}
else
{
@@ -898,14 +909,22 @@ class GraphContractor
}
else
{
inserted_edges.emplace_back(source, target, path_distance,
inserted_edges.emplace_back(source,
target,
path_distance,
out_data.originalEdges + in_data.originalEdges,
node, SHORTCUT_ARC, FORWARD_DIRECTION_ENABLED,
node,
SHORTCUT_ARC,
FORWARD_DIRECTION_ENABLED,
REVERSE_DIRECTION_DISABLED);
inserted_edges.emplace_back(target, source, path_distance,
inserted_edges.emplace_back(target,
source,
path_distance,
out_data.originalEdges + in_data.originalEdges,
node, SHORTCUT_ARC, FORWARD_DIRECTION_DISABLED,
node,
SHORTCUT_ARC,
FORWARD_DIRECTION_DISABLED,
REVERSE_DIRECTION_ENABLED);
}
}
+6 -6
View File
@@ -37,11 +37,10 @@ class BaseAPI
waypoints.values[0] = MakeWaypoint(segment_end_coordinates.front().source_phantom);
auto out_iter = std::next(waypoints.values.begin());
boost::range::transform(segment_end_coordinates, out_iter,
[this](const PhantomNodes &phantom_pair)
{
return MakeWaypoint(phantom_pair.target_phantom);
});
boost::range::transform(
segment_end_coordinates, out_iter, [this](const PhantomNodes &phantom_pair) {
return MakeWaypoint(phantom_pair.target_phantom);
});
return waypoints;
}
@@ -49,7 +48,8 @@ class BaseAPI
// protected:
util::json::Object MakeWaypoint(const PhantomNode &phantom) const
{
return json::makeWaypoint(phantom.location, facade.GetNameForID(phantom.name_id),
return json::makeWaypoint(phantom.location,
facade.GetNameForID(phantom.name_id),
Hint{phantom, facade.GetCheckSum()});
}
+5 -5
View File
@@ -28,14 +28,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ENGINE_API_BASE_PARAMETERS_HPP
#define ENGINE_API_BASE_PARAMETERS_HPP
#include "engine/hint.hpp"
#include "engine/bearing.hpp"
#include "engine/hint.hpp"
#include "util/coordinate.hpp"
#include <boost/optional.hpp>
#include <vector>
#include <algorithm>
#include <vector>
namespace osrm
{
@@ -72,9 +72,9 @@ struct BaseParameters
return (hints.empty() || hints.size() == coordinates.size()) &&
(bearings.empty() || bearings.size() == coordinates.size()) &&
(radiuses.empty() || radiuses.size() == coordinates.size()) &&
std::all_of(bearings.begin(), bearings.end(),
[](const boost::optional<Bearing> bearing_and_range)
{
std::all_of(bearings.begin(),
bearings.end(),
[](const boost::optional<Bearing> bearing_and_range) {
if (bearing_and_range)
{
return bearing_and_range->IsValid();
+11 -8
View File
@@ -3,12 +3,12 @@
#include "extractor/guidance/turn_instruction.hpp"
#include "extractor/travel_mode.hpp"
#include "engine/polyline_compressor.hpp"
#include "engine/guidance/leg_geometry.hpp"
#include "engine/guidance/route.hpp"
#include "engine/guidance/route_leg.hpp"
#include "engine/guidance/route_step.hpp"
#include "engine/guidance/step_maneuver.hpp"
#include "engine/guidance/route_leg.hpp"
#include "engine/guidance/route.hpp"
#include "engine/guidance/leg_geometry.hpp"
#include "engine/polyline_compressor.hpp"
#include "util/coordinate.hpp"
#include "util/json_container.hpp"
@@ -33,8 +33,8 @@ namespace json
namespace detail
{
std::string instructionTypeToString(extractor::guidance::TurnType type);
std::string instructionModifierToString(extractor::guidance::DirectionModifier modifier);
std::string instructionTypeToString(extractor::guidance::TurnType::Enum type);
std::string instructionModifierToString(extractor::guidance::DirectionModifier::Enum modifier);
util::json::Array coordinateToLonLat(const util::Coordinate coordinate);
@@ -57,7 +57,9 @@ util::json::Object makeGeoJSONGeometry(ForwardIter begin, ForwardIter end)
{
geojson.values["type"] = "LineString";
util::json::Array coordinates;
std::transform(begin, end, std::back_inserter(coordinates.values), &detail::coordinateToLonLat);
coordinates.values.reserve(num_coordinates);
std::transform(
begin, end, std::back_inserter(coordinates.values), &detail::coordinateToLonLat);
geojson.values["coordinates"] = std::move(coordinates);
}
else if (num_coordinates > 0)
@@ -85,7 +87,8 @@ makeWaypoint(const util::Coordinate location, std::string name, const Hint &hint
util::json::Object makeRouteLeg(guidance::RouteLeg leg, util::json::Array steps);
util::json::Array makeRouteLegs(std::vector<guidance::RouteLeg> legs,
std::vector<util::json::Value> step_geometries);
std::vector<util::json::Value> step_geometries,
std::vector<util::json::Object> annotations);
}
}
} // namespace engine
+1 -1
View File
@@ -1,8 +1,8 @@
#ifndef ENGINE_API_MATCH_HPP
#define ENGINE_API_MATCH_HPP
#include "engine/api/route_api.hpp"
#include "engine/api/match_parameters.hpp"
#include "engine/api/route_api.hpp"
#include "engine/datafacade/datafacade_base.hpp"
+1
View File
@@ -52,6 +52,7 @@ struct MatchParameters : public RouteParameters
{
MatchParameters()
: RouteParameters(false,
false,
false,
RouteParameters::GeometriesType::Polyline,
RouteParameters::OverviewType::Simplified,
+3 -3
View File
@@ -34,10 +34,10 @@ 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(),
std::transform(phantom_nodes.front().begin(),
phantom_nodes.front().end(),
waypoints.values.begin(),
[this](const PhantomNodeWithDistance &phantom_with_distance)
{
[this](const PhantomNodeWithDistance &phantom_with_distance) {
auto waypoint = MakeWaypoint(phantom_with_distance.phantom_node);
waypoint.values["distance"] = phantom_with_distance.distance;
return waypoint;
+74 -14
View File
@@ -12,6 +12,7 @@
#include "engine/guidance/assemble_overview.hpp"
#include "engine/guidance/assemble_route.hpp"
#include "engine/guidance/assemble_steps.hpp"
#include "engine/guidance/lane_processing.hpp"
#include "engine/guidance/post_processing.hpp"
#include "engine/internal_route_result.hpp"
@@ -42,14 +43,16 @@ class RouteAPI : public BaseAPI
auto number_of_routes = raw_route.has_alternative() ? 2UL : 1UL;
util::json::Array routes;
routes.values.resize(number_of_routes);
routes.values[0] =
MakeRoute(raw_route.segment_end_coordinates, raw_route.unpacked_path_segments,
raw_route.source_traversed_in_reverse, raw_route.target_traversed_in_reverse);
routes.values[0] = MakeRoute(raw_route.segment_end_coordinates,
raw_route.unpacked_path_segments,
raw_route.source_traversed_in_reverse,
raw_route.target_traversed_in_reverse);
if (raw_route.has_alternative())
{
std::vector<std::vector<PathData>> wrapped_leg(1);
wrapped_leg.front() = std::move(raw_route.unpacked_alternative);
routes.values[1] = MakeRoute(raw_route.segment_end_coordinates, wrapped_leg,
routes.values[1] = MakeRoute(raw_route.segment_end_coordinates,
wrapped_leg,
raw_route.alt_source_traversed_in_reverse,
raw_route.alt_target_traversed_in_reverse);
}
@@ -93,14 +96,23 @@ class RouteAPI : public BaseAPI
auto leg_geometry = guidance::assembleGeometry(
BaseAPI::facade, path_data, phantoms.source_phantom, phantoms.target_phantom);
auto leg = guidance::assembleLeg(facade, path_data, leg_geometry, phantoms.source_phantom,
phantoms.target_phantom, reversed_target, parameters.steps);
auto leg = guidance::assembleLeg(facade,
path_data,
leg_geometry,
phantoms.source_phantom,
phantoms.target_phantom,
reversed_target,
parameters.steps);
if (parameters.steps)
{
auto steps = guidance::assembleSteps(
BaseAPI::facade, path_data, leg_geometry, phantoms.source_phantom,
phantoms.target_phantom, reversed_source, reversed_target);
auto steps = guidance::assembleSteps(BaseAPI::facade,
path_data,
leg_geometry,
phantoms.source_phantom,
phantoms.target_phantom,
reversed_source,
reversed_target);
/* Perform step-based post-processing.
*
@@ -133,9 +145,13 @@ class RouteAPI : public BaseAPI
guidance::trimShortSegments(steps, leg_geometry);
leg.steps = guidance::postProcess(std::move(steps));
leg.steps = guidance::collapseTurns(std::move(leg.steps));
leg.steps = guidance::assignRelativeLocations(std::move(leg.steps), leg_geometry,
leg.steps = guidance::buildIntersections(std::move(leg.steps));
leg.steps = guidance::assignRelativeLocations(std::move(leg.steps),
leg_geometry,
phantoms.source_phantom,
phantoms.target_phantom);
leg.steps = guidance::anticipateLaneChange(std::move(leg.steps));
leg.steps = guidance::collapseUseLane(std::move(leg.steps));
leg_geometry = guidance::resyncGeometry(std::move(leg_geometry), leg.steps);
}
@@ -160,8 +176,13 @@ class RouteAPI : public BaseAPI
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(), std::back_inserter(step_geometries),
legs[idx].steps.begin(),
legs[idx].steps.end(),
std::back_inserter(step_geometries),
[this, &leg_geometry](const guidance::RouteStep &step) {
if (parameters.geometries == RouteParameters::GeometriesType::Polyline)
{
@@ -176,9 +197,48 @@ class RouteAPI : public BaseAPI
});
}
return json::makeRoute(route,
json::makeRouteLegs(std::move(legs), std::move(step_geometries)),
std::move(json_overview));
std::vector<util::json::Object> annotations;
if (parameters.annotations)
{
for (const auto idx : util::irange<std::size_t>(0UL, leg_geometries.size()))
{
util::json::Array durations;
util::json::Array distances;
util::json::Array nodes;
auto &leg_geometry = leg_geometries[idx];
durations.values.reserve(leg_geometry.annotations.size());
distances.values.reserve(leg_geometry.annotations.size());
nodes.values.reserve(leg_geometry.osm_node_ids.size());
std::for_each(
leg_geometry.annotations.begin(),
leg_geometry.annotations.end(),
[this, &durations, &distances](const guidance::LegGeometry::Annotation &step) {
durations.values.push_back(step.duration);
distances.values.push_back(step.distance);
});
std::for_each(leg_geometry.osm_node_ids.begin(),
leg_geometry.osm_node_ids.end(),
[this, &nodes](const OSMNodeID &node_id) {
nodes.values.push_back(static_cast<std::uint64_t>(node_id));
});
util::json::Object annotation;
annotation.values["distance"] = std::move(distances);
annotation.values["duration"] = std::move(durations);
annotation.values["nodes"] = std::move(nodes);
annotations.push_back(std::move(annotation));
}
}
auto result = json::makeRoute(route,
json::makeRouteLegs(std::move(legs),
std::move(step_geometries),
std::move(annotations)),
std::move(json_overview));
return result;
}
const RouteParameters &parameters;
+4 -1
View File
@@ -72,17 +72,20 @@ struct RouteParameters : public BaseParameters
template <typename... Args>
RouteParameters(const bool steps_,
const bool alternatives_,
const bool annotations_,
const GeometriesType geometries_,
const OverviewType overview_,
const boost::optional<bool> continue_straight_,
Args... args_)
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
geometries{geometries_}, overview{overview_}, continue_straight{continue_straight_}
annotations{annotations_}, geometries{geometries_}, overview{overview_},
continue_straight{continue_straight_}
{
}
bool steps = false;
bool alternatives = false;
bool annotations = false;
GeometriesType geometries = GeometriesType::Polyline;
OverviewType overview = OverviewType::Simplified;
boost::optional<bool> continue_straight;
+14 -14
View File
@@ -2,15 +2,15 @@
#define ENGINE_API_TABLE_HPP
#include "engine/api/base_api.hpp"
#include "engine/api/table_parameters.hpp"
#include "engine/api/json_factory.hpp"
#include "engine/api/table_parameters.hpp"
#include "engine/datafacade/datafacade_base.hpp"
#include "engine/guidance/assemble_leg.hpp"
#include "engine/guidance/assemble_route.hpp"
#include "engine/guidance/assemble_geometry.hpp"
#include "engine/guidance/assemble_leg.hpp"
#include "engine/guidance/assemble_overview.hpp"
#include "engine/guidance/assemble_route.hpp"
#include "engine/guidance/assemble_steps.hpp"
#include "engine/internal_route_result.hpp"
@@ -78,11 +78,10 @@ class TableAPI final : public BaseAPI
json_waypoints.values.reserve(phantoms.size());
BOOST_ASSERT(phantoms.size() == parameters.coordinates.size());
boost::range::transform(phantoms, std::back_inserter(json_waypoints.values),
[this](const PhantomNode &phantom)
{
return BaseAPI::MakeWaypoint(phantom);
});
boost::range::transform(
phantoms,
std::back_inserter(json_waypoints.values),
[this](const PhantomNode &phantom) { return BaseAPI::MakeWaypoint(phantom); });
return json_waypoints;
}
@@ -91,9 +90,9 @@ class TableAPI final : public BaseAPI
{
util::json::Array json_waypoints;
json_waypoints.values.reserve(indices.size());
boost::range::transform(indices, std::back_inserter(json_waypoints.values),
[this, phantoms](const std::size_t idx)
{
boost::range::transform(indices,
std::back_inserter(json_waypoints.values),
[this, phantoms](const std::size_t idx) {
BOOST_ASSERT(idx < phantoms.size());
return BaseAPI::MakeWaypoint(phantoms[idx]);
});
@@ -111,9 +110,10 @@ class TableAPI final : public BaseAPI
auto row_begin_iterator = values.begin() + (row * number_of_columns);
auto row_end_iterator = values.begin() + ((row + 1) * number_of_columns);
json_row.values.resize(number_of_columns);
std::transform(row_begin_iterator, row_end_iterator, json_row.values.begin(),
[](const EdgeWeight duration)
{
std::transform(row_begin_iterator,
row_end_iterator,
json_row.values.begin(),
[](const EdgeWeight duration) {
if (duration == INVALID_EDGE_WEIGHT)
{
return util::json::Value(util::json::Null());
+1 -4
View File
@@ -89,10 +89,7 @@ struct TableParameters : public BaseParameters
return false;
// 3/ 0 <= index < len(locations)
const auto not_in_range = [this](const std::size_t x)
{
return x >= coordinates.size();
};
const auto not_in_range = [this](const std::size_t x) { return x >= coordinates.size(); };
if (std::any_of(begin(sources), end(sources), not_in_range))
return false;
+1 -2
View File
@@ -79,8 +79,7 @@ class TripAPI final : public RouteAPI
std::vector<TripIndex> input_idx_to_trip_idx(parameters.coordinates.size());
for (auto sub_trip_index : util::irange<unsigned>(0u, sub_trips.size()))
{
for (auto point_index :
util::irange<unsigned>(0u, sub_trips[sub_trip_index].size()))
for (auto point_index : util::irange<unsigned>(0u, sub_trips[sub_trip_index].size()))
{
input_idx_to_trip_idx[sub_trips[sub_trip_index][point_index]] =
TripIndex{sub_trip_index, point_index};
+6 -6
View File
@@ -1,18 +1,18 @@
#ifndef OSRM_BASE64_HPP
#define OSRM_BASE64_HPP
#include <string>
#include <vector>
#include <iterator>
#include <string>
#include <type_traits>
#include <vector>
#include <cstddef>
#include <climits>
#include <cstddef>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/range/algorithm/copy.hpp>
namespace osrm
+35 -10
View File
@@ -3,13 +3,16 @@
// Exposes all data access interfaces to the algorithms via base class ptr
#include "contractor/query_edge.hpp"
#include "extractor/edge_based_node.hpp"
#include "extractor/external_memory_node.hpp"
#include "contractor/query_edge.hpp"
#include "engine/phantom_node.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "util/integer_range.hpp"
#include "extractor/guidance/turn_lane_types.hpp"
#include "engine/phantom_node.hpp"
#include "util/exception.hpp"
#include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp"
#include "util/integer_range.hpp"
#include "util/string_util.hpp"
#include "util/typedefs.hpp"
@@ -17,9 +20,9 @@
#include <cstddef>
#include <vector>
#include <utility>
#include <string>
#include <utility>
#include <vector>
namespace osrm
{
@@ -65,6 +68,7 @@ class BaseDataFacade
// node and edge information access
virtual util::Coordinate GetCoordinateOfNode(const unsigned id) const = 0;
virtual OSMNodeID GetOSMNodeIDOfNode(const unsigned id) const = 0;
virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const = 0;
@@ -113,14 +117,15 @@ class BaseDataFacade
const int bearing,
const int bearing_range) const = 0;
virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, const unsigned max_results) const = 0;
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results) const = 0;
virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results,
const double max_distance) const = 0;
virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate) const = 0;
virtual std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
const util::Coordinate input_coordinate) const = 0;
virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance) const = 0;
@@ -129,8 +134,15 @@ class BaseDataFacade
const double max_distance,
const int bearing,
const int bearing_range) const = 0;
virtual std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
const util::Coordinate input_coordinate, const int bearing, const int bearing_range) const = 0;
virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const int bearing,
const int bearing_range) const = 0;
virtual bool hasLaneData(const EdgeID id) const = 0;
virtual util::guidance::LaneTupelIdPair GetLaneData(const EdgeID id) const = 0;
virtual extractor::guidance::TurnLaneDescription
GetTurnDescription(const LaneDescriptionID lane_description_id) const = 0;
virtual unsigned GetCheckSum() const = 0;
@@ -140,11 +152,24 @@ class BaseDataFacade
virtual std::string GetNameForID(const unsigned name_id) const = 0;
virtual std::string GetPronunciationForID(const unsigned name_id) const = 0;
virtual std::string GetDestinationsForID(const unsigned name_id) const = 0;
virtual std::size_t GetCoreSize() const = 0;
virtual std::string GetTimestamp() const = 0;
virtual bool GetContinueStraightDefault() const = 0;
virtual BearingClassID GetBearingClassID(const NodeID id) const = 0;
virtual util::guidance::BearingClass
GetBearingClass(const BearingClassID bearing_class_id) const = 0;
virtual EntryClassID GetEntryClassID(const EdgeID eid) const = 0;
virtual util::guidance::EntryClass GetEntryClass(const EntryClassID entry_class_id) const = 0;
};
}
}
+230 -40
View File
@@ -6,21 +6,26 @@
#include "engine/datafacade/datafacade_base.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp"
#include "storage/storage_config.hpp"
#include "engine/geospatial_query.hpp"
#include "extractor/compressed_edge_container.hpp"
#include "extractor/original_edge_data.hpp"
#include "extractor/profile_properties.hpp"
#include "extractor/query_node.hpp"
#include "contractor/query_edge.hpp"
#include "storage/storage_config.hpp"
#include "engine/geospatial_query.hpp"
#include "util/graph_loader.hpp"
#include "util/guidance/turn_lanes.hpp"
#include "util/io.hpp"
#include "util/packed_vector.hpp"
#include "util/range_table.hpp"
#include "util/rectangle.hpp"
#include "util/shared_memory_vector_wrapper.hpp"
#include "util/simple_logger.hpp"
#include "util/static_graph.hpp"
#include "util/static_rtree.hpp"
#include "util/range_table.hpp"
#include "util/graph_loader.hpp"
#include "util/simple_logger.hpp"
#include "util/rectangle.hpp"
#include "extractor/compressed_edge_container.hpp"
#include "util/typedefs.hpp"
#include "osrm/coordinate.hpp"
@@ -70,9 +75,12 @@ class InternalDataFacade final : public BaseDataFacade
std::string m_timestamp;
util::ShM<util::Coordinate, false>::vector m_coordinate_list;
util::PackedVector<OSMNodeID, false> m_osmnodeid_list;
util::ShM<NodeID, false>::vector m_via_node_list;
util::ShM<unsigned, false>::vector m_name_ID_list;
util::ShM<extractor::guidance::TurnInstruction, false>::vector m_turn_instruction_list;
util::ShM<LaneDataID, false>::vector m_lane_data_id;
util::ShM<util::guidance::LaneTupelIdPair, false>::vector m_lane_tupel_id_pairs;
util::ShM<extractor::TravelMode, false>::vector m_travel_mode_list;
util::ShM<char, false>::vector m_names_char_list;
util::ShM<unsigned, false>::vector m_geometry_indices;
@@ -81,6 +89,8 @@ class InternalDataFacade final : public BaseDataFacade
util::ShM<unsigned, false>::vector m_segment_weights;
util::ShM<uint8_t, false>::vector m_datasource_list;
util::ShM<std::string, false>::vector m_datasource_names;
util::ShM<std::uint32_t, false>::vector m_lane_description_offsets;
util::ShM<extractor::guidance::TurnLaneType::Mask, false>::vector m_lane_description_masks;
extractor::ProfileProperties m_profile_properties;
std::unique_ptr<InternalRTree> m_static_rtree;
@@ -89,6 +99,18 @@ class InternalDataFacade final : public BaseDataFacade
boost::filesystem::path file_index_path;
util::RangeTable<16, false> m_name_table;
// bearing classes by node based node
util::ShM<BearingClassID, false>::vector m_bearing_class_id_table;
// entry class IDs by edge based egde
util::ShM<EntryClassID, false>::vector m_entry_class_id_list;
// the look-up table for entry classes. An entry class lists the possibility of entry for all
// available turns. For every turn, there is an associated entry class.
util::ShM<util::guidance::EntryClass, false>::vector m_entry_class_table;
// the look-up table for distinct bearing classes. A bearing class lists the available bearings
// at an intersection
util::RangeTable<16, false> m_bearing_ranges_table;
util::ShM<DiscreteBearing, false>::vector m_bearing_values_table;
void LoadProfileProperties(const boost::filesystem::path &properties_path)
{
boost::filesystem::ifstream in_stream(properties_path);
@@ -97,7 +119,22 @@ class InternalDataFacade final : public BaseDataFacade
throw util::exception("Could not open " + properties_path.string() + " for reading.");
}
in_stream.read(reinterpret_cast<char*>(&m_profile_properties), sizeof(m_profile_properties));
in_stream.read(reinterpret_cast<char *>(&m_profile_properties),
sizeof(m_profile_properties));
}
void LoadLaneTupelIdPairs(const boost::filesystem::path &lane_data_path)
{
boost::filesystem::ifstream in_stream(lane_data_path);
if (!in_stream)
{
throw util::exception("Could not open " + lane_data_path.string() + " for reading.");
}
std::uint64_t size;
in_stream.read(reinterpret_cast<char *>(&size), sizeof(size));
m_lane_tupel_id_pairs.resize(size);
in_stream.read(reinterpret_cast<char *>(&m_lane_tupel_id_pairs[0]),
sizeof(m_lane_tupel_id_pairs) * size);
}
void LoadTimestamp(const boost::filesystem::path &timestamp_path)
@@ -140,10 +177,12 @@ class InternalDataFacade final : public BaseDataFacade
unsigned number_of_coordinates = 0;
nodes_input_stream.read((char *)&number_of_coordinates, sizeof(unsigned));
m_coordinate_list.resize(number_of_coordinates);
m_osmnodeid_list.reserve(number_of_coordinates);
for (unsigned i = 0; i < number_of_coordinates; ++i)
{
nodes_input_stream.read((char *)&current_node, sizeof(extractor::QueryNode));
m_coordinate_list[i] = util::Coordinate(current_node.lon, current_node.lat);
m_osmnodeid_list.push_back(current_node.node_id);
BOOST_ASSERT(m_coordinate_list[i].IsValid());
}
@@ -153,7 +192,9 @@ class InternalDataFacade final : public BaseDataFacade
m_via_node_list.resize(number_of_edges);
m_name_ID_list.resize(number_of_edges);
m_turn_instruction_list.resize(number_of_edges);
m_lane_data_id.resize(number_of_edges);
m_travel_mode_list.resize(number_of_edges);
m_entry_class_id_list.resize(number_of_edges);
extractor::OriginalEdgeData current_edge_data;
for (unsigned i = 0; i < number_of_edges; ++i)
@@ -163,7 +204,9 @@ class InternalDataFacade final : public BaseDataFacade
m_via_node_list[i] = current_edge_data.via_node;
m_name_ID_list[i] = current_edge_data.name_id;
m_turn_instruction_list[i] = current_edge_data.turn_instruction;
m_lane_data_id[i] = current_edge_data.lane_data_id;
m_travel_mode_list[i] = current_edge_data.travel_mode;
m_entry_class_id_list[i] = current_edge_data.entry_classid;
}
}
@@ -224,13 +267,14 @@ class InternalDataFacade final : public BaseDataFacade
boost::filesystem::ifstream datasources_stream(datasource_indexes_file, std::ios::binary);
if (!datasources_stream)
{
throw util::exception("Could not open " + datasource_indexes_file.string() + " for reading!");
throw util::exception("Could not open " + datasource_indexes_file.string() +
" for reading!");
}
BOOST_ASSERT(datasources_stream);
std::size_t number_of_datasources = 0;
std::uint64_t number_of_datasources = 0;
datasources_stream.read(reinterpret_cast<char *>(&number_of_datasources),
sizeof(std::size_t));
sizeof(number_of_datasources));
if (number_of_datasources > 0)
{
m_datasource_list.resize(number_of_datasources);
@@ -241,7 +285,8 @@ class InternalDataFacade final : public BaseDataFacade
boost::filesystem::ifstream datasourcenames_stream(datasource_names_file, std::ios::binary);
if (!datasourcenames_stream)
{
throw util::exception("Could not open " + datasource_names_file.string() + " for reading!");
throw util::exception("Could not open " + datasource_names_file.string() +
" for reading!");
}
BOOST_ASSERT(datasourcenames_stream);
std::string name;
@@ -260,6 +305,15 @@ class InternalDataFacade final : public BaseDataFacade
new InternalGeospatialQuery(*m_static_rtree, m_coordinate_list, *this));
}
void LoadLaneDescriptions(const boost::filesystem::path &lane_description_file)
{
if (!util::deserializeAdjacencyArray(lane_description_file.string(),
m_lane_description_offsets,
m_lane_description_masks))
util::SimpleLogger().Write(logWARNING) << "Failed to read turn lane descriptions from "
<< lane_description_file.string();
}
void LoadStreetNames(const boost::filesystem::path &names_file)
{
boost::filesystem::ifstream name_stream(names_file, std::ios::binary);
@@ -277,6 +331,55 @@ class InternalDataFacade final : public BaseDataFacade
}
}
void LoadIntersectionClasses(const boost::filesystem::path &intersection_class_file)
{
std::ifstream intersection_stream(intersection_class_file.string(), std::ios::binary);
if (!intersection_stream)
throw util::exception("Could not open " + intersection_class_file.string() +
" for reading.");
if (!util::readAndCheckFingerprint(intersection_stream))
throw util::exception("Fingeprint does not match in " +
intersection_class_file.string());
{
util::SimpleLogger().Write(logINFO) << "Loading Bearing Class IDs";
std::vector<BearingClassID> bearing_class_id;
if (!util::deserializeVector(intersection_stream, bearing_class_id))
throw util::exception("Reading from " + intersection_class_file.string() +
" failed.");
m_bearing_class_id_table.resize(bearing_class_id.size());
std::copy(
bearing_class_id.begin(), bearing_class_id.end(), &m_bearing_class_id_table[0]);
}
{
util::SimpleLogger().Write(logINFO) << "Loading Bearing Classes";
// read the range table
intersection_stream >> m_bearing_ranges_table;
std::vector<util::guidance::BearingClass> bearing_classes;
// and the actual bearing values
std::uint64_t num_bearings;
intersection_stream.read(reinterpret_cast<char*>(&num_bearings),sizeof(num_bearings));
m_bearing_values_table.resize(num_bearings);
intersection_stream.read(reinterpret_cast<char *>(&m_bearing_values_table[0]),
sizeof(m_bearing_values_table[0]) * num_bearings);
if (!static_cast<bool>(intersection_stream))
throw util::exception("Reading from " + intersection_class_file.string() +
" failed.");
}
{
util::SimpleLogger().Write(logINFO) << "Loading Entry Classes";
std::vector<util::guidance::EntryClass> entry_classes;
if (!util::deserializeVector(intersection_stream, entry_classes))
throw util::exception("Reading from " + intersection_class_file.string() +
" failed.");
m_entry_class_table.resize(entry_classes.size());
std::copy(entry_classes.begin(), entry_classes.end(), &m_entry_class_table[0]);
}
}
public:
virtual ~InternalDataFacade()
{
@@ -284,7 +387,7 @@ class InternalDataFacade final : public BaseDataFacade
m_geospatial_query.reset();
}
explicit InternalDataFacade(const storage::StorageConfig& config)
explicit InternalDataFacade(const storage::StorageConfig &config)
{
ram_index_path = config.ram_index_path;
file_index_path = config.file_index_path;
@@ -302,8 +405,7 @@ class InternalDataFacade final : public BaseDataFacade
LoadGeometries(config.geometries_path);
util::SimpleLogger().Write() << "loading datasource info";
LoadDatasourceInfo(config.datasource_names_path,
config.datasource_indexes_path);
LoadDatasourceInfo(config.datasource_names_path, config.datasource_indexes_path);
util::SimpleLogger().Write() << "loading timestamp";
LoadTimestamp(config.timestamp_path);
@@ -314,8 +416,17 @@ class InternalDataFacade final : public BaseDataFacade
util::SimpleLogger().Write() << "loading street names";
LoadStreetNames(config.names_data_path);
util::SimpleLogger().Write() << "loading lane tags";
LoadLaneDescriptions(config.turn_lane_description_path);
util::SimpleLogger().Write() << "loading rtree";
LoadRTree();
util::SimpleLogger().Write() << "loading intersection class data";
LoadIntersectionClasses(config.intersection_class_path);
util::SimpleLogger().Write() << "Loading Lane Data Pairs";
LoadLaneTupelIdPairs(config.turn_lane_data_path);
}
// search graph access
@@ -367,6 +478,11 @@ class InternalDataFacade final : public BaseDataFacade
return m_coordinate_list[id];
}
OSMNodeID GetOSMNodeIDOfNode(const unsigned id) const override final
{
return m_osmnodeid_list.at(id);
}
extractor::guidance::TurnInstruction
GetTurnInstructionForEdgeID(const unsigned id) const override final
{
@@ -382,8 +498,8 @@ class InternalDataFacade final : public BaseDataFacade
const util::Coordinate north_east) const override final
{
BOOST_ASSERT(m_geospatial_query.get());
const util::RectangleInt2D bbox{south_west.lon, north_east.lon, south_west.lat,
north_east.lat};
const util::RectangleInt2D bbox{
south_west.lon, north_east.lon, south_west.lat, north_east.lat};
return m_geospatial_query->Search(bbox);
}
@@ -404,8 +520,8 @@ class InternalDataFacade final : public BaseDataFacade
{
BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodesInRange(input_coordinate, max_distance,
bearing, bearing_range);
return m_geospatial_query->NearestPhantomNodesInRange(
input_coordinate, max_distance, bearing, bearing_range);
}
std::vector<PhantomNodeWithDistance>
@@ -435,8 +551,8 @@ class InternalDataFacade final : public BaseDataFacade
{
BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, bearing,
bearing_range);
return m_geospatial_query->NearestPhantomNodes(
input_coordinate, max_results, bearing, bearing_range);
}
std::vector<PhantomNodeWithDistance>
@@ -448,13 +564,12 @@ class InternalDataFacade final : public BaseDataFacade
{
BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, max_distance,
bearing, bearing_range);
return m_geospatial_query->NearestPhantomNodes(
input_coordinate, max_results, max_distance, bearing, bearing_range);
}
std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance) const override final
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
const util::Coordinate input_coordinate, const double max_distance) const override final
{
BOOST_ASSERT(m_geospatial_query.get());
@@ -515,11 +630,30 @@ class InternalDataFacade final : public BaseDataFacade
{
result.resize(range.back() - range.front() + 1);
std::copy(m_names_char_list.begin() + range.front(),
m_names_char_list.begin() + range.back() + 1, result.begin());
m_names_char_list.begin() + range.back() + 1,
result.begin());
}
return result;
}
std::string GetPronunciationForID(const unsigned name_id) const override final
{
// We store the pronunciation after the name and destination of a street.
// We do this to get around the street length limit of 255 which would hit
// if we concatenate these. Order (see extractor_callbacks):
// name (0), destination (1), pronunciation (2)
return GetNameForID(name_id + 2);
}
std::string GetDestinationsForID(const unsigned name_id) const override final
{
// We store the destination after the name of a street.
// We do this to get around the street length limit of 255 which would hit
// if we concatenate these. Order (see extractor_callbacks):
// name (0), destination (1), pronunciation (2)
return GetNameForID(name_id + 1);
}
virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const override final
{
return m_via_node_list.at(id);
@@ -547,9 +681,9 @@ class InternalDataFacade final : public BaseDataFacade
result_nodes.clear();
result_nodes.reserve(end - begin);
std::for_each(m_geometry_list.begin() + begin, m_geometry_list.begin() + end,
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge)
{
std::for_each(m_geometry_list.begin() + begin,
m_geometry_list.begin() + end,
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge) {
result_nodes.emplace_back(edge.node_id);
});
}
@@ -563,9 +697,9 @@ class InternalDataFacade final : public BaseDataFacade
result_weights.clear();
result_weights.reserve(end - begin);
std::for_each(m_geometry_list.begin() + begin, m_geometry_list.begin() + end,
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge)
{
std::for_each(m_geometry_list.begin() + begin,
m_geometry_list.begin() + end,
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge) {
result_weights.emplace_back(edge.weight);
});
}
@@ -592,11 +726,10 @@ class InternalDataFacade final : public BaseDataFacade
}
else
{
std::for_each(m_datasource_list.begin() + begin, m_datasource_list.begin() + end,
[&](const uint8_t &datasource_id)
{
result_datasources.push_back(datasource_id);
});
std::for_each(
m_datasource_list.begin() + begin,
m_datasource_list.begin() + end,
[&](const uint8_t &datasource_id) { result_datasources.push_back(datasource_id); });
}
}
@@ -609,7 +742,64 @@ class InternalDataFacade final : public BaseDataFacade
std::string GetTimestamp() const override final { return m_timestamp; }
bool GetContinueStraightDefault() const override final { return m_profile_properties.continue_straight_at_waypoint; }
bool GetContinueStraightDefault() const override final
{
return m_profile_properties.continue_straight_at_waypoint;
}
BearingClassID GetBearingClassID(const NodeID nid) const override final
{
return m_bearing_class_id_table.at(nid);
}
util::guidance::BearingClass
GetBearingClass(const BearingClassID bearing_class_id) const override final
{
BOOST_ASSERT(bearing_class_id != INVALID_BEARING_CLASSID);
auto range = m_bearing_ranges_table.GetRange(bearing_class_id);
util::guidance::BearingClass result;
for (auto itr = m_bearing_values_table.begin() + range.front();
itr != m_bearing_values_table.begin() + range.back() + 1;
++itr)
result.add(*itr);
return result;
}
EntryClassID GetEntryClassID(const EdgeID eid) const override final
{
return m_entry_class_id_list.at(eid);
}
util::guidance::EntryClass GetEntryClass(const EntryClassID entry_class_id) const override final
{
return m_entry_class_table.at(entry_class_id);
}
bool hasLaneData(const EdgeID id) const override final
{
return m_lane_data_id[id] != INVALID_LANE_DATAID;
}
util::guidance::LaneTupelIdPair GetLaneData(const EdgeID id) const override final
{
BOOST_ASSERT(hasLaneData(id));
return m_lane_tupel_id_pairs[m_lane_data_id[id]];
}
extractor::guidance::TurnLaneDescription
GetTurnDescription(const LaneDescriptionID lane_description_id) const override final
{
if (lane_description_id == INVALID_LANE_DESCRIPTIONID)
return {};
else
return extractor::guidance::TurnLaneDescription(
m_lane_description_masks.begin() + m_lane_description_offsets[lane_description_id],
m_lane_description_masks.begin() +
m_lane_description_offsets[lane_description_id + 1]);
}
};
}
}
+219 -40
View File
@@ -3,21 +3,26 @@
// implements all data storage when shared memory _IS_ used
#include "engine/datafacade/datafacade_base.hpp"
#include "storage/shared_datatype.hpp"
#include "storage/shared_memory.hpp"
#include "engine/datafacade/datafacade_base.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "extractor/profile_properties.hpp"
#include "extractor/compressed_edge_container.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "extractor/guidance/turn_lane_types.hpp"
#include "extractor/profile_properties.hpp"
#include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp"
#include "util/guidance/turn_lanes.hpp"
#include "engine/geospatial_query.hpp"
#include "util/make_unique.hpp"
#include "util/range_table.hpp"
#include "util/rectangle.hpp"
#include "util/simple_logger.hpp"
#include "util/static_graph.hpp"
#include "util/static_rtree.hpp"
#include "util/make_unique.hpp"
#include "util/simple_logger.hpp"
#include "util/rectangle.hpp"
#include "util/typedefs.hpp"
#include <cstddef>
@@ -30,9 +35,9 @@
#include <vector>
#include <boost/assert.hpp>
#include <boost/thread/tss.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/lock_guard.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/tss.hpp>
namespace osrm
{
@@ -49,7 +54,7 @@ class SharedDataFacade final : public BaseDataFacade
using QueryGraph = util::StaticGraph<EdgeData, true>;
using GraphNode = QueryGraph::NodeArrayEntry;
using GraphEdge = QueryGraph::EdgeArrayEntry;
using NameIndexBlock = util::RangeTable<16, true>::BlockT;
using IndexBlock = util::RangeTable<16, true>::BlockT;
using InputEdge = QueryGraph::InputEdge;
using RTreeLeaf = super::RTreeLeaf;
using SharedRTree =
@@ -73,8 +78,10 @@ class SharedDataFacade final : public BaseDataFacade
extractor::ProfileProperties *m_profile_properties;
util::ShM<util::Coordinate, true>::vector m_coordinate_list;
util::PackedVector<OSMNodeID, true> m_osmnodeid_list;
util::ShM<NodeID, true>::vector m_via_node_list;
util::ShM<unsigned, true>::vector m_name_ID_list;
util::ShM<LaneDataID, true>::vector m_lane_data_id;
util::ShM<extractor::guidance::TurnInstruction, true>::vector m_turn_instruction_list;
util::ShM<extractor::TravelMode, true>::vector m_travel_mode_list;
util::ShM<char, true>::vector m_names_char_list;
@@ -83,10 +90,13 @@ class SharedDataFacade final : public BaseDataFacade
util::ShM<extractor::CompressedEdgeContainer::CompressedEdge, true>::vector m_geometry_list;
util::ShM<bool, true>::vector m_is_core_node;
util::ShM<uint8_t, true>::vector m_datasource_list;
util::ShM<std::uint32_t, true>::vector m_lane_description_offsets;
util::ShM<extractor::guidance::TurnLaneType::Mask, true>::vector m_lane_description_masks;
util::ShM<char, true>::vector m_datasource_name_data;
util::ShM<std::size_t, true>::vector m_datasource_name_offsets;
util::ShM<std::size_t, true>::vector m_datasource_name_lengths;
util::ShM<util::guidance::LaneTupelIdPair, true>::vector m_lane_tupel_id_pairs;
std::unique_ptr<SharedRTree> m_static_rtree;
std::unique_ptr<SharedGeospatialQuery> m_geospatial_query;
@@ -94,6 +104,18 @@ class SharedDataFacade final : public BaseDataFacade
std::shared_ptr<util::RangeTable<16, true>> m_name_table;
// bearing classes by node based node
util::ShM<BearingClassID, true>::vector m_bearing_class_id_table;
// entry class IDs
util::ShM<EntryClassID, true>::vector m_entry_class_id_list;
// 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::ShM<util::guidance::EntryClass, true>::vector m_entry_class_table;
// the look-up table for distinct bearing classes. A bearing class lists the available bearings
// at an intersection
std::shared_ptr<util::RangeTable<16, true>> m_bearing_ranges_table;
util::ShM<DiscreteBearing, true>::vector m_bearing_values_table;
void LoadChecksum()
{
m_check_sum = *data_layout->GetBlockPtr<unsigned>(shared_memory,
@@ -123,9 +145,11 @@ class SharedDataFacade final : public BaseDataFacade
auto tree_ptr = data_layout->GetBlockPtr<RTreeNode>(
shared_memory, storage::SharedDataLayout::R_SEARCH_TREE);
m_static_rtree.reset(new SharedRTree(
tree_ptr, data_layout->num_entries[storage::SharedDataLayout::R_SEARCH_TREE],
file_index_path, m_coordinate_list));
m_static_rtree.reset(
new SharedRTree(tree_ptr,
data_layout->num_entries[storage::SharedDataLayout::R_SEARCH_TREE],
file_index_path,
m_coordinate_list));
m_geospatial_query.reset(
new SharedGeospatialQuery(*m_static_rtree, m_coordinate_list, *this));
}
@@ -149,7 +173,17 @@ class SharedDataFacade final : public BaseDataFacade
{
auto coordinate_list_ptr = data_layout->GetBlockPtr<util::Coordinate>(
shared_memory, storage::SharedDataLayout::COORDINATE_LIST);
m_coordinate_list.reset(coordinate_list_ptr,
m_coordinate_list.reset(
coordinate_list_ptr,
data_layout->num_entries[storage::SharedDataLayout::COORDINATE_LIST]);
auto osmnodeid_list_ptr = data_layout->GetBlockPtr<std::uint64_t>(
shared_memory, storage::SharedDataLayout::OSM_NODE_ID_LIST);
m_osmnodeid_list.reset(
osmnodeid_list_ptr,
data_layout->num_entries[storage::SharedDataLayout::OSM_NODE_ID_LIST]);
// We (ab)use the number of coordinates here because we know we have the same amount of ids
m_osmnodeid_list.set_number_of_entries(
data_layout->num_entries[storage::SharedDataLayout::COORDINATE_LIST]);
auto travel_mode_list_ptr = data_layout->GetBlockPtr<extractor::TravelMode>(
@@ -158,6 +192,19 @@ class SharedDataFacade final : public BaseDataFacade
travel_mode_list_ptr, data_layout->num_entries[storage::SharedDataLayout::TRAVEL_MODE]);
m_travel_mode_list = std::move(travel_mode_list);
auto lane_data_id_ptr = data_layout->GetBlockPtr<LaneDataID>(
shared_memory, storage::SharedDataLayout::LANE_DATA_ID);
util::ShM<LaneDataID, true>::vector lane_data_id(
lane_data_id_ptr, data_layout->num_entries[storage::SharedDataLayout::LANE_DATA_ID]);
m_lane_data_id = std::move(lane_data_id);
auto lane_tupel_id_pair_ptr = data_layout->GetBlockPtr<util::guidance::LaneTupelIdPair>(
shared_memory, storage::SharedDataLayout::TURN_LANE_DATA);
util::ShM<util::guidance::LaneTupelIdPair, true>::vector lane_tupel_id_pair(
lane_tupel_id_pair_ptr,
data_layout->num_entries[storage::SharedDataLayout::TURN_LANE_DATA]);
m_lane_tupel_id_pairs = std::move(lane_tupel_id_pair);
auto turn_instruction_list_ptr =
data_layout->GetBlockPtr<extractor::guidance::TurnInstruction>(
shared_memory, storage::SharedDataLayout::TURN_INSTRUCTION);
@@ -171,6 +218,13 @@ class SharedDataFacade final : public BaseDataFacade
util::ShM<unsigned, true>::vector name_id_list(
name_id_list_ptr, data_layout->num_entries[storage::SharedDataLayout::NAME_ID_LIST]);
m_name_ID_list = std::move(name_id_list);
auto entry_class_id_list_ptr = data_layout->GetBlockPtr<EntryClassID>(
shared_memory, storage::SharedDataLayout::ENTRY_CLASSID);
typename util::ShM<EntryClassID, true>::vector entry_class_id_list(
entry_class_id_list_ptr,
data_layout->num_entries[storage::SharedDataLayout::ENTRY_CLASSID]);
m_entry_class_id_list = std::move(entry_class_id_list);
}
void LoadViaNodeList()
@@ -186,11 +240,11 @@ class SharedDataFacade final : public BaseDataFacade
{
auto offsets_ptr = data_layout->GetBlockPtr<unsigned>(
shared_memory, storage::SharedDataLayout::NAME_OFFSETS);
auto blocks_ptr = data_layout->GetBlockPtr<NameIndexBlock>(
auto blocks_ptr = data_layout->GetBlockPtr<IndexBlock>(
shared_memory, storage::SharedDataLayout::NAME_BLOCKS);
util::ShM<unsigned, true>::vector name_offsets(
offsets_ptr, data_layout->num_entries[storage::SharedDataLayout::NAME_OFFSETS]);
util::ShM<NameIndexBlock, true>::vector name_blocks(
util::ShM<IndexBlock, true>::vector name_blocks(
blocks_ptr, data_layout->num_entries[storage::SharedDataLayout::NAME_BLOCKS]);
auto names_list_ptr = data_layout->GetBlockPtr<char>(
@@ -203,6 +257,23 @@ class SharedDataFacade final : public BaseDataFacade
m_names_char_list = std::move(names_char_list);
}
void LoadTurnLaneDescriptions()
{
auto offsets_ptr = data_layout->GetBlockPtr<std::uint32_t>(
shared_memory, storage::SharedDataLayout::LANE_DESCRIPTION_OFFSETS);
util::ShM<std::uint32_t, true>::vector offsets(
offsets_ptr,
data_layout->num_entries[storage::SharedDataLayout::LANE_DESCRIPTION_OFFSETS]);
m_lane_description_offsets = std::move(offsets);
auto masks_ptr = data_layout->GetBlockPtr<extractor::guidance::TurnLaneType::Mask>(
shared_memory, storage::SharedDataLayout::LANE_DESCRIPTION_MASKS);
util::ShM<extractor::guidance::TurnLaneType::Mask, true>::vector masks(
masks_ptr, data_layout->num_entries[storage::SharedDataLayout::LANE_DESCRIPTION_MASKS]);
m_lane_description_masks = std::move(masks);
}
void LoadCoreInformation()
{
if (data_layout->num_entries[storage::SharedDataLayout::CORE_MARKER] <= 0)
@@ -263,6 +334,40 @@ class SharedDataFacade final : public BaseDataFacade
m_datasource_name_lengths = std::move(datasource_name_lengths);
}
void LoadIntersectionClasses()
{
auto bearing_class_id_ptr = data_layout->GetBlockPtr<BearingClassID>(
shared_memory, storage::SharedDataLayout::BEARING_CLASSID);
typename util::ShM<BearingClassID, true>::vector bearing_class_id_table(
bearing_class_id_ptr,
data_layout->num_entries[storage::SharedDataLayout::BEARING_CLASSID]);
m_bearing_class_id_table = std::move(bearing_class_id_table);
auto bearing_class_ptr = data_layout->GetBlockPtr<DiscreteBearing>(
shared_memory, storage::SharedDataLayout::BEARING_VALUES);
typename util::ShM<DiscreteBearing, true>::vector bearing_class_table(
bearing_class_ptr, data_layout->num_entries[storage::SharedDataLayout::BEARING_VALUES]);
m_bearing_values_table = std::move(bearing_class_table);
auto offsets_ptr = data_layout->GetBlockPtr<unsigned>(
shared_memory, storage::SharedDataLayout::BEARING_OFFSETS);
auto blocks_ptr = data_layout->GetBlockPtr<IndexBlock>(
shared_memory, storage::SharedDataLayout::BEARING_BLOCKS);
util::ShM<unsigned, true>::vector bearing_offsets(
offsets_ptr, data_layout->num_entries[storage::SharedDataLayout::BEARING_OFFSETS]);
util::ShM<IndexBlock, true>::vector bearing_blocks(
blocks_ptr, data_layout->num_entries[storage::SharedDataLayout::BEARING_BLOCKS]);
m_bearing_ranges_table = util::make_unique<util::RangeTable<16, true>>(
bearing_offsets, bearing_blocks, static_cast<unsigned>(m_bearing_values_table.size()));
auto entry_class_ptr = data_layout->GetBlockPtr<util::guidance::EntryClass>(
shared_memory, storage::SharedDataLayout::ENTRY_CLASS);
typename util::ShM<util::guidance::EntryClass, true>::vector entry_class_table(
entry_class_ptr, data_layout->num_entries[storage::SharedDataLayout::ENTRY_CLASS]);
m_entry_class_table = std::move(entry_class_table);
}
public:
virtual ~SharedDataFacade() {}
@@ -276,8 +381,8 @@ class SharedDataFacade final : public BaseDataFacade
"No shared memory blocks found, have you forgotten to run osrm-datastore?");
}
data_timestamp_ptr = static_cast<storage::SharedDataTimestamp *>(
storage::makeSharedMemory(storage::CURRENT_REGIONS,
sizeof(storage::SharedDataTimestamp), false, false)
storage::makeSharedMemory(
storage::CURRENT_REGIONS, sizeof(storage::SharedDataTimestamp), false, false)
->Ptr());
CURRENT_LAYOUT = storage::LAYOUT_NONE;
CURRENT_DATA = storage::DATA_NONE;
@@ -347,9 +452,11 @@ class SharedDataFacade final : public BaseDataFacade
LoadTimestamp();
LoadViaNodeList();
LoadNames();
LoadTurnLaneDescriptions();
LoadCoreInformation();
LoadProfileProperties();
LoadRTree();
LoadIntersectionClasses();
util::SimpleLogger().Write() << "number of geometries: "
<< m_coordinate_list.size();
@@ -411,6 +518,11 @@ class SharedDataFacade final : public BaseDataFacade
return m_coordinate_list[id];
}
OSMNodeID GetOSMNodeIDOfNode(const unsigned id) const override final
{
return m_osmnodeid_list.at(id);
}
virtual void GetUncompressedGeometry(const EdgeID id,
std::vector<NodeID> &result_nodes) const override final
{
@@ -419,9 +531,9 @@ class SharedDataFacade final : public BaseDataFacade
result_nodes.clear();
result_nodes.reserve(end - begin);
std::for_each(m_geometry_list.begin() + begin, m_geometry_list.begin() + end,
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge)
{
std::for_each(m_geometry_list.begin() + begin,
m_geometry_list.begin() + end,
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge) {
result_nodes.emplace_back(edge.node_id);
});
}
@@ -435,9 +547,9 @@ class SharedDataFacade final : public BaseDataFacade
result_weights.clear();
result_weights.reserve(end - begin);
std::for_each(m_geometry_list.begin() + begin, m_geometry_list.begin() + end,
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge)
{
std::for_each(m_geometry_list.begin() + begin,
m_geometry_list.begin() + end,
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge) {
result_weights.emplace_back(edge.weight);
});
}
@@ -462,8 +574,8 @@ class SharedDataFacade final : public BaseDataFacade
const util::Coordinate north_east) const override final
{
BOOST_ASSERT(m_geospatial_query.get());
const util::RectangleInt2D bbox{south_west.lon, north_east.lon, south_west.lat,
north_east.lat};
const util::RectangleInt2D bbox{
south_west.lon, north_east.lon, south_west.lat, north_east.lat};
return m_geospatial_query->Search(bbox);
}
@@ -484,8 +596,8 @@ class SharedDataFacade final : public BaseDataFacade
{
BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodesInRange(input_coordinate, max_distance,
bearing, bearing_range);
return m_geospatial_query->NearestPhantomNodesInRange(
input_coordinate, max_distance, bearing, bearing_range);
}
std::vector<PhantomNodeWithDistance>
@@ -515,8 +627,8 @@ class SharedDataFacade final : public BaseDataFacade
{
BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, bearing,
bearing_range);
return m_geospatial_query->NearestPhantomNodes(
input_coordinate, max_results, bearing, bearing_range);
}
std::vector<PhantomNodeWithDistance>
@@ -528,8 +640,8 @@ class SharedDataFacade final : public BaseDataFacade
{
BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, max_distance,
bearing, bearing_range);
return m_geospatial_query->NearestPhantomNodes(
input_coordinate, max_results, max_distance, bearing, bearing_range);
}
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
@@ -541,9 +653,8 @@ class SharedDataFacade final : public BaseDataFacade
input_coordinate);
}
std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance) const override final
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
const util::Coordinate input_coordinate, const double max_distance) const override final
{
BOOST_ASSERT(m_geospatial_query.get());
@@ -595,11 +706,30 @@ class SharedDataFacade final : public BaseDataFacade
{
result.resize(range.back() - range.front() + 1);
std::copy(m_names_char_list.begin() + range.front(),
m_names_char_list.begin() + range.back() + 1, result.begin());
m_names_char_list.begin() + range.back() + 1,
result.begin());
}
return result;
}
std::string GetPronunciationForID(const unsigned name_id) const override final
{
// We store the pronunciation after the name and destination of a street.
// We do this to get around the street length limit of 255 which would hit
// if we concatenate these. Order (see extractor_callbacks):
// name (0), destination (1), pronunciation (2)
return GetNameForID(name_id + 2);
}
std::string GetDestinationsForID(const unsigned name_id) const override final
{
// We store the destination after the name of a street.
// We do this to get around the street length limit of 255 which would hit
// if we concatenate these. Order (see extractor_callbacks):
// name (0), destination (1), pronunciation (2)
return GetNameForID(name_id + 1);
}
bool IsCoreNode(const NodeID id) const override final
{
if (m_is_core_node.size() > 0)
@@ -634,11 +764,10 @@ class SharedDataFacade final : public BaseDataFacade
}
else
{
std::for_each(m_datasource_list.begin() + begin, m_datasource_list.begin() + end,
[&](const uint8_t &datasource_id)
{
result_datasources.push_back(datasource_id);
});
std::for_each(
m_datasource_list.begin() + begin,
m_datasource_list.begin() + end,
[&](const uint8_t &datasource_id) { result_datasources.push_back(datasource_id); });
}
}
@@ -663,6 +792,56 @@ class SharedDataFacade final : public BaseDataFacade
{
return m_profile_properties->continue_straight_at_waypoint;
}
BearingClassID GetBearingClassID(const NodeID id) const override final
{
return m_bearing_class_id_table.at(id);
}
util::guidance::BearingClass
GetBearingClass(const BearingClassID bearing_class_id) const override final
{
BOOST_ASSERT(bearing_class_id != INVALID_BEARING_CLASSID);
auto range = m_bearing_ranges_table->GetRange(bearing_class_id);
util::guidance::BearingClass result;
for (auto itr = m_bearing_values_table.begin() + range.front();
itr != m_bearing_values_table.begin() + range.back() + 1;
++itr)
result.add(*itr);
return result;
}
EntryClassID GetEntryClassID(const EdgeID eid) const override final
{
return m_entry_class_id_list.at(eid);
}
util::guidance::EntryClass GetEntryClass(const EntryClassID entry_class_id) const override final
{
return m_entry_class_table.at(entry_class_id);
}
bool hasLaneData(const EdgeID id) const override final
{
return INVALID_LANE_DATAID != m_lane_data_id.at(id);
}
util::guidance::LaneTupelIdPair GetLaneData(const EdgeID id) const override final
{
BOOST_ASSERT(hasLaneData(id));
return m_lane_tupel_id_pairs.at(m_lane_data_id.at(id));
}
extractor::guidance::TurnLaneDescription
GetTurnDescription(const LaneDescriptionID lane_description_id) const override final
{
if (lane_description_id == INVALID_LANE_DESCRIPTIONID)
return {};
else
return extractor::guidance::TurnLaneDescription(
m_lane_description_masks.begin() + m_lane_description_offsets[lane_description_id],
m_lane_description_masks.begin() + m_lane_description_offsets[lane_description_id + 1]);
}
};
}
}
+1 -1
View File
@@ -3,8 +3,8 @@
#include "util/coordinate.hpp"
#include <vector>
#include <iterator>
#include <vector>
namespace osrm
{
+2 -2
View File
@@ -1,13 +1,13 @@
#ifndef ENGINE_HPP
#define ENGINE_HPP
#include "engine/status.hpp"
#include "storage/shared_barriers.hpp"
#include "engine/status.hpp"
#include "util/json_container.hpp"
#include <memory>
#include <unordered_map>
#include <string>
#include <unordered_map>
namespace osrm
{
+51 -70
View File
@@ -1,11 +1,11 @@
#ifndef GEOSPATIAL_QUERY_HPP
#define GEOSPATIAL_QUERY_HPP
#include "util/coordinate_calculation.hpp"
#include "util/typedefs.hpp"
#include "engine/phantom_node.hpp"
#include "util/bearing.hpp"
#include "util/coordinate_calculation.hpp"
#include "util/rectangle.hpp"
#include "util/typedefs.hpp"
#include "util/web_mercator.hpp"
#include "osrm/coordinate.hpp"
@@ -30,9 +30,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
using CandidateSegment = typename RTreeT::CandidateSegment;
public:
GeospatialQuery(RTreeT &rtree_,
const CoordinateList &coordinates_,
DataFacadeT &datafacade_)
GeospatialQuery(RTreeT &rtree_, const CoordinateList &coordinates_, DataFacadeT &datafacade_)
: rtree(rtree_), coordinates(coordinates_), datafacade(datafacade_)
{
}
@@ -45,17 +43,14 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// Returns nearest PhantomNodes in the given bearing range within max_distance.
// Does not filter by small/big component!
std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, const double max_distance) const
NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const double max_distance) const
{
auto results =
rtree.Nearest(input_coordinate,
[](const CandidateSegment &)
{
return std::make_pair(true, true);
},
[](const CandidateSegment &) { return std::make_pair(true, true); },
[this, max_distance, input_coordinate](const std::size_t,
const CandidateSegment &segment)
{
const CandidateSegment &segment) {
return CheckSegmentDistance(input_coordinate, segment, max_distance);
});
@@ -72,13 +67,11 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
{
auto results = rtree.Nearest(
input_coordinate,
[this, bearing, bearing_range, max_distance](const CandidateSegment &segment)
{
[this, bearing, bearing_range, max_distance](const CandidateSegment &segment) {
return CheckSegmentBearing(segment, bearing, bearing_range);
},
[this, max_distance, input_coordinate](const std::size_t,
const CandidateSegment &segment)
{
const CandidateSegment &segment) {
return CheckSegmentDistance(input_coordinate, segment, max_distance);
});
@@ -95,12 +88,10 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
{
auto results =
rtree.Nearest(input_coordinate,
[this, bearing, bearing_range](const CandidateSegment &segment)
{
[this, bearing, bearing_range](const CandidateSegment &segment) {
return CheckSegmentBearing(segment, bearing, bearing_range);
},
[max_results](const std::size_t num_results, const CandidateSegment &)
{
[max_results](const std::size_t num_results, const CandidateSegment &) {
return num_results >= max_results;
});
@@ -119,13 +110,11 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
{
auto results =
rtree.Nearest(input_coordinate,
[this, bearing, bearing_range](const CandidateSegment &segment)
{
[this, bearing, bearing_range](const CandidateSegment &segment) {
return CheckSegmentBearing(segment, bearing, bearing_range);
},
[this, max_distance, max_results, input_coordinate](
const std::size_t num_results, const CandidateSegment &segment)
{
const std::size_t num_results, const CandidateSegment &segment) {
return num_results >= max_results ||
CheckSegmentDistance(input_coordinate, segment, max_distance);
});
@@ -140,12 +129,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
{
auto results =
rtree.Nearest(input_coordinate,
[](const CandidateSegment &)
{
return std::make_pair(true, true);
},
[max_results](const std::size_t num_results, const CandidateSegment &)
{
[](const CandidateSegment &) { return std::make_pair(true, true); },
[max_results](const std::size_t num_results, const CandidateSegment &) {
return num_results >= max_results;
});
@@ -161,13 +146,9 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
{
auto results =
rtree.Nearest(input_coordinate,
[](const CandidateSegment &)
{
return std::make_pair(true, true);
},
[](const CandidateSegment &) { return std::make_pair(true, true); },
[this, max_distance, max_results, input_coordinate](
const std::size_t num_results, const CandidateSegment &segment)
{
const std::size_t num_results, const CandidateSegment &segment) {
return num_results >= max_results ||
CheckSegmentDistance(input_coordinate, segment, max_distance);
});
@@ -185,8 +166,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
bool has_big_component = false;
auto results = rtree.Nearest(
input_coordinate,
[&has_big_component, &has_small_component](const CandidateSegment &segment)
{
[&has_big_component, &has_small_component](const CandidateSegment &segment) {
auto use_segment = (!has_small_component ||
(!has_big_component && !segment.data.component.is_tiny));
auto use_directions = std::make_pair(use_segment, use_segment);
@@ -196,9 +176,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
return use_directions;
},
[this, &has_big_component, max_distance,
input_coordinate](const std::size_t num_results, const CandidateSegment &segment)
{
[this, &has_big_component, max_distance, input_coordinate](
const std::size_t num_results, const CandidateSegment &segment) {
return (num_results > 0 && has_big_component) ||
CheckSegmentDistance(input_coordinate, segment, max_distance);
});
@@ -222,8 +201,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
bool has_big_component = false;
auto results = rtree.Nearest(
input_coordinate,
[&has_big_component, &has_small_component](const CandidateSegment &segment)
{
[&has_big_component, &has_small_component](const CandidateSegment &segment) {
auto use_segment = (!has_small_component ||
(!has_big_component && !segment.data.component.is_tiny));
auto use_directions = std::make_pair(use_segment, use_segment);
@@ -233,8 +211,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
return use_directions;
},
[&has_big_component](const std::size_t num_results, const CandidateSegment &)
{
[&has_big_component](const std::size_t num_results, const CandidateSegment &) {
return num_results > 0 && has_big_component;
});
@@ -257,9 +234,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
bool has_big_component = false;
auto results = rtree.Nearest(
input_coordinate,
[this, bearing, bearing_range, &has_big_component,
&has_small_component](const CandidateSegment &segment)
{
[this, bearing, bearing_range, &has_big_component, &has_small_component](
const CandidateSegment &segment) {
auto use_segment = (!has_small_component ||
(!has_big_component && !segment.data.component.is_tiny));
auto use_directions = std::make_pair(use_segment, use_segment);
@@ -276,8 +252,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
return use_directions;
},
[&has_big_component](const std::size_t num_results, const CandidateSegment &)
{
[&has_big_component](const std::size_t num_results, const CandidateSegment &) {
return num_results > 0 && has_big_component;
});
@@ -303,9 +278,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
bool has_big_component = false;
auto results = rtree.Nearest(
input_coordinate,
[this, bearing, bearing_range, &has_big_component,
&has_small_component](const CandidateSegment &segment)
{
[this, bearing, bearing_range, &has_big_component, &has_small_component](
const CandidateSegment &segment) {
auto use_segment = (!has_small_component ||
(!has_big_component && !segment.data.component.is_tiny));
auto use_directions = std::make_pair(use_segment, use_segment);
@@ -322,9 +296,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
return use_directions;
},
[this, &has_big_component, max_distance,
input_coordinate](const std::size_t num_results, const CandidateSegment &segment)
{
[this, &has_big_component, max_distance, input_coordinate](
const std::size_t num_results, const CandidateSegment &segment) {
return (num_results > 0 && has_big_component) ||
CheckSegmentDistance(input_coordinate, segment, max_distance);
});
@@ -345,9 +318,10 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
const std::vector<EdgeData> &results) const
{
std::vector<PhantomNodeWithDistance> distance_and_phantoms(results.size());
std::transform(results.begin(), results.end(), distance_and_phantoms.begin(),
[this, &input_coordinate](const EdgeData &data)
{
std::transform(results.begin(),
results.end(),
distance_and_phantoms.begin(),
[this, &input_coordinate](const EdgeData &data) {
return MakePhantomNode(input_coordinate, data);
});
return distance_and_phantoms;
@@ -359,9 +333,11 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
util::Coordinate point_on_segment;
double ratio;
const auto current_perpendicular_distance =
util::coordinate_calculation::perpendicularDistance(
coordinates[data.u], coordinates[data.v], input_coordinate,
point_on_segment, ratio);
util::coordinate_calculation::perpendicularDistance(coordinates[data.u],
coordinates[data.v],
input_coordinate,
point_on_segment,
ratio);
// Find the node-based-edge that this belongs to, and directly
// calculate the forward_weight, forward_offset, reverse_weight, reverse_offset
@@ -390,7 +366,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
BOOST_ASSERT(data.fwd_segment_position < reverse_weight_vector.size());
for (std::size_t i = 0;
i < reverse_weight_vector.size() - data.fwd_segment_position - 1; i++)
i < reverse_weight_vector.size() - data.fwd_segment_position - 1;
i++)
{
reverse_offset += reverse_weight_vector[i];
}
@@ -408,9 +385,13 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
reverse_weight *= 1.0 - ratio;
}
auto transformed = PhantomNodeWithDistance{PhantomNode{data, forward_weight, forward_offset,
reverse_weight, reverse_offset,
point_on_segment, input_coordinate},
auto transformed = PhantomNodeWithDistance{PhantomNode{data,
forward_weight,
forward_offset,
reverse_weight,
reverse_offset,
point_on_segment,
input_coordinate},
current_perpendicular_distance};
return transformed;
@@ -449,12 +430,12 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
: (forward_edge_bearing + 180);
const bool forward_bearing_valid =
util::bearing::CheckInBounds(std::round(forward_edge_bearing), filter_bearing,
filter_bearing_range) &&
util::bearing::CheckInBounds(
std::round(forward_edge_bearing), filter_bearing, filter_bearing_range) &&
segment.data.forward_segment_id.enabled;
const bool backward_bearing_valid =
util::bearing::CheckInBounds(std::round(backward_edge_bearing), filter_bearing,
filter_bearing_range) &&
util::bearing::CheckInBounds(
std::round(backward_edge_bearing), filter_bearing, filter_bearing_range) &&
segment.data.reverse_segment_id.enabled;
return std::make_pair(forward_bearing_valid, backward_bearing_valid);
}
+41 -18
View File
@@ -1,18 +1,19 @@
#ifndef ENGINE_GUIDANCE_ASSEMBLE_GEOMETRY_HPP
#define ENGINE_GUIDANCE_ASSEMBLE_GEOMETRY_HPP
#include "engine/internal_route_result.hpp"
#include "engine/phantom_node.hpp"
#include "engine/guidance/route_step.hpp"
#include "engine/guidance/leg_geometry.hpp"
#include "engine/guidance/toolkit.hpp"
#include "util/coordinate_calculation.hpp"
#include "util/coordinate.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "extractor/travel_mode.hpp"
#include "engine/datafacade/datafacade_base.hpp"
#include "engine/guidance/leg_geometry.hpp"
#include "engine/guidance/route_step.hpp"
#include "engine/guidance/toolkit.hpp"
#include "engine/internal_route_result.hpp"
#include "engine/phantom_node.hpp"
#include "util/coordinate.hpp"
#include "util/coordinate_calculation.hpp"
#include <vector>
#include <utility>
#include <vector>
namespace osrm
{
@@ -31,11 +32,10 @@ namespace guidance
// |---| segment 1
// |---| segment 2
// |---| segment 3
template <typename DataFacadeT>
LegGeometry assembleGeometry(const DataFacadeT &facade,
const std::vector<PathData> &leg_data,
const PhantomNode &source_node,
const PhantomNode &target_node)
inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
const std::vector<PathData> &leg_data,
const PhantomNode &source_node,
const PhantomNode &target_node)
{
LegGeometry geometry;
@@ -43,34 +43,57 @@ LegGeometry assembleGeometry(const DataFacadeT &facade,
geometry.segment_offsets.push_back(0);
geometry.locations.push_back(source_node.location);
// Need to get the node ID preceding the source phantom node
// TODO: check if this was traversed in reverse?
std::vector<NodeID> reverse_geometry;
facade.GetUncompressedGeometry(source_node.reverse_packed_geometry_id, reverse_geometry);
geometry.osm_node_ids.push_back(facade.GetOSMNodeIDOfNode(
reverse_geometry[reverse_geometry.size() - source_node.fwd_segment_position - 1]));
auto cumulative_distance = 0.;
auto current_distance = 0.;
auto prev_coordinate = geometry.locations.front();
for (const auto &path_point : leg_data)
{
auto coordinate = facade.GetCoordinateOfNode(path_point.turn_via_node);
current_distance +=
current_distance =
util::coordinate_calculation::haversineDistance(prev_coordinate, coordinate);
cumulative_distance += current_distance;
// all changes to this check have to be matched with assemble_steps
if (path_point.turn_instruction.type != extractor::guidance::TurnType::NoTurn)
{
geometry.segment_distances.push_back(current_distance);
geometry.segment_distances.push_back(cumulative_distance);
geometry.segment_offsets.push_back(geometry.locations.size());
current_distance = 0.;
cumulative_distance = 0.;
}
prev_coordinate = coordinate;
geometry.annotations.emplace_back(
LegGeometry::Annotation{current_distance, path_point.duration_until_turn / 10.});
geometry.locations.push_back(std::move(coordinate));
geometry.osm_node_ids.push_back(facade.GetOSMNodeIDOfNode(path_point.turn_via_node));
}
current_distance +=
current_distance =
util::coordinate_calculation::haversineDistance(prev_coordinate, target_node.location);
cumulative_distance += current_distance;
// segment leading to the target node
geometry.segment_distances.push_back(current_distance);
geometry.segment_distances.push_back(cumulative_distance);
geometry.annotations.emplace_back(
LegGeometry::Annotation{current_distance, target_node.forward_weight / 10.});
geometry.segment_offsets.push_back(geometry.locations.size());
geometry.locations.push_back(target_node.location);
// Need to get the node ID following the destination phantom node
// TODO: check if this was traversed in reverse??
std::vector<NodeID> forward_geometry;
facade.GetUncompressedGeometry(target_node.forward_packed_geometry_id, forward_geometry);
geometry.osm_node_ids.push_back(
facade.GetOSMNodeIDOfNode(forward_geometry[target_node.fwd_segment_position]));
BOOST_ASSERT(geometry.segment_distances.size() == geometry.segment_offsets.size() - 1);
BOOST_ASSERT(geometry.locations.size() > geometry.segment_distances.size());
BOOST_ASSERT(geometry.annotations.size() == geometry.locations.size() - 1);
return geometry;
}
+42 -35
View File
@@ -35,11 +35,12 @@ struct NamedSegment
template <std::size_t SegmentNumber>
std::array<std::uint32_t, SegmentNumber> summarizeRoute(const std::vector<PathData> &route_data)
std::array<std::uint32_t, SegmentNumber> summarizeRoute(const std::vector<PathData> &route_data,
const PhantomNode &target_node,
const bool target_traversed_in_reverse)
{
// merges segments with same name id
const auto collapse_segments = [](std::vector<NamedSegment> &segments)
{
const auto collapse_segments = [](std::vector<NamedSegment> &segments) {
auto out = segments.begin();
auto end = segments.end();
@@ -69,47 +70,48 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const std::vector<PathDa
std::vector<NamedSegment> segments(route_data.size());
std::uint32_t index = 0;
std::transform(
route_data.begin(), route_data.end(), segments.begin(), [&index](const PathData &point)
{
route_data.begin(), route_data.end(), segments.begin(), [&index](const PathData &point) {
return NamedSegment{point.duration_until_turn, index++, point.name_id};
});
const auto target_duration =
target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight;
if (target_duration > 1)
segments.push_back({target_duration, index++, target_node.name_id});
// this makes sure that the segment with the lowest position comes first
std::sort(segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs)
{
return lhs.name_id < rhs.name_id ||
(lhs.name_id == rhs.name_id && lhs.position < rhs.position);
});
std::sort(
segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs) {
return lhs.name_id < rhs.name_id ||
(lhs.name_id == rhs.name_id && lhs.position < rhs.position);
});
auto new_end = collapse_segments(segments);
segments.resize(new_end - segments.begin());
// Filter out segments with an empty name (name_id == 0)
new_end = std::remove_if(segments.begin(), segments.end(), [](const NamedSegment &segment)
{
return segment.name_id == 0;
});
new_end = std::remove_if(segments.begin(), segments.end(), [](const NamedSegment &segment) {
return segment.name_id == 0;
});
segments.resize(new_end - segments.begin());
// sort descending
std::sort(segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs)
{
return lhs.duration > rhs.duration ||
(lhs.duration == rhs.duration && lhs.position < rhs.position);
});
std::sort(
segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs) {
return lhs.duration > rhs.duration ||
(lhs.duration == rhs.duration && lhs.position < rhs.position);
});
// make sure the segments are sorted by position
segments.resize(std::min(segments.size(), SegmentNumber));
std::sort(segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs)
{
return lhs.position < rhs.position;
});
std::sort(
segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs) {
return lhs.position < rhs.position;
});
std::array<std::uint32_t, SegmentNumber> summary;
std::fill(summary.begin(), summary.end(), 0);
std::transform(segments.begin(), segments.end(), summary.begin(),
[](const NamedSegment &segment)
{
return segment.name_id;
});
std::transform(segments.begin(),
segments.end(),
summary.begin(),
[](const NamedSegment &segment) { return segment.name_id; });
return summary;
}
}
@@ -126,9 +128,11 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
(target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight) /
10.;
auto distance = std::accumulate(leg_geometry.segment_distances.begin(),
leg_geometry.segment_distances.end(), 0.);
auto duration = std::accumulate(route_data.begin(), route_data.end(), 0.,
auto distance = std::accumulate(
leg_geometry.segment_distances.begin(), leg_geometry.segment_distances.end(), 0.);
auto duration = std::accumulate(route_data.begin(),
route_data.end(),
0.,
[](const double sum, const PathData &data) {
return sum + data.duration_until_turn;
}) /
@@ -166,14 +170,17 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
std::string summary;
if (needs_summary)
{
auto summary_array = detail::summarizeRoute<detail::MAX_USED_SEGMENTS>(route_data);
auto summary_array = detail::summarizeRoute<detail::MAX_USED_SEGMENTS>(
route_data, target_node, target_traversed_in_reverse);
if (route_data.empty())
summary_array[0] = source_node.name_id;
BOOST_ASSERT(detail::MAX_USED_SEGMENTS > 0);
BOOST_ASSERT(summary_array.begin() != summary_array.end());
summary = std::accumulate(std::next(summary_array.begin()), summary_array.end(),
summary = std::accumulate(std::next(summary_array.begin()),
summary_array.end(),
facade.GetNameForID(summary_array.front()),
[&facade](std::string previous, const std::uint32_t name_id)
{
[&facade](std::string previous, const std::uint32_t name_id) {
if (name_id != 0)
{
previous += ", " + facade.GetNameForID(name_id);
+1 -1
View File
@@ -1,8 +1,8 @@
#ifndef ENGINE_GUIDANCE_ASSEMBLE_ROUTE_HPP
#define ENGINE_GUIDANCE_ASSEMBLE_ROUTE_HPP
#include "engine/guidance/route_leg.hpp"
#include "engine/guidance/route.hpp"
#include "engine/guidance/route_leg.hpp"
#include <vector>
+150 -47
View File
@@ -1,17 +1,23 @@
#ifndef ENGINE_GUIDANCE_ASSEMBLE_STEPS_HPP_
#define ENGINE_GUIDANCE_ASSEMBLE_STEPS_HPP_
#include "extractor/guidance/turn_instruction.hpp"
#include "extractor/guidance/turn_lane_types.hpp"
#include "extractor/travel_mode.hpp"
#include "engine/datafacade/datafacade_base.hpp"
#include "engine/guidance/leg_geometry.hpp"
#include "engine/guidance/route_step.hpp"
#include "engine/guidance/step_maneuver.hpp"
#include "engine/guidance/toolkit.hpp"
#include "engine/internal_route_result.hpp"
#include "engine/phantom_node.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "extractor/travel_mode.hpp"
#include "util/bearing.hpp"
#include "util/coordinate.hpp"
#include "util/coordinate_calculation.hpp"
#include "util/guidance/entry_class.hpp"
#include "util/guidance/toolkit.hpp"
#include "util/guidance/turn_lanes.hpp"
#include "util/typedefs.hpp"
#include <boost/optional.hpp>
#include <cstddef>
@@ -25,24 +31,19 @@ namespace guidance
{
namespace detail
{
StepManeuver stepManeuverFromGeometry(extractor::guidance::TurnInstruction instruction,
const LegGeometry &leg_geometry,
const std::size_t segment_index);
StepManeuver stepManeuverFromGeometry(extractor::guidance::TurnInstruction instruction,
const WaypointType waypoint_type,
const LegGeometry &leg_geometry);
std::pair<short, short> getDepartBearings(const LegGeometry &leg_geometry);
std::pair<short, short> getArriveBearings(const LegGeometry &leg_geometry);
std::pair<short, short> getIntermediateBearings(const LegGeometry &leg_geometry,
const std::size_t segment_index);
} // ns detail
template <typename DataFacadeT>
std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
const std::vector<PathData> &leg_data,
const LegGeometry &leg_geometry,
const PhantomNode &source_node,
const PhantomNode &target_node,
const bool source_traversed_in_reverse,
const bool target_traversed_in_reverse)
inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &facade,
const std::vector<PathData> &leg_data,
const LegGeometry &leg_geometry,
const PhantomNode &source_node,
const PhantomNode &target_node,
const bool source_traversed_in_reverse,
const bool target_traversed_in_reverse)
{
const double constexpr ZERO_DURATION = 0., ZERO_DISTANCE = 0.;
const constexpr char *NO_ROTARY_NAME = "";
@@ -64,13 +65,25 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
std::size_t segment_index = 0;
BOOST_ASSERT(leg_geometry.locations.size() >= 2);
auto bearings = detail::getDepartBearings(leg_geometry);
StepManeuver maneuver{source_node.location,
bearings.first,
bearings.second,
extractor::guidance::TurnInstruction::NO_TURN(),
WaypointType::Depart,
0};
Intersection intersection{source_node.location,
std::vector<short>({bearings.second}),
std::vector<bool>({true}),
Intersection::NO_INDEX,
0,
util::guidance::LaneTupel(),
{}};
if (leg_data.size() > 0)
{
StepManeuver maneuver = detail::stepManeuverFromGeometry(
extractor::guidance::TurnInstruction::NO_TURN(), WaypointType::Depart, leg_geometry);
maneuver.location = source_node.location;
// PathData saves the information we need of the segment _before_ the turn,
// but a RouteStep is with regard to the segment after the turn.
// We need to skip the first segment because it is already covered by the
@@ -90,18 +103,61 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
{
BOOST_ASSERT(segment_duration >= 0);
const auto name = facade.GetNameForID(step_name_id);
const auto pronunciation = facade.GetPronunciationForID(step_name_id);
const auto destinations = facade.GetDestinationsForID(step_name_id);
const auto distance = leg_geometry.segment_distances[segment_index];
steps.push_back(RouteStep{step_name_id, name, NO_ROTARY_NAME,
segment_duration / 10.0, distance, path_point.travel_mode,
maneuver, leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1});
if (leg_data_index + 1 < leg_data.size()){
steps.push_back(RouteStep{step_name_id,
std::move(name),
std::move(pronunciation),
std::move(destinations),
NO_ROTARY_NAME,
segment_duration / 10.0,
distance,
path_point.travel_mode,
maneuver,
leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1,
{intersection}});
if (leg_data_index + 1 < leg_data.size())
{
step_name_id = leg_data[leg_data_index + 1].name_id;
} else {
}
else
{
step_name_id = target_node.name_id;
}
maneuver = detail::stepManeuverFromGeometry(path_point.turn_instruction,
leg_geometry, segment_index);
bearings = detail::getIntermediateBearings(leg_geometry, segment_index);
const auto entry_class = facade.GetEntryClass(path_point.entry_classid);
const auto bearing_class =
facade.GetBearingClass(facade.GetBearingClassID(path_point.turn_via_node));
intersection.in = bearing_class.findMatchingBearing(
util::bearing::reverseBearing(bearings.first));
intersection.out = bearing_class.findMatchingBearing(bearings.second);
intersection.location = facade.GetCoordinateOfNode(path_point.turn_via_node);
intersection.bearings.clear();
intersection.bearings.reserve(bearing_class.getAvailableBearings().size());
intersection.lanes = path_point.lane_data.first;
intersection.lane_description =
path_point.lane_data.second != INVALID_LANE_DESCRIPTIONID
? facade.GetTurnDescription(path_point.lane_data.second)
: extractor::guidance::TurnLaneDescription();
std::copy(bearing_class.getAvailableBearings().begin(),
bearing_class.getAvailableBearings().end(),
std::back_inserter(intersection.bearings));
intersection.entry.clear();
for (auto idx : util::irange<std::size_t>(0, intersection.bearings.size()))
{
intersection.entry.push_back(entry_class.allowsEntry(idx));
}
maneuver = {intersection.location,
bearings.first,
bearings.second,
path_point.turn_instruction,
WaypointType::None,
0};
segment_index++;
segment_duration = 0;
}
@@ -109,10 +165,18 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
const auto distance = leg_geometry.segment_distances[segment_index];
const int duration = segment_duration + target_duration;
BOOST_ASSERT(duration >= 0);
steps.push_back(RouteStep{step_name_id, facade.GetNameForID(step_name_id),
NO_ROTARY_NAME, duration / 10., distance, target_mode, maneuver,
steps.push_back(RouteStep{step_name_id,
facade.GetNameForID(step_name_id),
facade.GetPronunciationForID(step_name_id),
facade.GetDestinationsForID(step_name_id),
NO_ROTARY_NAME,
duration / 10.,
distance,
target_mode,
maneuver,
leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1});
leg_geometry.BackIndex(segment_index) + 1,
{intersection}});
}
// In this case the source + target are on the same edge segment
else
@@ -123,29 +187,68 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
// |---| source_duration
// |---------| target_duration
StepManeuver maneuver = detail::stepManeuverFromGeometry(
extractor::guidance::TurnInstruction::NO_TURN(), WaypointType::Depart, leg_geometry);
int duration = target_duration - source_duration;
BOOST_ASSERT(duration >= 0);
steps.push_back(RouteStep{source_node.name_id, facade.GetNameForID(source_node.name_id),
NO_ROTARY_NAME, duration / 10.,
leg_geometry.segment_distances[segment_index], source_mode,
std::move(maneuver), leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1});
steps.push_back(RouteStep{source_node.name_id,
facade.GetNameForID(source_node.name_id),
facade.GetPronunciationForID(source_node.name_id),
facade.GetDestinationsForID(source_node.name_id),
NO_ROTARY_NAME,
duration / 10.,
leg_geometry.segment_distances[segment_index],
source_mode,
std::move(maneuver),
leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1,
{intersection}});
}
BOOST_ASSERT(segment_index == number_of_segments - 1);
bearings = detail::getArriveBearings(leg_geometry);
// This step has length zero, the only reason we need it is the target location
auto final_maneuver = detail::stepManeuverFromGeometry(
extractor::guidance::TurnInstruction::NO_TURN(), WaypointType::Arrive, leg_geometry);
maneuver = {intersection.location,
bearings.first,
bearings.second,
extractor::guidance::TurnInstruction::NO_TURN(),
WaypointType::Arrive,
0};
intersection = {
target_node.location,
std::vector<short>({static_cast<short>(util::bearing::reverseBearing(bearings.first))}),
std::vector<bool>({true}),
0,
Intersection::NO_INDEX,
util::guidance::LaneTupel(),
{}};
BOOST_ASSERT(!leg_geometry.locations.empty());
steps.push_back(RouteStep{target_node.name_id, facade.GetNameForID(target_node.name_id),
NO_ROTARY_NAME, ZERO_DURATION, ZERO_DISTANCE, target_mode,
final_maneuver, leg_geometry.locations.size() - 1,
leg_geometry.locations.size()});
steps.push_back(RouteStep{target_node.name_id,
facade.GetNameForID(target_node.name_id),
facade.GetPronunciationForID(target_node.name_id),
facade.GetDestinationsForID(target_node.name_id),
NO_ROTARY_NAME,
ZERO_DURATION,
ZERO_DISTANCE,
target_mode,
std::move(maneuver),
leg_geometry.locations.size() - 1,
leg_geometry.locations.size(),
{intersection}});
BOOST_ASSERT(steps.front().intersections.size() == 1);
BOOST_ASSERT(steps.front().intersections.front().bearings.size() == 1);
BOOST_ASSERT(steps.front().intersections.front().entry.size() == 1);
BOOST_ASSERT(steps.front().maneuver.waypoint_type == WaypointType::Depart);
BOOST_ASSERT(steps.back().intersections.size() == 1);
BOOST_ASSERT(steps.back().intersections.front().bearings.size() == 1);
BOOST_ASSERT(steps.back().intersections.front().entry.size() == 1);
BOOST_ASSERT(steps.back().maneuver.waypoint_type == WaypointType::Arrive);
BOOST_ASSERT(steps.back().intersections.front().lanes.lanes_in_turn == 0);
BOOST_ASSERT(steps.back().intersections.front().lanes.first_lane_from_the_right == INVALID_LANEID);
BOOST_ASSERT(steps.back().intersections.front().lane_description.empty());
return steps;
}
@@ -0,0 +1,27 @@
#ifndef OSRM_ENGINE_GUIDANCE_LANE_PROCESSING_HPP_
#define OSRM_ENGINE_GUIDANCE_LANE_PROCESSING_HPP_
#include <vector>
#include "engine/guidance/route_step.hpp"
namespace osrm
{
namespace engine
{
namespace guidance
{
// Constrains lanes for multi-hop situations where lane changes depend on earlier ones.
// Instead of forcing users to change lanes rapidly in a short amount of time,
// we anticipate lane changes emitting only matching lanes early on.
// the second parameter describes the duration that we feel two segments need to be apart to count
// as separate maneuvers.
std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
const double min_duration_needed_for_lane_change = 15);
} // namespace guidance
} // namespace engine
} // namespace osrm
#endif /* OSRM_ENGINE_GUIDANCE_LANE_PROCESSING_HPP_ */

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