Compare commits

..

173 Commits

Author SHA1 Message Date
Patrick Niklaus f04377abff Update changelog 2016-10-10 12:31:26 +02:00
Patrick Niklaus e82f678665 Use a shared (!) reader writer lock to protect CURRENT_REGIONS
This fixes issue #3016.
2016-10-10 12:26:14 +02:00
Daniel J. Hofmann 4db1b7bea5 Implements Cucumber shared vs. static library detection, fixes #2999 2016-10-04 14:15:37 +02:00
Daniel J. Hofmann 32c5f14ed3 Makes the OSRM interface threadsafe.
Technically speaking we're changing the `libosrm` API.

But since we're only lifting restrictions by marking the API threadsafe,
we should be fine here.
2016-10-04 09:38:51 +02:00
Daniel J. Hofmann cbd88c63b9 Re-introduces the old RouteParameters ctor for API compatibility, see #2978 2016-10-03 20:02:11 +02:00
Daniel J. Hofmann 621e302a38 Disables ld.gold on binutils < 2.26, resolves #2984 2016-10-03 15:47:29 +02:00
Moritz Kobitzsch 1db794b2cb prepare 5.4.0-rc.7 2016-09-30 14:48:32 +02:00
Moritz Kobitzsch a1ccedb5bf re-introduce space into summaries 2016-09-30 14:46:34 +02:00
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
244 changed files with 9453 additions and 4532 deletions
+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?
+3 -23
View File
@@ -13,6 +13,7 @@ notifications:
branches:
only:
- master
- 5.4
cache:
ccache: true
@@ -24,7 +25,7 @@ env:
global:
- CCACHE_TEMPDIR=/tmp/.ccache-temp
- CCACHE_COMPRESS=1
- CASHER_TIME_OUT=1000
- 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,14 +43,6 @@ 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='Debug' COVERAGE=ON
- os: linux
compiler: "gcc-4.8-debug"
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', 'ccache']
env: CCOMPILER='gcc-4.8' CXXCOMPILER='g++-4.8' BUILD_TYPE='Debug'
- os: linux
compiler: "clang-3.8-debug"
addons: &clang38
@@ -76,19 +69,6 @@ matrix:
compiler: "gcc-5-release-i686"
env: TARGET_ARCH='i686' CCOMPILER='gcc-5' CXXCOMPILER='g++-5' BUILD_TYPE='Release'
- os: linux
compiler: "gcc-4.8-release-armhf"
env: TARGET_ARCH='armhf' CCOMPILER='arm-linux-gnueabihf-gcc-4.8' CXXCOMPILER='arm-linux-gnueabihf-g++-4.8' BUILD_TYPE='Release'
# Disabled because of CI slowness
#- os: linux
#- compiler: gcc
#- 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'
# Disabled because of CI slowness
#- os: linux
#- compiler: clang
@@ -151,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}
+70 -3
View File
@@ -1,5 +1,72 @@
# 5.4.1
- Changes from 5.4.0
- Bugfixes
- #3016: Fixes shared memory updates while queries are running
# 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.4.0-rc.7
- Chages from 5.4.0-rc.6
- Bugfixes re-introduce space between two entries in summaries
# 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.3.0
Changes from 5.3.0-rc.3
- 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.
@@ -7,7 +74,7 @@
- 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
- 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
@@ -31,7 +98,7 @@
- Fix devide by zero on updating speed data using osrm-contract
# 5.3.0 RC3
Changes from 5.3.0-rc.2
- Changes from 5.3.0-rc.2
- Guidance
- Improved detection of obvious turns
- Improved turn lane detection
+41 -5
View File
@@ -9,7 +9,7 @@ endif()
project(OSRM C CXX)
set(OSRM_VERSION_MAJOR 5)
set(OSRM_VERSION_MINOR 3)
set(OSRM_VERSION_MINOR 4)
set(OSRM_VERSION_PATCH 0)
# these two functions build up custom variables:
@@ -54,6 +54,8 @@ 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/)
@@ -115,6 +117,26 @@ 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.26")
message(STATUS "Disabling gc-sections on gold binutils < 2.26, 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
@@ -205,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
@@ -220,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
@@ -244,6 +266,7 @@ 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)
@@ -416,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)
@@ -498,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 ()
+5
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).
+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'
}
+41 -8
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.
@@ -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
@@ -414,11 +422,35 @@ With `steps=false` and `annotations=true`:
"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,6 +469,7 @@ 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.
@@ -505,7 +538,7 @@ step.
| `use lane` | going straight on a specific lane |
| `continue` | Turn in direction of `modifier` to stay on the same road |
| `roundabout` | traverse roundabout, has additional field `exit` with NR if the roundabout is left. `the modifier specifies the direction of entering the roundabout` |
| `rotary` | a larger version of a roundabout, can offer `rotary_name` in addition to the `exit` parameter. |
| `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 |
@@ -591,7 +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 turn location
- `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
```
+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
+3 -7
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)
{
@@ -34,7 +34,7 @@ int main(int argc, const char *argv[]) try
config.use_shared_memory = false;
// Routing machine with several services (such as Route, Table, Nearest, Trip, Match)
OSRM osrm{config};
const OSRM osrm{config};
// The following shows how to use the Route service; configure this service
RouteParameters params;
@@ -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;
}
+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
+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
+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 |
+44 -4
View File
@@ -149,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
@@ -430,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
+14 -14
View File
@@ -33,19 +33,19 @@ Feature: Traffic - turn penalties
| 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,def,def | 57 km/h | 12.5s +-1 |
| a | e | ad,def,def | 43 km/h | 16.7s +-1 |
# left
| 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,klm,klm | 60 km/h | 24s +-1 |
| a | l | ad,dhk,klm,klm | 51 km/h | 28.1s +-1 |
# straight-left
| l | e | klm,dhk,def,def | 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
@@ -53,12 +53,12 @@ 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 |
@@ -71,17 +71,17 @@ Feature: Traffic - turn penalties
# double straight
| p | g | mp,fim,fg,fg | 59 km/h | 24.5s +-1 |
# straight-right - ifg penalty
| a | l | ad,def,fim,klm,klm | 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 | klm,fim,def,def | 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,klm,fim,def,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 -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 |
+279 -62
View File
@@ -135,9 +135,9 @@ Feature: Turn Lane Guidance
| cj | | 1 | motorway_link | yes | xbcj |
When I route I should get
| waypoints | route | turns | lanes |
| a,i | ab,xbcj,ci,ci | depart,merge slight left,turn slight right,arrive | ,,none:false slight right:true, |
| a,j | ab,xbcj,xbcj | depart,merge slight left,arrive | ,, |
| 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
@@ -257,9 +257,172 @@ Feature: Turn Lane Guidance
When I route I should get
| waypoints | route | turns | lanes |
| a,f | abx,bcy,cdz,dew,ef,ef | depart,turn right,turn left,turn right,turn left,arrive | ,straight:false right:false right:true right:false,left:false left:true straight:false,straight:false right:true right:false,left:true straight:false, |
| 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 @todo @bug @2661
@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 | | |
@@ -271,20 +434,20 @@ Feature: Turn Lane Guidance
| | | i | | |
And the ways
| nodes | turn:lanes:forward | highway | junction | # |
| 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 | | |
| 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 |
@@ -301,20 +464,20 @@ Feature: Turn Lane Guidance
| | | c | | |
And the ways
| nodes | turn:lanes:forward | highway | junction |
| ab | | primary | |
| bc | | primary | roundabout |
| 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 | |
| de | | primary | roundabout |
| eb | | primary | roundabout |
| df | | primary | |
When I route I should get
| waypoints | route | turns | lanes |
| a,f | ab,df,df | depart,roundabout-exit-1,use lane slight right,arrive | ,,slight left:false slight left:false slight right:true, |
@anticipate
Scenario: Anticipate with lanes in roundabout where we stay on the roundabout for multiple exits
Scenario: No Lanes for Roundabouts, see #2626
Given the node map
| | | a | | |
| | | b | | |
@@ -331,7 +494,7 @@ Feature: Turn Lane Guidance
| cd | | primary | roundabout |
| de | | primary | roundabout |
| ef | | primary | roundabout |
| fg | slight_right | primary | roundabout |
| fg | through\|slight_right | primary | roundabout |
| gb | | primary | roundabout |
| gh | | primary | |
| cx | | primary | |
@@ -340,11 +503,11 @@ Feature: Turn Lane Guidance
| fy | | primary | |
When I route I should get
| waypoints | route | turns | lanes |
| a,h | ab,gh,gh | depart,roundabout-exit-5,arrive | ,slight right:false slight right:true, |
| waypoints | route | turns | lanes |
| a,h | ab,gh,gh | depart,roundabout-exit-5,arrive | ,, |
@anticipate
Scenario: Departing or arriving inside a roundabout does not yet anticipate lanes
Scenario: No Lanes for Roundabouts, see #2626
Given the node map
| | | a | | |
| x | b | | d | y |
@@ -360,13 +523,44 @@ Feature: Turn Lane Guidance
| da | | primary | roundabout | roundabout |
When I route I should get
| waypoints | route | turns | lanes |
| x,y | xb,dy,dy | depart,roundabout-exit-1,arrive | ,slight right:false slight right:true, |
| x,c | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,slight right:true slight right:true, |
| x,a | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,slight right:true slight right:true, |
| 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: Departing or arriving inside a roundabout does not yet anticipate lanes (BIG version)
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 |
@@ -416,13 +610,13 @@ Feature: Turn Lane Guidance
| da | | primary | roundabout | roundabout |
When I route I should get
| waypoints | route | turns | lanes |
| x,y | xb,dy,dy | depart,roundabout-exit-1,arrive | ,slight right:false slight right:true, |
| x,c | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,slight right:true slight right:true, |
| x,a | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,slight right:true slight right:true, |
| 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: Anticipate Lanes for turns before and / or after roundabout
@anticipate @todo @2032
Scenario: No Lanes for Roundabouts, see #2626
Given the node map
| a | b | | | x |
| | c | | | |
@@ -432,25 +626,48 @@ Feature: Turn Lane Guidance
| | 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 |
| nodes | turn:lanes:forward | highway | junction | name |
| ab | through\|right\|right\|right\|right | primary | | abx |
| bx | | primary | | abx |
| bc | right\|right\|right\|right | primary | | bc |
| cd | | primary | roundabout | cdefc |
| de | slight_left\|slight_left\|slight_left\|slight_right | primary | roundabout | cdefc |
| ef | left\|slight_right\|slight_right | primary | roundabout | cdefc |
| fc | | primary | roundabout | cdefc |
| ey | | primary | | ey |
| fg | through\|right | primary | | fg |
| gz | | primary | | gz |
| gh | | primary | | gh |
When I route I should get
| waypoints | route | turns | lanes |
| a,h | abx,bc,fg,gh,gh | depart,turn right,cdefc-exit-2,turn right,arrive | ,straight:false right:false right:false right:false right:true,right:false right:false right:false right:true,straight:false right:true, |
| 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 @bug @todo
Scenario: Tripple Right keeping Left
@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 |
| | | | | | | |
@@ -470,11 +687,11 @@ Feature: Turn Lane Guidance
| feg | | tertiary | fourth |
When I route I should get
| waypoints | route | turns | lanes |
| a,f | start,first,second,third,fourth,fourth | depart,turn right,turn right,turn right,end of road left,arrive | ,none:false none:true right:false right:false,none:false none:true right:false right:false,none:false none:true right:false right:false,left:true right:false right:false, |
| a,g | start,first,second,third,fourth,fourth | depart,turn right,turn right,turn right,end of road right,arrive | ,none:false none:false right:true right:true,none:false none:false right:true right:true,none:false none:false right:true right:true,left:false right:true right:true, |
| 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 @bug @todo
@anticipate
Scenario: Tripple Left keeping Right
Given the node map
| i | | b | | | | a |
@@ -495,6 +712,6 @@ Feature: Turn Lane Guidance
| feg | | tertiary | fourth |
When I route I should get
| waypoints | route | turns | lanes |
| a,f | start,first,second,third,fourth,fourth | depart,turn left,turn left,turn left,end of road right,arrive | ,left:false left:false none:true none:false,left:false left:false none:true none:false,left:false left:false none:true none:false,left:false left:false right:true, |
| a,g | start,first,second,third,fourth,fourth | depart,turn left,turn left,turn left,end of road left,arrive | ,left:true left:true none:false none:false,left:true left:true none:false none:false,left:true left:true none:false none:false,left:true left:true right:false, |
| 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 |
+244 -36
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,12 +352,12 @@ 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 |
@@ -383,13 +402,13 @@ Feature: Collapse
Scenario: Pankenbruecke
Given the node map
| h | | | | | | i | | | | | | |
| | | b | c | d | e | f | | | | | | g |
| a | | | | | | | | | | | | |
| j | | | | h | | | | | | i | | | | | | |
| | | | | | | b | c | d | e | f | | | | | | g |
| k | | | | a | | | | | | | | | | | | |
And the ways
| nodes | highway | name | oneway |
| abh | primary | inroad | yes |
| kabhj | primary | inroad | yes |
| bc | primary | inroad | no |
| cd | primary | bridge | no |
| defg | primary | outroad | no |
@@ -506,6 +525,36 @@ Feature: Collapse
| 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 |
@@ -571,26 +620,28 @@ Feature: Collapse
| bd | road | yes | primary |
| bc | road | yes | primary |
| de | road | yes | primary |
| fdcg | cross | no | secondary |
| 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 | fdcg | d | no_left_turn |
| restriction | bc | fdcg | c | no_right_turn |
| 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 |
| 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 |
| | | | | | g | | |
| | | | | | | | |
| | | | | | c | | |
| a | | | b | | | | |
| | | | | | | d | |
| | | | | | | f | e |
And the ways
| nodes | name | oneway | highway |
@@ -598,12 +649,14 @@ Feature: Collapse
| bd | road | yes | primary |
| bc | road | yes | primary |
| de | road | yes | primary |
| fdcg | cross | no | secondary |
| 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 | fdcg | d | no_left_turn |
| restriction | bc | fdcg | c | no_right_turn |
| restriction | bd | dc | d | no_left_turn |
| restriction | bc | dc | c | no_right_turn |
When I route I should get
| waypoints | route | turns |
@@ -630,3 +683,158 @@ Feature: Collapse
| 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 |
+186 -4
View File
@@ -52,8 +52,8 @@ 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
@@ -165,5 +165,187 @@ Feature: Slipways and Dedicated Turn Lanes
| qe | secondary_link | Ettlinger Allee | | yes |
When I route I should get
| waypoints | route | turns |
| a,o | Schwarzwaldstrasse (L561),Ettlinger Allee,Ettlinger Allee | depart,turn right,arrive |
| 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 | , | |
+3 -3
View File
@@ -311,6 +311,6 @@ Feature: Fork Instructions
| ab | on | motorway_link |
When I route I should get
| waypoints | route | turns |
| a,j | on,xbcj,xbcj | depart,merge slight left,arrive |
| a,i | on,xbcj,off,off | depart,merge slight left,turn slight right,arrive |
| waypoints | route | turns |
| a,j | on,xbcj | depart,arrive |
| a,i | on,off,off | depart,turn slight right,arrive |
+59 -19
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,15 +50,37 @@ 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 | |
| | | | | | | |
| | | | | | | |
@@ -71,6 +96,21 @@ Feature: Merging
| fd | residential | in |
When I route I should get
| waypoints | turns | route |
| f,e | depart,merge slight left,arrive | in,road,road |
| f,a | depart,turn sharp left,arrive | in,road,road |
| 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 |
+173 -4
View File
@@ -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 |
@@ -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 |
+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 |
+76 -149
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,87 +268,6 @@ 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
Given the node map
| a | | |
| b | | |
| c | d | f |
| e | | |
And the ways
| nodes | junction |
| ab | |
| bcdb | roundabout |
| ce | |
| df | |
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 |
Scenario: Collinear in X,Y
Given the node map
| a | | |
| d | | |
| b | c | f |
| e | | |
And the ways
| nodes | junction |
| ad | |
| bcdb | roundabout |
| be | |
| cf | |
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 |
Scenario: Collinear in X,Y
Given the node map
| a | | |
| c | | |
| d | b | f |
| e | | |
And the ways
| nodes | junction |
| ac | |
| bcdb | roundabout |
| de | |
| bf | |
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 |
Scenario: Motorway Roundabout
#See 39.933742 -75.082345
Given the node map
@@ -395,9 +302,9 @@ Feature: Basic Roundabout
| dmg | roundabout | | trunk_link | yes | |
When I route I should get
| waypoints | route | turns |
| a,e | crescent (US 130),crescent (US 130),crescent (US 130) | depart,roundabout-exit-3,arrive |
| j,l | NJ 38,NJ 38,NJ 38 | depart,roundabout-exit-2,arrive |
| 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: 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
@@ -438,41 +345,61 @@ Feature: Basic Roundabout
| waypoints | route | turns |
| a,k | massachusetts,massachusetts,massachusetts,massachusetts | depart,sheridan circle-exit-2,dupont circle-exit-1,arrive |
Scenario: Enter and Exit - Traffic Signals
#2856 - http://www.openstreetmap.org/#map=19/47.23318/-1.56563
Scenario: Linked Roundabouts
Given the node map
| | | a | | |
| | i | b | l | |
| h | g | | c | d |
| | j | e | k | |
| | | f | | |
| | | | | | | | | | | | | | 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 nodes
| node | highway |
| i | traffic_signals |
| j | traffic_signals |
| k | traffic_signals |
| l | traffic_signals |
And the ways
| 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 ways
| nodes | junction |
| ab | |
| cd | |
| ef | |
| gh | |
| bigjekclb | roundabout |
And the nodes
| node | highway |
| c | give_way |
| h | give_way |
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 |
When I route I should get
| 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 |
+299 -31
View File
@@ -5,7 +5,7 @@ Feature: Turn Lane Guidance
Given the profile "car"
Given a grid size of 20 meters
@bug
@simple
Scenario: Basic Turn Lane 3-way Turn with empty lanes
Given the node map
| a | | b | | c |
@@ -24,6 +24,23 @@ Feature: Turn Lane Guidance
| c,a | straight,in,in | depart,new name straight,arrive | ,left:false straight:true none:true none:true, |
| c,d | straight,right,right | depart,turn left,arrive | ,left:true straight:false none:false none:false, |
Scenario: Basic Turn Lane 3-way Turn with designated lane
Given the node map
| a | | b | | c |
| | | d | | |
And the ways
| nodes | turn:lanes | turn:lanes:forward | name | vehicle:lanes:forward |
| ab | | through\|through\|right | in | yes\|no\|yes |
| bc | | | straight | |
| bd | | | right | |
When I route I should get
| waypoints | route | turns | lanes |
| a,c | in,straight,straight | depart,new name straight,arrive | ,straight:true right:false, |
| a,d | in,right,right | depart,turn right,arrive | ,straight:false right:true, |
@simple
Scenario: Basic Turn Lane 4-Way Turn
Given the node map
| | | e | | |
@@ -46,6 +63,7 @@ Feature: Turn Lane Guidance
| d,e | right,left,left | depart,new name straight,arrive | ,left:false none:true, |
| d,c | right,straight,straight | depart,turn right,arrive | ,left:false none:true, |
@simple @none
Scenario: Basic Turn Lane 4-Way Turn using none
Given the node map
| | | e | | |
@@ -65,6 +83,7 @@ Feature: Turn Lane Guidance
| a,d | in,right,right | depart,turn right,arrive | ,none:false right:true, |
| a,e | in,left,left | depart,turn left,arrive | ,none:true right:false, |
@simple @reverse
Scenario: Basic Turn Lane 4-Way With U-Turn Lane
Given the node map
| | | e | | |
@@ -87,6 +106,7 @@ Feature: Turn Lane Guidance
#this next test requires decision on how to announce lanes for going straight if there is no turn
@simple @psv @none
Scenario: Turn with Bus-Lane
Given the node map
| a | | b | | c |
@@ -104,7 +124,44 @@ Feature: Turn Lane Guidance
| a,d | road,turn,turn | depart,turn right,arrive | ,straight:false right:true, |
| a,c | road,road | depart,arrive | , |
@PROFILE @LANES
Scenario: Turn with Bus-Lane Left
Given the node map
| | | d | | | | |
| | | | | | | |
| a | | b | | c | | f |
| | | | | e | | |
And the ways
| nodes | name | turn:lanes:forward | lanes:psv:forward | oneway |
| ab | road | left\|through\| | 1 | yes |
| bc | road | | | yes |
| bd | turn | | | yes |
| cf | turn | | | yes |
| ce | side | | | yes |
When I route I should get
| waypoints | route | turns | lanes |
| a,d | road,turn,turn | depart,turn left,arrive | ,left:true straight:false, |
| a,c | road,road | depart,arrive | , |
# This tests whether empty/invalid PSV tags cause osrm-extract to crash
Scenario: Turn with Bus-Lane
Given the node map
| a | | b | | c |
| | | | | |
| | | d | | |
And the ways
| nodes | name | turn:lanes:forward | lanes:psv:forward | lanes:psv:backward |
| ab | road | through\|right\| | 1 | foo |
| bc | road | | | |
| bd | turn | | | |
When I route I should get
| waypoints | route | turns | lanes |
| a,d | road,turn,turn | depart,turn right,arrive | ,straight:false right:true, |
@simple @psv
Scenario: Turn with Bus-Lane but without lanes
Given the node map
| a | | b | | c |
@@ -123,7 +180,7 @@ Feature: Turn Lane Guidance
| a,c | road,road | depart,arrive |
#turn lanes are often drawn at the incoming road, even though the actual turn requires crossing the intersection first
@todo @bug
@todo @collapse @partition-lanes
Scenario: Turn Lanes at Segregated Road
Given the node map
| | | i | l | | |
@@ -168,6 +225,7 @@ Feature: Turn Lane Guidance
| i,l | cross,cross,cross | depart,continue uturn,arrive | ,left:true straight:false, |
#copy of former case to prevent further regression
@collapse @partition-lanes
Scenario: Turn Lanes at Segregated Road
Given the node map
| | | i | l | | |
@@ -201,6 +259,7 @@ Feature: Turn Lane Guidance
| i,j | cross,cross | depart,arrive | , |
| i,l | cross,cross,cross | depart,continue uturn,arrive | ,left:true straight:false, |
@partition-lanes
Scenario: Turn Lanes at Segregated Road
Given the node map
| | | g | f | | |
@@ -223,6 +282,7 @@ Feature: Turn Lane Guidance
| a,j | road,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true, |
#this can happen due to traffic lights / lanes not drawn up to the intersection itself
@2654 @previous-lanes
Scenario: Turn Lanes Given earlier than actual turn
Given the node map
| a | | b | c | | d |
@@ -241,6 +301,7 @@ Feature: Turn Lane Guidance
| a,e | road,turn,turn | depart,turn right,arrive | ,none:false right:true, |
| a,d | road,road | depart,arrive | , |
@2654 @previous-lanes
Scenario: Turn Lanes Given earlier than actual turn
Given the node map
| a | | b | c | d | | e | | f | g | h | | i |
@@ -263,6 +324,7 @@ Feature: Turn Lane Guidance
| i,j | road,first-turn,first-turn | depart,turn left,arrive | ,left:true none:false, |
| i,a | road,road | depart,arrive | , |
@previous-lanes
Scenario: Passing a one-way street
Given the node map
| e | | | f | |
@@ -279,6 +341,7 @@ Feature: Turn Lane Guidance
| waypoints | route | turns | lanes |
| a,f | road,turn,turn | depart,turn left,arrive | ,left:true straight:false, |
@partition-lanes
Scenario: Passing a one-way street, partly pulled back lanes
Given the node map
| e | | | f | |
@@ -296,8 +359,10 @@ Feature: Turn Lane Guidance
When I route I should get
| waypoints | route | turns | lanes |
| a,f | road,turn,turn | depart,turn left,arrive | ,left:true straight;right:false, |
| a,d | road,road | depart,arrive | , |
| a,g | road,right,right | depart,turn right,arrive | ,left:false straight;right:true, |
@partition-lanes @previous-lanes
Scenario: Passing a one-way street, partly pulled back lanes, no through
Given the node map
| e | | | f |
@@ -317,7 +382,7 @@ Feature: Turn Lane Guidance
| a,f | road,turn,turn | depart,turn left,arrive | ,left:true right:false, |
| a,g | road,right,right | depart,turn right,arrive | ,left:false right:true, |
@todo @bug
@todo @partition-lanes @previous-lanes
Scenario: Narrowing Turn Lanes
Given the node map
| | | | | g | |
@@ -340,6 +405,7 @@ Feature: Turn Lane Guidance
| a,e | road,through,through | depart,new name straight,arrive | ,left:false straight:true right:false, |
| a,f | road,right,right | depart,turn right,arrive | ,left:false straight:false right:true, |
@previous-lanes
Scenario: Turn at a traffic light
Given the node map
| a | b | c | d |
@@ -361,7 +427,7 @@ Feature: Turn Lane Guidance
| a,d | road,road | depart,arrive | , |
| a,e | road,turn,turn | depart,turn right,arrive | ,straight:false right:true, |
@bug @todo
@todo @roundabout
Scenario: Theodor Heuss Platz
Given the node map
| | | | i | o | | | l | |
@@ -398,6 +464,7 @@ Feature: Turn Lane Guidance
| i,l | top,top-right-out,top-right-out | depart,roundabout-exit-4,arrive | ,slight left:true slight left;slight right:true slight right:false slight right:false, |
| i,o | top,top,top | depart,roundabout-exit-5,arrive | ,, |
@sliproads
Scenario: Turn Lanes Breaking up
Given the node map
| | | | g | |
@@ -408,30 +475,34 @@ Feature: Turn Lane Guidance
| | | | f | |
And the ways
| nodes | name | turn:lanes:forward | oneway | highway |
| ab | road | left\|left\|through\|through | yes | primary |
| bd | road | through\|through | yes | primary |
| bc | road | left\|left | yes | primary |
| de | road | | yes | primary |
| fdcg | cross | | | secondary |
| nodes | name | turn:lanes:forward | oneway | highway |
| ab | road | left\|left\|through\|through\|right | yes | primary |
| bd | road | through\|through\|right | yes | primary |
| bc | road | left\|left | yes | primary |
| de | road | | yes | primary |
| fd | cross | | | secondary |
| dc | cross | | | secondary |
| cg | cross | | | secondary |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | bd | fdcg | d | no_left_turn |
| restriction | bc | fdcg | c | no_right_turn |
| restriction | bd | dc | d | no_left_turn |
| restriction | bc | dc | c | no_right_turn |
When I route I should get
| waypoints | route | turns | lanes |
| a,g | road,cross,cross | depart,turn left,arrive | ,left:true left:true straight:false straight:false, |
| a,e | road,road | depart,arrive | , |
| waypoints | route | turns | lanes |
| a,g | road,cross,cross | depart,turn left,arrive | ,left:true left:true straight:false straight:false right:false, |
| a,e | road,road | depart,arrive | , |
#NEEDS TO BE INVESTIGATED. Turn restriction shouldn't be here. See #2867
@reverse @previous-lanes
Scenario: U-Turn Road at Intersection
Given the node map
| | | | | | h | |
| | | | | f | e | j |
| a | b | | | | | |
| | | | | c | d | i |
| | | | | | g | |
| | | | | | | h | |
| | | | | f | | e | j |
| a | b | | | | | | |
| | | | | c | | d | i |
| | | | | | | g | |
And the ways
| nodes | name | turn:lanes:forward | oneway | highway |
@@ -440,16 +511,25 @@ Feature: Turn Lane Guidance
| bc | road | \|through\|right | yes | primary |
| cd | road | \|through\|right | yes | primary |
| fc | road | | no | tertiary |
| jefb | road | | yes | primary |
| gdeh | cross | | no | primary |
| je | road | | yes | primary |
| ef | road | | yes | primary |
| fb | road | | yes | primary |
| eh | cross | | no | primary |
| de | cross | | no | primary |
| gd | cross | | no | primary |
When I route I should get
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | de | ef | e | no_left_turn |
When I route I should get
| from | to | bearings | route | turns | lanes |
| a | g | 180,180 180,180 | road,cross,cross | depart,turn right,arrive | ,none:false straight:false right:true, |
| a | h | 180,180 180,180 | road,cross,cross | depart,turn left,arrive | ,none:true straight:false right:false, |
| a | i | 180,180 180,180 | road,road | depart,arrive | , |
| b | a | 90,2 270,2 | road,road,road | depart,continue uturn,arrive | ,none:true straight:false right:false, |
@reverse
Scenario: Segregated Intersection Merges With Lanes
Given the node map
| | | | | | | f |
@@ -474,7 +554,7 @@ Feature: Turn Lane Guidance
| a,e | road,road,road | depart,turn uturn,arrive | ,left:true left:false left:false straight:false straight:false, |
| a,g | road,straight,straight | depart,new name straight,arrive | ,left:false left:false left:false straight:true straight:true, |
@bug @todo
@todo @roundabout
Scenario: Passing Through a Roundabout
Given the node map
| | | h | | g | | |
@@ -501,6 +581,7 @@ Feature: Turn Lane Guidance
| i,j | left,bottom,bottom | depart,round-exit-1,arrive | ,0, |
| i,k | left,right,right | depart,round-exit-2,arrive | ,1, |
@previous-lanes
Scenario: Crossing Traffic Light
Given the node map
| a | | b | | c | | d |
@@ -521,6 +602,7 @@ Feature: Turn Lane Guidance
| a,d | road,road | depart,arrive | , |
| a,e | road,cross,cross | depart,turn slight right,arrive | ,straight:false straight:false straight;slight right:true slight right:true, |
@ramp
Scenario: Highway Ramp
Given the node map
| a | | b | | c | | d |
@@ -537,7 +619,7 @@ Feature: Turn Lane Guidance
| a,d | hwy,hwy | depart,arrive | , |
| a,e | hwy,ramp,ramp | depart,off ramp slight right,arrive | ,straight:false straight:false straight;slight right:true slight right:true, |
@bug @todo
@todo
Scenario: Turning Off Ramp
Given the node map
| | a | |
@@ -559,6 +641,7 @@ Feature: Turn Lane Guidance
| a,g | off,road,road | depart,turn_left,arrive | ,left:true right:false, |
| a,h | | | |
@ramp
Scenario: Off Ramp In a Turn
Given the node map
| a | | | | | | | | | | | |
@@ -577,6 +660,7 @@ Feature: Turn Lane Guidance
| a,c | hwy,hwy | depart,arrive | , |
| a,d | hwy,ramp,ramp | depart,off ramp slight right,arrive | ,straight:false straight:false slight right:true, |
@reverse
Scenario: Reverse Lane in Segregated Road
Given the node map
| h | | | | | g | | | | | | f |
@@ -595,6 +679,7 @@ Feature: Turn Lane Guidance
| waypoints | route | turns | lanes |
| a,h | road,road,road | depart,continue uturn,arrive | ,uturn:true straight:false straight:false,|
@reverse
Scenario: Reverse Lane in Segregated Road with none
Given the node map
| h | | | | | g | | | | | | f |
@@ -613,6 +698,7 @@ Feature: Turn Lane Guidance
| waypoints | route | turns | lanes |
| a,h | road,road,road | depart,continue uturn,arrive | ,uturn:true straight:false none:false, |
@reverse
Scenario: Reverse Lane in Segregated Road with none, Service Turn Prior
Given the node map
| h | | | | | g | | | | | | f |
@@ -633,6 +719,7 @@ Feature: Turn Lane Guidance
| waypoints | route | turns | lanes |
| a,h | road,road,road | depart,continue uturn,arrive | ,uturn:true straight:false none:false, |
@simple
Scenario: Don't collapse everything to u-turn / too wide
Given the node map
| a | | b | | e |
@@ -652,6 +739,7 @@ Feature: Turn Lane Guidance
| a,d | depart,continue right,turn right,arrive | road,road,road,road | ,straight:false right:true,, |
| d,a | depart,continue left,turn left,arrive | road,road,road,road | ,left:true straight:false,, |
@simple
Scenario: Merge Lanes Onto Freeway
Given the node map
| a | | | b | c |
@@ -666,6 +754,7 @@ Feature: Turn Lane Guidance
| waypoints | turns | route | lanes |
| d,c | depart,merge slight left,arrive | ramp,Hwy,Hwy | ,slight right:true slight right:true, |
@2654 @simple
Scenario: Fork on motorway links - don't fork on through but use lane
Given the node map
| i | | | | | a |
@@ -680,9 +769,9 @@ Feature: Turn Lane Guidance
| ab | on | motorway_link | |
When I route I should get
| waypoints | route | turns | lanes |
| a,j | on,xbcj,xbcj | depart,merge slight left,arrive | ,, |
| a,i | on,xbcj,off,off | depart,merge slight left,turn slight right,arrive | ,,none:false slight right:true, |
| waypoints | route | turns | lanes |
| a,j | on,xbcj | depart,arrive | , |
| a,i | on,off,off | depart,turn slight right,arrive | ,none:false slight right:true, |
#http://www.openstreetmap.org/#map=17/52.47414/13.35712
@todo @ramp @2645
@@ -724,8 +813,8 @@ Feature: Turn Lane Guidance
And the ways
| nodes | name | highway | turn:lanes:forward |
| ab | road | primary | through,right |
| bc | road | primary | through,right |
| ab | road | primary | through;right |
| bc | road | primary | through;right |
| cd | road | primary | |
| xa | road | primary | |
| be | turn | primary | |
@@ -735,5 +824,184 @@ Feature: Turn Lane Guidance
| waypoints | route | turns | lanes |
| x,d | road,road | depart,arrive | , |
@partition-lanes
Scenario: Partitioned turn, Slight Curve
Given the node map
| | | f | | e |
| | | | | |
| | | | | |
| | | | | c |
| a | | b | | |
| | | g | | d |
And the ways
| nodes | name | highway | oneway | turn:lanes:forward |
| ab | road | primary | yes | left\|right |
| bc | cross | primary | yes | |
| fbg | cross | primary | yes | |
| dce | cross | primary | yes | |
When I route I should get
| waypoints | route | turns | lanes |
| a,g | road,cross,cross | depart,turn right,arrive | ,left:false right:true, |
| a,e | road,cross,cross | depart,turn left,arrive | ,left:true right:false, |
Scenario: Lane Parsing Issue #2694
Given the node map
| | c |
| a | b |
| | d |
And the ways
| nodes | highway | turn:lanes:forward |
| ab | primary | left;left\|right |
| bc | primary | |
| bd | primary | |
When I route I should get
| waypoints | route | turns | lanes |
| a,c | ab,bc,bc | depart,turn left,arrive | ,left:true right:false, |
# http://www.openstreetmap.org/#map=19/47.97685/7.82933&layers=D
@todo
Scenario: Lane Parsing Issue #2706: None Assignments I
Given the node map
| | f | | | j | |
| | | | | | |
| a | b | c | | d | e |
| | | | | | |
| | | | | i | |
| | g | | | h | |
And the nodes
| node | highway |
| a | traffic_signals |
| i | traffic_signals |
And the ways
| nodes | highway | name | oneway | turn:lanes:forward |
| ab | secondary | Wiesentalstr | | through;left\|right |
| bc | secondary | Wiesentalstr | | none\|left;through |
| cd | secondary | Wiesentalstr | | none\|left;through |
| de | residential | Wippertstr | | |
| fb | secondary | Merzhauser Str | yes | through\|through\|right |
| bg | secondary | Merzhauser Str | yes | |
| hi | secondary | Merzhauser Str | yes | left;reverse\|none\|none |
| ic | secondary_link | Merzhauser Str | yes | |
| id | secondary | Merzhauser Str | yes | through;right\|none |
| dj | secondary | Merzhauser Str | yes | |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | fb | fb | b | no_left_turn |
| restriction | ic | cb | c | only_left_turn |
| restriction | id | dc | d | no_left_turn |
When I route I should get
| waypoints | route | turns | lanes |
| h,a ||||
# Note: at the moment we don't care about routes, we care about the extract process triggering assertions
# https://www.openstreetmap.org/#map=19/47.99257/7.83276&layers=D
@todo
Scenario: Lane Parsing Issue #2706: None Assignments II
Given the node map
| | k | l | |
| j | a | b | f |
| i | c | d | e |
| | h | g | |
And the ways
| nodes | highway | name | oneway | turn:lanes |
| ka | secondary | Eschholzstr | yes | left;reverse\|through\|through\|none |
| kj | unclassified | kj | yes | |
| ac | secondary | Eschholzstr | yes | left;reverse\|none\|none\|none |
| ch | secondary | Eschholzstr | yes | |
| gd | secondary | Eschholzstr | yes | left;reverse\|through\|through\|none |
| db | secondary | Eschholzstr | yes | left;reverse\|through\|through\|none |
| bl | secondary | Eschholzstr | yes | |
| fb | residential | Haslacher Str | yes | left;reverse\|left;through\|right |
| ba | secondary_link | Haslacher Str | yes | left;reverse\|left;through |
| aj | unclassified | Haslacher Str | yes | |
| ic | unclassified | Haslacher Str | yes | left;reverse\|left\|through |
| cd | secondary_link | Haslacher Str | yes | left;reverse\|left\|through |
| de | residential | Haslacher Str | yes | |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | ka | ac | a | only_straight_on |
| restriction | ic | cd | c | only_straight_on |
| restriction | gd | db | d | only_straight_on |
When I route I should get
| waypoints | route | turns | lanes |
| i,e ||||
# Note: at the moment we don't care about routes, we care about the extract process triggering assertions
@todo
Scenario: Lane Parsing Issue #2706: None Assignments III - Minimal reproduction recipe
Given the node map
| | | l | |
| | a | b | |
| | | d | |
| | | | |
And the ways
| nodes | highway | name | oneway | turn:lanes |
| db | secondary | Eschholzstr | yes | left;reverse\|through\|through\|none |
| bl | secondary | Eschholzstr | yes | |
| ba | secondary_link | Haslacher Str | yes | |
When I route I should get
| waypoints | route | turns | lanes |
| d,a ||||
# Note: at the moment we don't care about routes, we care about the extract process triggering assertions
@reverse @2730 @todo
Scenario: Reverse on the right
Given the node map
| a | | | c | |
| | | | b | d |
| f | | | e | |
And the ways
| nodes | highway | name | turn:lanes:forward | oneway |
| ab | primary | in | left\|through\|right;reverse | yes |
| bc | primary | left | | no |
| bd | primary | through | | no |
| be | primary | right | | no |
| bf | primary | in | | yes |
When I route I should get
| waypoints | route | turns | lanes |
| a,c | in,left,left | depart,turn left,arrive | ,left:true straight:false right;uturn:false, |
| a,d | in,through,through | depart,new name straight,arrive | ,left:false straight:true right;uturn:false, |
| a,e | in,right,right | depart,turn right,arrive | ,left:false straight:false right;uturn:true, |
@todo @2654
#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, |
+198 -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 |
@@ -879,3 +885,182 @@ Feature: Simple Turns
| 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 |
+26 -34
View File
@@ -2,19 +2,23 @@ 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 ([0-9.]+) meters$/, (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]);
};
-18
View File
@@ -1,18 +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();
});
};
+2 -2
View File
@@ -6,7 +6,8 @@ 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);
@@ -156,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', 'osrm.tld', 'osrm.tls'].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', 'osrm.tld', 'osrm.tls'].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+~(.+)%$/),
+82 -48
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 = process.env.OSRM_BUILD_DIR && process.env.OSRM_BUILD_DIR || path.resolve(this.ROOT_FOLDER, 'build');
this.DEFAULT_INPUT_FORMAT = 'osm';
this.DEFAULT_ORIGIN = [1,1];
this.DEFAULT_LOAD_METHOD = 'datastore';
this.OSRM_ROUTED_LOG_FILE = path.resolve(this.TEST_FOLDER, 'osrm-routed.log');
this.ERROR_LOG_FILE = path.resolve(this.TEST_FOLDER, 'error.log');
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,67 @@ module.exports = function () {
} else {
this.TERMSIGNAL = 'SIGTERM';
this.EXE = '';
this.LIB = '.so';
// heuristically detect .so/.a suffix
this.LIB = null;
try {
const dot_a = util.format('%s/libosrm%s', this.BIN_PATH, '.a');
fs.accessSync(dot_a, fs.F_OK);
this.LIB = '.a';
} catch(e) { /*nop*/ }
try {
const dot_so = util.format('%s/libosrm%s', this.BIN_PATH, '.so');
fs.accessSync(dot_so, fs.F_OK);
this.LIB = '.so';
} catch(e) { /*nop*/ }
if (!this.LIB) {
throw new Error('*** Unable to detect dynamic or static libosrm libraries');
}
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');
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 +119,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;
};
+51 -26
View File
@@ -1,36 +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.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);
this.fingerprintExtract = this.hashString([this.luaLibHash, this.binExtractHash].join('-'));
this.fingerprintContract = this.hashString(this.binContractHash);
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.osrmLoader.setLoadMethod(this.DEFAULT_LOAD_METHOD);
this.setGridSize(this.DEFAULT_GRID_SIZE);
this.setOrigin(this.DEFAULT_ORIGIN);
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.AfterFeatures((features, callback) => {
callback();
});
};
+7 -5
View File
@@ -19,6 +19,9 @@ module.exports = function () {
return paramString;
};
// FIXME this needs to be simplified!
// - remove usage of node-timeout
// - replace with node's native timout mechanism
this.sendRequest = (baseUri, parameters, callback) => {
var limit = Timeout(this.TIMEOUT, { err: { statusCode: 408 } });
@@ -28,9 +31,9 @@ module.exports = function () {
request(this.query, (err, res, body) => {
if (err && err.code === 'ECONNREFUSED') {
throw new Error('*** osrm-routed is not running.');
return cb(new Error('*** osrm-routed is not running.'));
} else if (err && err.statusCode === 408) {
throw new Error();
return cb(new Error());
}
return cb(err, res, body);
@@ -40,11 +43,10 @@ module.exports = function () {
runRequest(limit((err, res, body) => {
if (err) {
if (err.statusCode === 408)
return callback(this.RoutedError('*** osrm-routed did not respond'));
return callback(new Error('*** osrm-routed did not respond'));
else if (err.code === 'ECONNREFUSED')
return callback(this.RoutedError('*** osrm-routed is not running'));
return callback(new Error('*** osrm-routed is not running'));
}
//console.log(body+"\n");
return callback(err, res, body);
}));
};
-5
View File
@@ -1,5 +0,0 @@
var launchClasses = require('./launch_classes');
module.exports = function () {
this._OSRMLoader = () => new (launchClasses._OSRMLoader.bind(launchClasses._OSRMLoader, this))();
};
-164
View File
@@ -1,164 +0,0 @@
'use strict';
var fs = require('fs');
var spawn = require('child_process').spawn;
var util = require('util');
var net = require('net');
var Timeout = require('node-timeout');
var OSRMBaseLoader = class {
constructor (scope) {
this.scope = scope;
}
launch (callback) {
var limit = Timeout(this.scope.TIMEOUT, { err: this.scope.RoutedError('Launching osrm-routed timed out.') });
var runLaunch = (cb) => {
this.osrmUp(() => { this.waitForConnection(cb); });
};
runLaunch(limit((e) => { if (e) callback(e); else callback(); }));
}
shutdown (callback) {
var limit = Timeout(this.scope.TIMEOUT, { err: this.scope.RoutedError('Shutting down osrm-routed timed out.')});
var runShutdown = (cb) => {
this.osrmDown(cb);
};
runShutdown(limit((e) => { if (e) callback(e); else callback(); }));
}
osrmIsRunning () {
return !!this.scope.pid && this.child && !this.child.killed;
}
osrmDown (callback) {
if (this.scope.pid) {
process.kill(this.scope.pid, this.scope.TERMSIGNAL);
this.waitForShutdown(callback);
this.scope.pid = null;
} else callback(true);
}
waitForConnection (callback) {
var retryCount = 0;
var connectWithRetry = () => {
net.connect({ port: this.scope.OSRM_PORT, host: '127.0.0.1' })
.on('connect', () => { callback(); })
.on('error', () => {
if (retryCount < 2) {
retryCount++;
setTimeout(connectWithRetry, 100);
} else {
callback(new Error('Could not connect to osrm-routed after three retires'));
}
});
};
connectWithRetry();
}
waitForShutdown (callback) {
var check = () => {
if (!this.osrmIsRunning()) return callback();
};
setTimeout(check, 100);
}
};
var OSRMDirectLoader = class extends OSRMBaseLoader {
constructor (scope) {
super(scope);
}
load (inputFile, callback) {
this.inputFile = inputFile;
this.shutdown(() => {
this.launch(callback);
});
}
osrmUp (callback) {
if (this.scope.pid) return callback();
var writeToLog = (data) => {
fs.appendFile(this.scope.OSRM_ROUTED_LOG_FILE, data, (err) => { if (err) throw err; });
};
var child = spawn(util.format('%s/osrm-routed', this.scope.BIN_PATH), [this.inputFile, util.format('-p%d', this.scope.OSRM_PORT)]);
this.scope.pid = child.pid;
child.stdout.on('data', writeToLog);
child.stderr.on('data', writeToLog);
callback();
}
};
var OSRMDatastoreLoader = class extends OSRMBaseLoader {
constructor (scope) {
super(scope);
}
load (inputFile, callback) {
this.inputFile = inputFile;
this.loadData((err) => {
if (err) return callback(err);
if (!this.scope.pid) return this.launch(callback);
else callback();
});
}
loadData (callback) {
this.scope.runBin('osrm-datastore', this.inputFile, (err) => {
if (err) return callback(this.scope.LaunchError(this.exitCode, 'datastore', err));
callback();
});
}
osrmUp (callback) {
if (this.scope.pid) return callback();
var writeToLog = (data) => {
fs.appendFile(this.scope.OSRM_ROUTED_LOG_FILE, data, (err) => { if (err) throw err; });
};
var child = spawn(util.format('%s/osrm-routed', this.scope.BIN_PATH), ['--shared-memory=1', util.format('-p%d', this.scope.OSRM_PORT)]);
this.child = child;
this.scope.pid = child.pid;
child.stdout.on('data', writeToLog);
child.stderr.on('data', writeToLog);
callback();
}
};
module.exports = {
_OSRMLoader: class {
constructor (scope) {
this.scope = scope;
this.loader = null;
}
load (inputFile, callback) {
var method = this.scope.loadMethod;
if (method === 'datastore') {
this.loader = new OSRMDatastoreLoader(this.scope);
this.loader.load(inputFile, callback);
} else if (method === 'directly') {
this.loader = new OSRMDirectLoader(this.scope);
this.loader.load(inputFile, callback);
} else {
callback(new Error('*** Unknown load method ' + method));
}
}
shutdown (callback) {
this.loader.shutdown(callback);
}
up () {
return this.loader ? this.loader.osrmIsRunning() : false;
}
}
};
-90
View File
@@ -1,90 +0,0 @@
var fs = require('fs');
module.exports = function () {
this.clearLogFiles = (callback) => {
// emptying existing files, rather than deleting and writing new ones makes it
// easier to use tail -f from the command line
fs.writeFile(this.OSRM_ROUTED_LOG_FILE, '', err => {
if (err) throw err;
fs.writeFile(this.PREPROCESS_LOG_FILE, '', err => {
if (err) throw err;
fs.writeFile(this.LOG_FILE, '', err => {
if (err) throw err;
callback();
});
});
});
};
var log = this.log = (s, type) => {
s = s || '';
type = type || null;
var file = type === 'preprocess' ? this.PREPROCESS_LOG_FILE : this.LOG_FILE;
fs.appendFile(file, s + '\n', err => {
if (err) throw err;
});
};
this.logScenarioFailInfo = () => {
if (this.hasLoggedScenarioInfo) return;
log('=========================================');
log('Failed scenario: ' + this.scenarioTitle);
log('Time: ' + this.scenarioTime);
log('Fingerprint osm stage: ' + this.osmData.fingerprintOSM);
log('Fingerprint extract stage: ' + this.fingerprintExtract);
log('Fingerprint contract stage: ' + this.fingerprintContract);
log('Fingerprint route stage: ' + this.fingerprintRoute);
log('Profile: ' + this.profile);
log();
log('```xml'); // so output can be posted directly to github comment fields
log(this.osmData.str.trim());
log('```');
log();
log();
this.hasLoggedScenarioInfo = true;
};
this.logFail = (expected, got, attempts) => {
this.logScenarioFailInfo();
log('== ');
log('Expected: ' + JSON.stringify(expected));
log('Got: ' + JSON.stringify(got));
log();
['route','forw','backw'].forEach((direction) => {
if (attempts[direction]) {
log('Direction: ' + direction);
log('Query: ' + attempts[direction].query);
log('Response: ' + attempts[direction].response.body);
log();
}
});
};
this.logPreprocessInfo = () => {
if (this.hasLoggedPreprocessInfo) return;
log('=========================================', 'preprocess');
log('Preprocessing data for scenario: ' + this.scenarioTitle, 'preprocess');
log('Time: ' + this.scenarioTime, 'preprocess');
log('', 'preprocess');
log('== OSM data:', 'preprocess');
log('```xml', 'preprocess'); // so output can be posted directly to github comment fields
log(this.osmData.str, 'preprocess');
log('```', 'preprocess');
log('', 'preprocess');
log('== Profile:', 'preprocess');
log(this.profile, 'preprocess');
log('', 'preprocess');
this.hasLoggedPreprocessInfo = true;
};
this.logPreprocess = (str) => {
this.logPreprocessInfo();
log(str, 'preprocess');
};
this.logPreprocessDone = () => {
log('Done with preprocessing at ' + new Date(), 'preprocess');
};
};
+14 -9
View File
@@ -1,7 +1,8 @@
'use strict';
var Timeout = require('node-timeout');
var request = require('request');
const Timeout = require('node-timeout');
const request = require('request');
const ensureDecimal = require('../lib/utils').ensureDecimal;
module.exports = function () {
this.requestPath = (service, params, callback) => {
@@ -42,7 +43,7 @@ module.exports = function () {
};
var encodeWaypoints = (waypoints) => {
return waypoints.map(w => [w.lon, w.lat].map(this.ensureDecimal).join(','));
return waypoints.map(w => [w.lon, w.lat].map(ensureDecimal).join(','));
};
this.requestRoute = (waypoints, bearings, userParams, callback) => {
@@ -131,7 +132,7 @@ module.exports = function () {
this.summary = (instructions) => {
if (instructions) {
return instructions.legs.map(l => l.summary).join(',');
return instructions.legs.map(l => l.summary).join(';');
}
};
@@ -139,6 +140,10 @@ module.exports = function () {
return this.extractInstructionList(instructions, s => s.name);
};
this.refList = (instructions) => {
return this.extractInstructionList(instructions, s => s.ref || '');
};
this.pronunciationList = (instructions) => {
return this.extractInstructionList(instructions, s => s.pronunciation || '');
};
@@ -152,15 +157,15 @@ module.exports = function () {
};
this.annotationList = (instructions) => {
function zip(list_1, list_2)
function zip(list_1, list_2, list_3)
{
let pairs = [];
let tuples = [];
for (let i = 0; i < list_1.length; ++i) {
pairs.push([list_1[i], list_2[i]]);
tuples.push([list_1[i], list_2[i], list_3[i]]);
}
return pairs;
return tuples;
}
return instructions.legs.map(l => {return zip(l.annotation.duration, l.annotation.distance).map(p => { return p.join(':'); }).join(','); }).join(',');
return instructions.legs.map(l => {return zip(l.annotation.duration, l.annotation.distance, l.annotation.datasources).map(p => { return p.join(':'); }).join(','); }).join(',');
};
this.OSMIDList = (instructions) => {
+42 -30
View File
@@ -1,40 +1,52 @@
var fs = require('fs');
var util = require('util');
var exec = require('child_process').exec;
'use strict';
const fs = require('fs');
const util = require('util');
const child_process = require('child_process');
module.exports = function () {
this.runBin = (bin, options, callback) => {
var opts = options.slice();
// replaces placeholders for in user supplied commands
this.expandOptions = (options) => {
let opts = options.slice();
let table = {
'{osm_file}': this.inputCacheFile,
'{processed_file}': this.processedCacheFile,
'{profile_file}': this.profileFile,
'{rastersource_file}': this.rasterCacheFile,
'{speeds_file}': this.speedsCacheFile,
'{penalties_file}': this.penaltiesCacheFile
};
if (opts.match('{osm_base}')) {
if (!this.osmData.osmFile) throw new Error('*** {osm_base} is missing');
opts = opts.replace('{osm_base}', this.osmData.osmFile);
for (let k in table) {
opts = opts.replace(k, table[k]);
}
if (opts.match('{extracted_base}')) {
if (!this.osmData.extractedFile) throw new Error('*** {extracted_base} is missing');
opts = opts.replace('{extracted_base}', this.osmData.extractedFile);
return opts;
};
this.setupOutputLog = (process, log) => {
if (process.logFunc) {
process.stdout.removeListener('data', process.logFunc);
process.stderr.removeListener('data', process.logFunc);
}
if (opts.match('{contracted_base}')) {
if (!this.osmData.contractedFile) throw new Error('*** {contracted_base} is missing');
opts = opts.replace('{contracted_base}', this.osmData.contractedFile);
}
process.logFunc = (message) => { log.write(message); };
process.stdout.on('data', process.logFunc);
process.stderr.on('data', process.logFunc);
};
if (opts.match('{profile}')) {
opts = opts.replace('{profile}', [this.PROFILES_PATH, this.profile + '.lua'].join('/'));
}
var cmd = util.format('%s%s/%s%s%s %s 2>%s', this.QQ, this.BIN_PATH, bin, this.EXE, this.QQ, opts, this.ERROR_LOG_FILE);
process.chdir(this.TEST_FOLDER);
exec(cmd, (err, stdout, stderr) => {
this.stdout = stdout.toString();
fs.readFile(this.ERROR_LOG_FILE, (e, data) => {
this.stderr = data ? data.toString() : '';
this.exitCode = err && err.code || 0;
process.chdir('../');
callback(err, stdout, stderr);
});
});
this.runBin = (bin, options, env, callback) => {
let cmd = util.format('%s%s/%s%s%s', this.QQ, this.BIN_PATH, bin, this.EXE, this.QQ);
let opts = options.split(' ').filter((x) => { return x && x.length > 0; });
let log = fs.createWriteStream(this.scenarioLogFile, {'flags': 'a'});
log.write(util.format('*** running %s %s\n', cmd, options));
// we need to set a large maxbuffer here because we have long running processes like osrm-routed
// with lots of log output
let child = child_process.execFile(cmd, opts, {maxBuffer: 1024 * 1024 * 1000, env: env}, callback);
child.on('exit', function(code) {
log.write(util.format('*** %s exited with code %d\n', bin, code));
}.bind(this));
this.setupOutputLog(child, log);
return child;
};
};
+12 -17
View File
@@ -24,7 +24,8 @@ module.exports = function () {
};
this.WhenIRouteIShouldGet = (table, callback) => {
this.reprocessAndLoadData(() => {
this.reprocessAndLoadData((e) => {
if (e) return callback(e);
var headers = new Set(table.raw()[0]);
var requestRow = (row, ri, cb) => {
@@ -33,7 +34,7 @@ module.exports = function () {
var afterRequest = (err, res, body) => {
if (err) return cb(err);
if (body && body.length) {
let destinations, pronunciations, instructions, bearings, turns, modes, times,
let destinations, pronunciations, instructions, refs, bearings, turns, modes, times,
distances, summary, intersections, lanes;
let json = JSON.parse(body);
@@ -43,6 +44,7 @@ module.exports = function () {
if (hasRoute) {
instructions = this.wayList(json.routes[0]);
pronunciations = this.pronunciationList(json.routes[0]);
refs = this.refList(json.routes[0]);
destinations = this.destinationsList(json.routes[0]);
bearings = this.bearingList(json.routes[0]);
turns = this.turnList(json.routes[0]);
@@ -91,7 +93,7 @@ module.exports = function () {
if (headers.has('distance')) {
if (row.distance.length) {
if (!row.distance.match(/\d+m/))
throw new Error('*** Distance must be specified in meters. (ex: 250m)');
return cb(new Error('*** Distance must be specified in meters. (ex: 250m)'));
got.distance = instructions ? util.format('%dm', distance) : '';
} else {
got.distance = '';
@@ -100,7 +102,7 @@ module.exports = function () {
if (headers.has('time')) {
if (!row.time.match(/\d+s/))
throw new Error('*** Time must be specied in seconds. (ex: 60s)');
return cb(new Error('*** Time must be specied in seconds. (ex: 60s)'));
got.time = instructions ? util.format('%ds', time) : '';
}
@@ -111,7 +113,7 @@ module.exports = function () {
if (headers.has('speed')) {
if (row.speed !== '' && instructions) {
if (!row.speed.match(/\d+ km\/h/))
throw new Error('*** Speed must be specied in km/h. (ex: 50 km/h)');
cb(new Error('*** Speed must be specied in km/h. (ex: 50 km/h)'));
var speed = time > 0 ? Math.round(3.6*distance/time) : null;
got.speed = util.format('%d km/h', speed);
} else {
@@ -127,6 +129,7 @@ module.exports = function () {
if (headers.has(key)) got[key] = instructions ? value : '';
};
putValue('ref', refs);
putValue('bearing', bearings);
putValue('turns', turns);
putValue('modes', modes);
@@ -136,20 +139,12 @@ module.exports = function () {
putValue('destinations', destinations);
}
var 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, { route: { query: this.query, response: res }});
}
cb(null, got);
} else {
cb(new Error('request failed to return valid body'));
@@ -186,11 +181,11 @@ module.exports = function () {
if (row.from && row.to) {
var fromNode = this.findNodeByName(row.from);
if (!fromNode) throw new Error(util.format('*** unknown from-node "%s"'), row.from);
if (!fromNode) return cb(new Error(util.format('*** unknown from-node "%s"'), row.from));
waypoints.push(fromNode);
var toNode = this.findNodeByName(row.to);
if (!toNode) throw new Error(util.format('*** unknown to-node "%s"'), row.to);
if (!toNode) return cb(new Error(util.format('*** unknown to-node "%s"'), row.to));
waypoints.push(toNode);
got.from = row.from;
@@ -199,13 +194,13 @@ module.exports = function () {
} else if (row.waypoints) {
row.waypoints.split(',').forEach((n) => {
var node = this.findNodeByName(n.trim());
if (!node) throw new Error('*** unknown waypoint node "%s"', n.trim());
if (!node) return cb(new Error('*** unknown waypoint node "%s"', n.trim()));
waypoints.push(node);
});
got.waypoints = row.waypoints;
this.requestRoute(waypoints, bearings, params, afterRequest);
} else {
throw new Error('*** no waypoints');
return cb(new Error('*** no waypoints'));
}
}
};
-11
View File
@@ -1,11 +0,0 @@
var DifferentError = require('./exception_classes').TableDiffError;
module.exports = function () {
this.diffTables = (expected, actual, options, callback) => {
// this is a temp workaround while waiting for https://github.com/cucumber/cucumber-js/issues/534
var error = new DifferentError(expected, actual);
return callback(error.string);
};
};
+2 -2
View File
@@ -11,8 +11,8 @@ Feature: Handle bad data in a graceful manner
Given the ways
| nodes |
When the data has been contracted
Then "osrm-extract" should return code 1
When I try to run "osrm-extract {osm_file} --profile {profile_file}"
Then it should exit with an error
Scenario: Only dead-end oneways
Given the node map
+9 -9
View File
@@ -104,12 +104,12 @@ Feature: Bearing parameter
| ha | yes | ring |
When I route I should get
| from | to | bearings | route | bearing |
| 0 | q | 0 90 | ia,ring,ring,ring,ring,ring | 0->0,0->90,180->270,270->0,0->90,90->0 |
| 0 | a | 45 90 | jb,ring,ring,ring,ring,ring | 0->45,45->180,180->270,270->0,0->90,90->0 |
| 0 | q | 90 90 | kc,ring,ring,ring,ring | 0->90,90->180,270->0,0->90,90->0 |
| 0 | a | 135 90 | ld,ring,ring,ring,ring | 0->135,135->270,270->0,0->90,90->0 |
| 0 | a | 180 90 | me,ring,ring,ring | 0->180,180->270,0->90,90->0 |
| 0 | a | 225 90 | nf,ring,ring,ring | 0->225,225->0,0->90,90->0 |
| 0 | a | 270 90 | og,ring,ring | 0->270,270->0,90->0 |
| 0 | a | 315 90 | ph,ring,ring | 0->315,315->90,90->0 |
| from | to | bearings | route | bearing |
| 0 | q | 0 90 | ia,ring,ring | 0->0,0->90,90->0 |
| 0 | a | 45 90 | jb,ring,ring | 0->45,45->180,90->0 |
| 0 | q | 90 90 | kc,ring,ring | 0->90,90->180,90->0 |
| 0 | a | 135 90 | ld,ring,ring | 0->135,135->270,90->0 |
| 0 | a | 180 90 | me,ring,ring | 0->180,180->270,90->0 |
| 0 | a | 225 90 | nf,ring,ring | 0->225,225->0,90->0 |
| 0 | a | 270 90 | og,ring,ring | 0->270,270->0,90->0 |
| 0 | a | 315 90 | ph,ring,ring | 0->315,315->90,90->0 |
-5
View File
@@ -1,5 +0,0 @@
@routing @testbot @bug
Feature: Known bugs
Background:
Given the profile "testbot"
+11 -3
View File
@@ -4,6 +4,7 @@ Feature: Basic Map Matching
Background:
Given the profile "testbot"
Given a grid size of 10 meters
Given the extract extra arguments "--generate-edge-lookup"
Scenario: Testbot - Map matching with outlier that has no candidate
Given a grid size of 100 meters
@@ -118,10 +119,17 @@ Feature: Basic Map Matching
| abcdegh | no |
| ci | no |
And the speed file
"""
1,2,36
"""
And the contract extra arguments "--segment-speed-file {speeds_file}"
When I match I should get
| trace | matchings | annotation |
| abeh | abcedgh | 1:9.897633,0:0,1:10.008842,1:10.008842,1:10.008842,0:0,2:20.017685,1:10.008842 |
| abci | abc,ci | 1:9.897633,0:0,1:10.008842,0:0.111209,1:10.010367 |
| trace | matchings | annotation |
| abeh | abcedgh | 1:9.897633:1,0:0:0,1:10.008842:0,1:10.008842:0,1:10.008842:0,0:0:0,2:20.017685:0,1:10.008842:0 |
| abci | abc,ci | 1:9.897633:1,0:0:0,1:10.008842:0,0:0.111209:0,1:10.010367:0 |
# The following is the same as the above, but separated for readability (line length)
When I match I should get
+83
View File
@@ -0,0 +1,83 @@
@routing @testbot @sidebias
Feature: Testbot - side bias
Scenario: Left hand bias
Given the profile "lhs"
And the node map
| a | | b | | c |
| | | | | |
| | | d | | |
And the ways
| nodes |
| ab |
| bc |
| bd |
When I route I should get
| from | to | route | time |
| d | a | bd,ab,ab | 82s +-1 |
| d | c | bd,bc,bc | 100s +-1 |
Scenario: Right hand bias
Given the profile "rhs"
And the node map
| a | | b | | c |
| | | | | |
| | | d | | |
And the ways
| nodes |
| ab |
| bc |
| bd |
When I route I should get
| from | to | route | time |
| d | a | bd,ab,ab | 100s +-1 |
| d | c | bd,bc,bc | 82s +-1 |
Scenario: Roundabout exit counting for left sided driving
Given the profile "lhs"
And a grid size of 10 meters
And the node map
| | | a | | |
| | | b | | |
| h | g | | c | d |
| | | e | | |
| | | f | | |
And the ways
| nodes | junction |
| ab | |
| cd | |
| ef | |
| gh | |
| bcegb | roundabout |
When I route I should get
| waypoints | route | turns |
| a,d | ab,cd,cd | depart,roundabout turn left exit-1,arrive |
| a,f | ab,ef,ef | depart,roundabout turn straight exit-2,arrive |
| a,h | ab,gh,gh | depart,roundabout turn right exit-3,arrive |
Scenario: Mixed Entry and Exit
Given the profile "lhs"
And a grid size of 10 meters
And the node map
| | c | | a | |
| j | | b | | f |
| | k | | e | |
| l | | h | | d |
| | g | | i | |
And the ways
| nodes | junction | oneway |
| cba | | yes |
| fed | | yes |
| ihg | | yes |
| lkj | | yes |
| behkb | roundabout | yes |
When I route I should get
| waypoints | route | turns |
| c,a | cba,cba,cba | depart,roundabout-exit-1,arrive |
| l,a | lkj,cba,cba | depart,roundabout-exit-2,arrive |
| i,a | ihg,cba,cba | depart,roundabout-exit-3,arrive |
+3 -3
View File
@@ -53,9 +53,9 @@ Feature: Basic Routing
| ab |
When I route I should get
| from | to | route | summary |
| a | b | ab,ab | ab |
| b | a | ab,ab | ab |
| from | to | route | summary |
| a | b | ab,ab | ab |
| b | a | ab,ab | ab |
@repeated
Scenario: Check handling empty values
@@ -23,10 +23,10 @@ Feature: Traffic - turn penalties applied to turn onto which a phantom node snap
Scenario: Weighting based on turn penalty file, with an extreme negative value -- clamps and does not fail
Given the turn penalty file
"""
1,2,5,0
1,2,5,0,comment
3,4,7,-20
"""
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 | e | ab,be,be | 36 km/h | 40s +-1 |
+15
View File
@@ -19,3 +19,18 @@ Feature: Handling of UTF characters
| a | b | Scandinavian København,Scandinavian København |
| b | c | Japanese ,Japanese |
| c | d | Cyrillic Москва,Cyrillic Москва |
@todo
Scenario: Up to 255 Unicode Code Points (255 x Panda Code Point)
Given the node map
| a | b | c |
And the ways
| nodes | name | highway |
| ab | ab | primary |
| bc | 🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼 | primary |
When I route 100 times I should get
| from | to | route |
| a | c | ab,🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼,🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼🐼 |
+36 -1
View File
@@ -173,7 +173,7 @@ Feature: Via points
| c,d,a | abc,bd,bd,bd,abc,abc |
# See issue #2349
@bug
@todo
Scenario: Via point at a dead end with oneway
Given the node map
| a | b | c |
@@ -262,3 +262,38 @@ Feature: Via points
| 3,2,1 | ab,bc,cd,da,ab,ab,ab,bc,cd,da,ab,ab | 3000m +-1 |
| 6,5,4 | bc,cd,da,ab,bc,bc,bc,cd,da,ab,bc,bc | 3000m +-1 |
| 9,8,7 | cd,da,ab,bc,cd,cd,cd,da,ab,bc,cd,cd | 3000m +-1 |
# See issue #2706
# this case is currently broken. It simply works as put here due to staggered intersections triggering a name collapse.
# See 2824 for further information
@todo
Scenario: Incorrect ordering of nodes can produce multiple U-turns
Given the node map
| | a | | | |
| e | b | c | d | f |
And the ways
| nodes | oneway |
| abcd | no |
| ebbdcf | yes |
When I route I should get
| from | to | route |
| e | f | ebbdcf,ebbdcf |
@2798
Scenario: UTurns Enabled
Given the node map
| a | b | c | d | e |
And the query options
| continue_straight | false |
And the ways
| nodes | oneway |
| abc | yes |
| edc | yes |
When I route I should get
| waypoints | route |
| a,b,e | |

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