Compare commits

...

266 Commits

Author SHA1 Message Date
Moritz Kobitzsch 189f8c3265 move summaries to car profile, test for references, use boost adaptors 2016-09-30 11:07:46 +02:00
karenzshea 12238ebb52 handle empty names in summaries 2016-09-30 11:06:39 +02:00
Moritz Kobitzsch b033ac9f0b initialize 5.4.0-rc.6 changelog 2016-09-29 17:44:28 +02:00
Moritz Kobitzsch a411589092 fix polyline decoding 2016-09-29 17:42:29 +02:00
Johan Uhle 45673581ea Changelog: Fix typo for 5.4.0-rc.5 2016-09-26 14:47:21 +02:00
Moritz Kobitzsch f9ecdca5d5 add changelog 2016-09-21 12:57:34 +02:00
Daniel J. Hofmann accdbe92f0 Reduce NewName Instructructions / Name Changes
With @karenzshea's name / ref split (ref. #2857) in master we want to
make use of it and reduce `NewName` instructions when ever possible.
This is a first step towards #2744 by using the already existing name
change heuristic from the extractor now in post-processing as well.

Limitations: at the moment we don't have the `SuffixTable` in
post-processing; this would require us serializing and subsequently
deserializing the table, passing it through from the profiles to the
API.
2016-09-21 12:56:38 +02:00
Moritz Kobitzsch 644d082cb9 add changelog entry for profile change 2016-09-21 11:48:09 +02:00
Daniel J. Hofmann f948fb081b Handle HOV designated-only Lanes, resolves #2929
In https://github.com/Project-OSRM/osrm-backend/issues/2711 we made
`hov=designated` routability configurable.

We want to handle designated-only lanes in the same way. Example:

    hov:lanes:forward=designated|designated
    hov:lanes:backward=designated

should have more or less the same effects as

    hov=designated

In contrast

    hov:lanes:forward=designated|no|yes hov:lanes:backward=yes

should not be handled. See

    https://github.com/Project-OSRM/osrm-backend/issues/2711

for explanation wrt. tag semantics with the difference that
backward/forward only set the backward/forward mode to inaccessible.

References:
- http://wiki.openstreetmap.org/wiki/Key:hov#hov:lanes.3D.2A
2016-09-21 11:47:03 +02:00
Michael Krasnyk 42445dc10c Fix "Error: write after end" and removed @bug tags
https://nodejs.org/api/child_process.html#child_process_event_exit
Note that when the 'exit' event is triggered, child process stdio streams might still be open.
2016-09-21 10:54:11 +02:00
Patrick Niklaus c1041e5a64 Close GH-2795: Rewrite cucumber test caching (and support logic). Fixes #2745 2016-09-20 08:36:20 +02:00
Moritz Kobitzsch b2bc169547 add changelog entry 2016-09-19 14:08:54 +02:00
Moritz Kobitzsch 5713460331 Prevent loops in extraction based on merge 2016-09-19 14:06:38 +02:00
Daniel J. Hofmann cc2e26fd52 Fixes sign mismatch in Nearest limit comparison 2016-09-16 15:43:21 +02:00
Moritz Kobitzsch c0bd9da645 remove dead code 2016-09-16 07:30:22 +02:00
Moritz Kobitzsch 7348e7ca55 fix may be uninitialised warnings 2016-09-15 13:24:58 +02:00
Daniel J. Hofmann 519dc986f9 Do Not Copy Lane Strings Into Fn 2016-09-15 08:22:39 +02:00
Moritz Kobitzsch 1ae2964b0f fix roundabout-intersection on immediate exit 2016-09-13 19:28:20 +02:00
Moritz Kobitzsch 237e8e02fd prepare 5.4.0-rc.2 2016-09-13 14:40:14 +02:00
Moritz Kobitzsch 865052352e fix false positives in sliproads 2016-09-13 14:37:25 +02:00
Moritz Kobitzsch 2064d6b2ce also reserve entry for refs 2016-09-13 14:01:13 +02:00
Daniel Patterson 6c9227d4d0 Update changelog for issue #2896 fix. 2016-09-12 15:15:04 -07:00
Michael Krasnyk ef66e271c1 Test for PR #2898
Test checks that osrm-extract terminates for
http://www.openstreetmap.org/way/198481519
2016-09-12 15:12:34 -07:00
Moritz Kobitzsch 7c3b587028 fix looping in sliproad handler for lanes 2016-09-12 18:34:28 +02:00
Daniel J. Hofmann d399014633 Adds a limit for number of results returned in Nearest service, resolves #2872 2016-09-12 12:08:49 +02:00
Daniel J. Hofmann e27ce0e518 Fixes issue where two ways with same name but different pronunciation where deduplicated, resolves #2860 2016-09-12 11:01:51 +02:00
Daniel J. Hofmann 1a1e16c5b4 We do duration based routing (also see #77); closes #2885 2016-09-09 16:27:58 +02:00
Daniel J. Hofmann 01e7232add Fixes compilation against newer Boost versions; seems like we were lucky before; closes #2889 2016-09-09 16:15:21 +02:00
Moritz Kobitzsch c69f99f282 make sure to reserve enough external memory 2016-09-09 15:55:57 +02:00
Daniel J. Hofmann 391163cba0 Fixes bearing range of zero exhaustive graph traversal 2016-09-08 17:38:40 +02:00
Moritz Kobitzsch 4cddec298f prepare 5.4.0-rc.1 2016-09-08 16:56:11 +02:00
Moritz Kobitzsch c306a59854 make sure to not-collapse different travel modes 2016-09-08 15:01:25 +02:00
karenzshea dcc1b5ab2b return name and reference separately 2016-09-08 14:28:23 +02:00
Moritz Kobitzsch 938dff011f handle all our new strings correctly, introduce rotary_pronunciation 2016-09-07 16:09:13 +02:00
Moritz Kobitzsch 9123c93a90 fix interaction between sliproads/segregated intersections 2016-09-07 12:36:29 +02:00
Moritz Kobitzsch a551286a8f adjust testscases for collapse of use lane 2016-09-07 12:17:36 +02:00
Daniel J. Hofmann 86fd04e556 Improves lane handling for subsequent going straight, resolves #2625
Before we only worked on subsequent quick turns, as in:
`right, right` keeps the user on the rightmost lanes.

This changeset modifies the logic to work on any subsequent steps
that are "quick" and have lane information we can constrain later.

Because we do not have a from-lane => to-lanes mapping we take the
lanes left and right of the turn lanes into account when heuristically
assigning the leftmost / rightmost lanes.

There are some edge cases where this still does not give us the optimal
solution but it gets close to what is actually possible at the moment
without having a lane mapping in post-processing.

References:
- https://github.com/Project-OSRM/osrm-backend/issues/2625

fix rebase
2016-09-07 12:17:36 +02:00
Moritz Kobitzsch b6dbf81206 don't assign lanes on delayed turns 2016-09-07 12:17:34 +02:00
Daniel J. Hofmann af47252efe Do not collapse away lane information as long as it is necessary 2016-09-07 12:17:00 +02:00
Moritz Kobitzsch 3b81b39998 turn lane handler moved to scenario based handling 2016-09-07 12:16:59 +02:00
Moritz Kobitzsch 802b93fa9a fix testcases, one case only works by turn restriction, needs investigation 2016-09-07 12:04:17 +02:00
Daniel Patterson 7899444135 Add example request to the route API esection 2016-09-06 10:31:08 -07:00
Daniel Patterson 1ab2b87cc0 Update turn penalty function to better fit measured data 2016-09-06 09:07:00 -07:00
Moritz Kobitzsch 97c66c6c82 added some concerns regarding the angles/length of the turns 2016-09-06 09:57:33 +02:00
Daniel J. Hofmann 733207d4a1 Be more strict classifying staggered intersections, resolves #2824 2016-09-06 09:57:33 +02:00
Moritz Kobitzsch a0ed70f0a2 don't detect sliproads at wrong locations, don't emit invalid instructions 2016-09-06 09:01:06 +02:00
Moritz Kobitzsch d3a6b5a77e detect broken roundabout-taggings 2016-09-05 16:49:57 +02:00
Moritz Kobitzsch 7a523713c7 remove broken assertion 2016-09-05 15:06:56 +02:00
Moritz Kobitzsch f7265892ed correctly detect loss of prefix/suffix 2016-09-05 15:03:21 +02:00
Moritz Kobitzsch be266c7c2b fix copy-paste typo in guidance lib 2016-09-05 15:00:42 +02:00
Moritz Kobitzsch b1b41435b6 Revert "make sure collapse only happens on valid indices"
This reverts commit 47a6cd5462.
2016-09-05 14:54:30 +02:00
Moritz Kobitzsch 8f32a80778 changelog entry 2016-09-05 14:52:14 +02:00
Moritz Kobitzsch 5d79e0ac2f catch infinite loops 2016-09-05 14:52:13 +02:00
Moritz Kobitzsch 47a6cd5462 make sure collapse only happens on valid indices 2016-09-05 12:41:33 +02:00
Moritz Kobitzsch 7528b27f99 mark broken case todo 2016-09-05 11:50:36 +02:00
Daniel Patterson a4f9499305 Invalid string values in lanes:psv:backward should result in 0 lanes,
not `nil`.
2016-09-04 14:23:43 -07:00
Daniel J. Hofmann bb244e28bb Adds a failing test case for 255 unicode code points
The OSM spec says "up to 255 full unicode chars", so we should be able
to handle 255 x 🐼 --- but we don't.

The internal limit is on 255 _bytes_ in the `std::string`, but there can
be up to four bytes in a utf8 encoded code point.

References:
- http://wiki.openstreetmap.org/wiki/API_v0.6#Tags
- http://www.fileformat.info/info/unicode/char/1f43c/browsertest.htm
- https://en.wikipedia.org/wiki/UTF-8#Description
2016-09-02 16:10:32 +02:00
Moritz Kobitzsch 6fac14dbd8 ignore invalid only_* restrictions 2016-09-01 09:14:01 +02:00
Daniel J. Hofmann 8b144f22c9 Exposes osrm::exception for client usage, resolves #2813 2016-09-01 09:12:35 +02:00
karenzshea 146eb3a20e add test case for ignoring unknown restrictions 2016-08-31 09:52:05 -04:00
karenzshea d8e444e620 explicitly return false for no_* restrictions 2016-08-31 08:33:56 -04:00
Patrick Niklaus da9d63a384 Always overwrite m_is_core_node on data swap
This fixes a seg fault when swapping between core/no core datasets
2016-08-30 17:31:08 +02:00
Patrick Niklaus c5e85f3d6d Set parent nodes of core entry nodes not to themselves 2016-08-30 17:31:08 +02:00
Patrick Niklaus e05750547c Merge pull request #2800 from oxidase/fix/2785
[ready] Don't use --gc-sections gold option for binutils < 2.25
2016-08-29 15:13:33 +02:00
Patrick Niklaus 315823cce1 Use service tag to penaltize alleys and forbid emergency access 2016-08-29 14:15:22 +02:00
Patrick Niklaus 6ff07f4e82 State all turn penalties in seconds 2016-08-29 13:54:56 +02:00
Michael Krasnyk 41b54cf25d Don't use gold gc-sections for binutils < 2.25
Issue 2785: check gold binutils version and don't use gc-sections for versions prior 2.25
due to https://sourceware.org/bugzilla/show_bug.cgi?id=17639

readelf --debug-dump=frames build/libosrm_extract.so
Contents of the .eh_frame section:
...
readelf: Warning: Invalid length 0xfff01dd8 in FDE at 0x000020
2016-08-25 23:51:25 +02:00
Patrick Niklaus 5ee15ee339 Use webkit code snippet to detect GNU gold 2016-08-25 22:45:49 +02:00
Patrick Niklaus 01b0bce2d5 Use gold linker by default if available 2016-08-25 22:45:49 +02:00
Patrick Niklaus cb57ccacef Merge pull request #2805 from rkcpi/centos-build-fix
Fix build on CentOS
2016-08-25 10:43:43 +02:00
Moritz Kobitzsch 7e0d14b113 make collapse work by better detecting continue/non-continue situations 2016-08-24 10:34:07 +02:00
Moritz Kobitzsch d06eec5e42 improve segregated road detection 2016-08-24 10:34:07 +02:00
Moritz Kobitzsch 9648821a79 handle missing cases, cleaning up 2016-08-24 10:34:07 +02:00
Moritz Kobitzsch 21fb18fe5e identify merges on non-perception cases 2016-08-24 10:34:07 +02:00
Moritz Kobitzsch 6a2518c0df handle stronger merge cases as well 2016-08-24 10:34:07 +02:00
Moritz Kobitzsch 7886d06839 adjust angles pre-merge as well 2016-08-24 10:34:07 +02:00
Moritz Kobitzsch 5a9eb6ef72 prepare solution 2016-08-24 10:34:07 +02:00
Moritz Kobitzsch b6c3d1d5bf Cucumber Scenario for #2725 2016-08-24 10:34:07 +02:00
Moritz Kobitzsch 9b2f6585fb handle non-through case 2016-08-24 10:12:27 +02:00
Moritz Kobitzsch 46fd17a9ff moved obviousness discovery. updated sliproad handler. back to original cases failing 2016-08-24 10:12:27 +02:00
Daniel J. Hofmann da73bae9c6 Scenario for unnecessary slight left onto Stralauer Str 2016-08-24 10:12:27 +02:00
Moritz Kobitzsch 766e2713ab fix segmentation fault for via-routes with invalid intermediate segments 2016-08-23 14:17:32 +02:00
Sandra Thieme 9957254a5a Use c++1y instead of c++14 2016-08-23 13:01:07 +02:00
Patrick Niklaus 9f6859561c Merge pull request #2796 from frodrigo/update_car_profile_from_omim
Add local maxspeed for Netherland
2016-08-22 23:20:17 +02:00
Frédéric Rodrigo 88573a66cd Add local maxspeed for Netherland 2016-08-22 18:53:33 +02:00
Moritz Kobitzsch 3ccbe9842c add a PR template to the repo 2016-08-19 14:21:20 +02:00
Daniel J. Hofmann 5971822f82 Enable data flow guided fuzzing using traces 2016-08-19 13:59:59 +02:00
Daniel J. Hofmann cdf6baba1d Add fuzz testing drivers for json escaping and uri decoding 2016-08-19 13:59:59 +02:00
Daniel J. Hofmann 4b7ddb6826 Add fuzz testing drivers for url and request parser 2016-08-19 13:59:59 +02:00
Daniel J. Hofmann 06b74c1f08 Add fuzz testing drivers for all parameters 2016-08-19 13:59:59 +02:00
Daniel J. Hofmann 3a0eed2ee5 Make sanitizer used for Fuzz testing configurable via FUZZ_SANITIZER 2016-08-19 13:59:59 +02:00
Daniel J. Hofmann 2557bdcf39 Basic Fuzz Testing.
[100%] Fuzzing libosrm
    /tmp/osrm-backend/build/fuzz/driver -max_len=4096 corpus  > fuzz-0.log 2>&1
    /tmp/osrm-backend/build/fuzz/driver -max_len=4096 corpus  > fuzz-1.log 2>&1
    /tmp/osrm-backend/build/fuzz/driver -max_len=4096 corpus  > fuzz-2.log 2>&1
    /tmp/osrm-backend/build/fuzz/driver -max_len=4096 corpus  > fuzz-3.log 2>&1

References:
- http://llvm.org/docs/LibFuzzer.html
- http://llvm.org/releases/3.8.0/docs/LibFuzzer.html
- https://github.com/Project-OSRM/osrm-backend/issues/1678
2016-08-19 13:59:59 +02:00
Patrick Niklaus 12d478784b Enable toll roads by default again.
Currently we don't route over the Golden Gate bridge by default.
This sets the value to false by default. To test the behavior for
tolls when ignored, we would need issue #2781 implemented.
2016-08-19 13:01:15 +02:00
Moritz Kobitzsch 38fef77d70 additional collapse cases 2016-08-19 12:43:51 +02:00
Moritz Kobitzsch e8bae78749 fix errors introduced in refactor 2016-08-18 11:36:36 +02:00
Moritz Kobitzsch e14bc30428 adjusted for comments 2016-08-18 11:36:36 +02:00
Moritz Kobitzsch 9485c97738 adjusting u-turn handling in lane matching to fully fix 2706 2016-08-18 11:36:36 +02:00
Patrick Niklaus 11aed6c93e Merge pull request #2734 from oxidase/gdb-printers
Added gdb pretty printers
2016-08-18 11:24:16 +02:00
Daniel J. Hofmann d53c267129 Be more aggresive classifying Roundabout Intersections.
Roundabout Intersections are roundabouts with up to four ways and turn
angles which makes the turns obvious, e.g. as in:

```
    *
    *
* *   * *
    *
    *
```

but not

```
     *
    *
* *   *
    * *
     * *
```

For Roundabout Intersections we issue instructions such as
"turn <direction>" instead of "take the <nth> exit".

At the moment we have a limit on the radius for these Roundabout
Intersections of 5 meters. Which fails to classify a wide range of
Roundabout Intersections in the US (with the US-wide streets).

This changeset removes the Roundabout Intersection radius limit:

- if the roundabout is larger than a threshold and is named we classify
  it as a rotary

- if the roundabout matches our criteria for Roundabout Intersections
  we classify it as a Roundabout Intersection

- else fallback to plain old Roundabout

There is a second issue with determining a roundabout's radius.
But that's for another pull request (tracking in #2716).

References:
- https://github.com/Project-OSRM/osrm-backend/issues/2716
2016-08-18 10:50:32 +02:00
Patrick Niklaus 2f6de614c1 Ignore any following columns in a CSV file 2016-08-18 10:19:36 +02:00
Moritz Kobitzsch 087080a6c3 mark via-case todo to prevent known failure to show up in local cucumber 2016-08-15 15:52:47 +02:00
Patrick Niklaus 41b22916f3 Merge pull request #2756 from gojuno/turn_annotation_bugfix
JSON instruction serialization fix.
2016-08-12 19:14:47 +02:00
Lev Dragunov 89f1071947 Static checks for guidance array sizes. 2016-08-12 18:52:54 +03:00
Moritz Kobitzsch 464de785cb fix removal of multiple geometries for first vertex 2016-08-09 12:02:07 +02:00
Lev Dragunov 8986777c58 JSON instruction serialization fix. 2016-08-08 20:32:01 +03:00
Daniel Patterson 65def1a9e2 We should be returning an error if any errors that occur during reprocessing. 2016-08-05 15:11:12 -07:00
Daniel Patterson 176c2244ad Catch and report errors during osrm-contract tests. 2016-08-05 14:19:22 -07:00
Daniel J. Hofmann b161e10b73 No Go To 2016-08-05 18:32:42 +02:00
Daniel J. Hofmann 5bef5dcb04 Disable our added failing cucumber tests for now 2016-08-05 18:32:42 +02:00
Daniel J. Hofmann 46a4c27582 Fall back to generic match finding if not a reverse-lane 2016-08-05 18:32:42 +02:00
Daniel J. Hofmann acc6da86de Skip handling none values for our edge cases for now..
Conflicts:
	src/extractor/guidance/turn_lane_augmentation.cpp
2016-08-05 18:32:42 +02:00
Daniel Patterson 4d84bc0f01 Add a minimal version of the failing test case. 2016-08-05 18:32:42 +02:00
Daniel J. Hofmann c737635a3b Reproducing breaking intersection in cucumber scenario
Conflicts:
	src/extractor/guidance/turn_lane_augmentation.cpp
2016-08-05 18:32:42 +02:00
Daniel J. Hofmann b7eeafb183 Try to come up with a small test case 2016-08-05 18:32:42 +02:00
Patrick Niklaus 677306eeee Merge pull request #2707 from oxidase/left_side_driving
Left side driving
2016-08-05 18:09:10 +02:00
Patrick Niklaus 2284ebaacb [skip ci] Iterate on the release docs 2016-08-05 18:07:28 +02:00
Patrick Niklaus 6b4975b2e4 Fix the release branch 2016-08-05 18:07:28 +02:00
Johan Uhle 94c38d115a Fixing up the release flow docs
- Clarifying guarantees between patch/minor/major versions
- Consolidating version release flow into one flow for patch/minor/major versions
- Add constraint that all minor/major released code needs to have had a release candidate before
2016-08-05 18:07:28 +02:00
Daniel J. Hofmann b1e309b4eb Collapse Staggered Intersections.
Staggered intersection are very short zig-zags of only a few meters.
They are common in rural and exurban areas, especially in the US.

(In addition, these cases could as well be tagging issues)

We do not want to announce these short left-rights or right-lefts:

          * -> b      a -> *
          |       or       |       becomes  a   ->   b
     a -> *                * -> b

Here is one example:

- https://www.openstreetmap.org/edit#map=20/39.26017/-84.25182

And here are two edge-cases that we don't handle at the moment:

- http://www.openstreetmap.org/edit#map=20/38.87900/-76.98519
- http://www.openstreetmap.org/edit#map=19/45.51056/-122.63462

and probably should not handle since the distance in between is
quite long (roughly 7-15 meters). For these we want to announce
two turns to not confuse the user.

Thanks to @1ec5 for raising this issue and @karenzshea for
providing additional US examples and cultural insights.
2016-08-05 14:35:13 +02:00
Patrick Niklaus e8ce119972 Merge pull request #2743 from Project-OSRM/avoid-10m-timeout
Set cacher timeout just under 10 minutes
2016-08-05 10:32:12 +02:00
Dane Springmeyer 8b7cd2931b set cacher timeout just under 10 minutes 2016-08-04 17:16:53 -07:00
Daniel J. Hofmann 8bee57b0b0 Makes toll=yes way's routability configurable in profiles.
The primary use-case is conditionally filtering ways such as:

https://www.openstreetmap.org/edit#map=18/38.94198/-77.28127

which we are guiding the user onto in the route from DC to IAD:

http://map.project-osrm.org/?z=12&center=38.934443%2C-77.167969&loc=38.902656%2C-77.029095&loc=38.952210%2C-77.453424&hl=en&alt=0

This changeset makes `toll=yes` configurable in the profiles, disabling
them by default. Neither do we support time-based fees nor vehicle
category fees at the moment.

References:
- http://wiki.openstreetmap.org/wiki/Key:toll
2016-08-04 14:29:22 +02:00
Patrick Niklaus 6bfe3a2d41 Merge pull request #2733 from gavinsherry/master
Remove unused variable node_info_list
2016-08-04 11:24:33 +02:00
Daniel J. Hofmann 7f71f0ed12 Warn on unused return values in guidance code, resolves #2686.
https://github.com/Project-OSRM/osrm-backend/pull/2685/files

fixes an issue where we did

    elongate(fstStep, sndStep);

instead of

    newStep = elongate(fstStep, sndStep);

we didn't get any warnings.

The only way to trigger a warning here is to use

```cpp
__attribute__((warn_unused_result))
```

This changeset does exactly that: for the new guidance code prone to
these kind of issue we add such an attribute to the declaration.
2016-08-03 12:26:07 +02:00
Daniel J. Hofmann 583aaff286 Makes designated HOV way's routability configurable in profiles.
Why only `hov=designated` and not all access tags, such as `hov:yes`,
`hov=no` and so on? From the Wiki:

- designated: The way is designated to high occupancy vehicles.
- yes: High occupancy vehicles are allowed. This by itself does not imply that other vehicles are restricted from using the way.
- no: High occupancy vehicles are not allowed on the way. This by itself does not imply that other vehicle types are allowed to use it.

The primary use-case is conditionally filtering ways such as:

http://www.openstreetmap.org/way/11198593#map=19/37.82571/-122.30521&layers=D

In addition there is a notion of HOV lanes for lane handling:

http://wiki.openstreetmap.org/wiki/Key:hov#hov:lanes.3D.2A

This changeset does not handle lanes at all, only designated HOV ways.
For HOV lane support, a logic similar to the lane access handling needs
to be implemented. This needs to go hand in hand with the existing lane
handling introduced in:

https://github.com/Project-OSRM/osrm-backend/commit/7d076e93445a4d016422a575f1132b267cd13c29

References:
- #2711
- http://wiki.openstreetmap.org/wiki/Key:access
- http://wiki.openstreetmap.org/wiki/Key:hov#Values
2016-08-03 12:24:43 +02:00
Daniel J. Hofmann b24f5c7c1a Adapt lane dump to lanes at intersection (#2675), resolves #2709 2016-08-03 12:19:14 +02:00
Daniel J. Hofmann 026f71934b Adds Cucumber Scenario for sharp left turn at traffic light 2016-08-03 12:18:31 +02:00
Michael Krasnyk 1353d55880 Added gdb pretty printers 2016-08-02 23:32:42 +02:00
Gavin Sherry b09f637d02 Remove unused variable node_info_list 2016-08-02 14:17:57 -07:00
Michael Krasnyk 979f9cab20 Added test for issue #2706 2016-08-02 19:06:10 +02:00
Michael Krasnyk eb6083daf5 Fix travis build 2016-08-02 12:31:46 +02:00
Daniel J. Hofmann c4718495a0 Add Florida Ave NW scenario for TurnLeft instead of MergeRight 2016-07-30 23:55:39 +02:00
Moritz Kobitzsch 0d36d472c9 change paradigm of merge to only emit on motorway-like roads 2016-07-30 23:55:39 +02:00
Daniel Patterson 35422a0fb5 Clang format. 2016-07-30 23:53:38 +02:00
Daniel Patterson d012b44b7f Filter out edges that have any speed=0 segments.
They become non-snappable and non-routable.  Note that a single segment
of speed=0 will eliminate the entire edge.
2016-07-30 23:53:38 +02:00
Patrick Niklaus eda6d9dc7c Builds components on travis again 2016-07-30 23:49:35 +02:00
Patrick Niklaus 63c86198a3 Fix compilation of components.cpp 2016-07-30 23:49:35 +02:00
Patrick Niklaus 33bdfe9cf9 Merge pull request #2720 from oxidase/issue/2706
Fix #2706 by using correct fallback u-turn
2016-07-30 16:25:26 +02:00
Michael Krasnyk a87c5998a1 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-30 12:15:22 +02:00
Michael Krasnyk c918a7957b Updated format and ChangeLog 2016-07-28 22:59:22 +02:00
Michael Krasnyk 61e6afdef0 added a lanes test in clockwise roundabouts 2016-07-28 22:59:22 +02:00
Michael Krasnyk 95dc36e908 addressed comments
Signed-off-by: Lauren Budorick <lauren@mapbox.com>
2016-07-28 22:59:22 +02:00
Lauren Budorick 951a4dc112 commit test file 2016-07-28 22:59:22 +02:00
Lauren Budorick c09b9b4c99 Initial left hand driving implementation 2016-07-28 22:59:22 +02:00
Patrick Niklaus b0873e2aa4 Merge pull request #2712 from Project-OSRM/talk-to-us
Talk to us!
2016-07-28 11:11:00 +02:00
Daniel J. Hofmann 2bdb8fce63 Talk to us! 2016-07-28 11:01:51 +02:00
Konstantin Shalnev d8a692740a Added 'return EXIT_SUCCESS' (#2710) 2016-07-27 16:31:57 -07:00
Patrick Niklaus 14797c421e Reformated the docs for annotations 2016-07-27 15:51:11 -07:00
Daniel Patterson 280b000f07 Include datasources for each segment in route annotation. 2016-07-27 15:51:11 -07:00
Daniel J. Hofmann fb4834458e No longer hard crash datastore on unrecognised options 2016-07-27 11:33:56 +02:00
Patrick Niklaus c7a1576100 Apply clang-format again 2016-07-26 15:00:58 +02:00
Daniel Patterson aebf6fa0b1 [skip ci] Update format script to enforce clang-format version, and work on OSX 2016-07-26 15:00:14 +02:00
Johan Uhle f76e3d4522 Docs: Clarify turn lanes on missing data
After https://github.com/Project-OSRM/osrm-backend/issues/2675#issuecomment-235230198
2016-07-26 13:18:01 +02:00
Daniel J. Hofmann eaf42ba437 Moves invalid id warnings to debug, closes #2630 2016-07-26 13:01:31 +02:00
Patrick Niklaus e83905b783 Fix exception handling around unrecognised options 2016-07-26 11:43:08 +02:00
Daniel Patterson 0b868969be Remove generic std::exception handlers, they don't seem to be adding value, and they hide useful info. 2016-07-26 11:43:08 +02:00
Patrick Niklaus b4710633b1 Rename function to reduce confusion 2016-07-26 11:23:14 +02:00
Moritz Kobitzsch 7d076e9344 handle access flags for lanes 2016-07-25 20:01:58 +02:00
Dane Springmeyer 71d64e8cd9 Default to c++14 / drop g++-4.8 from testing matrix 2016-07-25 19:30:43 +02:00
Daniel J. Hofmann 748fd3efa9 Remove lanes from roundabouts, closes #2626
After half a day of looking at the tagging and the data came to the
following conclusion:

We can't keep the user to the innermost / outermost lanes depending on
the exit the route takes: we found situations where both heuristics were
wrong.

Even on popular roundabouts the tagging is often wrong or in the best
case not present at all.

There are at least two different ways to interpret roundabout
indications: 1/ where e.g. a right arrow on the lane indicates turn
restrictions for the roundabout and the need to take this lane to exit
the roundabout to the right (possibly skipping multiple exits) and 2/
where a right arrow just means this is a lane in a immediate right turn.

Example: Australia marks lanes with arrows that seem to indicate
"angles you can exit the roundabout from", for example, these two ways:
- http://www.openstreetmap.org/way/320941710
- http://www.openstreetmap.org/way/42918021

Whereas Germany marks lanes with "directions you can travel in these
lanes immediately after entering the roundabout":
- http://www.openstreetmap.org/way/52578338

These two different interpretations of how to draw the arrows on the
roads mean we have conflicting solutions to "which lanes can you use to
take exit B from entry A" based on locality.

Continuing to tag ways based on lane markings is no problem, but
unfortunately, we can't reliably resolve good advice for navigation
system users (like "use the inside lane to take the second exit at the
roundabout"), there are too many situations that would generate bad
instructions (instructions that tell users to go into a lane they
shouldn't use).
2016-07-25 19:29:55 +02:00
Moritz Kobitzsch 1fc63e1e72 move hardcoded road priorities into profiles, change road classification 2016-07-25 13:07:54 +02:00
Daniel J. Hofmann fd6bb5ec1f 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-25 12:17:23 +02:00
Patrick Niklaus 261dbf3edd Fix log output of osrm-extract 2016-07-25 12:03:30 +02:00
Moritz Kobitzsch 9e323d2d42 improve sliproad / fork handling 2016-07-22 15:16:59 +02:00
Konstantin Käfer 1309dd2a0f Switch profiles from Lua to library interface
There's now an abstracted interface and no direct calls to Lua anymore.

fixes #1974
2016-07-22 15:03:57 +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
310 changed files with 16231 additions and 4783 deletions
+1 -1
View File
@@ -46,7 +46,7 @@ DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IncludeCategories:
IncludeCategories:
- Regex: '^<'
Priority: 3
- Regex: '^"(osrm|util|engine|extract|contract)/'
+12
View File
@@ -0,0 +1,12 @@
# Issue
What issue is this PR targeting? Is there no issue that covers the problem addressed here? Please open a corresponding issue and link it from here.
## Tasklist
- [ ] ADD OWN TASKS HERE
- [ ] add regression / cucumber cases (see docs/testing.md)
- [ ] review
- [ ] adjust for for comments
## Requirements / Relations
Link any requirements here. Other pull requests this PR is based on?
+21 -26
View File
@@ -13,6 +13,7 @@ notifications:
branches:
only:
- master
- 5.4
cache:
ccache: true
@@ -24,6 +25,7 @@ env:
global:
- CCACHE_TEMPDIR=/tmp/.ccache-temp
- CCACHE_COMPRESS=1
- CASHER_TIME_OUT=599 # one second less than 10m to avoid 10m timeout error: https://github.com/Project-OSRM/osrm-backend/issues/2742
- JOBS=4
matrix:
@@ -42,23 +44,12 @@ matrix:
env: CCOMPILER='gcc-5' CXXCOMPILER='g++-5' BUILD_TYPE='Debug' COVERAGE=ON
- os: linux
compiler: "gcc-4.8-debug"
addons: &gcc48
compiler: "clang-3.8-debug"
addons: &clang38
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.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='gcc-4.8' CXXCOMPILER='g++-4.8' BUILD_TYPE='Debug'
# LLVM APT servers switched off, commenting Clang builds out as they will always fail now
# http://lists.llvm.org/pipermail/llvm-foundation/2016-June/000025.html
#
# - os: linux
# 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
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
@@ -74,14 +65,9 @@ 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'
# Disabled because of CI slowness
#- os: linux
#- compiler: gcc
#- addons: &gcc48
#- apt:
#- sources: ['ubuntu-toolchain-r-test']
#- packages: ['g++-4.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']
#- env: CCOMPILER='gcc-4.8' CXXCOMPILER='g++-4.8' BUILD_TYPE='Release'
- os: linux
compiler: "gcc-5-release-i686"
env: TARGET_ARCH='i686' CCOMPILER='gcc-5' CXXCOMPILER='g++-5' BUILD_TYPE='Release'
# Disabled because of CI slowness
#- os: linux
@@ -117,13 +103,21 @@ 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"
- 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}
- travis_retry wget --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C ${DEPS_DIR} || exit 1
- |
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
@@ -137,7 +131,7 @@ install:
fi
- mkdir build && pushd build
- 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
- cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS:-OFF} -DCOVERAGE=${COVERAGE:-OFF} -DBUILD_TOOLS=ON -DBUILD_COMPONENTS=ON -DENABLE_CCACHE=ON
- echo "travis_fold:start:MAKE"
- make osrm-extract --jobs=3
- make --jobs=${JOBS}
@@ -152,11 +146,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"
+181 -2
View File
@@ -1,20 +1,199 @@
# 5.4.0-rc.6
- Changes from 5.4.0-rc.5
- Bugfixes
- fixed a bug where polyline decoding on a defective polyline could end up in out-of-bound access on a vector
- Guidance
- Summaries have been improved to consider references as well
# 5.4.0-rc.5
- Changes from 5.4.0-rc.4
- Guidance
- Improved detection of obvious name changes
- Profiles
- The default profile for car now excludes HOV-only routes in navigation by default
- Bugfixes
- Fixed a bug that could result in endless loops in combination with sliproads
# 5.4.0-rc.4
- Changes from 5.4.0-rc.3
- Bugfixes
- Fixed a bug where roundabout intersections could result in breaking assertions when immediately exited
# 5.4.0-rc.3
- Changes from 5.4.0-rc.2
- Bugfixes
- BREAKING: Fixed a bug where some roads could be falsly identified as sliproadsi This change requires reprocessing datasets with osrm-extract and osrm-contract
- BREAKING: Fixed a bug that resulted in false names/ref/destination/pronunciation This change requires reprocessing datasets with osrm-extract and osrm-contract
- `restrictions` is now used for namespaced restrictions and restriction exceptions (e.g. `restriction:motorcar=` as well as `except=motorcar`)
- replaced lhs/rhs profiles by using test defined profiles
- Trip Plugin
- changed internal behaviour to prefer the smallest lexicographic result over the largest one
# 5.4.0
- Changes from 5.3.0
- Profiles
- includes library guidance.lua that offers preliminary configuration on guidance.
- added left_hand_driving flag in global profile properties
- modified turn penalty function for car profile - better fit to real data
- return `ref` and `name` as separate fields. Do no use ref or destination as fallback for name value
- Guidance
- Handle Access tags for lanes, only considering valid lanes in lane-guidance (think car | car | bike | car)
- API:
- `annotations=true` now returns the data source id for each segment as `datasources`
- Reduced semantic of merge to refer only to merges from a lane onto a motorway-like road
- new `ref` field in the `RouteStep` object. It contains the reference code or name of a way. Previously merged into the `name` property like `name (ref)` and are now separate fields.
- Bugfixes
- Fixed an issue that would result in segfaults for viaroutes with an invalid intermediate segment when u-turns were allowed at the via-location
- Invalid only_* restrictions could result in loss of connectivity. As a fallback, we assume all turns allowed when the restriction is not valid
- Fixed a bug that could result in an infinite loop when finding information about an upcoming intersection
- Fixed a bug that led to not discovering if a road simply looses a considered prefix
- BREAKING: Fixed a bug that could crash postprocessing of instructions on invalid roundabout taggings. This change requires reprocessing datasets with osrm-extract and osrm-contract
- Fixed an issue that could emit `invalid` as instruction when ending on a sliproad after a traffic-light
- Fixed an issue that would detect turning circles as sliproads
- Fixed a bug where post-processing instructions (e.g. left + left -> uturn) could result in false pronunciations
- Fixes a bug where a bearing range of zero would cause exhaustive graph traversals
- Fixes a bug where certain looped geometries could cause an infinite loop during extraction
- Infrastructure:
- Adds a feature to limit results in nearest service with a default of 100 in `osrm-routed`
# 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 pronounciations. New member `pronounciation` in `RouteStep`, based on `name:pronounciation`
- 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.pronounciation` allows you to set way name pronounciations
- `result.pronunciation` allows you to set way name pronunciations
- `highway=motorway_link` no longer implies `oneway` as per the OSM Wiki
- Infrastructure
+111 -34
View File
@@ -9,9 +9,25 @@ endif()
project(OSRM C CXX)
set(OSRM_VERSION_MAJOR 5)
set(OSRM_VERSION_MINOR 2)
set(OSRM_VERSION_MINOR 4)
set(OSRM_VERSION_PATCH 0)
# 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)
include(FindPackageHandleStandardArgs)
@@ -23,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)
@@ -37,6 +53,9 @@ 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)
option(ENABLE_FUZZING "Fuzz testing using LLVM's libFuzzer" OFF)
option(ENABLE_GOLD_LINKER "Use GNU gold linker if available" ON)
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/include/)
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/include/)
@@ -98,11 +117,31 @@ if(CMAKE_BUILD_TYPE MATCHES Debug)
endif()
endif()
if(ENABLE_GOLD_LINKER)
execute_process(COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
if("${LD_VERSION}" MATCHES "GNU gold")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold -Wl,--disable-new-dtags")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold -Wl,--disable-new-dtags")
message(STATUS "Using GNU gold as linker.")
# Issue 2785: check gold binutils version and don't use gc-sections for versions prior 2.25
string(REGEX REPLACE ".*\\(GNU Binutils[^\\)0-9]+([0-9]+\\.[0-9]+)[^\\)]*\\).*" "\\1" GOLD_BINUTILS_VERSION "${LD_VERSION}")
if ("${GOLD_BINUTILS_VERSION}" VERSION_LESS "2.25")
message(STATUS "Disabling gc-sections on gold binutils < 2.25, see: https://sourceware.org/bugzilla/show_bug.cgi?id=17639")
set(LD_AVOID_GC_SECTIONS TRUE)
endif()
else()
message(WARNING "GNU gold linker isn't available.")
set(ENABLE_GOLD_LINKER OFF)
endif()
endif()
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")
@@ -164,7 +203,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")
@@ -173,12 +212,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()
@@ -188,7 +227,7 @@ execute_process(COMMAND ${CMAKE_CXX_COMPILER} "-Wl,--version" ERROR_QUIET OUTPUT
# For ld.gold and ld.bfs (the GNU linkers) we optimize hard
if("${LINKER_VERSION}" MATCHES "GNU gold" OR "${LINKER_VERSION}" MATCHES "GNU ld")
message(STATUS "Setting linker optimizations")
if(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC")
if(NOT (${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC" OR "${LD_AVOID_GC_SECTIONS}"))
# Tell compiler to put every function in separate section, linker can then match sections and functions
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections")
# Tell linker to do dead code and data eminination during link time discarding sections
@@ -203,9 +242,9 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LINKER_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${LINKER_FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${LINKER_FLAGS}")
# Activate C++11
# Activate C++1y
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++1y")
endif()
# Configuring other platform dependencies
@@ -227,44 +266,58 @@ if(UNIX AND NOT APPLE)
set(MAYBE_RT_LIBRARY rt)
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})
# 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_definitions(-DBOOST_TEST_DYN_LINK)
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)
@@ -274,20 +327,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
@@ -312,9 +368,8 @@ 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}
@@ -384,7 +439,7 @@ file(GLOB VariantGlob third_party/variant/*.hpp)
file(GLOB LibraryGlob include/osrm/*.hpp)
file(GLOB ParametersGlob include/engine/api/*_parameters.hpp)
set(EngineHeader include/engine/status.hpp include/engine/engine_config.hpp include/engine/hint.hpp include/engine/bearing.hpp include/engine/phantom_node.hpp)
set(UtilHeader include/util/coordinate.hpp include/util/json_container.hpp include/util/typedefs.hpp include/util/strong_typedef.hpp)
set(UtilHeader include/util/coordinate.hpp include/util/json_container.hpp include/util/typedefs.hpp include/util/strong_typedef.hpp include/util/exception.hpp)
set(ExtractorHeader include/extractor/extractor.hpp include/extractor/extractor_config.hpp include/extractor/travel_mode.hpp)
set(ContractorHeader include/contractor/contractor.hpp include/contractor/contractor_config.hpp)
set(StorageHeader include/storage/storage.hpp include/storage/storage_config.hpp)
@@ -414,14 +469,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)
@@ -457,3 +521,16 @@ add_custom_target(uninstall
# Modular build system: each directory registered here provides its own CMakeLists.txt
add_subdirectory(unit_tests)
add_subdirectory(src/benchmarks)
if (ENABLE_FUZZING)
# Requires libosrm being built with sanitizers; make configurable and default to ubsan
set(FUZZ_SANITIZER "undefined" CACHE STRING "Sanitizer to be used for Fuzz testing")
set_property(CACHE FUZZ_SANITIZER PROPERTY STRINGS "undefined" "integer" "address" "memory" "thread" "leak")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize-coverage=edge,indirect-calls,8bit-counters -fsanitize=address")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
message(STATUS "Using -fsanitize=${FUZZ_SANITIZER} for Fuzz testing")
add_subdirectory(fuzz)
endif ()
+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.
+7 -2
View File
@@ -10,6 +10,11 @@ The Open Source Routing Machine is a high performance routing engine written in
| Windows | [![Build status](https://ci.appveyor.com/api/projects/status/4iuo3s9gxprmcjjh)](https://ci.appveyor.com/project/DennisOSRM/osrm-backend) |
| Coverage | [![codecov](https://codecov.io/gh/Project-OSRM/osrm-backend/branch/master/graph/badge.svg)](https://codecov.io/gh/Project-OSRM/osrm-backend) |
## Contact
- IRC: server `irc.oftc.net`, channel: `#osrm` (see: `https://www.oftc.net`, and for a webchat: `https://webchat.oftc.net`)
- Mailinglist: `https://lists.openstreetmap.org/listinfo/osrm-talk`
## Building
For instructions on how to [build](https://github.com/Project-OSRM/osrm-backend/wiki/Building-OSRM) and [run OSRM](https://github.com/Project-OSRM/osrm-backend/wiki/Running-OSRM), please consult [the Wiki](https://github.com/Project-OSRM/osrm-backend/wiki).
@@ -46,7 +51,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 +61,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 -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@
+4 -6
View File
@@ -1,10 +1,8 @@
module.exports = {
default: '--require features --tags ~@stress --tags ~@todo',
verify: '--require features --tags ~@todo --tags ~@bug --tags ~@stress -f progress',
jenkins: '--require features --tags ~@todo --tags ~@bug --tags ~@stress --tags ~@options -f progress',
bugs: '--require features --tags @bug',
todo: '--require features --tags @todo',
all: '--require features'
default: '--strict --tags ~@stress --tags ~@todo --require features/support --require features/step_definitions',
verify: '--strict --tags ~@stress --tags ~@todo -f progress --require features/support --require features/step_definitions',
todo: '--strict --tags @todo --require features/support --require features/step_definitions',
all: '--strict --require features/support --require features/step_definitions'
}
+4 -13
View File
@@ -1,18 +1,9 @@
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 -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
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
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
WORKDIR /opt
RUN git clone --depth 1 --branch v0.31.0 https://github.com/creationix/nvm.git
+2 -1
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 \
/bin/bash -lc "osrm-backend/docker/test.sh"
+130 -53
View File
@@ -30,17 +30,17 @@ http://{server}/{service}/{version}/{profile}/{coordinates}[.{format}]?option=va
| Service | Description |
|-------------|-----------------------------------------------------------|
| [`route`](#service-route) | shortest path between given coordinates |
| [`route`](#service-route) | fastest path between given coordinates |
| [`nearest`](#service-nearest) | returns the nearest street segment for a given coordinate |
| [`table`](#service-table) | computes distance tables for given coordinates |
| [`match`](#service-match) | matches given coordinates to the road network |
| [`trip`](#service-trip) | Compute the shortest round trip between given coordinates |
| [`trip`](#service-trip) | Compute the fastest round trip between given coordinates |
| [`tile`](#service-tile) | Return vector tiles containing debugging info |
- `version`: Version of the protocol implemented by the service.
- `profile`: Mode of transportation, is determined by the profile that is used to prepare the data
- `coordinates`: String of format `{longitude},{latitude};{longitude},{latitude}[;{longitude},{latitude} ...]` or `polyline({polyline})`.
- `format`: Only `json` is supportest at the moment. This parameter is optional and defaults to `json`.
- `format`: Only `json` is supported at the moment. This parameter is optional and defaults to `json`.
Passing any `option=value` is optional. `polyline` follows Google's polyline format with precision 5 and can be generated using [this package](https://www.npmjs.com/package/polyline).
To pass parameters to each location some options support an array like encoding:
@@ -181,6 +181,14 @@ In case of error the following `code`s are supported in addition to the general
All other fields might be undefined.
### Example
Query on Berlin with three coordinates and no overview geometry returned:
```
http://router.project-osrm.org/route/v1/driving/13.388860,52.517037;13.397634,52.529407;13.428555,52.523219?overview=false
```
## Service `table`
### Request
```
@@ -294,7 +302,7 @@ All other fields might be undefined.
## Service `trip`
The trip plugin solves the Traveling Salesman Problem using a greedy heuristic (farthest-insertion algorithm).
The returned path does not have to be the shortest path, as TSP is NP-hard it is only an approximation.
The returned path does not have to be the fastest path, as TSP is NP-hard it is only an approximation.
Note that if the input coordinates can not be joined by a single trip (e.g. the coordinates are on several disconnected islands)
multiple trips for each connected component are returned.
@@ -357,7 +365,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,
@@ -399,8 +407,8 @@ Represents a route between two waypoints.
| annotations | |
|--------------|-----------------------------------------------------------------------|
| true | returns distance and durations of each coordinate along the route |
| false | will not exist |
| true | An `Annotation` object containing node ids, durations and distances |
| false | `undefined` |
#### Example
@@ -410,15 +418,39 @@ With `steps=false` and `annotations=true`:
{
"distance": 30.0,
"duration": 100.0,
"steps": []
"steps": [],
"annotation": {
"distance": [5,5,10,5,5],
"duration": [15,15,40,15,15],
"datasources": [1,0,0,0,1],
"nodes": [49772551,49772552,49786799,49786800,49786801,49786802]
}
}
```
### Annotation
Annotation of the whole route leg with fine-grained information about each segment or node id.
#### Properties
- `distance`: The distance, in metres, between each pair of coordinates
- `duration`: The duration between each pair of coordinates, in seconds
- `datasources`: The index of the datasource for the speed between each pair of coordinates. `0` is the default profile, other values are supplied via `--segment-speed-file` to `osrm-contract`
- `nodes`: The OSM node ID for each coordinate along the route, excluding the first/last user-supplied coordinates
#### Example
```json
{
"distance": [5,5,10,5,5],
"duration": [15,15,40,15,15],
"datasources": [1,0,0,0,1],
"nodes": [49772551,49772552,49786799,49786800,49786801,49786802]
}
```
### RouteStep
A step consists of a maneuver such as a turn or merge, followed
@@ -437,11 +469,12 @@ 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.
- `ref`: A reference number or code for the way. Optionally included, if ref data is available for the given way.
- `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 `Intersections` that are passed along the segment, the very first belonging to the StepManeuver
- `intersections`: A list of `Intersection` objects that are passed along the segment, the very first belonging to the StepManeuver
#### Example
@@ -451,22 +484,30 @@ step.
"duration":15.6,
"name":"Lortzingstraße",
"maneuver":{
"type":"depart",
"modifier":"left"
},
"type":"turn",
"modifier":"right",
},
"geometry":"{lu_IypwpAVrAvAdI",
"mode":"driving",
"intersections":[
{"location":[13.39677,52.54366],
"out":1,
"bearings":[66,246],
"entry":["true","true"]},
"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":2,
"bearings":[60,150,240,330],
"entry":["false","true","true","true"]
}
"out":1,
"bearings":[60,240,330],
"entry":["false","true","true"]
"lanes":[
{"indications":["straight"], "valid":"true"},
{"indications":["right"], "valid":"false"}
]}
]}
```
@@ -482,62 +523,92 @@ step.
- `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/rotary_pronunciation` 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. |
| else | Indicates the number of intersections passed until the turn. Example instruction: `at the fourth intersection, turn left` |
New properties (potentially depending on `type`) may be introduced in the future without an API version change.
### Intersections
### 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.
@@ -553,6 +624,7 @@ location of the StepManeuver. Further intersections are listed for every cross-w
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 intersection. If no lane information is available for an intersection, the `lanes` property will not be present.
#### Example
```
@@ -562,6 +634,11 @@ location of the StepManeuver. Further intersections are listed for every cross-w
"out":2,
"bearings":[60,150,240,330],
"entry":["false","true","true","true"]
"lanes":{
"indications": ["left", "straight"],
"valid": "false"
}
]}
}
```
+13
View File
@@ -32,3 +32,16 @@ Given an OpenStreetMap way, the way_function will either return nothing (meaning
All other calculations stem from that, including the returned timings in driving directions, but also, less directly, it feeds into the actual routing decisions the engine will take (a way with a slow traversal speed, may be less favoured than a way with fast traversal speed, but it depends how long it is, and... what it connects to in the rest of the network graph)
Using the power of the scripting language you wouldn't typically see something as simple as a `result.forward_speed = 20` line within the way_function. Instead a way_function will examine the tagging (e.g. `way:get_value_by_key("highway")` and many others), process this information in various ways, calling other local functions, referencing the global variables and look-up hashes, before arriving at the result.
## Guidance
The guidance parameters in profiles are currently a work in progress. They can and will change.
Please be aware of this when using guidance configuration possibilities.
### Road Classification
Guidance uses road classes to decide on when/if to emit specific instructions and to discover which road is obvious when following a route.
Classification uses three flags and a priority-category.
The flags indicate whether a road is a motorway (required for on/off ramps), a link type (the ramps itself, if also a motorway) and whether a road may be omittted in considerations (is considered purely for connectivity).
The priority-category influences the decision which road is considered the obvious choice and which roads can be seen as fork.
Forks can be emitted between roads of similar priority category only. Obvious choices follow a major priority road, if the priority difference is large.
+32 -32
View File
@@ -1,50 +1,50 @@
# Releasing a new OSRM version
Do decide if this is a major or minor version bump use: http://semver.org/
We are using http://semver.org/ for versioning with major, minor and patch versions.
What we guarantee on major version changes:
## Guarantees
- Breaking changes will be in the changelog
- If we break an HTTP API we bump the version
We are giving the following guarantees between versions:
What we guarantee on minor version changes:
### Major version change
- HTTP API does not include breaking changes
- C++ library API does not include breaking changes
- node-osrm API does not include breaking changes
- There are no guarantees about compatiblity of APIs or datasets
- Breaking changes will be noted as `BREAKING` in the changelog
What we DO NOT guarantee on minor version changes:
### Minor version change
- file format comp ability. Breakage will be listed in the changelog.
- new turn types and fields may be introduced. How to handle this see [the HTTP API docs](http.md).
We may introduce forward-compatible changes: query parameters and response properties may be added in responses, but existing properties may not be changed or removed. One exception to this is the addition of new turn types, which we see as forward-compatible changes.
What we guarantee on patch version changes:
- Forward-compatible HTTP API
- Forward-compatible C++ library API
- Forward-compatible node-osrm API
- No compatiblity between OSRM datasets (needs new processing)
- HTTP API does not include breaking changes
- C++ library API does not include breaking changes
- node-osrm API does not include breaking changes
- full file format compatibility
### Patch version change
## Major or Minor release x.y
- No change of query parameters or response formats
- Compatible HTTP API
- Compatible C++ library API
- Compatible node-osrm API
- Compatible OSRM datasets
1. Make sure all tests are passing (e.g. Travis CI gives you a :thumbs_up:)
2. Make sure `CHANGELOG.md` is up to date.
3. Make sure the OSRM version in `CMakeLists.txt` is up to date
4. Use an annotated tag to mark the release: `git tag vx.y.0 -a` Body of the tag description should be the changelog entries.
5. Push tags and commits: `git push; git push --tags`
6. Branch of the `vx.y.0` tag to create a release branch `x.y`:
`git branch x.y. vx.y.0; git push -u x.y:origin/x.y`
7. Modify `.travis.yml` to allow builds for the `x.y` branch.
8. Write a mailing-list post to osrm-talk@openstreetmap.org to announce the release
## Release and branch management
## Patch release x.y.z
- The `master` branch is for the bleeding edge development
- We create and maintain release branches `x.y` to control the release flow
- No minor or major version will be released without a code-equal release candidates
- For quality assurance, release candidates will be run on the demo server for 24 hours before releaseing the version proper
- Patch versions may be released without a release candidate
- We may backport fixes to older versions and release them as patch versions
1. Check out the appropriate release branch x.y
2. Make sure all fixes are listed in the changelog and included in the branch
3. Make sure all tests are passing (e.g. Travis CI gives you a :thumbs_up:)
## Releasing a version
1. Check out the appropriate release branch `x.y`
2. Make sure all tests are passing (e.g. Travis CI gives you a :thumbs_up:)
3. Make sure `CHANGELOG.md` is up to date.
4. Make sure the OSRM version in `CMakeLists.txt` is up to date
5. Use an annotated tag to mark the release: `git tag vx.y.z -a` Body of the tag description should be the changelog entries.
6. Push tags and commits: `git push; git push --tags`
7. Proceede with the `node-osrm` release as outlined in the repository.
8. Write a mailing-list post to osrm-talk@openstreetmap.org to announce the release
8. Proceede with the `node-osrm` release as [outlined in the repository](https://github.com/Project-OSRM/node-osrm/blob/master/docs/releasing.md).
9. If not a release-candidate: Write a mailing-list post to osrm-talk@openstreetmap.org to announce the release
+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 iostreams 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)
+4 -8
View File
@@ -18,7 +18,7 @@
#include <cstdlib>
int main(int argc, const char *argv[]) try
int main(int argc, const char *argv[])
{
if (argc < 2)
{
@@ -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;
@@ -67,6 +67,7 @@ int main(int argc, const char *argv[]) try
std::cout << "Distance: " << distance << " meter\n";
std::cout << "Duration: " << duration << " seconds\n";
return EXIT_SUCCESS;
}
else if (status == Status::Error)
{
@@ -78,8 +79,3 @@ int main(int argc, const char *argv[]) try
return EXIT_FAILURE;
}
}
catch (const std::exception &e)
{
std::cerr << "Error: " << e.what() << std::endl;
return EXIT_FAILURE;
}
+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 |
+2 -2
View File
@@ -15,8 +15,8 @@ Feature: Bike - Street names in instructions
| bc | Your Way | A7 |
When I route I should get
| from | to | route |
| a | c | My Way (A6),Your Way (A7),Your Way (A7) |
| from | to | route | ref |
| a | c | My Way,Your Way,Your Way | A6,A7,A7 |
@unnamed
Scenario: Bike - Use way type to describe unnamed ways
+5 -3
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 |
@@ -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 |
+4 -4
View File
@@ -13,8 +13,8 @@ Feature: Bike - Way ref
| ab | Utopia Drive | E7 |
When I route I should get
| from | to | route |
| a | b | Utopia Drive (E7),Utopia Drive (E7) |
| from | to | route | ref |
| a | b | Utopia Drive,Utopia Drive | E7,E7 |
Scenario: Bike - Way with only ref
Given the node map
@@ -25,8 +25,8 @@ Feature: Bike - Way ref
| ab | | E7 |
When I route I should get
| from | to | route |
| a | b | E7,E7 |
| from | to | route | ref |
| a | b | {highway:primary},{highway:primary} | E7,E7 |
Scenario: Bike - Way with only name
Given the node map
+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 |
+40 -1
View File
@@ -5,7 +5,7 @@ Feature: Car - Restricted access
Background:
Given the profile "car"
Scenario: Car - Access tag hierarchy on ways
Scenario: Car - Access tag hierarchy on ways
Then routability should be
| access | vehicle | motor_vehicle | motorcar | bothw |
| | | | | x |
@@ -148,3 +148,42 @@ Feature: Car - Restricted access
| primary | | | no | | x |
| runway | | | | yes | |
| primary | | | | no | x |
Scenario: Car - only designated HOV ways are ignored by default
Then routability should be
| highway | hov | bothw |
| primary | designated | |
| primary | yes | x |
| primary | no | x |
Scenario: Car - a way with all lanes HOV-designated is inaccessible by default (similar to hov=designated)
Then routability should be
| highway | hov:lanes:forward | hov:lanes:backward | hov:lanes | oneway | forw | backw |
| primary | designated | designated | | | | |
| primary | | designated | | | x | |
| primary | designated | | | | | x |
| primary | designated\|designated | designated\|designated | | | | |
| primary | designated\|no | designated\|no | | | x | x |
| primary | yes\|no | yes\|no | | | x | x |
| primary | | | | | x | x |
| primary | designated | | | -1 | | |
| primary | | designated | | -1 | | x |
| primary | | | designated | yes | | |
| primary | | | designated | -1 | | |
| primary | | | designated\|designated | yes | | |
| primary | | | designated\|designated | -1 | | |
| primary | | | designated\|yes | yes | x | |
| primary | | | designated\|no | -1 | | x |
Scenario: Car - these toll roads always work
Then routability should be
| highway | toll | bothw |
| primary | no | x |
| primary | snowmobile | x |
# To test this we need issue #2781
@todo
Scenario: Car - only toll=yes ways are ignored by default
Then routability should be
| highway | toll | bothw |
| primary | yes | |
+8 -8
View File
@@ -41,10 +41,10 @@ Feature: Car - Handle ferry routes
When I route I should get
| from | to | route | modes | speed |
| a | g | abc,cde,efg,efg | driving,ferry,driving,driving | 25 km/h |
| b | f | abc,cde,efg,efg | driving,ferry,driving,driving | 20 km/h |
| c | e | cde,cde | ferry,ferry | 12 km/h |
| e | c | cde,cde | ferry,ferry | 12 km/h |
| a | g | abc,cde,efg,efg | driving,ferry,driving,driving | 24 km/h |
| b | f | abc,cde,efg,efg | driving,ferry,driving,driving | 18 km/h |
| c | e | cde,cde | ferry,ferry | 11 km/h |
| e | c | cde,cde | ferry,ferry | 11 km/h |
Scenario: Car - Properly handle ISO 8601 durations
Given the node map
@@ -60,7 +60,7 @@ Feature: Car - Handle ferry routes
When I route I should get
| from | to | route | modes | speed |
| a | g | abc,cde,efg,efg | driving,ferry,driving,driving | 25 km/h |
| b | f | abc,cde,efg,efg | driving,ferry,driving,driving | 20 km/h |
| c | e | cde,cde | ferry,ferry | 12 km/h |
| e | c | cde,cde | ferry,ferry | 12 km/h |
| a | g | abc,cde,efg,efg | driving,ferry,driving,driving | 24 km/h |
| b | f | abc,cde,efg,efg | driving,ferry,driving,driving | 18 km/h |
| c | e | cde,cde | ferry,ferry | 11 km/h |
| e | c | cde,cde | ferry,ferry | 11 km/h |
+51 -6
View File
@@ -15,8 +15,8 @@ Feature: Car - Street names in instructions
| bc | Your Way | A1 |
When I route I should get
| from | to | route |
| a | c | My Way,Your Way (A1),Your Way (A1) |
| from | to | route | ref |
| a | c | My Way,Your Way,Your Way | ,A1,A1|
Scenario: Car - A named street with pronunciation
Given the node map
@@ -25,15 +25,32 @@ Feature: Car - Street names in instructions
| | c | |
And the ways
| nodes | name |name:pronunciation | ref |
| 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 |
| from | to | route | pronunciations | ref |
| a | d | My Way,My Way | ,meyeway | ,A1 |
| 1 | c | Your Way,Your Way | yourewaye,yourewaye | , |
# See #2860
Scenario: Car - same street name but different pronunciation
Given the node map
| a | b | c |
| | d | |
| | e | |
And the ways
| nodes | name | name:pronunciation |
| abc | Houston St | hew-stun |
| bde | Houston St | how-stun |
When I route I should get
| from | to | route | pronunciations |
| a | c | Houston St,Houston St | hew-stun,hew-stun |
| a | e | Houston St,Houston St,Houston St | hew-stun,how-stun,how-stun |
@todo
Scenario: Car - Use way type to describe unnamed ways
@@ -48,3 +65,31 @@ Feature: Car - Street names in instructions
When I route I should get
| from | to | route |
| a | c | tertiary,residential,residential |
Scenario: Inner city expressway with on road
Given the node map
| a | b | | | | c | g |
| | | | | f | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | d | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | e | |
And the ways
| nodes | highway | name | name:pronunciation |
| abc | primary | road | roooaad |
| cg | primary | road | roooaad |
| bfd | trunk_link | | |
| cde | trunk | trunk | truank |
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 | pronunciations |
| a,e | road,trunk,trunk | depart,turn right,arrive | roooaad,truank,truank |
+5 -3
View File
@@ -35,8 +35,8 @@ Feature: Car - Oneway streets
Scenario: Car - Around the Block
Given the node map
| a | b |
| d | c |
| | a | b | |
| f | d | c | e |
And the ways
| nodes | oneway |
@@ -44,6 +44,8 @@ Feature: Car - Oneway streets
| bc | |
| cd | |
| da | |
| ce | |
| df | |
When I route I should get
| from | to | route |
@@ -68,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 |
+45 -4
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
@@ -148,11 +149,27 @@ Feature: Car - Turn restrictions
| type | way:from | way:to | node:via | restriction |
| restriction | sj | wj | j | only_left_turn |
Scenario: Car - Only right turn, invalid
Given the node map
| | n | | |
| w | j | e | r |
| | s | | |
And the ways
| nodes | oneway |
| sj | yes |
| nj | -1 |
| wj | -1 |
| ej | -1 |
| re | -1 |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | sj | er | j | only_right_on |
When I route I should get
| from | to | route |
| s | w | sj,wj,wj |
| s | n | |
| s | e | |
| from | to | route |
| s | r | sj,ej,re,re |
@only_turning
Scenario: Car - Only right turn
@@ -429,3 +446,27 @@ Feature: Car - Turn restrictions
| a | b | ax,xy,yb,yb |
| b | a | yb,xy,ax,ax |
@specific
Scenario: Car - Ignore unrecognized restriction
Given the node map
| | n | |
| w | j | e |
| | s | |
And the ways
| nodes | oneway |
| sj | yes |
| nj | -1 |
| wj | -1 |
| ej | -1 |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | sj | wj | j | yield |
When I route I should get
| from | to | route |
| s | w | sj,wj,wj |
| s | n | sj,nj,nj |
| s | e | sj,ej,ej |
+13
View File
@@ -0,0 +1,13 @@
@routing @car @surface
Feature: Car - Surfaces
Background:
Given the profile "car"
Scenario: Car - Surface should reduce speed
Then routability should be
| highway | service | forw | backw |
| service | alley | 5 km/h +-1 | 5 km/h +-1 |
| service | emergency_access | | |
| service | driveway | 15 km/h +-1| 15 km/h +-1 |
+94
View File
@@ -0,0 +1,94 @@
@routing @basic @car
Feature: Basic Routing
Background:
Given the profile "car"
Given a grid size of 500 meters
@smallest
Scenario: Summaries when routing on a simple network
Given the node map
| b | | | f |
| | | | |
| c | d | | g |
| | | | |
| a | | e | |
And the ways
| nodes | name |
| acb | road |
| de | 1 st |
| cd | |
| dg | blvd |
| df | street |
When I route I should get
| waypoints | route | summary |
| a,e | road,,1 st,1 st | road,1 st |
| a,d,f | road,,,street,street | road;street |
| a,e,f | road,,1 st,1 st,1 st,street,street | road,1 st;1 st,street |
Scenario: Name Empty
Given the node map
| a | | b | | | c |
And the ways
| nodes | name |
| ab | road |
| bc | |
When I route I should get
| waypoints | route | summary |
| a,c | road, | road |
Scenario: Name Empty But Ref
Given the node map
| a | | b | | | c |
And the ways
| nodes | name | ref |
| ab | road | |
| bc | | 101 |
When I route I should get
| waypoints | route | summary |
| a,c | road, | road,101 |
Scenario: Only Refs
Given the node map
| a | | b | | | c |
And the ways
| nodes | name | ref |
| ab | | 100 |
| bc | | 101 |
When I route I should get
| waypoints | route | summary |
| a,c | , | 100,101 |
Scenario: Single Ref
Given the node map
| a | | b | | | c |
And the ways
| nodes | name | ref |
| ab | | |
| bc | | 101 |
When I route I should get
| waypoints | route | summary |
| a,c | ,, | 101 |
Scenario: Nothing
Given the node map
| a | | b | | | c |
And the ways
| nodes | name |
| ab | |
| bc | |
When I route I should get
| waypoints | route | summary |
| a,c | , | |
+93 -13
View File
@@ -2,6 +2,8 @@
Feature: Traffic - speeds
Background: Use specific speeds
Scenario: Weighting based on speed file
Given the node locations
| node | lat | lon |
| a | 0.1 | 0.1 |
@@ -21,27 +23,105 @@ Feature: Traffic - speeds
| eb | primary |
| df | primary |
| fb | primary |
And the speed file
Given the profile "testbot"
Given the extract extra arguments "--generate-edge-lookup"
Given the contract extra arguments "--segment-speed-file {speeds_file}"
Given the speed file
"""
1,2,27
2,1,27
1,2,0
2,1,0
2,3,27
3,2,27
1,4,27
4,1,27
"""
And I route I should get
| from | to | route | speed |
| a | b | ad,de,eb,eb | 30 km/h |
| a | c | ad,dc,dc | 31 km/h |
| b | c | bc,bc | 27 km/h |
| a | d | ad,ad | 27 km/h |
| d | c | dc,dc | 36 km/h |
| g | b | fb,fb | 36 km/h |
| a | g | ad,df,fb,fb | 30 km/h |
Scenario: Weighting based on speed file
Scenario: Speeds that isolate a single node (a)
Given the node locations
| node | lat | lon |
| a | 0.1 | 0.1 |
| b | .05 | 0.1 |
| c | 0.0 | 0.1 |
| d | .05 | .03 |
| e | .05 | .066 |
| f | .075 | .066 |
| g | .075 | 0.1 |
| h | 2.075 | 19.1 |
And the ways
| nodes | highway |
| ab | primary |
| ad | primary |
| bc | primary |
| dc | primary |
| de | primary |
| eb | primary |
| df | primary |
| fb | primary |
Given the profile "testbot"
Given the extract extra arguments "--generate-edge-lookup"
Given the contract extra arguments "--segment-speed-file speeds.csv"
Given the contract extra arguments "--segment-speed-file {speeds_file}"
Given the speed file
"""
1,2,0
2,1,0
2,3,27
3,2,27
1,4,0
4,1,0
"""
And I route I should get
| from | to | route | speed |
| a | b | ab,ab | 27 km/h |
| a | c | ab,bc,bc | 27 km/h |
| b | c | bc,bc | 27 km/h |
| a | d | ad,ad | 27 km/h |
| d | c | dc,dc | 36 km/h |
| g | b | ab,ab | 27 km/h |
| a | g | ab,ab | 27 km/h |
| from | to | route | speed |
| a | b | fb,fb | 36 km/h |
| a | c | fb,bc,bc | 30 km/h |
| b | c | bc,bc | 27 km/h |
| a | d | fb,df,df | 36 km/h |
| d | c | dc,dc | 36 km/h |
| g | b | fb,fb | 36 km/h |
| a | g | fb,fb | 36 km/h |
Scenario: Verify that negative values cause an error, they're not valid at all
Given the node locations
| node | lat | lon |
| a | 0.1 | 0.1 |
| b | .05 | 0.1 |
| c | 0.0 | 0.1 |
| d | .05 | .03 |
| e | .05 | .066 |
| f | .075 | .066 |
| g | .075 | 0.1 |
| h | 1.075 | 10.1 |
And the ways
| nodes | highway |
| ab | primary |
| ad | primary |
| bc | primary |
| dc | primary |
| de | primary |
| eb | primary |
| df | primary |
| fb | primary |
Given the profile "testbot"
Given the extract extra arguments "--generate-edge-lookup"
Given the speed file
"""
1,2,-10
2,1,-20
2,3,27
3,2,27
1,4,-3
4,1,-5
"""
And the data has been extracted
When I try to run "osrm-contract --segment-speed-file {speeds_file} {processed_file}"
And stderr should contain "malformed"
And it should exit with an error
+30 -32
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 | 53 km/h | 13.5s +-1 |
# right
| a | e | ad,de,de | 57 km/h | 12.5s +-1 |
| a | e | ad,def,def | 43 km/h | 16.7s +-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 | 58 km/h | 24.9s +-1 |
# straight-right
| a | l | ad,dhk,kl,kl | 60 km/h | 24s +-1 |
| a | l | ad,dhk,klm,klm | 51 km/h | 28.1s +-1 |
# straight-left
| l | e | kl,dhk,de,de | 59 km/h | 24.5s +-1 |
| l | e | klm,dhk,def,def | 53 km/h | 27s +-1 |
# double right
| g | n | fg,fim,mn,mn | 57 km/h | 25s +-1 |
| g | n | fg,fim,mn,mn | 43 km/h | 33.4s +-1 |
# double left
Scenario: Weighting based on turn penalty file
@@ -55,43 +53,43 @@ Feature: Traffic - turn penalties
"""
9,6,7,1.8
9,13,14,24.5
8,4,3,26
8,4,3,30
12,11,8,9
8,11,12,13
8,11,12,23
1,4,5,-0.2
"""
And the contract extra arguments "--turn-penalty-file penalties.csv"
And the contract extra arguments "--turn-penalty-file {penalties_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 | 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 | 57 km/h | 38.2s +-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 | 43 km/h | 33.4s +-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 | 27 km/h | 52.6s +-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 | 51 km/h | 56.2s +-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
Given the contract extra arguments "--turn-penalty-file penalties.csv"
Given the contract extra arguments "--turn-penalty-file {penalties_file}"
And the profile "testbot"
And the turn penalty file
"""
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 |
+1 -1
View File
@@ -16,7 +16,7 @@ Feature: Foot - Street names in instructions
When I route I should get
| from | to | route |
| a | c | My Way (A6),Your Way (B7),Your Way (B7) |
| a | c | My Way,Your Way,Your Way |
@unnamed
Scenario: Foot - Use way type to describe unnamed ways
+3 -3
View File
@@ -14,7 +14,7 @@ Feature: Foot - Way ref
When I route I should get
| from | to | route |
| a | b | Utopia Drive (E7),Utopia Drive (E7) |
| a | b | Utopia Drive,Utopia Drive |
Scenario: Foot - Way with only ref
Given the node map
@@ -25,8 +25,8 @@ Feature: Foot - Way ref
| ab | | E7 |
When I route I should get
| from | to | route |
| a | b | E7,E7 |
| from | to | route |
| a | b | {highway:primary},{highway:primary} |
Scenario: Foot - Way with only name
Given the node map
+236
View File
@@ -0,0 +1,236 @@
@routing @guidance @turn-lanes
Feature: Turn Lane Guidance
Background:
Given the profile "car"
Given a grid size of 3 meters
@sliproads
Scenario: Separate Turn Lanes
Given the node map
| | | | | | | | e | |
| a | | | b | | | | c | g |
| | | | | | | | d | |
| | | | | | | | f | |
And the ways
| nodes | turn:lanes:forward | name | oneway |
| ab | | in | yes |
| bc | left\|through | in | yes |
| bd | right | in | yes |
| ec | | cross | no |
| cd | | cross | no |
| df | | cross | no |
| cg | | straight | no |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | bd | cd | d | no_left_turn |
| restriction | bc | cd | c | no_right_turn |
When I route I should get
| waypoints | route | turns | lanes |
| a,e | in,cross,cross | depart,turn left,arrive | ,left:true straight:false right:false, |
| a,g | in,straight,straight | depart,new name straight,arrive | ,left:false straight:true right:false, |
| a,f | in,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true, |
@sliproads
Scenario: Separate Turn Lanes
Given the node map
| | | | | | | | e | |
| a | | | b | | | | c | g |
| | | | | | | | d | |
| | | | | | | | f | |
And the ways
| nodes | turn:lanes:forward | name | oneway |
| ab | | in | yes |
| bc | left\|through | in | yes |
| bd | right | in | yes |
| ec | | cross | no |
| cd | | cross | no |
| df | | cross | no |
| cg | | straight | no |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | bd | cd | d | no_left_turn |
| restriction | bc | cd | c | no_right_turn |
When I route I should get
| waypoints | route | turns | lanes |
| a,e | in,cross,cross | depart,turn left,arrive | ,left:true straight:false right:false, |
| a,g | in,straight,straight | depart,new name straight,arrive | ,left:false straight:true right:false, |
| a,f | in,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true, |
@sliproads
Scenario: Separate Turn Lanes Next to other turns
Given the node map
| | | | | | | | e | |
| a | | | b | | | | c | g |
| | | | | | | | d | |
| | | | | | | | f | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| i | | | h | | | | j | |
And the ways
| nodes | turn:lanes:forward | name | oneway |
| ab | | in | yes |
| bc | left\|through | in | yes |
| bd | right | in | yes |
| ec | | cross | no |
| cd | | cross | no |
| df | | cross | no |
| cg | | straight | no |
| bh | left\|right | turn | yes |
| ihj | | other | no |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | bd | cd | d | no_left_turn |
| restriction | bc | cd | c | no_right_turn |
When I route I should get
| waypoints | route | turns | lanes |
| a,e | in,cross,cross | depart,turn left,arrive | ,left:true straight:false right:false, |
| a,g | in,straight,straight | depart,new name straight,arrive | ,left:false straight:true right:false, |
| a,f | in,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true, |
| a,j | in,turn,other,other | depart,turn right,turn left,arrive | ,,left:true right:false, |
| a,i | in,turn,other,other | depart,turn right,turn right,arrive | ,,left:false right:true, |
@todo @2654 @none
#https://github.com/Project-OSRM/osrm-backend/issues/2645
#http://www.openstreetmap.org/export#map=19/52.56054/13.32152
Scenario: Kurt-Schuhmacher-Damm
Given the node map
| | | | g | | f |
| | | | | | |
| j | | | h | | e |
| | | | | | |
| a | | | b | | c |
| | | | i | | d |
And the ways
| nodes | name | highway | oneway | turn:lanes |
| ab | | motorway_link | yes | left\|none\|right |
| bc | | primary_link | yes | |
| cd | ksd | secondary | yes | |
| cef | ksd | primary | yes | |
| hj | | motorway_link | yes | |
| eh | | secondary_link | yes | |
| gh | ksd | primary | yes | |
| hbi | ksd | secondary | yes | |
When I route I should get
| waypoints | route | turns | lanes |
| a,f | ,ksd,ksd | depart,turn left,arrive | ,left:true none:true right:false, |
| a,i | ,ksd,ksd | depart,turn right,arrive | ,left:false none:true right:true, |
@todo @2650 @sliproads
#market and haight in SF, restricted turn
#http://www.openstreetmap.org/#map=19/37.77308/-122.42238
Scenario: Market/Haight without Through Street
Given the node map
| | | | | | | | g | j | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | f |
| | | | | | | | | e | |
| | | | | | | | d | | |
| a | | | | | | b | c | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | l | | | h | i | |
And the ways
| nodes | name | highway | oneway | turn:lanes:forward |
| ab | ghough | secondary | yes | |
| bc | ghough | secondary | yes | through\|through |
| bd | ghough | secondary | yes | none\|through |
| def | ghough | secondary | yes | |
| gd | market | primary | yes | |
| dc | market | primary | yes | |
| ch | market | primary | yes | |
| iej | market | primary | yes | |
| bl | haight | residential | yes | left\|none |
And the relations
| type | way:from | way:to | node:via | restriction |
| relation | bd | dc | d | no_right_turn |
When I route I should get
| waypoints | route | turns | lanes |
| a,l | ghough,haight,haight | depart,turn right,arrive | ,none:false straight:false straight:false straight:true, |
| a,h | ghough,market,market | depart,turn slight right,arrive | ,none:false straight:false straight:true straight:true, |
| a,j | ghough,market,market | depart,turn left,arrive | ,none:true straight:false straight:false straight:false, |
| a,f | ghough,ghough,ghough | depart,continue slight left,arrive | ,none:true straight:true straight:false straight:false, |
@todo @2650 @sliproads
#market and haight in SF, unrestricted
#http://www.openstreetmap.org/#map=19/37.77308/-122.42238
Scenario: Market/Haight without Through Street
Given the node map
| | | | | | | | g | j | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | f |
| | | | | | | | | e | |
| | | | | | | | d | | |
| a | | | | | | b | c | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | l | | | h | i | |
And the ways
| nodes | name | highway | oneway | turn:lanes:forward |
| ab | ghough | secondary | yes | |
| bc | ghough | secondary | yes | through\|through |
| bd | ghough | secondary | yes | none\|through |
| def | ghough | secondary | yes | |
| gd | market | primary | yes | |
| dc | market | primary | yes | |
| ch | market | primary | yes | |
| iej | market | primary | yes | |
| bl | haight | residential | yes | left\|none |
When I route I should get
| waypoints | route | turns | lanes |
| a,l | ghough,haight,haight | depart,turn right,arrive | ,none:false straight:false straight:false straight:true, |
| a,h | ghough,market,market | depart,turn slight right,arrive | ,none:false straight:false straight:true straight:true, |
| a,j | ghough,market,market | depart,turn left,arrive | ,none:true straight:false straight:false straight:false, |
| a,f | ghough,ghough,ghough | depart,continue slight left,arrive | ,none:true straight:true straight:false straight:false, |
Scenario: Check sliproad handler loop's exit condition, Issue #2896
# http://www.openstreetmap.org/way/198481519
Given the node locations
| node | lat | lon |
| a | 7.6125350 | 126.5708309 |
| b | 7.6125156 | 126.5707219 |
| c | 7.6125363 | 126.5708337 |
And the ways
| nodes | name |
| cbac | |
When I route I should get
| from | to | route | turns |
| a | c | , | depart,arrive |
+717
View File
@@ -0,0 +1,717 @@
@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,ci,ci | depart,turn slight right,arrive | ,none:false slight right:true, |
| a,j | ab,xbcj | depart,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:true right:false right:false,left:true left:false straight:false,straight:false right:true right:false,left:true straight:false, |
@anticipate
Scenario: Anticipate Lanes for through, through with lanes
Given the node map
| | | | f | g | |
| | | | | | |
| a | b | c | d | | e |
| | | | | | |
| | | | h | i | |
And the ways
| nodes | turn:lanes:forward | name |
| ab | | main |
| bc | left\|through\|through\|through\|right | main |
| cd | left\|through\|right | main |
| de | | main |
| cf | | off |
| ch | | off |
| dg | | off |
| di | | off |
When I route I should get
| waypoints | route | turns | lanes |
| a,e | main,main,main | depart,use lane straight,arrive | ,left:false straight:false straight:true straight:false right:false, |
@anticipate
Scenario: Anticipate Lanes for through and collapse multiple use lanes
Given the node map
| | | e | f | g |
| | | | | |
| a | b | c | d | |
| | | | | |
| | | h | i | j |
And the ways
| nodes | turn:lanes:forward | name |
| ab | left\|through\|through\|right | main |
| bc | left\|through\|through\|right | main |
| cd | left\|through\|through\|through\|right | main |
| be | | off |
| bh | | off |
| cf | | off |
| ci | | off |
| dg | | off |
| dj | | off |
When I route I should get
| waypoints | route | turns | lanes |
| a,c | main,main | depart,arrive | , |
| a,d | main,main | depart,arrive | , |
@anticipate
Scenario: Anticipate Lanes for through followed by left/right
Given the node map
| | | f | g | |
| | | | | d |
| a | b | c | x | |
| | | | | e |
| | | h | i | |
And the ways
| nodes | turn:lanes:forward | name |
| ab | left\|through\|through\|through\|through\|right | main |
| bc | left\|through\|through\|right | main |
| cx | left\|right | main |
| xd | | left |
| xe | | right |
| bf | | off |
| bh | | off |
| cg | | off |
| ci | | off |
When I route I should get
| waypoints | route | turns | lanes |
| a,d | main,main,main,left,left | depart,use lane straight,use lane straight,turn left,arrive | ,left:false straight:false straight:true straight:false straight:false right:false,left:false straight:true straight:false right:false,left:true right:false, |
| a,e | main,main,main,right,right | depart,use lane straight,use lane straight,turn right,arrive | ,left:false straight:false straight:false straight:true straight:false right:false,left:false straight:false straight:true right:false,left:false right:true, |
@anticipate
Scenario: Anticipate Lanes for through with turn before / after
Given the node map
| a | b | c |
| | d | |
| f | e | g |
| | h | |
| j | i | l |
And the ways
| nodes | turn:lanes:forward | name | oneway |
| ab | right\|right\|right\|right | ab | yes |
| cb | left\|left\|left\|left | cb | yes |
| bd | | bdehi | |
| de | left\|left\|through\|through\|through\|through\|right\|right | bdehi | |
| ef | | ef | |
| eg | | eg | |
| eh | | bdehi | |
| hi | left\|left\|right\|right | bdehi | |
| ij | | ij | |
| il | | il | |
When I route I should get
| waypoints | route | turns | lanes | # |
| a,f | ab,bdehi,ef,ef | depart,turn right,turn right,arrive | ,right:false right:false right:true right:true,left:false left:false straight:false straight:false straight:false straight:false right:true right:true, | |
| a,g | ab,bdehi,eg,eg | depart,turn right,turn left,arrive | ,right:true right:true right:false right:false,left:true left:true straight:false straight:false straight:false straight:false right:false right:false, | |
| a,j | ab,bdehi,bdehi,ij,ij | depart,turn right,use lane straight,turn right,arrive | ,right:true right:true right:false right:false,left:false left:false straight:false straight:false straight:true straight:true right:false right:false,left:false left:false right:true right:true, | |
| a,l | ab,bdehi,bdehi,il,il | depart,turn right,use lane straight,turn left,arrive | ,right:false right:false right:true right:true,left:false left:false straight:true straight:true straight:false straight:false right:false right:false,left:true left:true right:false right:false, | not perfect |
| c,g | cb,bdehi,eg,eg | depart,turn left,turn left,arrive | ,left:true left:true left:false left:false,left:true left:true straight:false straight:false straight:false straight:false right:false right:false, | |
| c,f | cb,bdehi,ef,ef | depart,turn left,turn right,arrive | ,left:false left:false left:true left:true,left:false left:false straight:false straight:false straight:false straight:false right:true right:true, | |
| c,l | cb,bdehi,bdehi,il,il | depart,turn left,use lane straight,turn left,arrive | ,left:false left:false left:true left:true,left:false left:false straight:true straight:true straight:false straight:false right:false right:false,left:true left:true right:false right:false, | |
| c,j | cb,bdehi,bdehi,ij,ij | depart,turn left,use lane straight,turn right,arrive | ,left:true left:true left:false left:false,left:false left:false straight:false straight:false straight:true straight:true right:false right:false,left:false left:false right:true right:true, | not perfect |
@anticipate
Scenario: Anticipate Lanes for turns with through before and after
Given the node map
| a | b | q | | s | h | i |
| | | e | f | g | | |
| c | d | r | | t | j | k |
And the ways
| nodes | turn:lanes:forward | name |
| ab | through\|right\|right\|right | top |
| be | | top |
| bq | | off |
| ef | left\|through\|through\|through\|through\|right | main |
| fg | left\|left\|right\|right | main |
| fs | | off |
| ft | | off |
| gh | | top |
| hi | | top |
| cd | left\|left\|left\|through | bot |
| de | | bot |
| dr | | off |
| gj | | bot |
| jk | | bot |
When I route I should get
| waypoints | route | turns | lanes |
| a,i | top,main,main,top,top | depart,turn right,use lane straight,turn left,arrive | ,straight:false right:false right:true right:true,left:false straight:true straight:true straight:false straight:false right:false,left:true left:true right:false right:false, |
| a,k | top,main,main,bot,bot | depart,turn right,use lane straight,turn right,arrive | ,straight:false right:true right:true right:false,left:false straight:false straight:false straight:true straight:true right:false,left:false left:false right:true right:true, |
| c,i | bot,main,main,top,top | depart,turn left,use lane straight,turn left,arrive | ,left:false left:true left:true straight:false,left:false straight:true straight:true straight:false straight:false right:false,left:true left:true right:false right:false, |
| c,k | bot,main,main,bot,bot | depart,turn left,use lane straight,turn right,arrive | ,left:true left:true left:false straight:false,left:false straight:false straight:false straight:true straight:true right:false,left:false left:false right:true right:true, |
@anticipate
Scenario: Anticipate Lanes for turn between throughs
Given the node map
| | q | | |
| a | b | c | s |
| | r | d | t |
| | | e | |
And the ways
| nodes | turn:lanes:forward | name |
| ab | left\|through\|through\|through\|through\|through\|right | main |
| bq | | off |
| br | | off |
| bc | through\|through\|right\|right\|right | main |
| cs | | off |
| cd | left\|through\|through | main |
| de | | main |
| dt | | off |
When I route I should get
| waypoints | route | turns | lanes |
| a,e | main,main,main,main | depart,use lane straight,continue right,arrive | ,left:false straight:false straight:false straight:false straight:true straight:true right:false,straight:false straight:false right:false right:true right:true, |
@anticipate @todo @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: No Lanes for Roundabouts, see #2626
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 | through\|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 | ,, |
@anticipate
Scenario: No Lanes for Roundabouts, see #2626
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 | ,, |
| x,c | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,, |
| x,a | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,, |
@anticipate
Scenario: No Lanes for Roundabouts, see #2626
Given the profile "lhs"
And the node map
| | | a | | |
| | | b | | |
| h | c | | g | |
| | | | | |
| | d | | f | |
| | | e | | |
| x | | | | y |
And the ways
| nodes | turn:lanes:forward | highway | junction |
| ab | slight_left\|slight_left | primary | |
| bg | | primary | roundabout |
| gf | | primary | roundabout |
| fe | | primary | roundabout |
| ed | | primary | roundabout |
| dc | slight_left | primary | roundabout |
| cb | | primary | roundabout |
| ch | | primary | |
| ex | | primary | |
| dx | | primary | |
| gy | | primary | |
| fy | | primary | |
When I route I should get
| waypoints | route | turns | lanes |
| a,h | ab,ch,ch | depart,roundabout-exit-5,arrive | ,, |
@anticipate
Scenario: No Lanes for Roundabouts, see #2626
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 | ,, |
| x,c | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,, |
| x,a | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,, |
@anticipate @todo @2032
Scenario: No Lanes for Roundabouts, see #2626
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,,straight:false right:true, |
@anticipate
Scenario: Anticipate none tags
Given the node map
| a | b | c |
| | d | |
| f | e | g |
| | h | |
And the ways
| nodes | turn:lanes:forward | highway | name |
| ab | none\|none\|right\|right | primary | abc |
| bc | | primary | abc |
| bd | | primary | bdeh |
| de | left\|none\|none\|right | primary | bdeh |
| eh | | primary | bdeh |
| ef | | primary | feg |
| eg | | primary | feg |
When I route I should get
| waypoints | route | turns | lanes |
| a,g | abc,bdeh,feg,feg | depart,turn right,turn left,arrive | ,none:false none:false right:true right:false,left:true none:false none:false right:false, |
| a,f | abc,bdeh,feg,feg | depart,turn right,turn right,arrive | ,none:false none:false right:false right:true,left:false none:false none:false right:true, |
@anticipate
Scenario: Triple 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,turn left,arrive | ,none:false none:false right:true right:false,none:false none:false right:true right:false,none:false none:false right:true right:false,left:true right:false right:false, |
| a,g | start,first,second,third,fourth,fourth | depart,turn right,turn right,turn right,turn 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
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,turn right,arrive | ,left:false left:true none:false none:false,left:false left:true none:false none:false,left:false left:true none:false none:false,left:false left:false right:true, |
| a,g | start,first,second,third,fourth,fourth | depart,turn left,turn left,turn left,turn 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, |
+35
View File
@@ -0,0 +1,35 @@
@routing @guidance
Feature: Features related to bugs
Background:
Given the profile "car"
Given a grid size of 5 meters
@2852
Scenario: Loop
Given the node map
| a | 1 | | g | | | b |
| | | | | | | |
| | | | | | | |
| e | | | | | | f |
| | | | | | | |
| | | | | | | 2 |
| d | | | h | | | c |
And the ways
| nodes | name | oneway |
| agb | top | yes |
| bfc | right | yes |
| chd | bottom | yes |
| dea | left | yes |
And the nodes
| node | highway |
| g | traffic_signals |
| f | traffic_signals |
| h | traffic_signals |
| e | traffic_signals |
When I route I should get
| waypoints | route | turns |
| 1,2 | top,right,right | depart,new name right,arrive |
+53
View File
@@ -0,0 +1,53 @@
@routing @guidance @collapsing
Feature: Collapse
Background:
Given the profile "car"
Given a grid size of 5 meters
@reverse
Scenario: Collapse U-Turn Triangle Intersection
Given the node map
| g | | f | | e | | d |
| | | | | | | |
| | | | | | | |
| a | | | b | | | c |
And the ways
| nodes | highway | name | oneway |
| abc | primary | road | yes |
| defg | primary | road | yes |
| fb | primary_link | | |
| be | primary_link | | |
When I route I should get
| waypoints | route | turns |
| a,g | road,road,road | depart,continue uturn,arrive |
| d,c | road,road,road | depart,continue uturn,arrive |
@reverse @traffic-signals
Scenario: Collapse U-Turn Triangle Intersection
Given the node map
| g | | f | | j | | e | | d |
| | | | | | | | | |
| | | | h | | i | | | |
| | | | | | | | | |
| a | | | | b | | | | c |
And the ways
| nodes | highway | name | oneway |
| abc | primary | road | yes |
| dejfg | primary | road | yes |
| fhb | primary_link | | |
| bie | primary_link | | |
And the nodes
| node | highway |
| j | traffic_signals |
| h | traffic_signals |
| i | traffic_signals |
When I route I should get
| waypoints | route | turns |
| a,g | road,road,road | depart,continue uturn,arrive |
| d,c | road,road,road | depart,continue uturn,arrive |
+510 -17
View File
@@ -136,6 +136,12 @@ Feature: Collapse
Scenario: Partly Segregated Intersection, Two Segregated Roads
Given the node map
| | n | | m | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | g | | h | |
| | | | | |
| | | | | |
@@ -144,6 +150,12 @@ Feature: Collapse
| | | | | |
| | | | | |
| | j | | i | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | k | | l | |
And the ways
| nodes | highway | name | oneway |
@@ -152,8 +164,8 @@ Feature: Collapse
| de | primary | first | yes |
| ef | primary | first | yes |
| be | primary | first | no |
| gbh | primary | second | yes |
| iej | primary | second | yes |
| ngbhm | primary | second | yes |
| liejk | primary | second | yes |
When I route I should get
| waypoints | route | turns |
@@ -176,6 +188,10 @@ Feature: Collapse
Scenario: Partly Segregated Intersection, Two Segregated Roads, Intersection belongs to Second
Given the node map
| | n | | m | |
| | | | | |
| | | | | |
| | | | | |
| | g | | h | |
| | | | | |
| | | | | |
@@ -184,6 +200,10 @@ Feature: Collapse
| | | | | |
| | | | | |
| | j | | i | |
| | | | | |
| | | | | |
| | | | | |
| | k | | l | |
And the ways
| nodes | highway | name | oneway |
@@ -192,8 +212,8 @@ Feature: Collapse
| de | primary | first | yes |
| ef | primary | first | yes |
| be | primary | second | no |
| gbh | primary | second | yes |
| iej | primary | second | yes |
| ngbhm | primary | second | yes |
| liejk | primary | second | yes |
When I route I should get
| waypoints | route | turns |
@@ -302,12 +322,12 @@ Feature: Collapse
Scenario: Entering a segregated road
Given the node map
| | a | f | | |
| | | | | g |
| | b | e | | |
| | | | | |
| | | | | |
| c | d | | | |
| | a | f | | | | g |
| | | | | | | |
| | b | e | | | | |
| | | | | | | |
| | | | | | | |
| c | d | | | | | |
And the ways
| nodes | highway | name | oneway |
@@ -325,7 +345,6 @@ Feature: Collapse
| g,f | second,first,first | depart,turn right,arrive |
| g,c | second,first,first | depart,end of road left,arrive |
Scenario: Do not collapse turning roads
Given the node map
| | | e | | |
@@ -333,15 +352,489 @@ Feature: Collapse
| a | | b | f | |
And the ways
| nodes | highway | name |
| ab | primary | first |
| bc | primary | first |
| cd | primary | first |
| ce | primary | second |
| bf | primary | third |
| nodes | highway | name | oneway |
| ab | primary | first | yes |
| bc | primary | first | yes |
| cd | primary | first | yes |
| ce | primary | second | yes |
| bf | primary | third | yes |
When I route I should get
| 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,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
| j | | | | h | | | | | | i | | | | | | |
| | | | | | | b | c | d | e | f | | | | | | g |
| k | | | | a | | | | | | | | | | | | |
And the ways
| nodes | highway | name | oneway |
| kabhj | 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 left,arrive |
| a,d | road,road | depart,arrive |
| a,j | road,out,out | depart,turn slight right,arrive |
Scenario: Segregated Intersection into Very 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 |
| fd | cross | no | secondary |
| dc | cross | no | secondary |
| cg | cross | no | secondary |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | bd | dc | d | no_left_turn |
| restriction | bc | dc | 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 |
| fd | cross | no | secondary |
| dc | cross | no | secondary |
| cg | cross | no | secondary |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | bd | dc | d | no_left_turn |
| restriction | bc | dc | 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 |
@negative @straight
Scenario: Don't collapse going straight if actual turn
Given the node map
| | c | e | | |
| | | d | | f |
| | | | | |
| | | b | | |
| | | | | |
| | | | | |
| | | a | | |
And the ways
| nodes | name | highway |
| abc | main | primary |
| bde | straight | residential |
| df | right | residential |
When I route I should get
| waypoints | route | turns |
| a,c | main,main | depart,arrive |
| a,e | main,straight,straight | depart,turn straight,arrive |
| a,f | main,straight,right,right | depart,turn straight,turn right,arrive |
Scenario: Entering a segregated road
Given the node map
| | a | f | | |
| | | | | g |
| | b | e | | |
| | | | | |
| | | | | |
| c | d | | | |
And the ways
| nodes | highway | name | oneway |
| abc | primary | first | yes |
| def | primary | first | yes |
| be | primary | first | no |
| ge | primary | second | no |
When I route I should get
| waypoints | route | turns |
| d,c | first,first,first | depart,continue uturn,arrive |
Scenario: Entering a segregated road slight turn
Given the node map
| | | a | f | |
| | | | | g |
| | b | e | | |
| | | | | |
| | | | | |
| c | d | | | |
And the ways
| nodes | highway | name | oneway |
| abc | primary | first | yes |
| def | primary | first | yes |
| be | primary | first | no |
| ge | primary | second | no |
When I route I should get
| waypoints | route | turns |
| d,c | first,first,first | depart,continue uturn,arrive |
Scenario: Do not collapse UseLane step when lanes change
Given the node map
| | | | f | g | |
| | | | | | |
| a | b | c | d | | e |
| | | | | | |
| | | | h | i | |
And the ways
| nodes | turn:lanes:forward | name |
| ab | | main |
| bc | left\|through\|through\|through\|right | main |
| cd | left\|through\|right | main |
| de | | main |
| cf | | off |
| ch | | off |
| dg | | off |
| di | | off |
When I route I should get
| waypoints | route | turns |
| a,e | main,main,main | depart,use lane straight,arrive |
Scenario: But _do_ collapse UseLane step when lanes stay the same
Given the node map
| | | | f | g | |
| | | | | | |
| a | b | c | d | | e |
| | | | | | |
| | | | h | i | |
And the ways
| nodes | turn:lanes:forward | name |
| ab | | main |
| bc | left\|through\|through\|through\|right | main |
| cd | left\|through\|through\|through\|right | main |
| de | | main |
| cf | | off |
| ch | | off |
| dg | | off |
| di | | off |
When I route I should get
| waypoints | route | turns |
| a,e | main,main | depart,arrive |
Scenario: Don't collapse different travel modes
Given the node map
| g | | | | | | | h | |
| a | b | | c | | | | e | f |
| | | | | | d | | | |
| | | | i | j | | | | |
And the ways
| nodes | highway | route | name |
| ab | primary | | road |
| bc | primary | ferry | |
| cd | primary | | road |
| de | | ferry | |
| ef | primary | | road |
| bg | service | | turn |
| ci | service | | turn |
| dj | service | | turn |
| eh | service | | turn |
When I route I should get
| waypoints | route |
| a,f | road,,road,,road,road |
Scenario: U-Turn onto a Ferry
Given the node map
| | | | | | | i | | |
| j | e | | | | | d | c | h |
| | | | | | | | | |
| | | | | | | | | |
| k | g | | | | | a | b | f |
And the ways
| nodes | highway | route | name | oneway |
| bf | primary | | road | yes |
| hcd | primary | | road | yes |
| bc | primary | | | yes |
| di | service | | serv | yes |
| ed | | ferry | ferry | |
| gab | | ferry | ferry | |
| kg | primary | | on | yes |
| ej | primary | | off | yes |
When I route I should get
| waypoints | route | turns |
| k,j | on,ferry,,ferry,off,off | depart,new name straight,continue uturn,turn straight,new name straight,arrive |
+238 -12
View File
@@ -52,25 +52,26 @@ Feature: Slipways and Dedicated Turn Lanes
| 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 |
| waypoints | route | turns |
| a,g | first,,second,second | depart,off ramp slight right,turn straight,arrive |
Scenario: Inner city expressway with on road
Given the node map
| a | b | | | | c |
| | | | | f | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | d |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | e |
| 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 |
@@ -123,3 +124,228 @@ Feature: Slipways and Dedicated Turn Lanes
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 | ref |
| a,o | Schwarzwaldstrasse,Ettlinger Allee,Ettlinger Allee | depart,turn right,arrive | L561,, |
Scenario: Traffic Lights everywhere
#http://map.project-osrm.org/?z=18&center=48.995336%2C8.383813&loc=48.995467%2C8.384548&loc=48.995115%2C8.382761&hl=en&alt=0
Given the node map
| a | | | k | l | | | j | |
| | | | | | d | b | c | i |
| | | | | | | | | |
| | | | | | | e | g | |
| | | | | | | | | |
| | | | | | | 1 | | |
| | | | | | | | h | |
| | | | | | | | | |
| | | | | | | | f | |
And the nodes
| node | highway |
| b | traffic_signals |
| e | traffic_signals |
| g | traffic_signals |
And the ways
| nodes | highway | name | oneway |
| aklbci | secondary | Ebertstrasse | yes |
| kdeh | secondary_link | | yes |
| jcghf | primary | Brauerstrasse | yes |
When I route I should get
| waypoints | route | turns |
| a,i | Ebertstrasse,Ebertstrasse | depart,arrive |
| a,l | Ebertstrasse,Ebertstrasse | depart,arrive |
| a,f | Ebertstrasse,Brauerstrasse,Brauerstrasse | depart,turn right,arrive |
| a,1 | Ebertstrasse,, | depart,turn slight right,arrive |
#2839
Scenario: Self-Loop
Given the node map
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| | | | | | | | | | | | | | | | | | | | | | l | | | k | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | j | | | |
| | | | | | | | | | | | | | | | | | | | m | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | n | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g |
| | | | | | | | | | | | | | | | | | | o | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f | |
| | | | | | | | | | | | | | | | | | p | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | e | | | |
| a | | | | | b | | | | | | | | | c | | | | | | | | | | d | | | | | | |
And the ways
| nodes | name | oneway | highway | lanes |
| abc | circled | no | residential | 1 |
| cdefghijklmnopc | circled | yes | residential | 1 |
When I route I should get
| waypoints | bearings | route | turns |
| b,a | 90,10 270,10 | circled,circled | depart,arrive |
@todo
#due to the current turn function, the left turn bcp is exactly the same cost as pcb, a right turn. The right turn should be way faster,though
#for that reason we cannot distinguish between driving clockwise through the circle or counter-clockwise. Until this is improved, this case here
#has to remain as todo (see #https://github.com/Project-OSRM/osrm-backend/pull/2849)
Scenario: Self-Loop - Bidirectional
Given the node map
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| | | | | | | | | | | | | | | | | | | | | | l | | | k | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | j | | | |
| | | | | | | | | | | | | | | | | | | | m | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | n | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g |
| | | | | | | | | | | | | | | | | | | o | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f | |
| | | | | | | | | | | | | | | | | | p | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | e | | | |
| a | | | | | b | | | | | | | | | c | | | | | | | | | | d | | | | | | |
And the ways
| nodes | name | oneway | highway | lanes |
| abc | circled | no | residential | 1 |
| cdefghijklmnopc | circled | no | residential | 1 |
When I route I should get
| waypoints | bearings | route | turns |
| b,a | 90,10 270,10 | circled,circled | depart,arrive |
#http://www.openstreetmap.org/#map=19/38.90597/-77.01276
Scenario: Don't falsly classify as sliproads
Given the node map
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| | | | | | | | | | | | | | | | | | | | | | | | j | | | | | | | |
| a | b | | | | | | | | | | | | | | | | | | | | | | c | | | | | | | d |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | 1 | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | f | | | | | g | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | i | | | | | | | h |
And the ways
| nodes | name | highway | oneway | maxspeed |
| abcd | new york | primary | yes | 35 |
| befgh | m street | secondary | yes | 35 |
| igcj | 1st street | tertiary | no | 20 |
And the nodes
| node | highway |
| c | traffic_signals |
| g | traffic_signals |
When I route I should get
| waypoints | route | turns | # |
| a,d | new york,new york | depart,arrive | this is the sinatra route |
| a,j | new york,1st street,1st street | depart,turn left,arrive | |
| a,1 | new york,m street,1st street,1st street | depart,turn right,turn left,arrive | this can false be seen as a sliproad |
# Merging into degree two loop on dedicated turn detection / 2927
Scenario: Turn Instead of Ramp
Given the node map
| | | | | | | | | | | | | | | | f |
| | | | | g | | | | | | h | | | | | |
| | | | | | | | | | | | | d | | | e |
| i | | | | c | | | | | | j | | | | | |
| | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | |
| | | b | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | |
| | | a | | | | | | | | | | | | | |
And the ways
| nodes | highway | name | oneway |
| abi | primary | road | yes |
| bcjd | primary | loop | yes |
| dhgf | primary | loop | yes |
| fed | primary | loop | yes |
And the nodes
| node | highway |
| g | traffic_signals |
| c | traffic_signals |
# We don't actually care about routes here, this is all about endless loops in turn discovery
When I route I should get
| waypoints | route | turns |
| a,i | road,road,road | depart,fork slight left,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 | 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 | |
| from | to | route | destinations | ref | # |
| a | b | AB,AB | , | E1,E1 | |
| c | d | CD,CD | Berlin,Berlin | , | |
| e | f | EF,EF | A1: Berlin,A1: Berlin | , | |
| g | h | , | A1: Berlin,A1: Berlin | , | |
| i | j | , | Berlin,Berlin | , | |
| k | l | KL,KL | A1: Berlin,A1: Berlin | E1,E1 | |
| m | n | MN,MN | A1, A2: Berlin, Hamburg,A1, A2: Berlin, Hamburg | , | |
| o | p | OP,OP | , | , | guard against mis-tagging |
| q | r | QR,QR | 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 | depart,arrive |
| a,i | on,off,off | depart,turn slight right,arrive |
+20 -39
View File
@@ -17,8 +17,8 @@ Feature: Intersections Data
| bd | corner |
When I route I should get
| waypoints | route | turns | intersections |
| a,c | through,through | depart,arrive | true:90,true:90 true:180 false:270;true:270 |
| 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
@@ -32,8 +32,8 @@ Feature: Intersections Data
| bd | corner |
When I route I should get
| waypoints | route | turns | intersections |
| a,c | through,through | depart,arrive | true:90,true:0 true:90 false:270;true:270 |
| 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
@@ -47,8 +47,8 @@ Feature: Intersections Data
| db | corner | yes |
When I route I should get
| waypoints | route | turns | intersections |
| a,c | through,through | depart,arrive | true:90,false:0 true:90 false:270;true:270 |
| 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
@@ -62,8 +62,8 @@ Feature: Intersections Data
| bd | corner | yes |
When I route I should get
| waypoints | route | turns | intersections |
| a,c | through,through | depart,arrive | true:90,true:0 true:90 false:270;true:270 |
| 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
@@ -80,27 +80,8 @@ Feature: Intersections Data
| cf | corner |
When I route I should get
| waypoints | route | turns | intersections |
| a,d | through,through | depart,arrive | true:90,true:0 true:90 false:270,true:90 true:180 false:270;true:270 |
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 |
When I route I should get
| waypoints | route | turns |
| a,m | Fritz-Elsas-Straße,Fritz-Elsas-Straße| depart,arrive |
| 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
@@ -117,9 +98,9 @@ Feature: Intersections Data
| cf | corner |
When I route I should get
| waypoints | route | turns | intersections |
| a,d | through,through | depart,arrive | true:90,true:0 true:90 false:270,true:90 true:180 false:270;true:270 |
| f,a | corner,throughbridge,through | depart,end of road left,arrive | true:0;true:90 false:180 true:270,true:0 false:90 true:270;true:90 |
| 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
@@ -144,10 +125,10 @@ Feature: Intersections Data
| hd | |
When I route I should get
| waypoints | route | turns | intersections |
| e,f | ea,fb,fb | depart,abcda-exit-1,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:90 |
| e,g | ea,gc,gc | depart,abcda-exit-2,arrive | 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 | depart,abcda-exit-3,arrive | 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 | depart,abcda-exit-undefined,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:327 +-1|
| 1,g | abcda,gc,gc | depart,abcda-exit-2,arrive | true:214;true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:0|
| 1,3 | abcda,abcda | depart,arrive | true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:214|
| 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 |
+80 -16
View File
@@ -3,13 +3,14 @@ Feature: Merging
Background:
Given the profile "car"
Given a grid size of 10 meters
And a grid size of 10 meters
@merge
Scenario: Merge on Four Way Intersection
Given the node map
| d | | |
| a | b | c |
| e | | |
| d | | | | | | | | | |
| a | | b | | | | | | | c |
| e | | | | | | | | | |
And the ways
| nodes | highway |
@@ -18,14 +19,15 @@ Feature: Merging
| eb | primary |
When I route I should get
| waypoints | route | turns |
| d,c | db,abc,abc | depart,merge slight right,arrive |
| e,c | eb,abc,abc | depart,merge slight left,arrive |
| waypoints | route | turns |
| d,c | db,abc,abc | depart,turn straight,arrive |
| e,c | eb,abc,abc | depart,turn straight,arrive |
@merge
Scenario: Merge on Three Way Intersection Right
Given the node map
| d | | |
| a | b | c |
| d | | | | | | | | | |
| a | | b | | | | | | | c |
And the ways
| nodes | highway |
@@ -33,13 +35,14 @@ Feature: Merging
| db | primary |
When I route I should get
| waypoints | route | turns |
| d,c | db,abc,abc | depart,merge slight right,arrive |
| waypoints | route | turns |
| d,c | db,abc,abc | depart,turn straight,arrive |
Scenario: Merge on Three Way Intersection Right
@merge @negative
Scenario: Don't Merge on Short-Three Way Intersection Right
Given the node map
| a | b | c |
| d | | |
| d | | | | | | | |
| a | | b | | | | | c |
And the ways
| nodes | highway |
@@ -47,6 +50,67 @@ Feature: Merging
| db | primary |
When I route I should get
| waypoints | route | turns |
| d,c | db,abc,abc | depart,merge slight left,arrive |
| waypoints | route | turns |
| d,c | db,abc,abc | depart,turn slight left,arrive |
@merge
Scenario: Merge on Three Way Intersection Right
Given the node map
| a | | b | | | | | | | c |
| d | | | | | | | | | |
And the ways
| nodes | highway |
| abc | primary |
| db | primary |
When I route I should get
| waypoints | route | turns |
| d,c | db,abc,abc | depart,turn straight,arrive |
@merge
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,turn straight,arrive | in,road,road |
| f,a | depart,turn sharp left,arrive | in,road,road |
@merge
Scenario: Merge onto a motorway
Given the node map
| d | | | | | | | | | |
| a | | | b | | | | | | c |
And the ways
| nodes | name | highway | oneway |
| abc | A100 | motorway | yes |
| db | | motorway_link | yes |
When I route I should get
| waypoints | route | turns |
| d,c | ,A100,A100 | depart,merge slight right,arrive |
+18
View File
@@ -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 |
+176 -7
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
@@ -125,10 +125,10 @@ Feature: New-Name Instructions
| | | | | c |
And the ways
| nodes | highway |
| ab | residential |
| bc | residential |
| bd | service |
| nodes | highway | oneway |
| ab | residential | yes |
| bc | residential | yes |
| bd | service | yes |
When I route I should get
| waypoints | route | turns |
@@ -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
@@ -164,3 +164,172 @@ Feature: New-Name Instructions
| waypoints | route | turns |
| a,e | name,with-name,with-name | depart,new name straight,arrive |
| b,e | with-name,with-name | depart,arrive |
Scenario: Both Name and Ref Empty
Given the node map
| a | | b | | c |
And the ways
| nodes | name | ref |
| ab | | |
| bc | | |
When I route I should get
| waypoints | route | turns |
| a,c | , | depart,arrive |
Scenario: Same Name, Ref Extended
Given the node map
| a | | b | | c |
And the ways
| nodes | name | ref |
| ab | A | B1 |
| bc | C | B1;B2 |
When I route I should get
| waypoints | route | turns |
| a,c | A,C,C | depart,new name straight,arrive |
Scenario: Same Name, Ref Removed
Given the node map
| a | | b | | c |
And the ways
| nodes | name | ref |
| ab | A | B1;B2 |
| bc | C | B1 |
When I route I should get
| waypoints | route | turns |
| a,c | A,C,C | depart,new name straight,arrive |
Scenario: Name Removed, Ref Extended
Given the node map
| a | | b | | c |
And the ways
| nodes | name | ref |
| ab | A | B1 |
| bc | | B1;B2 |
When I route I should get
| waypoints | route | turns |
| a,c | A, | depart,arrive |
Scenario: Name Added, Ref Removed
Given the node map
| a | | b | | c |
And the ways
| nodes | name | ref |
| ab | | B1 |
| bc | A | |
When I route I should get
| waypoints | route | turns |
| a,c | ,A,A | depart,new name straight,arrive |
Scenario: Prefix Change
Given the node map
| a | | | | b | | | | c |
And the ways
| nodes | name | ref | highway |
| ab | North Central Expressway | US 75 | motorway |
| bc | Central Expressway | US 75 | motorway |
When I route I should get
| waypoints | route | turns |
| a,c | North Central Expressway,Central Expressway,Central Expressway | depart,new name straight,arrive |
Scenario: Prefix Change
Given the node map
| a | | | | b | | | | c |
And the ways
| nodes | name | ref | highway |
| ba | North Central Expressway | US 75 | motorway |
| cb | Central Expressway | US 75 | motorway |
When I route I should get
| waypoints | route | turns |
| c,a | Central Expressway,North Central Expressway,North Central Expressway | depart,new name straight,arrive |
Scenario: No Name, Same Reference
Given the node map
| a | | | | b | | | | c |
And the ways
| nodes | name | ref | highway |
| ab | Central Expressway | US 75 | motorway |
| bc | | US 75 | motorway |
When I route I should get
| waypoints | route | turns |
| a,c | Central Expressway, | depart,arrive |
Scenario: No Name, Same Reference
Given the node map
| a | | | | b | | | | c |
And the ways
| nodes | name | ref | highway |
| ab | | US 75 | motorway |
| bc | Central Expressway | US 75 | motorway |
When I route I should get
| waypoints | route | turns |
| a,c | ,Central Expressway | depart,arrive |
Scenario: No Name, Same Reference
Given the node map
| a | | | | b | | | | c |
And the ways
| nodes | name | ref | highway |
| ab | | US 75;US 69 | motorway |
| bc | | US 75 | motorway |
When I route I should get
| waypoints | route | turns |
| a,c | , | depart,arrive |
Scenario: No Name, Same Reference
Given the node map
| a | | | | b | | | | c |
And the ways
| nodes | name | ref | highway |
| ab | | US 69;US 75 | motorway |
| bc | | US 75 | motorway |
When I route I should get
| waypoints | route | turns |
| a,c | , | depart,arrive |
Scenario: No Name, Same Reference
Given the node map
| a | | | | b | | | | c |
And the ways
| nodes | name | ref | highway |
| ab | | US 75 | motorway |
| bc | | US 75;US 69 | motorway |
When I route I should get
| waypoints | route | turns |
| a,c | , | depart,arrive |
Scenario: No Name, Same Reference
Given the node map
| a | | | | b | | | | c |
And the ways
| nodes | name | ref | highway |
| ab | | US 75 | motorway |
| bc | | US 69;US 75 | motorway |
When I route I should get
| waypoints | route | turns |
| a,c | , | depart,arrive |
+126
View File
@@ -0,0 +1,126 @@
@routing @guidance @perceived-angles
Feature: Simple Turns
Background:
Given the profile "car"
Given a grid size of 5 meters
Scenario: Turning into splitting road
Given the node map
| | a | | |
| | b | | |
| | | | |
| | | | |
| c | | d | |
| | | | |
| | | | e |
| | | | |
| | | f | |
And the ways
| nodes | name | highway | oneway |
| ab | road | primary | no |
| bc | road | primary | yes |
| fdb | road | primary | yes |
| de | turn | primary | no |
When I route I should get
| waypoints | turns | route |
| f,a | depart,arrive | road,road |
| e,a | depart,turn slight right,arrive | turn,road,road |
Scenario: Middle Island
Given the node map
| | a | |
| | | |
| | b | |
| c | | h |
| | | |
| | | |
| | | |
| | | |
| d | | g |
| | e | |
| | | |
| | f | |
And the ways
| nodes | name | oneway |
| ab | road | no |
| ef | road | no |
| bcde | road | yes |
| eghb | road | yes |
When I route I should get
| waypoints | turns | route |
| a,f | depart,arrive | road,road |
| c,f | depart,arrive | road,road |
| f,a | depart,arrive | road,road |
| g,a | depart,arrive | road,road |
Scenario: Middle Island Over Bridge
Given the node map
| | a | |
| | | |
| | b | |
| c | | h |
| | | |
| | | |
| 1 | | 2 |
| | | |
| d | | g |
| | e | |
| | | |
| | f | |
And the ways
| nodes | name | oneway |
| ab | road | no |
| ef | road | no |
| bc | road | yes |
| cd | bridge | yes |
| de | road | yes |
| eg | road | yes |
| gh | bridge | yes |
| hb | road | yes |
When I route I should get
| waypoints | turns | route |
| a,f | depart,arrive | road,road |
| c,f | depart,new name straight,arrive | bridge,road,road |
| 1,f | depart,new name straight,arrive | bridge,road,road |
| f,a | depart,arrive | road,road |
| g,a | depart,new name straight,arrive | bridge,road,road |
| 2,a | depart,new name straight,arrive | bridge,road,road |
@negative
Scenario: Don't Collapse Places:
Given the node map
| | | | | | | h | | | | | | |
| | | | | | | g | | | | | | |
| | | | | | | | | | | | | |
| | | | | | | | | | | | | |
| | | | | | | | | | | | | |
| | | | | | | | | | | | | |
| a | b | | | | | | | | | | e | f |
| | | | | | | | | | | | | |
| | | | | | | | | | | | | |
| | | | | | | | | | | | | |
| | | | | | | | | | | | | |
| | | | | | | c | | | | | | |
| | | | | | | d | | | | | | |
And the ways
| nodes | name | oneway |
| ab | place | no |
| cd | bottom | no |
| ef | place | no |
| gh | top | no |
| bcegb | place | yes |
When I route I should get
| waypoints | turns | route |
| a,d | depart,turn right,arrive | place,bottom,bottom |
| a,f | depart,continue left,continue right,arrive | place,place,place,place |
| d,f | depart,turn right,continue right,arrive | bottom,place,place,place |
| d,h | depart,turn right,continue left,turn right,arrive | bottom,place,place,top,top |
+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 |
+15 -15
View File
@@ -83,14 +83,14 @@ Feature: Ramp Guidance
Scenario: Ramp Off Though Street
Given the node map
| | | c |
| a | b | |
| | d | |
| | | | | c |
| a | | | b | |
| | | | d | |
And the ways
| nodes | highway |
| abc | tertiary |
| bd | motorway_link |
| nodes | highway | oneway |
| abc | tertiary | yes |
| bd | motorway_link | yes |
When I route I should get
| waypoints | route | turns |
@@ -108,9 +108,9 @@ Feature: Ramp Guidance
| bd | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,on ramp straight,arrive |
| a,c | abc,abc,abc | depart,continue left,arrive |
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,on ramp straight,arrive |
| a,c | abc,abc | depart,arrive |
Scenario: Fork Ramp Off Turning Though Street
Given the node map
@@ -124,9 +124,9 @@ Feature: Ramp Guidance
| bd | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,on ramp right,arrive |
| a,c | abc,abc,abc | depart,continue left,arrive |
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,on ramp right,arrive |
| a,c | abc,abc | depart,arrive |
Scenario: Fork Ramp
Given the node map
@@ -174,9 +174,9 @@ Feature: Ramp Guidance
| bd | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,on ramp slight right,arrive |
| a,c | abc,abc,abc | depart,continue slight left,arrive |
| waypoints | route | turns |
| a,d | abc,bd,bd | depart,on ramp slight right,arrive |
| a,c | abc,abc | depart,arrive |
Scenario: Fork Slight Ramp on Obvious Through Street
Given the node map
-31
View File
@@ -5,37 +5,6 @@ Feature: Basic Roundabout
Given the profile "bicycle"
Given a grid size of 10 meters
Scenario: Enter and Exit
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 |
| 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 |
Scenario: Only Enter
Given the node map
| | | a | | |
@@ -0,0 +1,37 @@
@routing @guidance
Feature: Basic Roundabout
Background:
Given the profile "bicycle"
Given a grid size of 10 meters
Scenario: Enter and Exit
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 |
| a,d | ab,cd,cd | depart,roundabout turn left exit-3,arrive |
| a,f | ab,ef,ef | depart,roundabout turn straight exit-2,arrive |
| a,h | ab,gh,gh | depart,roundabout turn right exit-1,arrive |
| d,f | cd,ef,ef | depart,roundabout turn left exit-3,arrive |
| d,h | cd,gh,gh | depart,roundabout turn straight exit-2,arrive |
| d,a | cd,ab,ab | depart,roundabout turn right exit-1,arrive |
| f,h | ef,gh,gh | depart,roundabout turn left exit-3,arrive |
| f,a | ef,ab,ab | depart,roundabout turn straight exit-2,arrive |
| f,d | ef,cd,cd | depart,roundabout turn right exit-1,arrive |
| h,a | gh,ab,ab | depart,roundabout turn left exit-3,arrive |
| h,d | gh,cd,cd | depart,roundabout turn straight exit-2,arrive |
| h,f | gh,ef,ef | depart,roundabout turn right exit-1,arrive |
+122
View File
@@ -389,3 +389,125 @@ Feature: Basic Roundabout
| 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 |
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 turn left exit-3,arrive | 0->180,180->270,90->0 |
| a,f | ab,ef,ef | depart,roundabout turn straight exit-2,arrive | 0->180,180->270,180->0 |
| a,h | ab,gh,gh | depart,roundabout turn right exit-1,arrive | 0->180,180->270,270->0 |
Scenario: Large radius Roundabout Intersection and ways modelled out: East Mission St, North 7th St
# http://www.openstreetmap.org/way/348812150
# Note: grid size is 3 meter, this roundabout is more like 5-10 meters in radius
Given the node map
| | | | a | | | | | |
| | | | | | | | | |
| | | | b | | n | | | |
| | | | | | | | | |
| | | c | | | | m | | |
| | | | | | | | | |
| e | | d | | | | k | | l |
| | | | | | | | | |
| | | f | | | | j | | |
| | | | | | | | | |
| | | | g | | i | | | |
| | | | | | | | | |
| | | | h | | | | | |
And the ways
| nodes | junction | highway | name |
| ab | | tertiary | North 7th St |
| ed | | tertiary | East Mission St |
| hg | | tertiary | North 7th St |
| lk | | tertiary | East Mission St |
| bcdfgijkmnb | roundabout | tertiary | Roundabout |
When I route I should get
| waypoints | route | turns |
| a,e | North 7th St,East Mission St,East Mission St | depart,roundabout turn right exit-1,arrive |
| a,h | North 7th St,North 7th St,North 7th St | depart,roundabout turn straight exit-2,arrive |
| a,l | North 7th St,East Mission St,East Mission St | depart,roundabout turn left exit-3,arrive |
| h,l | North 7th St,East Mission St,East Mission St | depart,roundabout turn right exit-1,arrive |
| h,a | North 7th St,North 7th St,North 7th St | depart,roundabout turn straight exit-2,arrive |
| h,e | North 7th St,East Mission St,East Mission St | depart,roundabout turn left exit-3,arrive |
| e,h | East Mission St,North 7th St,North 7th St | depart,roundabout turn right exit-1,arrive |
| e,l | East Mission St,East Mission St,East Mission St | depart,roundabout turn straight exit-2,arrive |
| e,a | East Mission St,North 7th St,North 7th St | depart,roundabout turn left exit-3,arrive |
| l,a | East Mission St,North 7th St,North 7th St | depart,roundabout turn right exit-1,arrive |
| l,e | East Mission St,East Mission St,East Mission St | depart,roundabout turn straight exit-2,arrive |
| l,h | East Mission St,North 7th St,North 7th St | depart,roundabout turn left exit-3,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 turn left exit-3,arrive |
| a,f | ab,ef,ef | depart,roundabout turn straight exit-2,arrive |
| a,h | ab,gh,gh | depart,roundabout turn right exit-1,arrive |
| d,f | cd,ef,ef | depart,roundabout turn left exit-3,arrive |
| d,h | cd,gh,gh | depart,roundabout turn straight exit-2,arrive |
| d,a | cd,ab,ab | depart,roundabout turn right exit-1,arrive |
| f,h | ef,gh,gh | depart,roundabout turn left exit-3,arrive |
| f,a | ef,ab,ab | depart,roundabout turn straight exit-2,arrive |
| f,d | ef,cd,cd | depart,roundabout turn right exit-1,arrive |
| h,a | gh,ab,ab | depart,roundabout turn left exit-3,arrive |
| h,d | gh,cd,cd | depart,roundabout turn straight exit-2,arrive |
| h,f | gh,ef,ef | depart,roundabout turn right exit-1,arrive |
#http://www.openstreetmap.org/#map=19/41.03275/-2.18990
#at some point we probably want to recognise these situations and don't mention the roundabout at all here
Scenario: Enter And Exit Throughabout
Given the node map
| | | | | | h | | | | |
| | | | | | | | | | |
| c | b | | d | | | | e | | f |
| | | | | | | | | | |
| | a | | | | g | | | | |
And the ways
| nodes | highway | name | junction | oneway |
| dghd | tertiary_link | | roundabout | |
| cbdef | trunk | through | | no |
| ab | residential | in | | |
When I route I should get
| waypoints | turns | route |
| a,f | depart,turn right,roundabout turn straight exit-1,arrive | in,through,through,through |
+137 -95
View File
@@ -5,37 +5,6 @@ Feature: Basic Roundabout
Given the profile "car"
Given a grid size of 10 meters
Scenario: Enter and Exit
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 |
| 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 |
Scenario: Only Enter
Given the node map
| | | a | | |
@@ -67,6 +36,25 @@ Feature: Basic Roundabout
| h,c | gh,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| h,e | gh,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
#2927
Scenario: Only Roundabout
Given the node map
| | | a | | |
| | | | | |
| | | | | |
| b | | | | d |
| | | | | |
| | | | | |
| | | c | | |
And the ways
| nodes | junction |
| abcda | roundabout |
When I route I should get
| waypoints | route | turns |
| a,c | abcda,abcda | depart,arrive |
Scenario: Only Exit
Given the node map
| | | a | | |
@@ -260,7 +248,7 @@ Feature: Basic Roundabout
| a,e | ab,ce,ce | depart,roundabout-exit-1,arrive |
| a,f | ab,df,df | depart,roundabout-exit-2,arrive |
Scenario: Collinear in Y
Scenario: Collinear in Y
Given the node map
| | a |
| | b |
@@ -280,84 +268,138 @@ Feature: Basic Roundabout
| a,e | ab,ce,ce | depart,roundabout-exit-1,arrive |
| a,f | ab,df,df | depart,roundabout-exit-2,arrive |
Scenario: Collinear in X,Y
Scenario: Motorway Roundabout
#See 39.933742 -75.082345
Given the node map
| a | | |
| b | | |
| c | d | f |
| e | | |
| | | | | l | | | | a | | i |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | b | | | | |
| | | | c | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | h | | |
| n | | | | | | | | | | |
| | | | | | | | | | | |
| | | d | | | | | | | | j |
| | | | | | | | | | | |
| | | | | m | | | g | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | e | | f | | | | | | |
And the ways
| nodes | junction |
| ab | |
| bcdb | roundabout |
| ce | |
| df | |
| 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 | ab,ce,ce | depart,roundabout-exit-1,arrive |
| a,f | ab,df,df | depart,roundabout-exit-2,arrive |
| waypoints | route | turns | ref |
| a,e | crescent,crescent,crescent | depart,roundabout-exit-3,arrive | US 130,US 130,US 130 |
| j,l | ,, | depart,roundabout-exit-2,arrive | NJ 38,NJ 38,NJ 38 |
Scenario: Collinear in X,Y
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
| a | | |
| d | | |
| b | c | f |
| e | | |
| | | | | 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 |
| ad | |
| bcdb | roundabout |
| be | |
| cf | |
| 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,e | ad,be,be | depart,roundabout-exit-1,arrive |
| a,f | ad,cf,cf | depart,roundabout-exit-2,arrive |
| waypoints | route | turns |
| a,k | massachusetts,massachusetts,massachusetts,massachusetts | depart,sheridan circle-exit-2,dupont circle-exit-1,arrive |
Scenario: Collinear in X,Y
#2856 - http://www.openstreetmap.org/#map=19/47.23318/-1.56563
Scenario: Linked Roundabouts
Given the node map
| a | | |
| c | | |
| d | b | f |
| e | | |
| | | | | | | | | | | | | | x |
| | u | | | | | | | | | | | r | |
| | | | | | | | | | | | | | |
| | | | t | | | | | | | | | | |
| | | | | | | | | | | s | | | |
| | | v | | | i | | h | | g | | | | |
| | | | | | | | | | | | q | | |
| | | | | | | | | | | | | | |
| | | | j | | | | | | | | f | | |
| | | | | | | | | | | | | | |
| | | | | | | | | | | | | | |
| | | | a | | | | | | | | e | | |
| | | | | | | | | | | | | | |
| | | | | | | | | | | | | | |
| | | | | | b | | c | | d | | p | | |
| | | | | | | | | | | | | | |
| | | m | | | | | | | | n | | | |
| | | | | l | | | | | | | | | |
| | | | | | | | | | | | | | |
| | | | | | | | | | | | | | |
| | | | | | | | | | | | | | |
| | | | | | | | | | | | | | |
| | | | | | | | | | | | | | |
| | | | | | | | | | | | | | |
| | | | | | | | | | | | | | |
| | | k | | | | | | | | | | | |
| | | | | | | | | | | | | | |
| | | | | | | | | | | | | | |
| | | | | | | | | | | | | | |
| | w | | | | | | | | | | o | | |
And the ways
| nodes | junction |
| ac | |
| bcdb | roundabout |
| de | |
| bf | |
| nodes | junction | name | highway | oneway |
| abija | roundabout | egg | primary | yes |
| defgd | roundabout | egg | primary | yes |
| bcd | roundabout | egg | primary | yes |
| ghi | | egg | primary | yes |
| amklb | | ll | primary | yes |
| wk | | ll | primary | no |
| dnope | | lr | secondary | yes |
| fqrsg | | tr | primary | yes |
| rx | | tr | primary | no |
| ituvj | | tl | primary | yes |
And the nodes
| node | highway |
| c | give_way |
| h | give_way |
When I route I should get
| waypoints | route | turns |
| 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 |
| waypoints | route | turns |
# since we cannot handle these invalid roundabout tags yet, we cannout output roundabout taggings. This will hopefully change some day
#| w,x | ll,egg,egg,tr,tr | depart,roundabout-exit-1,roundabout-exit-2,arrive |
| w,x | ll,egg,egg,tr,tr | depart,turn right,continue left,turn slight left,arrive |
@@ -0,0 +1,92 @@
@routing @guidance @staggered-intersections
Feature: Staggered Intersections
Background:
Given the profile "car"
Given a grid size of 1 meters
# Note the one meter grid size: staggered intersections make zig-zags of a couple of meters only
# https://www.openstreetmap.org/#map=19/39.26022/-84.25144
Scenario: Staggered Intersection: Oak St, Cedar Dr
Given the node map
| | | j | | |
| a | b | c | | |
| | | d | | |
| | | e | f | g |
| | | h | | |
| | | i | | |
And the ways
| nodes | highway | name |
| abc | residential | Oak St |
| efg | residential | Oak St |
| jcdehi | residential | Cedar Dr |
When I route I should get
| waypoints | route | turns |
| a,g | Oak St,Oak St | depart,arrive |
| g,a | Oak St,Oak St | depart,arrive |
Scenario: Staggered Intersection: do not collapse if long segment in between
Given the node map
| | | j | | |
| a | b | c | | |
| | | | | |
| | | | | |
| | | d | | |
| | | | | |
| | | | | |
| | | e | f | g |
| | | h | | |
| | | i | | |
And the ways
| nodes | highway | name |
| abc | residential | Oak St |
| efg | residential | Oak St |
| jcdehi | residential | Cedar Dr |
When I route I should get
| waypoints | route | turns |
| a,g | Oak St,Cedar Dr,Oak St,Oak St | depart,turn right,turn left,arrive |
| g,a | Oak St,Cedar Dr,Oak St,Oak St | depart,turn right,turn left,arrive |
Scenario: Staggered Intersection: do not collapse if not left-right or right-left
Given the node map
| | | j | | |
| a | b | c | | |
| | | d | | |
| g | f | e | | |
| | | h | | |
| | | i | | |
And the ways
| nodes | highway | name |
| abc | residential | Oak St |
| efg | residential | Oak St |
| jcdehi | residential | Cedar Dr |
When I route I should get
| waypoints | route | turns |
| a,g | Oak St,Oak St,Oak St | depart,continue uturn,arrive |
| g,a | Oak St,Oak St,Oak St | depart,continue uturn,arrive |
Scenario: Staggered Intersection: do not collapse if the names are not the same
Given the node map
| | | j | | |
| a | b | c | | |
| | | d | | |
| | | e | f | g |
| | | h | | |
| | | i | | |
And the ways
| nodes | highway | name |
| abc | residential | Oak St |
| efg | residential | Elm St |
| jcdehi | residential | Cedar Dr |
When I route I should get
| waypoints | route | turns |
| a,g | Oak St,Cedar Dr,Elm St,Elm St | depart,turn right,turn left,arrive |
| g,a | Elm St,Cedar Dr,Oak St,Oak St | depart,turn right,turn left,arrive |
+18 -5
View File
@@ -3,7 +3,7 @@ Feature: Suppress New Names on dedicated Suffices
Background:
Given the profile "car"
Given a grid size of 10 meters
Given a grid size of 2000 meters
Scenario: Suffix To Suffix
Given the node map
@@ -28,8 +28,8 @@ Feature: Suppress New Names on dedicated Suffices
| bc | 42 S | 101 |
When I route I should get
| waypoints | route | turns |
| a,c | 42 N,42 S (101) | depart,arrive |
| waypoints | route | turns | ref |
| a,c | 42 N,42 S | depart,arrive | ,101 |
Scenario: Prefix Change
Given the node map
@@ -44,6 +44,19 @@ Feature: Suppress New Names on dedicated Suffices
| waypoints | route | turns |
| a,c | West 42,East 42 | depart,arrive |
Scenario: Prefix Change ref
Given the node map
| a | | b | | c |
And the ways
| nodes | name |
| ab | West 42 |
| bc | 42 |
When I route I should get
| waypoints | route | turns |
| a,c | West 42,42 | depart,arrive |
Scenario: Prefix Change and Reference
Given the node map
| a | | b | | c |
@@ -54,8 +67,8 @@ Feature: Suppress New Names on dedicated Suffices
| bc | East 42 | |
When I route I should get
| waypoints | route | turns |
| a,c | West 42 (101),East 42 | depart,arrive |
| waypoints | route | turns | ref |
| a,c | West 42,East 42 | depart,arrive | 101, |
Scenario: Suffix To Suffix - Turn
Given the node map
+2 -2
View File
@@ -32,8 +32,8 @@ Feature: Suppressed Turns
| ef | motorway | highway | A1 |
When I route I should get
| waypoints | route | turns |
| a,f | highway (A1),highway (A1) | depart,arrive |
| waypoints | route | turns | ref |
| a,f | highway,highway | depart,arrive | A1,A1 |
Scenario: Don't Announce Turn on following major road class -- service
+52
View File
@@ -0,0 +1,52 @@
@routing @guidance @post-processing
Feature: General Post-Processing related features
Background:
Given the profile "car"
Given a grid size of 0.1 meters
# this testcase used to crash geometry generation (at that time handled during intersection generation)
Scenario: Regression Test 2754
Given the node map
| a | b | c | d | e | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | f | g | h | i | j |
And the ways
| nodes |
| abcde |
| ef |
| fghij |
When I route I should get
| waypoints | route |
| a,j | ef,ef |
File diff suppressed because it is too large Load Diff
+271 -13
View File
@@ -246,22 +246,28 @@ Feature: Simple Turns
Scenario: Four Way Intersection Double Through Street Segregated
Given the node map
| | b | | c | |
| i | | | | d |
| | | a | | |
| h | | | | e |
| | g | | f | |
| | | | | q | | p | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | b | | c | | | | |
| j | | | i | | | | d | | | o |
| | | | | | a | | | | | |
| k | | | h | | | | e | | | n |
| | | | | g | | f | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | l | | m | | | | |
And the ways
| nodes | highway | oneway | name |
| ha | primary | yes | first |
| ai | primary | yes | first |
| ae | primary | yes | first |
| da | primary | yes | first |
| ba | primary | yes | second |
| ac | primary | yes | second |
| fa | primary | yes | second |
| ag | primary | yes | second |
| khaij | primary | yes | first |
| odaen | primary | yes | first |
| qbacp | primary | yes | second |
| mfagl | primary | yes | second |
When I route I should get
| waypoints | route | turns |
@@ -806,3 +812,255 @@ 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 |
Scenario: V St NW, Florida Ave NW: Turn Instruction
# https://www.mapillary.com/app/?focus=map&lat=38.91815595&lng=-77.03880249&z=17&pKey=sCxepTOCTZD3OoBXuqGEOw
# http://www.openstreetmap.org/way/6062557#map=19/38.91805/-77.03892
Given the node map
| y | | | x | | |
| | | c | | | |
| | d | | | b | a |
| | | | | | |
| e | | | | | |
And the ways
| nodes | name | highway | oneway |
| abc | V St NW | tertiary | yes |
| xcde | Florida Ave NW | tertiary | yes |
| yd | Champlain St NW | residential | |
When I route I should get
| waypoints | turns | route |
| a,e | depart,turn left,arrive | V St NW,Florida Ave NW,Florida Ave NW |
# http://www.openstreetmap.org/node/182805179
Scenario: Make Sharp Left at Traffic Signal
Given the node map
| | | | g | | | |
| | | | | | | |
| | | | f | | | y |
| i | | | | | | |
| j | k | a | | b | | x |
| | | | e | | c | |
| | | | | d | | |
| | | | | | | |
| | | | h | | | |
And the nodes
| node | highway |
| f | traffic_signals |
And the ways
| nodes | name | highway | oneway |
| yf | yf | trunk_link | yes |
| gfeh | Centreville Road | primary | |
| fi | fi | trunk_link | yes |
| ij | Bloomingdale Road | residential | |
| jkabx | Blue Star Memorial Hwy | trunk | |
| bcde | bcde | trunk_link | yes |
| kh | kh | trunk_link | yes |
When I route I should get
| waypoints | turns | route |
| a,h | depart,off ramp right,turn sharp left,arrive | Blue Star Memorial Hwy,bcde,Centreville Road,Centreville Road |
@todo
# https://www.openstreetmap.org/#map=20/52.51609/13.41080
Scenario: Unnecessary Slight Left onto Stralauer Strasse
Given the node map
| | e | | | | | |
| | | | | | | |
| a | | b | | c | | d |
And the ways
| nodes | name | highway | oneway |
| ab | Molkenmarkt | secondary | yes |
| bc | Stralauer Str | secondary | yes |
| cd | Stralauer Str | secondary | yes |
| ec | Molkenmarkt | secondary | yes |
When I route I should get
| waypoints | turns | route |
| a,d | depart,arrive | Molkenmarkt,Stralauer Str |
| e,d | depart,arrive | Molkenmarkt,Stralauer Str |
Scenario: Unnecessary Slight Left onto Stralauer Strasse
Given the node map
| | e | | | | | |
| | | | | | | |
| a | | b | | c | | d |
And the ways
| nodes | name | highway | oneway |
| ab | Molkenmarkt | secondary | yes |
| bc | Molkenmarkt | secondary | yes |
| cd | Stralauer Str | secondary | yes |
| ec | Molkenmarkt | secondary | yes |
When I route I should get
| waypoints | turns | route |
| a,d | depart,new name straight,arrive | Molkenmarkt,Stralauer Str,Stralauer Str |
| e,d | depart,new name slight left,arrive | Molkenmarkt,Stralauer Str,Stralauer Str |
# https://www.mapillary.com/app/?lat=52.466483333333336&lng=13.431908333333332&z=17&focus=photo&pKey=LWXnKqoGqUNLnG0lofiO0Q
# http://www.openstreetmap.org/#map=19/52.46750/13.43171
Scenario: Collapse Turn Instruction, Issue #2725
Given the node map
| | f | |
| | e | |
| | | |
| | | |
| g | | d |
| | | |
| | | |
| h | | c |
| | | |
| | | |
| | b | |
| | a | |
| | | |
| | | |
| r | x | s |
| | y | |
And the ways
| nodes | name | highway | oneway |
| ab | Hermannstr | secondary | |
| bc | Hermannstr | secondary | yes |
| cd | Hermannbruecke | secondary | yes |
| de | Hermannstr | secondary | yes |
| ef | Hermannstr | secondary | |
| eg | Hermannstr | secondary | yes |
| gh | Hermannbruecke | secondary | yes |
| hb | Hermannstr | secondary | yes |
| xa | Hermannstr | secondary | |
| yx | Hermannstr | secondary | |
| rxs | Silbersteinstr | tertiary | |
And the nodes
| node | highway |
| x | traffic_signals |
When I route I should get
| waypoints | turns | route |
| a,f | depart,arrive | Hermannstr,Hermannstr |
| f,a | depart,arrive | Hermannstr,Hermannstr |
| y,f | depart,arrive | Hermannstr,Hermannstr |
| f,y | depart,arrive | Hermannstr,Hermannstr |
Scenario: Collapse Turn Instruction, Issue #2725 - not trivially mergable at e
# https://www.mapillary.com/app/?lat=52.466483333333336&lng=13.431908333333332&z=17&focus=photo&pKey=LWXnKqoGqUNLnG0lofiO0Q
# http://www.openstreetmap.org/#map=19/52.46750/13.43171
Given the node map
| | f | |
| | e | |
| g | | d |
| | | |
| | | |
| h | | c |
| | | |
| | | |
| | b | |
| | a | |
| | | |
| | | |
| r | x | s |
| | y | |
And the ways
| nodes | name | highway | oneway |
| ab | Hermannstr | secondary | |
| bc | Hermannstr | secondary | yes |
| cd | Hermannbruecke | secondary | yes |
| de | Hermannstr | secondary | yes |
| ef | Hermannstr | secondary | |
| eg | Hermannstr | secondary | yes |
| gh | Hermannbruecke | secondary | yes |
| hb | Hermannstr | secondary | yes |
| xa | Hermannstr | secondary | |
| yx | Hermannstr | secondary | |
| rxs | Silbersteinstr | tertiary | |
And the nodes
| node | highway |
| x | traffic_signals |
When I route I should get
| waypoints | turns | route |
| a,f | depart,arrive | Hermannstr,Hermannstr |
| f,a | depart,arrive | Hermannstr,Hermannstr |
| y,f | depart,arrive | Hermannstr,Hermannstr |
| f,y | depart,arrive | Hermannstr,Hermannstr |
+31
View File
@@ -0,0 +1,31 @@
'use strict';
const fs = require('fs');
const crypto = require('crypto');
const d3 = require('d3-queue');
module.exports = {
hashOfFiles: (paths, cb) => {
let queue = d3.queue();
for (let i = 0; i < paths.length; ++i) {
queue.defer(fs.readFile, paths[i]);
}
queue.awaitAll((err, results) => {
if (err) return cb(err);
let checksum = crypto.createHash('md5');
for (let i = 0; i < results.length; ++i) {
checksum.update(results[i]);
}
cb(null, checksum.digest('hex'));
});
},
hashOfFile: (path, cb) => {
fs.readFile(path, (err, result) => {
if (err) return cb(err);
let checksum = crypto.createHash('md5');
checksum.update(result);
cb(null, checksum.digest('hex'));
});
}
};
@@ -1,11 +1,7 @@
'use strict';
var builder = require('xmlbuilder');
var ensureDecimal = (i) => {
if (parseInt(i) === i) return i.toFixed(1);
else return i;
};
const builder = require('xmlbuilder');
const ensureDecimal = require('./utils').ensureDecimal;
class DB {
constructor () {
+169
View File
@@ -0,0 +1,169 @@
'use strict';
const fs = require('fs');
const util = require('util');
const Timeout = require('node-timeout');
const tryConnect = require('../lib/try_connect');
const errorReason = require('./utils').errorReason;
class OSRMBaseLoader{
constructor (scope) {
this.scope = scope;
this.child = null;
}
launch (callback) {
var limit = Timeout(this.scope.TIMEOUT, { err: new Error('*** Launching osrm-routed timed out.') });
var runLaunch = (cb) => {
this.osrmUp(() => { this.waitForConnection(cb); });
};
runLaunch(limit((e) => { if (e) callback(e); else callback(); }));
}
shutdown (callback) {
if (!this.osrmIsRunning()) return callback();
var limit = Timeout(this.scope.TIMEOUT, { err: new Error('*** Shutting down osrm-routed timed out.')});
this.osrmDown(limit(callback));
}
osrmIsRunning () {
return this.child && !this.child.killed;
}
osrmDown (callback) {
if (this.osrmIsRunning()) {
this.child.on('exit', (code, signal) => {callback();});
this.child.kill();
} else callback();
}
waitForConnection (callback) {
var retryCount = 0;
let retry = (err) => {
if (err) {
if (retryCount < 10) {
retryCount++;
setTimeout(() => { tryConnect(this.scope.OSRM_PORT, retry); }, 10);
} else {
callback(new Error("Could not connect to osrm-routed after ten retries."));
}
}
else
{
callback();
}
};
tryConnect(this.scope.OSRM_PORT, retry);
}
};
class OSRMDirectLoader extends OSRMBaseLoader {
constructor (scope) {
super(scope);
}
load (inputFile, callback) {
this.inputFile = inputFile;
this.shutdown(() => {
this.launch(callback);
});
}
osrmUp (callback) {
if (this.osrmIsRunning()) return callback(new Error("osrm-routed already running!"));
this.child = this.scope.runBin('osrm-routed', util.format("%s -p %d", this.inputFile, this.scope.OSRM_PORT), this.scope.environment, (err) => {
if (err) {
throw new Error(util.format('osrm-routed %s: %s', errorReason(err), err.cmd));
}
});
callback();
}
};
class OSRMDatastoreLoader extends OSRMBaseLoader {
constructor (scope) {
super(scope);
}
load (inputFile, callback) {
this.inputFile = inputFile;
this.loadData((err) => {
if (err) return callback(err);
if (!this.osrmIsRunning()) this.launch(callback);
else {
this.scope.setupOutputLog(this.child, fs.createWriteStream(this.scope.scenarioLogFile, {'flags': 'a'}));
callback();
}
});
}
loadData (callback) {
this.scope.runBin('osrm-datastore', this.inputFile, this.scope.environment, (err) => {
if (err) return callback(new Error('*** osrm-datastore exited with ' + err.code + ': ' + err));
callback();
});
}
osrmUp (callback) {
if (this.osrmIsRunning()) return callback();
this.child = this.scope.runBin('osrm-routed', util.format('--shared-memory=1 -p %d', this.scope.OSRM_PORT), this.scope.environment, (err) => {
if (err) {
throw new Error(util.format('osrm-routed %s: %s', errorReason(err), err.cmd));
}
});
// we call the callback here, becuase we don't want to wait for the child process to finish
callback();
}
};
class OSRMLoader {
constructor (scope) {
this.scope = scope;
this.sharedLoader = new OSRMDatastoreLoader(this.scope);
this.directLoader = new OSRMDirectLoader(this.scope);
this.method = scope.DEFAULT_LOAD_METHOD;
}
load (inputFile, callback) {
if (this.method === 'datastore') {
this.directLoader.shutdown((err) => {
if (err) return callback(err);
this.loader = this.sharedLoader;
this.sharedLoader.load(inputFile, callback);
});
} else if (this.method === 'directly') {
this.sharedLoader.shutdown((err) => {
if (err) return callback(err);
this.loader = this.directLoader;
this.directLoader.load(inputFile, callback);
});
} else {
callback(new Error('*** Unknown load method ' + method));
}
}
setLoadMethod (method) {
this.method = method;
}
shutdown (callback) {
if (!this.loader) return callback();
this.loader.shutdown(callback);
}
up () {
return this.loader ? this.loader.osrmIsRunning() : false;
}
};
module.exports = OSRMLoader;
+54
View File
@@ -0,0 +1,54 @@
'use strict';
var util = require('util');
var path = require('path');
var fs = require('fs');
var chalk = require('chalk');
var unescapeStr = (str) => str.replace(/\\\|/g, '\|').replace(/\\\\/g, '\\');
module.exports = function (expected, actual) {
let headers = expected.raw()[0];
let expected_keys = expected.hashes();
let diff = [];
let hasErrors = false;
var good = 0, bad = 0;
expected_keys.forEach((row, i) => {
var rowError = false;
for (var j in row) {
if (unescapeStr(row[j]) != actual[i][j]) {
rowError = true;
hasErrors = true;
break;
}
}
if (rowError) {
bad++;
diff.push(Object.assign({}, row, {c_status: 'undefined'}));
diff.push(Object.assign({}, actual[i], {c_status: 'comment'}));
} else {
good++;
diff.push(row);
}
});
if (!hasErrors) return null;
var s = ['Tables were not identical:'];
s.push(headers.map(key => ' ' + key).join(' | '));
diff.forEach((row) => {
var rowString = '| ';
headers.forEach((header) => {
if (!row.c_status) rowString += chalk.green(' ' + row[header] + ' | ');
else if (row.c_status === 'undefined') rowString += chalk.yellow('(-) ' + row[header] + ' | ');
else rowString += chalk.red('(+) ' + row[header] + ' | ');
});
s.push(rowString);
});
return s.join('\n') + '\nTODO this is a temp workaround waiting for https://github.com/cucumber/cucumber-js/issues/534';
};
+13
View File
@@ -0,0 +1,13 @@
'use strict';
const net = require('net');
const Timeout = require('node-timeout');
module.exports = function tryConnect(port, callback) {
net.connect({ port: port, host: '127.0.0.1' })
.on('connect', () => { callback(); })
.on('error', () => {
callback(new Error('Could not connect.'));
});
}
+17
View File
@@ -0,0 +1,17 @@
'use strict';
const util = require('util');
module.exports = {
ensureDecimal: (i) => {
if (parseInt(i) === i) return i.toFixed(1);
else return i;
},
errorReason: (err) => {
return err.signal ?
util.format('killed by signal %s', err.signal) :
util.format('exited with code %d', err.code);
}
};
@@ -1,8 +1,7 @@
@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
# {processed_file} => path to .osrm file
Background:
Given the profile "testbot"
@@ -24,7 +23,6 @@ Feature: osrm-contract command line options: datasources
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
When I run "osrm-contract --segment-speed-file {speeds_file} {processed_file}"
Then datasource names should contain "lua profile,25_osrmcontract_passing_base_file_speeds"
And it should exit successfully
+4 -9
View File
@@ -1,9 +1,5 @@
@prepare @options @files
Feature: osrm-contract command line options: files
# expansions:
# {extracted_base} => path to current extracted input file
# {profile} => path to current profile script
Background:
Given the profile "testbot"
And the node map
@@ -14,12 +10,11 @@ Feature: osrm-contract command line options: files
And the data has been extracted
Scenario: osrm-contract - Passing base file
When I run "osrm-contract {extracted_base}.osrm"
Then stderr should be empty
And it should exit with code 0
When I run "osrm-contract {processed_file}"
Then it should exit successfully
Scenario: osrm-contract - Missing input file
When I run "osrm-contract over-the-rainbow.osrm"
When I try to run "osrm-contract over-the-rainbow.osrm"
And stderr should contain "over-the-rainbow.osrm"
And stderr should contain "not found"
And it should exit with code 1
And it should exit with an error
+4 -4
View File
@@ -2,7 +2,7 @@
Feature: osrm-contract command line options: help
Scenario: osrm-contract - Help should be shown when no options are passed
When I run "osrm-contract"
When I try to run "osrm-contract"
Then stderr should be empty
And stdout should contain "osrm-contract <input.osrm> [options]:"
And stdout should contain "Options:"
@@ -13,7 +13,7 @@ Feature: osrm-contract command line options: help
And stdout should contain "--core"
And stdout should contain "--level-cache"
And stdout should contain "--segment-speed-file"
And it should exit with code 1
And it should exit with an error
Scenario: osrm-contract - Help, short
When I run "osrm-contract -h"
@@ -27,7 +27,7 @@ Feature: osrm-contract command line options: help
And stdout should contain "--core"
And stdout should contain "--level-cache"
And stdout should contain "--segment-speed-file"
And it should exit with code 0
And it should exit successfully
Scenario: osrm-contract - Help, long
When I run "osrm-contract --help"
@@ -41,4 +41,4 @@ Feature: osrm-contract command line options: help
And stdout should contain "--core"
And stdout should contain "--level-cache"
And stdout should contain "--segment-speed-file"
And it should exit with code 0
And it should exit successfully
+2 -2
View File
@@ -5,8 +5,8 @@ Feature: osrm-contract command line options: invalid options
Given the profile "testbot"
Scenario: osrm-contract - Non-existing option
When I run "osrm-contract --fly-me-to-the-moon"
When I try to run "osrm-contract --fly-me-to-the-moon"
Then stdout should be empty
And stderr should contain "option"
And stderr should contain "fly-me-to-the-moon"
And it should exit with code 1
And it should exit with an error
+2 -2
View File
@@ -12,11 +12,11 @@ Feature: osrm-contract command line options: version
Then stderr should be empty
And stdout should contain 1 line
And stdout should contain /(v\d{1,2}\.\d{1,2}\.\d{1,2}|\w*-\d+-\w+)/
And it should exit with code 0
And it should exit successfully
Scenario: osrm-contract - Version, long
When I run "osrm-contract --version"
Then stderr should be empty
And stdout should contain 1 line
And stdout should contain /(v\d{1,2}\.\d{1,2}\.\d{1,2}|\w*-\d+-\w+)/
And it should exit with code 0
And it should exit successfully
+6 -8
View File
@@ -14,17 +14,15 @@ Feature: osrm-extract command line options: files
And the data has been saved to disk
Scenario: osrm-extract - Passing base file
When I run "osrm-extract {osm_base}.osm --profile {profile}"
Then stderr should be empty
And it should exit with code 0
When I run "osrm-extract {osm_file} --profile {profile_file}"
Then it should exit successfully
Scenario: osrm-extract - Order of options should not matter
When I run "osrm-extract --profile {profile} {osm_base}.osm"
Then stderr should be empty
And it should exit with code 0
When I run "osrm-extract --profile {profile_file} {osm_file}"
Then it should exit successfully
Scenario: osrm-extract - Missing input file
When I run "osrm-extract over-the-rainbow.osrm --profile {profile}"
When I try to run "osrm-extract over-the-rainbow.osrm --profile {profile_file}"
And stderr should contain "over-the-rainbow.osrm"
And stderr should contain "not found"
And it should exit with code 1
And it should exit with an error
+3 -3
View File
@@ -16,7 +16,7 @@ Feature: osrm-extract command line options: help
And stdout should contain "--threads"
And stdout should contain "--generate-edge-lookup"
And stdout should contain "--small-component-size"
And it should exit with code 0
And it should exit successfully
Scenario: osrm-extract - Help, short
When I run "osrm-extract -h"
@@ -30,7 +30,7 @@ Feature: osrm-extract command line options: help
And stdout should contain "--threads"
And stdout should contain "--generate-edge-lookup"
And stdout should contain "--small-component-size"
And it should exit with code 0
And it should exit successfully
Scenario: osrm-extract - Help, long
When I run "osrm-extract --help"
@@ -44,4 +44,4 @@ Feature: osrm-extract command line options: help
And stdout should contain "--threads"
And stdout should contain "--generate-edge-lookup"
And stdout should contain "--small-component-size"
And it should exit with code 0
And it should exit successfully
+2 -2
View File
@@ -5,8 +5,8 @@ Feature: osrm-extract command line options: invalid options
Given the profile "testbot"
Scenario: osrm-extract - Non-existing option
When I run "osrm-extract --fly-me-to-the-moon"
When I try to run "osrm-extract --fly-me-to-the-moon"
Then stdout should be empty
And stderr should contain "option"
And stderr should contain "fly-me-to-the-moon"
And it should exit with code 1
And it should exit with an error
+2 -2
View File
@@ -12,11 +12,11 @@ Feature: osrm-extract command line options: version
Then stderr should be empty
And stdout should contain 1 line
And stdout should contain /(v\d{1,2}\.\d{1,2}\.\d{1,2}|\w*-\d+-\w+)/
And it should exit with code 0
And it should exit successfully
Scenario: osrm-extract - Version, long
When I run "osrm-extract --version"
Then stderr should be empty
And stdout should contain 1 line
And stdout should contain /(v\d{1,2}\.\d{1,2}\.\d{1,2}|\w*-\d+-\w+)/
And it should exit with code 0
And it should exit successfully
+1 -1
View File
@@ -29,4 +29,4 @@ Feature: osrm-routed command line options: files
And stdout should contain /^\[info\] loaded plugin: viaroute/
And stdout should contain /^\[info\] trial run/
And stdout should contain /^\[info\] shutdown completed/
And it should exit with code 0
And it should exit successfully
+3 -3
View File
@@ -21,7 +21,7 @@ Feature: osrm-routed command line options: help
And stdout should contain "--max-trip-size"
And stdout should contain "--max-table-size"
And stdout should contain "--max-matching-size"
And it should exit with code 0
And it should exit successfully
Scenario: osrm-routed - Help, short
When I run "osrm-routed -h"
@@ -40,7 +40,7 @@ Feature: osrm-routed command line options: help
And stdout should contain "--max-trip-size"
And stdout should contain "--max-table-size"
And stdout should contain "--max-matching-size"
And it should exit with code 0
And it should exit successfully
Scenario: osrm-routed - Help, long
When I run "osrm-routed --help"
@@ -59,4 +59,4 @@ Feature: osrm-routed command line options: help
And stdout should contain "--max-table-size"
And stdout should contain "--max-table-size"
And stdout should contain "--max-matching-size"
And it should exit with code 0
And it should exit successfully
+5 -5
View File
@@ -5,14 +5,14 @@ Feature: osrm-routed command line options: invalid options
Given the profile "testbot"
Scenario: osrm-routed - Non-existing option
When I run "osrm-routed --fly-me-to-the-moon"
When I try to run "osrm-routed --fly-me-to-the-moon"
Then stdout should be empty
And stderr should contain "exception"
And stderr should contain "unrecognised"
And stderr should contain "fly-me-to-the-moon"
And it should exit with code 1
And it should exit with an error
Scenario: osrm-routed - Missing file
When I run "osrm-routed over-the-rainbow.osrm"
When I try to run "osrm-routed over-the-rainbow.osrm"
Then stderr should contain "over-the-rainbow.osrm"
And stderr should contain "not found"
And it should exit with code 1
And it should exit with an error
+2 -2
View File
@@ -12,11 +12,11 @@ Feature: osrm-routed command line options: version
Then stderr should be empty
And stdout should contain 1 line
And stdout should contain /(v\d{1,2}\.\d{1,2}\.\d{1,2}|\w*-\d+-\w+)/
And it should exit with code 0
And it should exit successfully
Scenario: osrm-routed - Version, long
When I run "osrm-routed --version"
Then stderr should be empty
And stdout should contain 1 line
And stdout should contain /(v\d{1,2}\.\d{1,2}\.\d{1,2}|\w*-\d+-\w+)/
And it should exit with code 0
And it should exit successfully
+11 -8
View File
@@ -1,9 +1,5 @@
@raster @extract
Feature: osrm-extract with a profile containing raster source
# expansions:
# {osm_base} => path to current input file
# {profile} => path to current profile script
Scenario: osrm-extract on a valid profile
Given the profile "rasterbot"
And the node map
@@ -11,8 +7,15 @@ Feature: osrm-extract with a profile containing raster source
And the ways
| nodes |
| ab |
And the raster source
"""
0 0 0 0
0 0 0 250
0 0 250 500
0 0 0 250
0 0 0 0
"""
And the data has been saved to disk
When I run "osrm-extract {osm_base}.osm -p {profile}"
Then stderr should be empty
And stdout should contain "source loader"
And it should exit with code 0
When I run "osrm-extract {osm_file} -p {profile_file}"
Then stdout should contain "source loader"
And it should exit successfully
+6 -6
View File
@@ -32,8 +32,8 @@ Feature: Raster - weights
Scenario: Weighting not based on raster sources
Given the profile "testbot"
When I run "osrm-extract {osm_base}.osm -p {profile}"
And I run "osrm-contract {osm_base}.osm"
When I run "osrm-extract {osm_file} -p {profile_file}"
And I run "osrm-contract {processed_file}"
And I route I should get
| from | to | route | speed |
| a | b | ab,ab | 36 km/h |
@@ -44,9 +44,9 @@ Feature: Raster - weights
Scenario: Weighting based on raster sources
Given the profile "rasterbot"
When I run "osrm-extract {osm_base}.osm -p {profile}"
When I run "osrm-extract {osm_file} -p {profile_file}"
Then stdout should contain "evaluating segment"
And I run "osrm-contract {osm_base}.osm"
And I run "osrm-contract {processed_file}"
And I route I should get
| from | to | route | speed |
| a | b | ab,ab | 8 km/h |
@@ -62,9 +62,9 @@ Feature: Raster - weights
Scenario: Weighting based on raster sources
Given the profile "rasterbotinterp"
When I run "osrm-extract {osm_base}.osm -p {profile}"
When I run "osrm-extract {osm_file} -p {profile_file}"
Then stdout should contain "evaluating segment"
And I run "osrm-contract {osm_base}.osm"
And I run "osrm-contract {processed_file}"
And I route I should get
| from | to | route | speed |
| a | b | ab,ab | 8 km/h |
+27 -35
View File
@@ -2,22 +2,26 @@ var util = require('util');
var path = require('path');
var fs = require('fs');
var d3 = require('d3-queue');
var OSM = require('../support/build_osm');
var OSM = require('../lib/osm');
module.exports = function () {
this.Given(/^the profile "([^"]*)"$/, (profile, callback) => {
this.setProfile(profile, callback);
this.profile = profile;
this.profileFile = path.join(this.PROFILES_PATH, this.profile + '.lua');
callback();
});
this.Given(/^the extract extra arguments "(.*?)"$/, (args, callback) => {
this.setExtractArgs(args, callback);
this.extractArgs = this.expandOptions(args);
callback();
});
this.Given(/^the contract extra arguments "(.*?)"$/, (args, callback) => {
this.setContractArgs(args, callback);
this.contractArgs = this.expandOptions(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,58 +232,46 @@ module.exports = function () {
});
this.Given(/^the raster source$/, (data, callback) => {
this.updateFingerprintExtract(data);
fs.writeFile(path.resolve(this.TEST_FOLDER, 'rastersource.asc'), data, callback);
// TODO: Don't overwrite if it exists
fs.writeFile(this.rasterCacheFile, data, callback);
// we need this to pass it to the profiles
this.environment = Object.assign({OSRM_RASTER_SOURCE: this.rasterCacheFile}, this.environment);
});
this.Given(/^the speed file$/, (data, callback) => {
this.updateFingerprintContract(data);
fs.writeFile(path.resolve(this.TEST_FOLDER, 'speeds.csv'), data, callback);
// TODO: Don't overwrite if it exists
fs.writeFile(this.speedsCacheFile, data, callback);
});
this.Given(/^the turn penalty file$/, (data, callback) => {
this.updateFingerprintContract(data);
fs.writeFile(path.resolve(this.TEST_FOLDER, 'penalties.csv'), data, callback);
// TODO: Don't overwrite if it exists
fs.writeFile(this.penaltiesCacheFile, data, callback);
});
this.Given(/^the data has been saved to disk$/, (callback) => {
try {
this.reprocess(callback);
} catch(e) {
this.processError = e;
callback(e);
}
this.reprocess(callback);
});
this.Given(/^the data has been extracted$/, (callback) => {
this.osmData.populate(() => {
this.writeAndExtract((err) => {
if (err) this.processError = err;
callback();
});
});
this.reprocess(callback);
});
this.Given(/^the data has been contracted$/, (callback) => {
this.reprocess((err) => {
if (err) this.processError = err;
callback();
});
this.reprocess(callback);
});
this.Given(/^osrm\-routed is stopped$/, (callback) => {
this.OSRMLoader.shutdown((err) => {
if (err) this.processError = err;
callback();
});
this.OSRMLoader.shutdown(callback);
});
this.Given(/^data is loaded directly/, () => {
this.loadMethod = 'directly';
this.Given(/^data is loaded directly/, (callback) => {
this.osrmLoader.setLoadMethod('directly');
callback();
});
this.Given(/^data is loaded with datastore$/, () => {
this.loadMethod = 'datastore';
this.Given(/^data is loaded with datastore$/, (callback) => {
this.osrmLoader.setLoadMethod('datastore');
callback();
});
this.Given(/^the HTTP method "([^"]*)"$/, (method, callback) => {
+2 -9
View File
@@ -35,7 +35,8 @@ module.exports = function () {
var actual = [];
actual.push(table.headers);
this.reprocessAndLoadData(() => {
this.reprocessAndLoadData((e) => {
if (e) return callback(e);
// compute matrix
var params = this.queryParams;
@@ -52,8 +53,6 @@ module.exports = function () {
});
var testRow = (row, ri, cb) => {
var ok = true;
for (var k in result[ri]) {
if (this.FuzzyMatch.match(result[ri][k], row[k])) {
result[ri][k] = row[k];
@@ -61,15 +60,9 @@ module.exports = function () {
result[ri][k] = '';
} else {
result[ri][k] = result[ri][k].toString();
ok = false;
}
}
if (!ok) {
var failed = { attempt: 'distance_matrix', query: this.query, response: response };
this.logFail(row, result[ri], [failed]);
}
result[ri][''] = row[''];
cb(null, result[ri]);
};
-30
View File
@@ -1,30 +0,0 @@
var util = require('util');
module.exports = function () {
this.Before((scenario, callback) => {
this.scenarioTitle = scenario.getName();
this.loadMethod = this.DEFAULT_LOAD_METHOD;
this.queryParams = {};
var d = new Date();
this.scenarioTime = util.format('%d-%d-%dT%s:%s:%sZ', d.getFullYear(), d.getMonth()+1, d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds());
this.resetData();
this.hasLoggedPreprocessInfo = false;
this.hasLoggedScenarioInfo = false;
this.setGridSize(this.DEFAULT_GRID_SIZE);
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();
});
};
+16 -2
View File
@@ -1,11 +1,13 @@
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) => {
var got;
this.reprocessAndLoadData(() => {
this.reprocessAndLoadData((e) => {
if (e) return callback(e);
var testRow = (row, ri, cb) => {
var afterRequest = (err, res) => {
if (err) return cb(err);
@@ -35,6 +37,7 @@ module.exports = function () {
route = '',
duration = '',
annotation = '',
geometry = '',
OSMIDs = '';
@@ -63,6 +66,11 @@ module.exports = function () {
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]);
@@ -85,6 +93,13 @@ module.exports = function () {
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;
}
@@ -142,7 +157,6 @@ module.exports = function () {
} else {
got.matchings = encodedResult;
row.matchings = extendedTarget;
this.logFail(row, got, { matching: { query: this.query, response: res } });
}
cb(null, got);
+2 -9
View File
@@ -2,7 +2,8 @@ var util = require('util');
module.exports = function () {
this.When(/^I request nearest I should get$/, (table, callback) => {
this.reprocessAndLoadData(() => {
this.reprocessAndLoadData((e) => {
if (e) return callback(e);
var testRow = (row, ri, cb) => {
var inNode = this.findNodeByName(row.in);
if (!inNode) throw new Error(util.format('*** unknown in-node "%s"'), row.in);
@@ -21,24 +22,16 @@ module.exports = function () {
var got = { in: row.in, out: row.out };
var ok = true;
Object.keys(row).forEach((key) => {
if (key === 'out') {
if (this.FuzzyMatch.matchLocation(coord, outNode)) {
got[key] = row[key];
} else {
row[key] = util.format('%s [%d,%d]', row[key], outNode.lat, outNode.lon);
ok = false;
}
}
});
if (!ok) {
var failed = { attempt: 'nearest', query: this.query, response: response };
this.logFail(row, got, [failed]);
}
cb(null, got);
}
else {
+41 -15
View File
@@ -2,32 +2,58 @@ var assert = require('assert');
var fs = require('fs');
module.exports = function () {
this.When(/^I run "osrm\-routed\s?(.*?)"$/, { timeout: this.TIMEOUT }, (options, callback) => {
this.runBin('osrm-routed', options, () => {
callback();
this.resetOptionsOutput = () => {
this.stdout = null;
this.stderr = null;
this.exitCode = null;
this.termSignal = null;
};
this.runAndSafeOutput = (binary, options, callback) => {
this.runBin(binary, this.expandOptions(options), this.environment, (err, stdout, stderr) => {
this.stdout = stdout;
this.stderr = stderr;
this.exitCode = err && err.code || 0;
this.termSignal = err && err.signal || '';
callback(err);
});
};
this.When(/^I run "osrm\-routed\s?(.*?)"$/, { timeout: this.TIMEOUT }, (options, callback) => {
this.runAndSafeOutput('osrm-routed', options, callback);
});
this.When(/^I run "osrm\-extract\s?(.*?)"$/, (options, callback) => {
this.runBin('osrm-extract', options, () => {
callback();
});
this.runAndSafeOutput('osrm-extract', options, callback);
});
this.When(/^I run "osrm\-contract\s?(.*?)"$/, (options, callback) => {
this.runBin('osrm-contract', options, () => {
callback();
});
this.runAndSafeOutput('osrm-contract', options, callback);
});
this.When(/^I try to run "osrm\-routed\s?(.*?)"$/, (options, callback) => {
this.runAndSafeOutput('osrm-routed', options, () => { callback(); });
});
this.When(/^I try to run "osrm\-extract\s?(.*?)"$/, (options, callback) => {
this.runAndSafeOutput('osrm-extract', options, () => { callback(); });
});
this.When(/^I try to run "osrm\-contract\s?(.*?)"$/, (options, callback) => {
this.runAndSafeOutput('osrm-contract', options, () => { callback(); });
});
this.When(/^I run "osrm\-datastore\s?(.*?)"$/, (options, callback) => {
this.runBin('osrm-datastore', options, () => {
callback();
});
this.runAndSafeOutput('osrm-datastore', options, callback);
});
this.Then(/^it should exit with code (\d+)$/, (code) => {
assert.equal(this.exitCode, parseInt(code));
this.Then(/^it should exit successfully$/, () => {
assert.equal(this.exitCode, 0);
assert.equal(this.termSignal, '');
});
this.Then(/^it should exit with an error$/, () => {
assert.ok(this.exitCode !== 0 || this.termSignal);
});
this.Then(/^stdout should contain "(.*?)"$/, (str) => {
@@ -61,7 +87,7 @@ module.exports = function () {
});
this.Then(/^datasource names should contain "(.+)"$/, (expectedData) => {
var actualData = fs.readFileSync(this.osmData.extractedFile + '.osrm.datasource_names', {encoding:'UTF-8'}).trim().split('\n').join(',');
var actualData = fs.readFileSync(this.processedCacheFile + '.datasource_names', {encoding:'UTF-8'}).trim().split('\n').join(',');
assert.equal(actualData, expectedData);
});
+3 -2
View File
@@ -2,7 +2,8 @@ var assert = require('assert');
module.exports = function () {
this.When(/^I request \/(.*)$/, (path, callback) => {
this.reprocessAndLoadData(() => {
this.reprocessAndLoadData((e) => {
if (e) return callback(e);
this.requestPath(path, {}, (err, res, body) => {
this.response = res;
callback(err, res, body);
@@ -50,7 +51,7 @@ module.exports = function () {
});
this.Then(/^"([^"]*)" should return code (\d+)$/, (binary, code) => {
assert.ok(this.processError instanceof this.OSRMError);
assert.ok(this.processError instanceof Error);
assert.equal(this.processError.process, binary);
assert.equal(parseInt(this.processError.code), parseInt(code));
});
+2 -6
View File
@@ -13,7 +13,7 @@ module.exports = function () {
}
this.reprocessAndLoadData((e) => {
if (e) callback(e);
if (e) return callback(e);
var testRow = (row, i, cb) => {
var outputRow = row;
@@ -41,10 +41,6 @@ module.exports = function () {
}
});
if (outputRow != row) {
this.logFail(row, outputRow, result);
}
cb(null, outputRow);
});
};
@@ -116,7 +112,7 @@ module.exports = function () {
sq.defer(parseRes, key);
});
sq.awaitAll(() => { cb(null, result); });
sq.awaitAll((err) => { cb(err, result); });
});
};
};
+2 -10
View File
@@ -4,7 +4,8 @@ module.exports = function () {
this.When(/^I plan a trip I should get$/, (table, callback) => {
var got;
this.reprocessAndLoadData(() => {
this.reprocessAndLoadData((e) => {
if (e) return callback(e);
var testRow = (row, ri, cb) => {
var afterRequest = (err, res) => {
if (err) return cb(err);
@@ -84,23 +85,14 @@ module.exports = function () {
} else {
got.trips = encodedResult;
got.trips = extendedTarget;
this.logFail(row, got, { trip: { query: this.query, response: res }});
}
ok = true;
for (var key in row) {
if (this.FuzzyMatch.match(got[key], row[key])) {
got[key] = row[key];
} else {
ok = false;
}
}
if (!ok) {
this.logFail(row, got, { trip: { query: this.query, response: res }});
}
cb(null, got);
};
+184
View File
@@ -0,0 +1,184 @@
'use strict';
const d3 = require('d3-queue');
const fs = require('fs');
const util = require('util');
const path = require('path');
const mkdirp = require('mkdirp');
const hash = require('../lib/hash');
const rimraf = require('rimraf');
module.exports = function() {
this.initializeCache = (callback) => {
this.getOSRMHash((err, osrmHash) => {
if (err) return callback(err);
this.osrmHash = osrmHash;
callback();
});
};
// computes all paths for every feature
this.setupFeatures = (features, callback) => {
this.featureIDs = {};
this.featureCacheDirectories = {};
this.featureProcessedCacheDirectories = {};
let queue = d3.queue();
function initializeFeature(feature, callback) {
let uri = feature.getUri();
// setup cache for feature data
hash.hashOfFile(uri, (err, hash) => {
if (err) return callback(err);
// shorten uri to be realtive to 'features/'
let featurePath = path.relative(path.resolve('./features'), uri);
// bicycle/bollards/{HASH}/
let featureID = path.join(featurePath, hash);
let featureCacheDirectory = this.getFeatureCacheDirectory(featureID);
let featureProcessedCacheDirectory = this.getFeatureProcessedCacheDirectory(featureCacheDirectory, this.osrmHash);
this.featureIDs[uri] = featureID;
this.featureCacheDirectories[uri] = featureCacheDirectory;
this.featureProcessedCacheDirectories[uri] = featureProcessedCacheDirectory;
d3.queue(1)
.defer(mkdirp, featureProcessedCacheDirectory)
.defer(this.cleanupFeatureCache.bind(this), featureCacheDirectory, hash)
.defer(this.cleanupProcessedFeatureCache.bind(this), featureProcessedCacheDirectory, this.osrmHash)
.awaitAll(callback);
});
}
for (let i = 0; i < features.length; ++i) {
queue.defer(initializeFeature.bind(this), features[i]);
}
queue.awaitAll(callback);
};
this.cleanupProcessedFeatureCache = (directory, osrmHash, callback) => {
let parentPath = path.resolve(path.join(directory, '..'));
fs.readdir(parentPath, (err, files) => {
let q = d3.queue();
function runStats(path, callback) {
fs.stat(path, (err, stat) => {
if (err) return callback(err);
callback(null, {file: path, stat: stat});
});
}
files.map(f => { q.defer(runStats, path.join(parentPath, f)); });
q.awaitAll((err, results) => {
if (err) return callback(err);
let q = d3.queue();
results.forEach(r => {
if (r.stat.isDirectory() && r.file.search(osrmHash) < 0) {
q.defer(rimraf, r.file);
}
});
q.awaitAll(callback);
});
});
};
this.cleanupFeatureCache = (directory, featureHash, callback) => {
let parentPath = path.resolve(path.join(directory, '..'));
fs.readdir(parentPath, (err, files) => {
let q = d3.queue();
files.filter(name => { return name !== featureHash;})
.map((f) => { q.defer(rimraf, path.join(parentPath, f)); });
q.awaitAll(callback);
});
};
this.setupFeatureCache = (feature) => {
let uri = feature.getUri();
this.featureID = this.featureIDs[uri];
this.featureCacheDirectory = this.featureCacheDirectories[uri];
this.featureProcessedCacheDirectory = this.featureProcessedCacheDirectories[uri];
};
this.setupScenarioCache = (scenarioID) => {
this.scenarioCacheFile = this.getScenarioCacheFile(this.featureCacheDirectory, scenarioID);
this.processedCacheFile = this.getProcessedCacheFile(this.featureProcessedCacheDirectory, scenarioID);
this.inputCacheFile = this.getInputCacheFile(this.featureProcessedCacheDirectory, scenarioID);
this.rasterCacheFile = this.getRasterCacheFile(this.featureProcessedCacheDirectory, scenarioID);
this.speedsCacheFile = this.getSpeedsCacheFile(this.featureProcessedCacheDirectory, scenarioID);
this.penaltiesCacheFile = this.getPenaltiesCacheFile(this.featureProcessedCacheDirectory, scenarioID);
};
// returns a hash of all OSRM code side dependencies
this.getOSRMHash = (callback) => {
let dependencies = [
this.OSRM_EXTRACT_PATH,
this.OSRM_CONTRACT_PATH,
this.LIB_OSRM_EXTRACT_PATH,
this.LIB_OSRM_CONTRACT_PATH
];
var addLuaFiles = (directory, callback) => {
fs.readdir(path.normalize(directory), (err, files) => {
if (err) return callback(err);
var luaFiles = files.filter(f => !!f.match(/\.lua$/)).map(f => path.normalize(directory + '/' + f));
Array.prototype.push.apply(dependencies, luaFiles);
callback();
});
};
// Note: we need a serialized queue here to ensure that the order of the files
// passed is stable. Otherwise the hash will not be stable
d3.queue(1)
.defer(addLuaFiles, this.PROFILES_PATH)
.defer(addLuaFiles, this.PROFILES_PATH + '/lib')
.awaitAll(hash.hashOfFiles.bind(hash, dependencies, callback));
};
// test/cache/bicycle/bollards/{HASH}/
this.getFeatureCacheDirectory = (featureID) => {
return path.join(this.CACHE_PATH, featureID);
};
// converts the scenario titles in file prefixes
this.getScenarioID = (scenario) => {
let name = scenario.getName().toLowerCase().replace(/[\/\-'=,\(\)]/g, '').replace(/\s/g, '_').replace(/__/g, '_').replace(/\.\./g, '.');
return util.format('%d_%s', scenario.getLine(), name);
};
// test/cache/{feature_path}/{feature_hash}/{scenario}_raster.asc
this.getRasterCacheFile = (featureCacheDirectory, scenarioID) => {
return path.join(featureCacheDirectory, scenarioID) + '_raster.asc';
};
// test/cache/{feature_path}/{feature_hash}/{scenario}_speeds.csv
this.getSpeedsCacheFile = (featureCacheDirectory, scenarioID) => {
return path.join(featureCacheDirectory, scenarioID) + '_speeds.csv';
};
// test/cache/{feature_path}/{feature_hash}/{scenario}_penalties.csv
this.getPenaltiesCacheFile = (featureCacheDirectory, scenarioID) => {
return path.join(featureCacheDirectory, scenarioID) + '_penalties.csv';
};
// test/cache/{feature_path}/{feature_hash}/{scenario}.osm
this.getScenarioCacheFile = (featureCacheDirectory, scenarioID) => {
return path.join(featureCacheDirectory, scenarioID) + '.osm';
};
// test/cache/{feature_path}/{feature_hash}/{osrm_hash}/
this.getFeatureProcessedCacheDirectory = (featureCacheDirectory, osrmHash) => {
return path.join(featureCacheDirectory, osrmHash);
};
// test/cache/{feature_path}/{feature_hash}/{osrm_hash}/{scenario}.osrm
this.getProcessedCacheFile = (featureProcessedCacheDirectory, scenarioID) => {
return path.join(featureProcessedCacheDirectory, scenarioID) + '.osrm';
};
// test/cache/{feature_path}/{feature_hash}/{osrm_hash}/{scenario}.osm
this.getInputCacheFile = (featureProcessedCacheDirectory, scenarioID) => {
return path.join(featureProcessedCacheDirectory, scenarioID) + '.osm';
};
return this;
};
-127
View File
@@ -1,127 +0,0 @@
var fs = require('fs');
var path = require('path');
var util = require('util');
var d3 = require('d3-queue');
var OSM = require('./build_osm');
var classes = require('./data_classes');
module.exports = function () {
this.initializeOptions = (callback) => {
this.profile = this.profile || this.DEFAULT_SPEEDPROFILE;
this.OSMDB = this.OSMDB || new OSM.DB();
this.nameNodeHash = this.nameNodeHash || {};
this.locationHash = this.locationHash || {};
this.nameWayHash = this.nameWayHash || {};
this.osmData = new classes.osmData(this);
this.OSRMLoader = this._OSRMLoader();
this.PREPROCESS_LOG_FILE = path.resolve(this.TEST_FOLDER, 'preprocessing.log');
this.LOG_FILE = path.resolve(this.TEST_FOLDER, 'fail.log');
this.HOST = 'http://127.0.0.1:' + this.OSRM_PORT;
this.DESTINATION_REACHED = 15; // OSRM instruction code
this.shortcutsHash = this.shortcutsHash || {};
var hashLuaLib = (cb) => {
fs.readdir(path.normalize(this.PROFILES_PATH + '/lib/'), (err, files) => {
if (err) cb(err);
var luaFiles = files.filter(f => !!f.match(/\.lua$/)).map(f => path.normalize(this.PROFILES_PATH + '/lib/' + f));
this.hashOfFiles(luaFiles, hash => {
this.luaLibHash = hash;
cb();
});
});
};
var hashProfile = (cb) => {
this.hashProfile((hash) => {
this.profileHash = hash;
cb();
});
};
var hashExtract = (cb) => {
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) => {
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;
cb();
});
};
var hashRouted = (cb) => {
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();
});
};
d3.queue()
.defer(hashLuaLib)
.defer(hashProfile)
.defer(hashExtract)
.defer(hashContract)
.defer(hashRouted)
.awaitAll(() => {
this.AfterConfiguration(() => {
callback();
});
});
};
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) => {
var lastProfile = this.profile;
if (profile !== lastProfile) {
this.profile = profile;
this.hashProfile((hash) => {
this.profileHash = hash;
this.updateFingerprintExtract(this.profileHash);
cb();
});
} else {
this.updateFingerprintExtract(this.profileHash);
cb();
}
};
this.setExtractArgs = (args, callback) => {
this.extractArgs = args;
this.updateFingerprintExtract(args);
callback();
};
this.setContractArgs = (args, callback) => {
this.contractArgs = args;
this.updateFingerprintContract(args);
callback();
};
};
+72 -193
View File
@@ -1,11 +1,14 @@
var fs = require('fs');
var path = require('path');
var util = require('util');
var exec = require('child_process').exec;
var d3 = require('d3-queue');
'use strict';
var OSM = require('./build_osm');
var classes = require('./data_classes');
const fs = require('fs');
const util = require('util');
const d3 = require('d3-queue');
const OSM = require('../lib/osm');
const classes = require('./data_classes');
const tableDiff = require('../lib/table_diff');
const ensureDecimal = require('../lib/utils').ensureDecimal;
const errorReason = require('../lib/utils').errorReason;
module.exports = function () {
this.setGridSize = (meters) => {
@@ -94,13 +97,8 @@ module.exports = function () {
q.awaitAll(callback);
};
this.ensureDecimal = (i) => {
if (parseInt(i) === i) return i.toFixed(1);
else return i;
};
this.tableCoordToLonLat = (ci, ri) => {
return [this.origin[0] + ci * this.zoom, this.origin[1] - ri * this.zoom].map(this.ensureDecimal);
return [this.origin[0] + ci * this.zoom, this.origin[1] - ri * this.zoom].map(ensureDecimal);
};
this.addOSMNode = (name, lon, lat, id) => {
@@ -132,10 +130,6 @@ module.exports = function () {
return this.nameWayHash[s.toString()] || this.nameWayHash[s.toString().split('').reverse().join('')];
};
this.resetData = () => {
this.resetOSM();
};
this.makeOSMId = () => {
this.osmID = this.osmID + 1;
return this.osmID;
@@ -143,205 +137,88 @@ module.exports = function () {
this.resetOSM = () => {
this.OSMDB.clear();
this.osmData.reset();
this.nameNodeHash = {};
this.locationHash = {};
this.shortcutsHash = {};
this.nameWayHash = {};
this.osmID = 0;
};
this.writeOSM = (callback) => {
fs.exists(this.DATA_FOLDER, (exists) => {
var mkDirFn = exists ? (cb) => { cb(); } : fs.mkdir.bind(fs.mkdir, this.DATA_FOLDER);
mkDirFn((err) => {
if (err) return callback(err);
var osmPath = path.resolve(this.DATA_FOLDER, util.format('%s.osm', this.osmData.osmFile));
fs.exists(osmPath, (exists) => {
if (!exists) fs.writeFile(osmPath, this.osmData.str, callback);
else callback();
fs.exists(this.scenarioCacheFile, (exists) => {
if (exists) callback();
else {
this.OSMDB.toXML((xml) => {
fs.writeFile(this.scenarioCacheFile, xml, callback);
});
});
});
};
this.isExtracted = (callback) => {
fs.exists(util.format('%s.osrm', this.osmData.extractedFile), (core) => {
if (!core) return callback(false);
fs.exists(util.format('%s.osrm.names', this.osmData.extractedFile), (names) => {
if (!names) return callback(false);
fs.exists(util.format('%s.osrm.restrictions', this.osmData.extractedFile), (restrictions) => {
return callback(restrictions);
});
});
});
};
this.isContracted = (callback) => {
fs.exists(util.format('%s.osrm.hsgr', this.osmData.contractedFile), callback);
};
this.writeTimestamp = (callback) => {
fs.writeFile(util.format('%s.osrm.timestamp', this.osmData.contractedFile), this.OSM_TIMESTAMP, callback);
};
this.writeInputData = (callback) => {
this.writeOSM((err) => {
if (err) return callback(err);
this.writeTimestamp(callback);
});
};
this.extractData = (callback) => {
this.logPreprocessInfo();
this.log(util.format('== Extracting %s.osm...', this.osmData.osmFile), 'preprocess');
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) => {
if (err) {
this.log(util.format('*** Exited with code %d', err.code), 'preprocess');
process.chdir('../');
return callback(this.ExtractError(err.code, util.format('osrm-extract exited with code %d', err.code)));
}
var q = d3.queue();
var rename = (file, cb) => {
this.log(util.format('Renaming %s.%s to %s.%s', this.osmData.osmFile, file, this.osmData.extractedFile, file), 'preprocess');
fs.rename([this.osmData.osmFile, file].join('.'), [this.osmData.extractedFile, file].join('.'), (err) => {
if (err) return cb(this.FileError(null, 'failed to rename data file after extracting'));
cb();
});
};
var renameIfExists = (file, cb) => {
fs.stat([this.osmData.osmFile, file].join('.'), (doesNotExistErr, exists) => {
if (exists) rename(file, cb);
else cb();
});
};
['osrm', 'osrm.ebg', 'osrm.edges', 'osrm.enw', 'osrm.fileIndex', 'osrm.geometry', 'osrm.icd',
'osrm.names', 'osrm.nodes', 'osrm.properties', 'osrm.ramIndex', 'osrm.restrictions'].forEach(file => {
q.defer(rename, file);
});
['osrm.edge_penalties', 'osrm.edge_segment_lookup'].forEach(file => {
q.defer(renameIfExists, file);
});
q.awaitAll((err) => {
this.log('Finished extracting ' + this.osmData.extractedFile, 'preprocess');
process.chdir('../');
callback(err);
});
});
};
this.contractData = (callback) => {
this.logPreprocessInfo();
this.log(util.format('== Contracting %s.osm...', this.osmData.extractedFile), 'preprocess');
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) => {
if (err) {
this.log(util.format('*** Exited with code %d', err.code), 'preprocess');
process.chdir('../');
return callback(this.ContractError(err.code, util.format('osrm-contract exited with code %d', err.code)));
this.linkOSM = (callback) => {
fs.exists(this.inputCacheFile, (exists) => {
if (exists) callback();
else {
fs.link(this.scenarioCacheFile, this.inputCacheFile, callback);
}
});
};
var rename = (file, cb) => {
this.log(util.format('Renaming %s.%s to %s.%s', this.osmData.extractedFile, file, this.osmData.contractedFile, file), 'preprocess');
fs.rename([this.osmData.extractedFile, file].join('.'), [this.osmData.contractedFile, file].join('.'), (err) => {
if (err) return cb(this.FileError(null, 'failed to rename data file after contracting.'));
cb();
});
};
this.extractData = (p, callback) => {
let stamp = p.processedCacheFile + '.extract';
fs.exists(stamp, (exists) => {
if (exists) return callback();
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('.'))
.pipe(fs.createWriteStream([this.osmData.contractedFile, file].join('.'))
.on('finish', cb)
)
.on('error', () => {
return cb(this.FileError(null, 'failed to copy data after contracting.'));
});
};
var q = d3.queue();
['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'].forEach((file) => {
q.defer(rename, file);
});
['osrm.edge_penalties', 'osrm.edge_segment_lookup'].forEach(file => {
q.defer(renameIfExists, file);
});
[].forEach((file) => {
q.defer(copy, file);
});
q.awaitAll((err) => {
this.log('Finished contracting ' + this.osmData.contractedFile, 'preprocess');
process.chdir('../');
callback(err);
this.runBin('osrm-extract', util.format('%s --profile %s %s', p.extractArgs, p.profileFile, p.inputCacheFile), p.environment, (err) => {
if (err) {
return callback(new Error(util.format('osrm-extract %s: %s', errorReason(err), err.cmd)));
}
fs.writeFile(stamp, 'ok', callback);
});
});
};
var noop = (cb) => cb();
this.contractData = (p, callback) => {
let stamp = p.processedCacheFile + '.contract';
fs.exists(stamp, (exists) => {
if (exists) return callback();
this.runBin('osrm-contract', util.format('%s %s', p.contractArgs, p.processedCacheFile), p.environment, (err) => {
if (err) {
return callback(new Error(util.format('osrm-contract %s: %s', errorReason(err), err)));
}
fs.writeFile(stamp, 'ok', callback);
});
});
};
this.extractAndContract = (callback) => {
// a shallow copy of scenario parameters to avoid data inconsistency
// if a cucumber timeout occurs during deferred jobs
let p = {extractArgs: this.extractArgs, contractArgs: this.contractArgs,
profileFile: this.profileFile, inputCacheFile: this.inputCacheFile,
processedCacheFile: this.processedCacheFile, environment: this.environment};
let queue = d3.queue(1);
queue.defer(this.extractData.bind(this), p);
queue.defer(this.contractData.bind(this), p);
queue.awaitAll(callback);
};
this.reprocess = (callback) => {
this.osmData.populate(() => {
this.isContracted((isContracted) => {
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.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);
});
});
});
let queue = d3.queue(1);
queue.defer(this.writeOSM.bind(this));
queue.defer(this.linkOSM.bind(this));
queue.defer(this.extractAndContract.bind(this));
queue.awaitAll(callback);
};
this.reprocessAndLoadData = (callback) => {
this.reprocess(() => {
this.OSRMLoader.load(util.format('%s.osrm', this.osmData.contractedFile), callback);
});
let queue = d3.queue(1);
queue.defer(this.writeOSM.bind(this));
queue.defer(this.linkOSM.bind(this));
queue.defer(this.extractAndContract.bind(this));
queue.defer(this.osrmLoader.load.bind(this.osrmLoader), this.processedCacheFile);
queue.awaitAll(callback);
};
this.processRowsAndDiff = (table, fn, callback) => {
@@ -351,7 +228,9 @@ module.exports = function () {
q.awaitAll((err, actual) => {
if (err) return callback(err);
this.diffTables(table, actual, {}, callback);
let diff = tableDiff(table, actual);
if (diff) callback(new Error(diff));
else callback();
});
};
};
+1 -39
View File
@@ -1,7 +1,6 @@
'use strict';
var util = require('util');
var path = require('path');
const util = require('util');
module.exports = {
Location: class {
@@ -11,43 +10,6 @@ module.exports = {
}
},
osmData: class {
constructor (scope) {
this.scope = scope;
this.str = null;
this.hash = null;
this.fingerprintOSM = null;
this.osmFile = null;
this.extractedFile = null;
this.contractedFile = null;
}
populate (callback) {
this.scope.OSMDB.toXML((str) => {
this.str = str;
this.hash = this.scope.hashString(str);
this.fingerprintOSM = this.scope.hashString(this.hash);
this.osmFile = path.resolve(this.scope.DATA_FOLDER, this.fingerprintOSM);
this.extractedFile = path.resolve([this.osmFile, this.scope.fingerprintExtract].join('_'));
this.contractedFile = path.resolve([this.osmFile, this.scope.fingerprintExtract, this.scope.fingerprintContract].join('_'));
callback();
});
}
reset () {
this.str = null;
this.hash = null;
this.fingerprintOSM = null;
this.osmFile = null;
this.extractedFile = null;
this.contractedFile = null;
}
},
FuzzyMatch: class {
match (got, want) {
var matchPercent = want.match(/(.*)\s+~(.+)%$/),
+63 -47
View File
@@ -1,32 +1,46 @@
var path = require('path');
var util = require('util');
var fs = require('fs');
var exec = require('child_process').exec;
var d3 = require('d3-queue');
'use strict';
const path = require('path');
const util = require('util');
const fs = require('fs');
const d3 = require('d3-queue');
const child_process = require('child_process');
const tryConnect = require('../lib/try_connect');
// Sets up all constants that are valid for all features
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) || 5000;
// set cucumber default timeout
this.setDefaultTimeout(this.TIMEOUT);
this.ROOT_FOLDER = process.cwd();
this.ROOT_PATH = process.cwd();
this.TEST_PATH = path.resolve(this.ROOT_PATH, 'test');
this.CACHE_PATH = path.resolve(this.TEST_PATH, 'cache');
this.LOGS_PATH = path.resolve(this.TEST_PATH, 'logs');
this.PROFILES_PATH = path.resolve(this.ROOT_PATH, 'profiles');
this.FIXTURES_PATH = path.resolve(this.ROOT_PATH, 'unit_tests/fixtures');
this.BIN_PATH = process.env.OSRM_BUILD_DIR && process.env.OSRM_BUILD_DIR || path.resolve(this.ROOT_PATH, 'build');
var stxxl_config = path.resolve(this.ROOT_PATH, 'test/.stxxl');
if (!fs.existsSync(stxxl_config)) {
return callback(new Error('*** '+stxxl_config+ 'does not exist'));
}
this.DEFAULT_ENVIRONMENT = Object.assign({STXXLCFG: stxxl_config}, process.env);
this.DEFAULT_PROFILE = 'bicycle';
this.DEFAULT_INPUT_FORMAT = 'osm';
this.DEFAULT_LOAD_METHOD = 'datastore';
this.DEFAULT_ORIGIN = [1,1];
this.OSM_USER = 'osrm';
this.OSM_GENERATOR = 'osrm-test';
this.OSM_UID = 1;
this.TEST_FOLDER = path.resolve(this.ROOT_FOLDER, 'test');
this.DATA_FOLDER = path.resolve(this.TEST_FOLDER, 'cache');
this.OSM_TIMESTAMP = '2000-01-01T00:00:00Z';
this.DEFAULT_SPEEDPROFILE = 'bicycle';
this.WAY_SPACING = 100;
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.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');
this.DEFAULT_GRID_SIZE = 100; // meters
this.OSRM_PORT = process.env.OSRM_PORT && parseInt(process.env.OSRM_PORT) || 5000;
this.HOST = 'http://127.0.0.1:' + this.OSRM_PORT;
// TODO make sure this works on win
if (process.platform.match(/indows.*/)) {
@@ -37,36 +51,49 @@ module.exports = function () {
} else {
this.TERMSIGNAL = 'SIGTERM';
this.EXE = '';
this.LIB = '.so';
// TODO autodetect if this was build with shared or static libraries
this.LIB = process.env.BUILD_SHARED_LIBS && '.so' || '.a';
this.QQ = '';
}
this.OSRM_EXTRACT_PATH = path.resolve(util.format('%s/%s%s', this.BIN_PATH, 'osrm-extract', this.EXE));
this.OSRM_CONTRACT_PATH = path.resolve(util.format('%s/%s%s', this.BIN_PATH, 'osrm-contract', this.EXE));
this.OSRM_ROUTED_PATH = path.resolve(util.format('%s/%s%s', this.BIN_PATH, 'osrm-routed', this.EXE));
this.LIB_OSRM_EXTRACT_PATH = util.format('%s/libosrm_extract%s', this.BIN_PATH, this.LIB),
this.LIB_OSRM_CONTRACT_PATH = util.format('%s/libosrm_contract%s', this.BIN_PATH, this.LIB),
this.LIB_OSRM_PATH = util.format('%s/libosrm%s', this.BIN_PATH, this.LIB);
// eslint-disable-next-line no-console
console.info(util.format('Node Version', process.version));
if (parseInt(process.version.match(/v(\d)/)[1]) < 4) throw new Error('*** PLease upgrade to Node 4.+ to run OSRM cucumber tests');
fs.exists(this.TEST_FOLDER, (exists) => {
if (!exists) throw new Error(util.format('*** Test folder %s doesn\'t exist.', this.TEST_FOLDER));
callback();
fs.exists(this.TEST_PATH, (exists) => {
if (exists)
return callback();
else
return callback(new Error('*** Test folder doesn\'t exist.'));
});
};
this.verifyOSRMIsNotRunning = () => {
if (this.OSRMLoader.up()) {
throw new Error('*** osrm-routed is already running.');
}
this.getProfilePath = (profile) => {
return path.resolve(this.PROFILES_PATH, profile + '.lua');
};
this.verifyOSRMIsNotRunning = (callback) => {
tryConnect(this.OSRM_PORT, (err) => {
if (!err) return callback(new Error('*** osrm-routed is already running.'));
else callback();
});
};
this.verifyExistenceOfBinaries = (callback) => {
var verify = (bin, cb) => {
var binPath = path.resolve(util.format('%s/%s%s', this.BIN_PATH, bin, this.EXE));
var verify = (binPath, cb) => {
fs.exists(binPath, (exists) => {
if (!exists) throw new Error(util.format('%s is missing. Build failed?', binPath));
if (!exists) return cb(new Error(util.format('%s is missing. Build failed?', binPath)));
var helpPath = util.format('%s --help > /dev/null 2>&1', binPath);
exec(helpPath, (err) => {
child_process.exec(helpPath, (err) => {
if (err) {
this.log(util.format('*** Exited with code %d', err.code), 'preprocess');
throw new Error(util.format('*** %s exited with code %d', helpPath, err.code));
return cb(new Error(util.format('*** %s exited with code %d', helpPath, err.code)));
}
cb();
});
@@ -74,23 +101,12 @@ module.exports = function () {
};
var q = d3.queue();
['osrm-extract', 'osrm-contract', 'osrm-routed'].forEach(bin => { q.defer(verify, bin); });
q.awaitAll(() => {
callback();
});
};
this.AfterConfiguration = (callback) => {
this.clearLogFiles(() => {
this.verifyOSRMIsNotRunning();
this.verifyExistenceOfBinaries(() => {
callback();
});
});
[this.OSRM_EXTRACT_PATH, this.OSRM_CONTRACT_PATH, this.OSRM_ROUTED_PATH].forEach(bin => { q.defer(verify, bin); });
q.awaitAll(callback);
};
process.on('exit', () => {
if (this.OSRMLoader.loader) this.OSRMLoader.shutdown(() => {});
this.osrmLoader.shutdown(() => {});
});
process.on('SIGINT', () => {
-132
View File
@@ -1,132 +0,0 @@
'use strict';
var util = require('util');
var path = require('path');
var fs = require('fs');
var chalk = require('chalk');
var OSRMError = class extends Error {
constructor (process, code, msg, log, lines) {
super(msg);
this.process = process;
this.code = code;
this.msg = msg;
this.lines = lines;
this.log = log;
}
extract (callback) {
this.logTail(this.log, this.lines, callback);
}
// toString (callback) {
// this.extract((tail) => {
// callback(util.format('*** %s\nLast %s from %s:\n%s\n', this.msg, this.lines, this.log, tail));
// });
// }
logTail (logPath, n, callback) {
var expanded = path.resolve(this.TEST_FOLDER, logPath);
fs.exists(expanded, (exists) => {
if (exists) {
fs.readFile(expanded, (err, data) => {
var lines = data.toString().trim().split('\n');
callback(lines
.slice(lines.length - n)
.map(line => util.format(' %s', line))
.join('\n'));
});
} else {
callback(util.format('File %s does not exist!', expanded));
}
});
}
};
var unescapeStr = (str) => str.replace(/\\\|/g, '\|').replace(/\\\\/g, '\\');
module.exports = {
OSRMError: OSRMError,
FileError: class extends OSRMError {
constructor (logFile, code, msg) {
super ('fileutil', code, msg, logFile, 5);
}
},
LaunchError: class extends OSRMError {
constructor (logFile, launchProcess, code, msg) {
super (launchProcess, code, msg, logFile, 5);
}
},
ExtractError: class extends OSRMError {
constructor (logFile, code, msg) {
super('osrm-extract', code, msg, logFile, 3);
}
},
ContractError: class extends OSRMError {
constructor (logFile, code, msg) {
super('osrm-contract', code, msg, logFile, 3);
}
},
RoutedError: class extends OSRMError {
constructor (logFile, msg) {
super('osrm-routed', null, msg, logFile, 3);
}
},
TableDiffError: class extends Error {
constructor (expected, actual) {
super();
this.headers = expected.raw()[0];
this.expected = expected.hashes();
this.actual = actual;
this.diff = [];
this.hasErrors = false;
var good = 0, bad = 0;
this.expected.forEach((row, i) => {
var rowError = false;
for (var j in row) {
if (unescapeStr(row[j]) != actual[i][j]) {
rowError = true;
this.hasErrors = true;
break;
}
}
if (rowError) {
bad++;
this.diff.push(Object.assign({}, row, {c_status: 'undefined'}));
this.diff.push(Object.assign({}, actual[i], {c_status: 'comment'}));
} else {
good++;
this.diff.push(row);
}
});
}
get string () {
if (!this.hasErrors) return null;
var s = ['Tables were not identical:'];
s.push(this.headers.map(key => ' ' + key).join(' | '));
this.diff.forEach((row) => {
var rowString = '| ';
this.headers.forEach((header) => {
if (!row.c_status) rowString += chalk.green(' ' + row[header] + ' | ');
else if (row.c_status === 'undefined') rowString += chalk.yellow('(-) ' + row[header] + ' | ');
else rowString += chalk.red('(+) ' + row[header] + ' | ');
});
s.push(rowString);
});
return s.join('\n') + '\nTODO this is a temp workaround waiting for https://github.com/cucumber/cucumber-js/issues/534';
}
}
};
-15
View File
@@ -1,15 +0,0 @@
var exceptions = require('./exception_classes');
module.exports = function () {
this.OSRMError = exceptions.OSRMError,
this.FileError = (code, msg) => new (exceptions.FileError.bind(exceptions.FileError, this.PREPROCESS_LOG_FILE))(code, msg);
this.LaunchError = (code, launchProcess, msg) => new (exceptions.LaunchError.bind(exceptions.LaunchError, this.ERROR_LOG_FILE))(code, launchProcess, msg);
this.ExtractError = (code, msg) => new (exceptions.ExtractError.bind(exceptions.ExtractError, this.PREPROCESS_LOG_FILE))(code, msg);
this.ContractError = (code, msg) => new (exceptions.ContractError.bind(exceptions.ContractError, this.PREPROCESS_LOG_FILE))(code, msg);
this.RoutedError = (msg) => new (exceptions.RoutedError.bind(exceptions.RoutedError, this.OSRM_ROUTED_LOG_FILE))(msg);
};
-43
View File
@@ -1,43 +0,0 @@
var fs = require('fs');
var path = require('path');
var crypto = require('crypto');
var d3 = require('d3-queue');
module.exports = function () {
this.hashOfFiles = (paths, cb) => {
paths = Array.isArray(paths) ? paths : [paths];
var shasum = crypto.createHash('sha1'), hashedFiles = false;
var q = d3.queue(1);
var addFile = (path, cb) => {
fs.readFile(path, (err, data) => {
if (err && err.code === 'ENOENT') cb(); // ignore non-existing files
else if (err) cb(err);
else {
shasum.update(data);
hashedFiles = true;
cb();
}
});
};
paths.forEach(path => { q.defer(addFile, path); });
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'));
});
};
this.hashProfile = (cb) => {
this.hashOfFiles(path.resolve(this.PROFILES_PATH, this.profile + '.lua'), cb);
};
this.hashString = (str) => {
return crypto.createHash('sha1').update(str).digest('hex');
};
return this;
};
+46 -26
View File
@@ -1,41 +1,61 @@
var util = require('util');
'use strict';
var d3 = require('d3-queue');
var path = require('path');
var mkdirp = require('mkdirp');
var rimraf = require('rimraf');
var OSM = require('../lib/osm');
var OSRMLoader = require('../lib/osrm_loader');
module.exports = function () {
this.BeforeFeatures((features, callback) => {
this.pid = null;
this.initializeEnv(() => {
this.initializeOptions(callback);
});
this.registerHandler('BeforeFeatures', {timeout: 30000}, (features, callback) => {
this.osrmLoader = new OSRMLoader(this);
this.OSMDB = new OSM.DB();
let queue = d3.queue(1);
queue.defer(this.initializeEnv.bind(this));
queue.defer(this.verifyOSRMIsNotRunning.bind(this));
queue.defer(this.verifyExistenceOfBinaries.bind(this));
queue.defer(this.initializeCache.bind(this));
queue.defer(this.setupFeatures.bind(this, features));
queue.awaitAll(callback);
});
this.BeforeFeature((feature, callback) => {
this.profile = this.DEFAULT_PROFILE;
this.profileFile = path.join(this.PROFILES_PATH, this.profile + '.lua');
this.setupFeatureCache(feature);
callback();
});
this.Before((scenario, callback) => {
this.scenarioTitle = scenario.getName();
this.loadMethod = this.DEFAULT_LOAD_METHOD;
this.queryParams = {};
var d = new Date();
this.scenarioTime = util.format('%d-%d-%dT%s:%s:%sZ', d.getFullYear(), d.getMonth()+1, d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds());
this.resetData();
this.hasLoggedPreprocessInfo = false;
this.hasLoggedScenarioInfo = false;
this.osrmLoader.setLoadMethod(this.DEFAULT_LOAD_METHOD);
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();
this.queryParams = {};
this.extractArgs = '';
this.contractArgs = '';
this.environment = Object.assign(this.DEFAULT_ENVIRONMENT);
this.resetOSM();
this.scenarioID = this.getScenarioID(scenario);
this.setupScenarioCache(this.scenarioID);
// setup output logging
let logDir = path.join(this.LOGS_PATH, this.featureID);
this.scenarioLogFile = path.join(logDir, this.scenarioID) + '.log';
d3.queue(1)
.defer(mkdirp, logDir)
.defer(rimraf, this.scenarioLogFile)
.awaitAll(callback);
});
this.After((scenario, callback) => {
this.setExtractArgs('', () => {
this.setContractArgs('', () => {
if (this.loadMethod === 'directly' && !!this.OSRMLoader.loader) this.OSRMLoader.shutdown(callback);
else callback();
});
});
this.resetOptionsOutput();
callback();
});
this.Around('@stress', (scenario, callback) => {
// TODO implement stress timeout? Around support is being dropped in cucumber-js anyway
this.AfterFeatures((features, callback) => {
callback();
});
};

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