Compare commits

..

324 Commits

Author SHA1 Message Date
Daniel J. Hofmann 9500facd9c Bumps version to 5.9.1 2017-07-24 14:30:34 +02:00
Daniel J. Hofmann 615e015700 Merges Changelog entries into 5.9.1 section 2017-07-24 13:09:32 +02:00
Michael Krasnyk 02922ecf5e Don't use STXXL library by default 2017-07-24 13:08:41 +02:00
Daniel J. Hofmann bae1b9c5e2 Documents system-wide limit constructor parameters in node bindings, resolves #4317 2017-07-24 13:04:20 +02:00
Emil Tin 4c35352707 fix profile debugging related to way classes 2017-07-24 13:02:10 +02:00
Daniel J. Hofmann c362a3d46d Fixes line endings, related to #4235 2017-07-24 12:48:33 +02:00
Daniel J. Hofmann 293a7177d0 Updates changelog 2017-07-24 12:37:30 +02:00
Daniel J. Hofmann 8af54ffe83 Handles distinction of no-route vs invalid-route in mld alternatives
The viaroute plugin always expects a route to be there potentially
with invalid edge weight to represent no-route-found. By switching
to the many-route-result for the mld alternatives algorithm we might
return an empty many-route-result invalidating the post-condition.
2017-07-24 12:27:06 +02:00
Daniel J. Hofmann 253c2dc570 Trigger lane anticipation based on distance, see discussion in #4260 2017-07-22 17:30:48 +02:00
Moritz Kobitzsch 0c6bb534fd changelog, consistent deprecated documentation
Conflicts:
	CHANGELOG.md
2017-07-22 17:30:33 +02:00
Moritz Kobitzsch 2d02fad09b remove usage of use-lane completely 2017-07-22 17:28:44 +02:00
Moritz Kobitzsch 361e6b998f deprecate use-lane -- the information can be found in the intersections array 2017-07-22 17:28:36 +02:00
Patrick Niklaus 210fa9d545 Update changelog and version 2017-07-19 16:34:49 +00:00
Daniel J. Hofmann 7eafb48d20 Introduces a construction whitelist in profiles 2017-07-19 16:32:42 +00:00
Daniel J. Hofmann df0f407591 Makes construction=minor ways routable again, see #4258 2017-07-19 16:27:31 +00:00
Patrick Niklaus f9a8bcc75c Bump version to v5.9.0-rc.3 2017-07-18 16:50:51 +00:00
Patrick Niklaus f815daf026 Update the changelog 2017-07-18 16:50:24 +00:00
Patrick Niklaus f393f47d43 Move classes to intersection object and don't emit notifications 2017-07-18 16:48:59 +00:00
Daniel J. Hofmann 1e258ed3fa Changelog entry for openmp 2017-07-17 19:24:27 +02:00
Daniel J. Hofmann de084f201c Only enables -fopenmp in case the user wants stxxl 2017-07-17 19:20:35 +02:00
Patrick Niklaus e34a74d4ac Add changelog entry 2017-07-13 21:50:01 +00:00
Daniel J. Hofmann bd1391f6f7 Exposes EngineConfig system-wide limits in Node.js bindings, resolves #4226 2017-07-13 21:49:27 +00:00
Patrick Niklaus f54631619a Add bug fix to changelog 2017-07-13 09:01:08 +00:00
Moritz Kobitzsch 070fa1a24c only consider allowed entries when continuing on motorways 2017-07-13 09:00:00 +00:00
Moritz Kobitzsch f15285e9ee add test indicating missdetection of continuing on motorways 2017-07-13 09:00:00 +00:00
Patrick Niklaus bae21f0d5d Bump version to RC2 2017-07-12 22:13:56 +00:00
Daniel Patterson 305df1fb6e Include osrm-customize when doing 'make install' 2017-07-12 22:12:14 +00:00
Daniel J. Hofmann 9ab0fca31c Canonicalizes all OSM string list handling in the profiles 2017-07-12 22:09:28 +00:00
Michael Krasnyk e2e398edc5 Remove STXXL from OSM parsing and enable in CMake by default 2017-07-11 08:24:29 +00:00
Michael Krasnyk b87366132b Updated ChangeLog 2017-07-11 08:24:29 +00:00
Michael Krasnyk f4ef4b022e Added STXXL configuration 2017-07-11 08:24:29 +00:00
Michael Krasnyk 81d479304e Don't use stxxl vector in contractor 2017-07-11 08:24:29 +00:00
Michael Krasnyk 92b53e5be0 Switch from stxxl::vector to std::vector in extractor 2017-07-11 08:24:29 +00:00
Michael Krasnyk cc73e753bd Removed external_to_internal_node_id_map container 2017-07-11 08:24:28 +00:00
Daniel J. Hofmann 725dc396c7 Fixes Node.js bindings always enabling alternatives when using boolean overload 2017-07-10 10:45:56 +02:00
Daniel J. Hofmann 890f0d8d7e Discards construction and proposed ways, resolves #4230 2017-07-10 10:38:30 +02:00
Patrick Niklaus c9017090a2 Bump verison to 5.9.0-rc.1 2017-07-07 17:07:52 +00:00
Patrick Niklaus e7061591e3 Enable travis on 5.9 2017-07-07 17:06:47 +00:00
Emil Tin 5ede5577d1 avoid fuzzy ferry test 2017-07-07 16:16:13 +00:00
Emil Tin 0bfbe5ad16 handle startpoint in bicycle profile, add tests 2017-07-07 16:16:13 +00:00
Daniel J. Hofmann 54ceb05420 Implements Alternatives for MLD 2017-07-07 16:12:46 +00:00
Patrick Niklaus fef0344be0 Don't use bool flags on ExternalMemoryNode because they blow up the struct 2017-07-07 13:24:34 +00:00
Lev Dragunov b12fee5c0a Load graph before creating a server 2017-07-06 21:18:24 +00:00
Daniel J. Hofmann 1ef75c7a61 Bundles nan, node-cmake and node-pre-gyp for bootstrapping node-osrm, resolves #4216
Building `node-osrm` from source requires nan, node-cmake and
node-pre-gyp npm packages already \*. In order to bootstrap we
bundle these dev packages in the bundle we publish to npm.

\* See `src/nodejs/CMakeLists.txt`

Check `npm pack` - we now expect to see a `node_modules` directory
with nan, node-cmake, and node-pre-gyp already there.
2017-07-06 14:40:43 +00:00
Daniel J. Hofmann 8c5ac84f0c Lets approaches cuke test run under testbot profile, resolves #4181
🥒 🚗-> 🤖
2017-07-06 14:40:21 +00:00
Patrick Niklaus 44739f2dc3 Allow users to specify a class for each way
This adds the ability to mark ways with a user-defined
class in the profile. This class information will be included
in the response as property of the RouteStep object.
2017-07-06 09:17:49 +00:00
Patrick Niklaus d52d530cbe Fix indentation and dead-code from c&p in cucumber to silence eslint 2017-07-05 07:57:46 +00:00
Patrick Niklaus 5fb00ff7bf [skip ci] Revert back gitattributes, was unrelated to OSX 2017-07-04 22:49:30 +00:00
Moritz Kobitzsch 4c7aa8f1c0 only consider narrow turns onto through streets straight 2017-07-04 22:03:04 +00:00
Moritz Kobitzsch 2522f70f86 add test case illustrating 4205 2017-07-04 22:03:04 +00:00
Mateusz Loskot e47e8ed335 Add .gitattributes
Add the good default options as recommended by GitHub.
Helps to work around issues when using hybrid environments like
the Bash On Windows (see #4228).
2017-07-04 20:59:35 +00:00
Daniel J. Hofmann 2927b491c3 Updates Changelog with Exit Numbers 2017-07-04 20:58:19 +00:00
Daniel J. Hofmann ba2a0b3566 Adds more exits cucumber scenarios 2017-07-04 20:58:19 +00:00
Moritz Kobitzsch 98caa0bcd9 adjust name-table checks for increased name table size 2017-07-04 20:58:19 +00:00
Moritz Kobitzsch 4a2a100569 add exits to unit-test initialisation 2017-07-04 20:58:19 +00:00
Moritz Kobitzsch 3073f4c0d1 don't announce something if we loose exit numbers while on the ramp 2017-07-04 20:58:19 +00:00
Daniel J. Hofmann 7d900e3b5a Implements Exit Numbers + Names (junction:ref way tag for now) 2017-07-04 20:58:19 +00:00
Patrick Niklaus 6d78c11fd2 [skip ci] Bump OSRM version to 5.9 2017-07-03 22:44:56 +00:00
Michael Krasnyk 1bee82e288 Make safety penalties graduation for primary, secondary and tertiary 2017-07-03 21:58:32 +00:00
Michael Krasnyk a41caf0efb Adjustment of bicycle profile to review comments 2017-07-03 21:58:32 +00:00
Michael Krasnyk a3e0eb03db Implement bicycle safety penalty 2017-07-03 21:58:32 +00:00
Patrick Niklaus 34f62b4894 Add test case for safety features on cycleways 2017-07-03 21:58:32 +00:00
Michael Krasnyk b28077a437 Use rate rounding up to tenth in routability tests 2017-07-03 21:58:32 +00:00
Michael Krasnyk 359ab2b56e Use highest different level with source but not parent node 2017-07-03 14:57:52 +00:00
Michael Krasnyk e42c23686b Edge case for MLD matrix plugin 2017-07-03 14:57:52 +00:00
Michael Krasnyk d98f1a2632 Update "Multi level routing" test 2017-07-03 14:57:52 +00:00
Michael Krasnyk aa736dbe3a Generalize directShortestPathSearch interface 2017-07-03 14:57:52 +00:00
Michael Krasnyk 3534203083 Generalize manyToManySearch and remove duplications 2017-07-03 14:57:52 +00:00
Michael Krasnyk 517cb5f094 Matrix plugin with MLD overlay 2017-07-03 14:57:52 +00:00
Michael Krasnyk b910ab9bcb Add duration values to overlay graph 2017-07-03 14:57:52 +00:00
Michael Krasnyk 5a29e29535 Add matrix tests that checks MLD overlay 2017-07-03 14:57:52 +00:00
Michael Krasnyk 0fd71260d3 Enable ManyToManySearch in MLD 2017-07-03 14:57:52 +00:00
Michael Krasnyk 54367bfa98 Reduce memory consumption during partition 2017-07-03 14:57:52 +00:00
Michael Krasnyk 1e9806f872 Some osrm-runner fixes 2017-07-03 14:57:52 +00:00
Mateusz Loskot 1e704aa7f2 Ignore Visual Studio/Visual Studio Code related files 2017-07-03 14:42:51 +00:00
Michael Krasnyk 8a404ea850 Use correctly traffic light penalty for no_turn turns 2017-07-03 13:43:13 +02:00
Harry Wood e2e279bc85 example curl command needs quotes
We need to add quotes around the URL in the curl command (at least in the shell
I'm using). Otherwise it truncates the URL at ';'
2017-06-30 14:04:46 +00:00
Michael Krasnyk c914afdbf1 Fix missing-field-initializers warnings in PackedVector 2017-06-30 14:27:43 +02:00
Daniel J. Hofmann 49a057ebc0 Adds a link to Mapbox's mapping for navigation guide 2017-06-30 12:19:14 +02:00
Moritz Kobitzsch d660c1609c don't collapse u-turns into combined turns 2017-06-30 09:25:03 +00:00
Michael Krasnyk 74bc8966a8 Test case with incorrect u-turn collapsing
http://map.project-osrm.org/?z=18&center=52.169237%2C10.032722&loc=52.168628%2C10.030759&loc=52.168707%2C10.030952&loc=52.168457%2C10.030432&hl=en&alt=0
2017-06-30 09:25:03 +00:00
Michael Krasnyk 9d8a3e3c97 Propagate lane data across traffic lights 2017-06-29 15:10:37 +00:00
Michael Krasnyk a308b86056 Test case for #4189 2017-06-29 15:10:37 +00:00
Michael Krasnyk 1b540fe0ba Correct condition for is_going_straight_and_turns_continue 2017-06-29 15:10:37 +00:00
Michael Krasnyk 929e5a4de6 Review adjustments for driveway handler, #4151 2017-06-29 15:07:32 +00:00
Michael Krasnyk df4f0d043a Added driveway handler 2017-06-29 15:07:32 +00:00
Michael Krasnyk 09df8d47a5 Re-enable edge-weight-updates-over-factor test 2017-06-27 13:02:53 +02:00
Michael Krasnyk c8b75c9046 Use thread-safe lock-free assignment in PackedVector::set_value
PR uses TBB internal atomic's for atomic CAS on non-atomic data

Corresponding PR https://github.com/Project-OSRM/osrm-backend/pull/4199

Other options:

* use sequential update

* use an internal packed vector lock -> makes packed vector non-movable

* use boost.interprocess atomics implementation -> outdated and only 32 bit version

* use glib atomic's -> requires new dependency

*  wait for https://isocpp.org/blog/2014/05/n4013 as_atomic

*  use c11 _Atomic and atomic_compare_exchange_weak -> not possible to mix c++11 and c11

* use builtin functions gcc __sync_bool_compare_and_swap and msvc _InterlockedCompareExchange64 -> possible, but requires proper testing

boolean CompareAndSwapPointer(volatile * void * ptr,
                              void * new_value,
                              void * old_value) {
if defined(_MSC_VER)
   if (InterlockedCompareExchange(ptr, new_value, old_value) == old_value) return false;
   else return true;
elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
   return __sync_bool_compare_and_swap(ptr, old_value, new_value);
else
  error No implementation
endif
}

* use Boost.Atomic -> requires new dependency

        WordT local_lower_word = lower_word, new_lower_word;
        do
        {
            new_lower_word = set_lower_value<WordT, T>(local_lower_word,
                                                       lower_mask[internal_index.element],
                                                       lower_offset[internal_index.element],
                                                       value);
        } while (!boost::atomics::detail::operations<sizeof(WordT), false>::compare_exchange_weak(
            lower_word,
            local_lower_word,
            new_lower_word,
            boost::memory_order_release,
            boost::memory_order_relaxed));
2017-06-27 13:02:53 +02:00
Patrick Niklaus dd8f5ac01d Make EMPTY_ENTRY_CLASS constexpr 2017-06-27 09:58:19 +00:00
Patrick Niklaus 22479ff5d8 Avoid dead-lock if other = this 2017-06-27 09:58:19 +00:00
Patrick Niklaus 688b1f8bef Remove serialization test 2017-06-27 09:58:19 +00:00
Patrick Niklaus e5464526c8 Port isc file 2017-06-27 09:58:19 +00:00
Patrick Niklaus 37b8d3acd4 Refactor turn lane passing 2017-06-27 09:58:19 +00:00
Patrick Niklaus 4f13208ce8 Fix the propfile properties reading/writing 2017-06-27 09:58:19 +00:00
Michael Krasnyk 383640caaf Cleanup temporary test files 2017-06-26 11:03:32 +02:00
Michael Krasnyk 42f3401dd7 Add gdb svg printer for facade 2017-06-23 12:28:50 +02:00
Patrick Niklaus 7fb57c924f Explicitly implement move constructor for DeallocationVector 2017-06-23 09:22:30 +00:00
Patrick Niklaus 97592e5bc3 Refactor file writing in OSRM contract 2017-06-23 09:22:30 +00:00
Emil Tin 9922c0f4f7 adjust tests, cycleway allows cycling on footway 2017-06-22 14:20:42 +00:00
Emil Tin f27434f2fb fixes #4060, incorrect cycling against oneways 2017-06-22 14:20:42 +00:00
Daniel J. Hofmann 32d39b7b49 Adds Node.js docs to readme 2017-06-22 14:02:49 +02:00
Daniel J. Hofmann 5c20c7b295 Explains what a roundtrip is in the api docs 2017-06-22 14:01:45 +02:00
Daniel J. Hofmann df000debe9 Adapts obvious turn classification: no longer take entry_allowed into account, resolves #3987 2017-06-21 18:09:32 +02:00
Daniel J. Hofmann 31511416ed Adds a failing test case for obvious turn at the end of the road, see #3987 2017-06-21 18:09:32 +02:00
Patrick Niklaus 99b02cedfb Refactor tile tests 2017-06-19 15:59:38 +00:00
Daniel Patterson 4136bf2808 Add layer to debug tiles to expose all OSM nodes in that area. 2017-06-19 15:59:38 +00:00
Lev Dragunov 93d6fd05a9 No timestamps SIGSEV fix 2017-06-17 17:33:33 +00:00
Lev Dragunov 73c4bc1411 clang-format 2017-06-17 17:33:33 +00:00
Lev Dragunov dc9b4bcfec Time information for maximum distance in matching 2017-06-17 17:33:33 +00:00
Daniel Patterson e3276324b9 Include 'rate' property (reciprocal of weight) on debug tile edges. (#4162)
Include 'rate' property (reciprocal of weight) on debug tile edges and add turn weight data to debug tiles.
2017-06-15 17:50:57 +02:00
Moritz Kobitzsch f80e5db346 add support for visualising turn penalties in MLD Debug tiles (#4157)
- template function for tile functionality with edge finder operator
 - refactors unit tests into single function (reduce code duplication)
 - adds unit tests for core-ch
2017-06-15 13:59:44 +02:00
Daniel Patterson 35550d8c0a Parallelize generation of the edge-expanded-edges. 2017-06-15 09:05:45 +00:00
Daniel J. Hofmann b68d79407e Takes fn by forwarding ref. in for_each_pair, resolves #4148 2017-06-14 15:17:26 +00:00
Patrick Niklaus 27ed69b08f Parallize scripting on osmium::Buffer granularity
Fixes #3447 and reduces parsing time by about 15%.
2017-06-13 21:47:54 +00:00
Daniel Patterson cd8fb82215 Add flag to allow skipping calling node function for nodes with no tags. 2017-06-13 12:23:00 +00:00
Daniel Patterson 5c8e2b6f78 Don't copy the node/way/segment/turn function objects for every call. 12-13% speedup for lua processing right there. 2017-06-13 12:23:00 +00:00
Stepan Kuzmin 9d30817294 add tests for the gaps and tidy map matching flags #4145 2017-06-12 11:32:06 +00:00
Stepan Kuzmin 5ee3c4de9f Expose Map Matching gaps and tidy parameters in Node.js bindings #4021 2017-06-12 11:32:06 +00:00
Michael Krasnyk afbcb3d38c Don't filter out MLD tests 2017-06-10 11:05:57 +00:00
Daniel J. Hofmann de1d5f199f Uses correct coefficients for local optimality in CH alternatives
The alpha constant is for the local optimality T-Test threshold.

Before we used epsilon for the T-Test threshold, but the epsilon
constant is meant to be used for the stretch test(s) only.

This changeset fixes the local optimality T-Test and uses the
epsilon constant for the two stretch tests:
- We test the stretch for the total route against epsilon and
- We test the detour against the epsilon now, too

We can discuss if the second stretch test should actually use
epsilon, too, or a adapted value of it - but definitly not alpha.
2017-06-09 13:20:41 +02:00
Michael Krasnyk 9158f69ea0 Failing test for alternative path 2017-06-09 13:20:41 +02:00
Daniel J. Hofmann 2cfd9c8d01 Adds npm5 lockfile 2017-06-08 21:58:09 +00:00
Daniel Patterson 5026741652 Make initialization fail with a specific exception if the dataset isn't compatible with the algorithm being used, rather than crashing when a query occurs. 2017-06-08 18:31:51 +00:00
Daniel Patterson 3d77714c36 Make most command-line tools return useful error codes on well-known exceptions. 2017-06-08 15:03:24 +00:00
Michael Krasnyk 03e83ec6a0 Fix invalid roundabout instructions for different driving modes, #4129 2017-06-08 15:01:27 +00:00
Michael Krasnyk 9315dc1c73 Test for a roundabout with footway exits, #4129 2017-06-08 15:01:27 +00:00
Patrick Niklaus b8bb12b2e2 Merge pull request #4134 from gojuno/polyline_input
Polyline6 support for the http REST API
2017-06-08 12:05:49 +00:00
Lev Dragunov bd1532847c Changelog entry 2017-06-07 21:46:19 +03:00
Lev Dragunov 3602b58517 Review fixes 2017-06-07 21:43:49 +03:00
Lev Dragunov d7035291ea clang-format 2017-06-07 15:39:08 +03:00
Lev Dragunov 6b0bcb5171 Docs and tests 2017-06-07 15:24:00 +03:00
Lev Dragunov 6b8f3c7fef Polyline6 support in the REST input 2017-06-06 19:51:00 +03:00
Patrick Niklaus 0d12d2fd28 Merge pull request #4094 from Project-OSRM/refactor/rapidash
Replace timezone shapefile parsing with geojson parsing
2017-06-02 20:01:04 +00:00
Patrick Niklaus 10460fc2fb Fix PR comments 2017-06-02 18:46:21 +00:00
Patrick Niklaus 6c7f0edf50 Don't use manual extract commands in weight tests 2017-06-02 18:12:13 +00:00
Patrick Niklaus 51bf9c4ff2 Small fixes for osrm-runner 2017-06-02 18:12:13 +00:00
Patrick Niklaus 0266c9d969 Renumber nodes after running osrm-partition
The new numbering uses the partition information
to sort border nodes first to compactify storages
that need access indexed by border node ID.

We also get an optimized cache performance for free
sincr we can also recursively sort the nodes by cell ID.

This implements issue #3779.
2017-06-02 18:12:13 +00:00
Michael Krasnyk 879de346ea Add timezone names customization in tests 2017-06-02 17:35:18 +02:00
Michael Krasnyk 50d9c4b34a Add local time support for windows 2017-06-02 17:35:18 +02:00
Patrick Niklaus a195d7dfd3 Remove compiler errors and use 32bit for segment_index 2017-06-02 12:15:06 +00:00
Daniel Patterson 1c3cb897c1 Refactor RTree so that .fileIndex only contains EdgeDataT, and all r-tree structure is in the .ramIndex file.
Also tunes the BRANCHING_FACTOR a bit to speed up access with this new layout.
2017-06-02 12:15:06 +00:00
karenzshea 0e39320a77 do not run conditional cuke tests by default 2017-06-02 11:15:34 +02:00
karenzshea 1b162c1962 remove rapidjson gtest dep 2017-06-02 10:26:39 +02:00
karenzshea f497201322 add check that restrictions are off when not found in timezone polygons 2017-06-02 10:00:07 +02:00
karenzshea 65746edd2d deps and lint 2017-06-02 10:00:07 +02:00
karenzshea 91e1ac83d9 add london geojson fixture 2017-06-02 10:00:07 +02:00
karenzshea 63ea75612b by default restrictions are off if timezone is not found 2017-06-02 10:00:07 +02:00
Michael Krasnyk f9a650792a Fix updating conditional turn restrictions 2017-06-02 10:00:07 +02:00
karenzshea 564a29141e add testing geojson files 2017-06-02 10:00:07 +02:00
karenzshea c937d20e48 unit tests for geojson validation 2017-06-02 10:00:07 +02:00
karenzshea ca353eb7db refactor timezoner a bit for unit tests, add initial unit tests 2017-06-02 10:00:07 +02:00
karenzshea f268163ea0 remove shapefile dependency from build 2017-06-02 10:00:07 +02:00
karenzshea 6f41e3faf1 fixes to get compiling 2017-06-02 10:00:07 +02:00
karenzshea aed2c0124a rapidjson steppin in 2017-06-02 10:00:07 +02:00
Michael Krasnyk f5564c9275 Merge commit '632ce270fa23d00e969877e983da6bc7cbaf1458' as 'third_party/rapidjson' 2017-06-02 09:35:53 +02:00
Michael Krasnyk 632ce270fa Squashed 'third_party/rapidjson/' content from commit f54b0e47a
git-subtree-dir: third_party/rapidjson
git-subtree-split: f54b0e47a08782a6131cc3d60f94d038fa6e0a51
2017-06-02 09:35:53 +02:00
karenzshea 93dac6b246 vendoring rapidjson, header only library 2017-06-02 09:35:30 +02:00
Moritz Kobitzsch a92674022a make all u-turns continue 2017-06-01 12:39:10 +02:00
Moritz Kobitzsch ceaf065d0e don't collapse highway ramps into uturns (#4074) 2017-06-01 12:39:10 +02:00
Michael Krasnyk a58139dfb5 Terminate earlier if mason fails to install clang++ on travis 2017-06-01 10:26:11 +00:00
Moritz Kobitzsch 9bd2b0deaa fix invalid turn angle in forks 2017-06-01 11:43:18 +02:00
Michael Krasnyk d262c4dfaa [skip ci] Add comments about order of post-processing calls 2017-06-01 11:13:31 +02:00
Michael Krasnyk dd009322de Remove roundabout skip as no leavesRoundabout steps after postProcess 2017-06-01 11:13:31 +02:00
Michael Krasnyk 858ec2e655 Fix steps collapsing after non-closed roundabouts, #4100 2017-06-01 11:13:31 +02:00
Michael Krasnyk 5d4ab4100a Test for collapsing sliproads after crossing a roundabout, #4100 2017-06-01 11:13:31 +02:00
FILLAU Jean-Maxime 43ddc63d67 Adds documentations on 'approaches' parameter.
Adds changelog
Adds doc/http.md doc
Adds doc/nodejs/api.md doc

Signed-off-by: FILLAU Jean-Maxime <jean-maxime.fillau@mapotempo.com>
2017-05-31 15:02:55 +00:00
Daniel J. Hofmann b5d1565dec Let's Travis check that for yarn lockfile and package.json sync
See https://yarnpkg.com/lang/en/docs/cli/check/
2017-05-31 14:40:31 +02:00
Daniel J. Hofmann 6658bb7d51 Runs yarn upgrade to sync yarn lockfile 2017-05-31 14:40:31 +02:00
Daniel J. Hofmann eb2db4994f Updates NAN for Node.js bindings 2017-05-31 14:40:31 +02:00
Daniel J. Hofmann d88e5ddf20 Uses node-cmake's CMake module directly, resolves #3912
No need for vendoring.
2017-05-31 14:40:31 +02:00
Daniel J. Hofmann f3558260b6 Splits turn penalty tests into bicycle and testbot domain, resolves #4067 2017-05-31 10:47:43 +02:00
Daniel J. Hofmann 0317bbb35d Splits via tests into car and testbot domain, resolves #4061 2017-05-30 16:38:51 +02:00
Daniel J. Hofmann a4a6ed7e38 Puts approach test into car domain 2017-05-30 16:37:05 +02:00
FILLAU Jean-Maxime 15a1e10487 Add nodejs binding test
Signed-off-by: FILLAU Jean-Maxime <jean-maxime.fillau@mapotempo.com>
2017-05-30 10:19:41 +00:00
FILLAU Jean-Maxime 98ad9d8b61 Refactoring enum Approach in enum class.
Suppress "engine::"

Signed-off-by: FILLAU Jean-Maxime <jean-maxime.fillau@mapotempo.com>
2017-05-30 10:19:41 +00:00
FILLAU Jean-Maxime c573cdb0ae Use formating script.
Signed-off-by: FILLAU Jean-Maxime <jean-maxime.fillau@mapotempo.com>
2017-05-30 10:19:41 +00:00
FILLAU Jean-Maxime 82a149eb87 Propagating approach parameter to every phantom nodes search function.
Propagating approach parameter for plugins :
 - tabler
 - nearest
 - trip

Signed-off-by: FILLAU Jean-Maxime <jean-maxime.fillau@mapotempo.com>
2017-05-30 10:19:41 +00:00
FILLAU Jean-Maxime 089c98a107 Adding support for left left hand driving.
Signed-off-by: FILLAU Jean-Maxime <jean-maxime.fillau@mapotempo.com>
2017-05-30 10:19:41 +00:00
FILLAU Jean-Maxime 17a73e3979 Add NodeJS API for Approaches param.
Signed-off-by: FILLAU Jean-Maxime <jean-maxime.fillau@mapotempo.com>
2017-05-30 10:19:41 +00:00
FILLAU Jean-Maxime f65299d665 Rename side API
Side -> Approach
 - DEFAULT -> CURB
 - BOTH -> UNRESTRICTED
 - remove OPPOSITE param

Signed-off-by: FILLAU Jean-Maxime <jean-maxime.fillau@mapotempo.com>
2017-05-30 10:19:41 +00:00
FILLAU Jean-Maxime f782dfbfd9 Add uturn test case in cucumber for sides param.
Signed-off-by: FILLAU Jean-Maxime <jean-maxime.fillau@mapotempo.com>
2017-05-30 10:19:41 +00:00
FILLAU Jean-Maxime ec7934ea33 Change qi::lit for qi::symbols for the sides parameter parser.
Refactor code :
 - Suppress StartSide Enum
 - Change Side Structure for Enum

Signed-off-by: FILLAU Jean-Maxime <jean-maxime.fillau@mapotempo.com>
2017-05-30 10:19:41 +00:00
FILLAU Jean-Maxime 2de17f3fd0 Adding url unit test for "sides" parameters
Signed-off-by: FILLAU Jean-Maxime <jean-maxime.fillau@mapotempo.com>
2017-05-30 10:19:41 +00:00
FILLAU Jean-Maxime ba2bf4f78e Adding cucumber file test "side_param_feature" for the side parameter.
- test on normal segment
 - test on oneway segment

Signed-off-by: FILLAU Jean-Maxime <jean-maxime.fillau@mapotempo.com>
2017-05-30 10:19:41 +00:00
FILLAU Jean-Maxime 8a54e6a0ec Adding "sides" params for the sides option tests into java script
Signed-off-by: FILLAU Jean-Maxime <jean-maxime.fillau@mapotempo.com>
2017-05-30 10:19:41 +00:00
FILLAU Jean-Maxime 8e70c87e64 New "sides" setting in base parameters for phantom nodes.
- Adding sides parameter into base parameters, it can take the values SIDE, OPPOSITE or DEFAULT.
 - Adding url parser for "sides" parameter, url values are "s" for SIDE, "o" for OPPOSITE and "d" for DEFAULT, example : "sides=s;s".
 - Checking parameters, if "sides" parameter is used, the number of parameter is the same as number of location.
 - Create a phantom to start at side driving or Opposite side driving.

Signed-off-by: FILLAU Jean-Maxime <jean-maxime.fillau@mapotempo.com>
2017-05-30 10:19:41 +00:00
Patrick Niklaus 579a1ed42e Don't copy the object on WriteOne 2017-05-29 15:09:36 +00:00
Patrick Niklaus a544935e7d Fix unit-test 2017-05-29 15:09:36 +00:00
Daniel Patterson 7eab227ab1 Use FileWriter for better error handling when writing name data. 2017-05-29 15:09:36 +00:00
Daniel Patterson 382a5cebab Use FileWriter for writing LeafNode data to improve error handling. 2017-05-29 15:09:36 +00:00
Johan Uhle 6d2353c302 Allow docker image with assertions (#4016) 2017-05-29 12:08:44 +02:00
Lev Dragunov 45ee096260 Ignore split breakage fix. 2017-05-26 10:55:03 +00:00
Daniel Patterson c21a476b00 Overridden virtual function should be marked as override final. 2017-05-26 09:15:34 +00:00
Daniel Patterson 25c870dc57 Unused padding doesn't need to be named, removing name silences compiler warnings. 2017-05-26 09:15:34 +00:00
Daniel Patterson 4605c35101 Mark NodeJS headers as system includes to suppress compiler warnings. 2017-05-26 09:15:34 +00:00
Daniel Patterson 8655c61ec2 Remove variable name for unused parameters to silence compiler warnings. 2017-05-26 09:15:34 +00:00
Michael Krasnyk 314cf3f31a Add a comment line about counting 2017-05-23 18:27:47 +00:00
Michael Krasnyk 1d26deb0be Allow counting of service exits on service roundabouts, see #4075 2017-05-23 18:27:47 +00:00
Michael Krasnyk ac35757616 [skip ci] Adjust CHANGELOG and the test description 2017-05-23 14:35:23 +02:00
Michael Krasnyk 47f2f17987 Change order of guidance post-processing, fix #4030 2017-05-23 14:35:23 +02:00
Michael Krasnyk a63b43c259 Place reverse entering_via_edge in the front of intersection_view 2017-05-22 09:33:59 +00:00
Michael Krasnyk 14582fea5f Added example for roundabout overlapping 2017-05-22 09:33:59 +00:00
Daniel J. Hofmann 862ec14e06 Asserts Valid Iterators in Roundabout Exit Invalidation, see #4024 2017-05-22 09:33:59 +00:00
Daniel Patterson 570d81c6dd Bypass boost::numeric_cast checks for coordinate values that have already been validated (#4059)
(i.e. stuff that's stored in our datafiles).  Keep those checks for user-supplied values
(i.e. coordinates coming from files during preprocessing, or coordinates supplied by users
 during requests)
2017-05-19 10:52:44 -07:00
Michael Krasnyk 4964d0dcbd Adjust expectation and remove non-valid assertions 2017-05-19 09:47:47 +00:00
Patrick Niklaus 5c00fc9769 Disable weight update factor test, see issue #4065 2017-05-19 08:25:03 +00:00
Patrick Niklaus 3599d1db8e Switch code to use packed vector for segment weights/durations 2017-05-19 08:25:03 +00:00
Michael Krasnyk 5c61f00ffa Add testbot profile to zero-speed-updates.feature 2017-05-19 09:00:23 +02:00
Daniel Patterson aef3ff3e7b Use correct node-loading code in rtree benchmark. (#4064) 2017-05-18 13:29:50 -07:00
Daniel J. Hofmann a971c2ef37 Applies max turn weight for turns onto restricted weights: no need for custom penalty 2017-05-18 16:33:50 +00:00
Daniel J. Hofmann c757f70b97 Prevents possible overflow in applying a turn penalty onto restricted roads 2017-05-18 16:33:50 +00:00
Daniel J. Hofmann 403db7cc84 Lets MakeResponse(Route) explicitly call MakeResponse(ManyRoutes) in Route API
https://github.com/Project-OSRM/osrm-backend/pull/4035#discussion_r116890340
2017-05-18 10:54:32 +02:00
Michael Krasnyk 7a4c5a64fa Simplify angleBetween to avoid cancellation losses 2017-05-17 15:52:11 +00:00
Michael Krasnyk c535e74a65 Added test to check bearing::angleBetween precision 2017-05-17 15:52:11 +00:00
Michael Krasnyk e605917083 Changed some assert to OSRM_ASSERT 2017-05-17 15:52:11 +00:00
Michael Krasnyk 14db5f8d1f Fix OSRM_ASSERT_MSG compilation fail in Release mode 2017-05-17 15:52:11 +00:00
Michael Krasnyk 3546abc30e Added ChangeLog entry 2017-05-17 15:21:51 +00:00
Michael Krasnyk e4b58c1258 Reverted connection of forward and backward nodes in one SCC 2017-05-17 15:21:51 +00:00
Michael Krasnyk 5e2e1d4c96 Renamed EdgeBasedNode to EdgeBasedNodeSegment 2017-05-17 15:21:51 +00:00
Michael Krasnyk 1a7cd785f2 Rename .nodes -> .nbg_nodes and .nodes_data -> .ebg_nodes 2017-05-17 15:21:51 +00:00
Michael Krasnyk 65de940882 Change EdgeBasedNodeDataExternalContainer to EdgeBasedNodeDataContainer 2017-05-17 15:21:51 +00:00
Michael Krasnyk 26702920b4 Move ComponentID to EdgeBasedNodeDataContainer 2017-05-17 15:21:51 +00:00
Michael Krasnyk 373087d74f Initialize unused bits in PhantomNode 2017-05-17 15:21:51 +00:00
Michael Krasnyk ca6b1b39b7 Remove data duplicates in .node file 2017-05-17 15:21:51 +00:00
Michael Krasnyk 8934167e76 Merge part of .nodes fields into .nodes_data 2017-05-17 15:21:51 +00:00
Daniel J. Hofmann 9972b5f1f9 Removes unused PUBLISH_NODE_BINDINGS var from .travis.yml 2017-05-16 16:23:24 +00:00
Patrick Niklaus d8877abf26 Fix weight value for alley 2017-05-16 16:19:17 +00:00
Patrick Niklaus bce3b68281 Add regression test 2017-05-16 16:19:17 +00:00
Patrick Niklaus 7d42e18479 Fix bicycle turn penalties 2017-05-16 16:19:17 +00:00
Mateusz Loskot 4294295242 Mark way_function properties as mandatory
Format values and function names as code (refines #4040)
2017-05-16 15:17:57 +00:00
Frederik Ramm 16f492026a remove penalty_table from car.lua
remove penalty_table as it is apparently not used anywhere.
2017-05-16 10:40:21 +00:00
Mateusz Loskot 7d58f0ec53 Document default values of global properties set in profile 2017-05-16 10:39:51 +00:00
Patrick Niklaus 6bd724fe24 Rewrite packed vector to also allow random access
This fixes issues #3952. The new approach pre-computes masks for fast
access. Since elements can potentially span multiple words we need masks
and offsets for each upper and lower word.

Due to a bug in the C++14 standart the mask computation is not
recognized as constexpr, but would work on C++17.
2017-05-16 10:25:29 +00:00
Patrick Niklaus 26a208529e [skip ci] Fix alternatives_count documentation 2017-05-15 17:02:41 +00:00
Patrick Niklaus 3fbdb19956 Bump cucumber timeout of gcc-6 with coverage 2017-05-15 12:23:07 +00:00
Patrick Niklaus ea9d5eca0f Update yarn.lock 2017-05-15 12:23:07 +00:00
Patrick Niklaus 0f66278532 Disbale doc builds again 2017-05-15 12:23:07 +00:00
Patrick Niklaus b9206ef017 Upgrade docbox 2017-05-15 12:23:07 +00:00
Patrick Niklaus 9d8f1d9dbf Try documentation 4.0.0 JS RC1 2017-05-15 12:23:07 +00:00
Daniel J. Hofmann e064a9334b Lifts restriction to only provide zero or one alternative routes 2017-05-12 13:54:22 +02:00
Daniel J. Hofmann e12c7756d9 Weight-ifies alternatives related code-paths 2017-05-12 13:54:22 +02:00
Moritz Kobitzsch f8002480c2 fix continue_straight interaction with bearing specification 2017-05-12 13:38:04 +02:00
Karen Shea 799a677e7a Conditional turn restriction support (#3841)
* optionally include condition and via node coords in InputRestrictionContainer

* only write conditionals to disk, custom serialization for restrictions

* conditional turn lookup, reuse timezone validation from
extract-conditionals

* adapt updater to use coordinates/osm ids, remove internal to external map

* add utc time now parameter to contraction

* only compile timezone code where libshp is found, adapt test running

* slight refactor, more tests

* catch invalid via nodes in restriction parsing, set default cucumber
origin to guinée

* add another run to test mld routed paths

* cosmetic review changes

* Simplify Timezoner for windows build

* Split declaration and parsing parts for opening hours

* adjust conditional tests to run without shapefiles

* always include parse conditionals option

* Adjust travis timeout

* Added dummy TZ shapefile with test timezone polygons

* [skip ci] update changelog
2017-05-11 12:13:52 +02:00
Michael Krasnyk 12f47708cd Adjust method and function names 2017-05-11 09:13:42 +00:00
Michael Krasnyk 9358aa1128 Disable nodes with invalid segments 2017-05-11 09:13:42 +00:00
Michael Krasnyk a44b63fbb9 Add response codes of trip and routability queries 2017-05-11 09:13:42 +00:00
Mateusz Łoskot e2b7e8a4da Refactor osrm-extract and osrm-contract to use osrm lib interface
Simplifies implementation of the tools slightly.
Ensures osrm::extract and osrm::contract keep working.

Follows up PR #3787
2017-05-10 21:35:42 +00:00
Michael Krasnyk a5bfcd876f Add response code to test result values 2017-05-09 16:58:23 +00:00
Patrick Niklaus 2f02384d22 Disbale boost::interprocess condition variables on Linux to fix issue #3911 2017-05-08 09:15:01 +00:00
Michael Krasnyk 3de8613843 Added test with an empty CSV file 2017-05-05 22:15:05 +00:00
Michael Krasnyk ccb8a07dc7 Hide qi namespace alias 2017-05-05 22:15:05 +00:00
Michael Krasnyk 6484fed190 Remove generate-edge-lookup argument in feature tests 2017-05-05 22:15:05 +00:00
Michael Krasnyk 6b103c6d0b Add zero file size check 2017-05-05 22:15:05 +00:00
Michael Krasnyk 669ac058b8 Print diagnostic information to avoid boost cryptic errors 2017-05-05 22:15:05 +00:00
Michael Krasnyk e92967167f Use mapped_file_source for CSV files 2017-05-05 22:15:05 +00:00
Patrick Niklaus f3de2c9b94 For the cyclability profile add alley penalties 2017-05-05 17:06:50 +00:00
Patrick Niklaus 21cd1a44e8 Add failing test case for alleys 2017-05-05 17:06:50 +00:00
Johan Uhle 6ca46795aa Fix gitsha output in dockerfile (#4014) 2017-05-05 15:55:48 +02:00
Patrick Niklaus 35d7b7ceaf Regenerate docs 2017-05-05 08:51:36 +00:00
Patrick Niklaus faa2094488 Fix docs for radius 2017-05-05 08:51:36 +00:00
Patrick Niklaus e6d776699f Fix overloaded parameter docs 2017-05-05 08:51:36 +00:00
Patrick Niklaus 200e90ad43 Disable TOC 2017-05-05 08:51:36 +00:00
Michael Krasnyk c66f67ac07 Updated assertions to catch negative duration values for weights > 0
but still clamping negative duration values at 0 without checking weights
2017-05-04 21:03:45 +00:00
Michael Krasnyk 334a7b50cd Use rectified linear unit to prevent negative duration values 2017-05-04 21:03:45 +00:00
Michael Krasnyk a9d3e61884 Fix minor review comments 2017-05-03 21:59:38 +00:00
Michael Krasnyk 88082c48cf Remove GetEdgeBasedNodeID from TurnDataContainer 2017-05-03 21:59:38 +00:00
Michael Krasnyk 40d0297885 Added unpacked_nodes vector to annotatePath interface 2017-05-03 21:59:38 +00:00
Michael Krasnyk be1acae20c Use edge_id as index in ebg_node_data_container 2017-05-03 21:59:38 +00:00
Michael Krasnyk f1e4349c82 Move geometry ids, name_ids and travel_modes to EdgeBasedNodeData 2017-05-03 21:59:38 +00:00
Michael Krasnyk 1f701341db Move reserve call before pushing weights 2017-05-03 21:59:38 +00:00
Patrick Niklaus 2a24468267 Regenerate API docs 2017-05-03 15:23:03 +00:00
Patrick Niklaus f531a956f5 Update nodejs docs to document the constructor better 2017-05-03 15:23:03 +00:00
Patrick Niklaus 1aea10010b Run the docs in CI again 2017-05-02 16:57:23 +00:00
Patrick Niklaus 2cf6010665 Split travis jobs 2017-05-02 16:57:23 +00:00
Michael Krasnyk 2402d60429 Adjusted to PR comments 2017-05-02 16:55:03 +00:00
Michael Krasnyk 19494984eb Fix incorrect exit turn invalidation 2017-05-02 16:55:03 +00:00
Michael Krasnyk 07c7cb3c6c Rename BinaryHeap to QueryHeap 2017-05-02 15:54:25 +00:00
Michael Krasnyk 358aebec4d Decrease memory footprint of HeapHandle from 32 to 24 bytes 2017-05-02 15:54:25 +00:00
Michael Krasnyk 05826150f6 Use boost::heap::d_ary_heap 2017-05-02 15:54:25 +00:00
Michael Krasnyk 5827358a1e node.js script to run random osrm queries 2017-05-02 15:54:25 +00:00
Daniel J. Hofmann 9334cc463d Fixes Table not checking for valid phantom nodes
We failed to check if we could actually find phantom nodes for all
coordinates in the table plugin, leading to corrupt internal state.

```
curl 'http://localhost:5000/table/v1/car/7.4151,43.7305;7.4222,43.7368?radiuses=0;'
```

```
[assert][140505627227904] /tmp/osrm-backend/include/engine/routing_algorithms/routing_base.hpp:68
in: void osrm::engine::routing_algorithms::insertNodesInHeap(osrm::engine::SearchEngineData<osrm::engine::routing_algorithms::ch::Algorithm>::ManyToManyQueryHeap&, const osrm::engine::PhantomNode&) [with bool DIRECTION = false; osrm::engine::SearchEngineData<osrm::engine::routing_algorithms::ch::Algorithm>::ManyToManyQueryHeap = osrm::util::BinaryHeap<unsigned int, unsigned int, int, osrm::engine::ManyToManyHeapData, osrm::util::UnorderedMapStorage<unsigned int, int> >]: phantom_node.IsValid()
terminate called without an active exception
```
2017-05-02 13:41:33 +02:00
Daniel J. Hofmann 5532ee627f Fixes util.format calls in Cucumber support code 2017-05-02 12:52:10 +02:00
Freenerd 2021c30805 Save gitsha for later use in docker container 2017-05-02 09:36:09 +00:00
Patrick Niklaus 0e39aa9488 Address PR comments 2017-04-24 16:04:41 +00:00
Patrick Niklaus 8ec0745883 Add benchmark 2017-04-24 16:04:41 +00:00
Patrick Niklaus c446b017ef Switch from macro based StrongTypedef to template version 2017-04-24 16:04:41 +00:00
Patrick Niklaus a68435d856 Move clip functions to lambda 2017-04-20 14:58:26 +00:00
Patrick Niklaus 814324146b signed -> unsigned 2017-04-20 14:58:26 +00:00
Patrick Niklaus 11d8b2ba5a Add clipping for 20 bits to SegmentWeight/SegmentDuration 2017-04-20 14:58:26 +00:00
Patrick Niklaus d6c6a262d8 Use 16bit for SegmentWeight and SegmentDuration 2017-04-20 14:58:26 +00:00
Patrick Niklaus 5c4f96e4bc Fix checking columns if route is not specified 2017-04-20 13:52:13 +00:00
Patrick Niklaus 9974b8b1da Apply traffic light penalty also for non-turns 2017-04-20 13:52:13 +00:00
Michael Krasnyk c81baae1b9 Fix incorrect weight fallback for distance-based weights 2017-04-19 08:28:38 +02:00
Patrick Niklaus e96545be2e Disable is_integral check because it fails for strong-type-def 2017-04-18 17:24:46 +00:00
Patrick Niklaus 609801ae99 Fix PR comments 2017-04-18 17:24:46 +00:00
Patrick Niklaus a66918a303 Make PackedVector generic 2017-04-18 17:24:46 +00:00
Pepijn Schoen e85c4f87e9 Skip fingerprinting .turn_penalties_index, to be done in a separate iteration because of Appveyor issues. 2017-04-18 12:01:06 +00:00
Pepijn Schoen 8ff5a22799 clang-format 2017-04-18 12:01:06 +00:00
Pepijn Schoen 4929d1297e Address PR comments 2017-04-18 12:01:06 +00:00
Pepijn Schoen b830a8f942 Replace Count32 with Count64 2017-04-18 12:01:06 +00:00
Pepijn Schoen 0c388a5264 Fingerprint .turn_penalties_index 2017-04-18 12:01:06 +00:00
Pepijn Schoen e4eb18cf4e Fingerprint .properties 2017-04-18 12:01:06 +00:00
Pepijn Schoen 5b4f432cba Fingerprint .tld 2017-04-18 12:01:06 +00:00
Pepijn Schoen 15f7257645 Fingerprint .turn_duration_penalties and .turn_weight_penalties 2017-04-18 12:01:06 +00:00
Pepijn Schoen 12c11f1d48 Fingerprint .names 2017-04-18 12:01:06 +00:00
Pepijn Schoen a196d5ced3 Fingerprint .timestamp, normalize use of Size / GetSize and make that function Fingerprint-aware 2017-04-18 12:01:06 +00:00
Pepijn Schoen 802af08179 Fingerprint .core 2017-04-18 12:01:06 +00:00
Pepijn Schoen 85ec50552d fingerprint .ramIndex / tree nodes 2017-04-18 12:01:06 +00:00
Pepijn Schoen 8da96f8d94 fingerprint .tld 2017-04-18 12:01:06 +00:00
Pepijn Schoen 5b9d858f57 Fingerprint .edges 2017-04-18 12:01:06 +00:00
Pepijn Schoen 023242ec03 Fingerprint geometries 2017-04-18 12:01:06 +00:00
Pepijn Schoen 683e53e950 Fingerprint .osrm.datasource_names 2017-04-18 12:01:06 +00:00
Pepijn Schoen df0ee955e8 Fingerprint and move .levels 2017-04-18 12:01:06 +00:00
Daniel Patterson 771834793f Only log components in Debug mode, it's very wordy and not really useful (#3948)
for Release builds.

Log component counts at the end of the SCC run.
2017-04-17 16:49:26 -07:00
Michael Krasnyk 3915c1286b Don't remove the last original coordinate during tiding 2017-04-13 21:27:00 +00:00
Patrick Niklaus b422b636d3 Remove boost::make_unique to fix travis node builds 2017-04-13 21:19:09 +00:00
Patrick Niklaus 5bbc675c6b Bump osrm version to 5.8 2017-04-13 21:19:09 +00:00
Patrick Niklaus addf4d90e9 Use .gitignore default instead of .npmignore 2017-04-13 21:19:09 +00:00
Patrick Niklaus 721e5e7947 Restructure travis build 2017-04-13 21:19:09 +00:00
Michael Krasnyk dea3144c4d Use total angle for turn instruction if entry step has large distance 2017-04-12 23:22:44 +00:00
Patrick Niklaus 1080d25fcf Install node version as well 2017-04-12 20:27:32 +00:00
Patrick Niklaus afb553a31e Only use three jobs for node builds 2017-04-12 20:27:32 +00:00
Patrick Niklaus e2c231234d Use nvm instead of travis node_js key
This fixes issues on container builds that would always use
node 6 even when 4 was specified.
2017-04-12 20:27:32 +00:00
Patrick Niklaus 103f7117ed Update changelog 2017-04-12 14:59:26 +00:00
632 changed files with 76808 additions and 8371 deletions
+15
View File
@@ -0,0 +1,15 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
# Explicitly declare text files you want to always be normalized and converted
# to native line endings on checkout.
*.cpp text
*.hpp text
# Declare files that will always have CRLF line endings on checkout.
*.bat text eol=crlf
*.cmd text eol=crlf
*.ps1 text eol=crlf
# Declare files that will always have LF line endings on checkout.
*.sh text eol=lf
+5
View File
@@ -61,6 +61,11 @@ Thumbs.db
.cproject .cproject
.project .project
# Visual Studio (Code) related files #
######################################
/.vs*
/*.local.bat
# stxxl related files # # stxxl related files #
####################### #######################
.stxxl .stxxl
+56 -28
View File
@@ -17,9 +17,9 @@ notifications:
branches: branches:
only: only:
- master - master
- "5.7"
# enable building tags # enable building tags
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/ - /^v\d+\.\d+(\.\d+)?(-\S*)?$/
- "5.9"
cache: cache:
yarn: true yarn: true
@@ -49,21 +49,49 @@ matrix:
# Debug Builds # Debug Builds
- os: linux - os: linux
compiler: "gcc-6-debug-cov-asan" compiler: "format-taginfo-docs"
env: NODE=6
sudo: false
before_install:
install:
- source $NVM_DIR/nvm.sh
- nvm install $NODE
- nvm use $NODE
- npm --version
- npm install --ignore-scripts
- npm link --ignore-scripts
script:
- ./scripts/check_taginfo.py taginfo.json profiles/car.lua
- ${MASON} install clang-format 3.8.1
- PATH=$(${MASON} prefix clang-format 3.8.1)/bin:${PATH} ./scripts/format.sh && ./scripts/error_on_dirty.sh
# See issue 4043
#- npm run docs && ./scripts/error_on_dirty.sh
after_success:
- os: linux
compiler: "gcc-6-debug-cov"
addons: &gcc6 addons: &gcc6
apt: apt:
sources: ['ubuntu-toolchain-r-test'] sources: ['ubuntu-toolchain-r-test']
packages: ['g++-6', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev'] packages: ['g++-6', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Debug' TARGET_ARCH='x86_64-asan' ENABLE_COVERAGE=ON ENABLE_SANITIZER=ON env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Debug' ENABLE_COVERAGE=ON CUCUMBER_TIMEOUT=20000
after_success: after_success:
- bash <(curl -s https://codecov.io/bash) - bash <(curl -s https://codecov.io/bash)
- os: linux
compiler: "gcc-6-debug-asan"
addons: &gcc6
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-6', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Debug' TARGET_ARCH='x86_64-asan' ENABLE_SANITIZER=ON CUCUMBER_TIMEOUT=20000
- os: linux - os: linux
compiler: "clang-4.0-debug" compiler: "clang-4.0-debug"
addons: &clang40 addons: &clang40
apt: apt:
sources: ['ubuntu-toolchain-r-test'] sources: ['ubuntu-toolchain-r-test']
packages: ['libstdc++-5-dev', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev'] packages: ['libstdc++-5-dev', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Debug' CUCUMBER_TIMEOUT=60000 env: CLANG_VERSION='4.0.0' BUILD_TYPE='Debug' CUCUMBER_TIMEOUT=60000
- os: linux - os: linux
@@ -88,7 +116,7 @@ matrix:
addons: &gcc6 addons: &gcc6
apt: apt:
sources: ['ubuntu-toolchain-r-test'] sources: ['ubuntu-toolchain-r-test']
packages: ['g++-6', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev'] packages: ['g++-6', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release' env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release'
- os: linux - os: linux
@@ -97,12 +125,20 @@ matrix:
TARGET_ARCH='i686' CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release' TARGET_ARCH='i686' CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release'
CFLAGS='-m32 -msse2 -mfpmath=sse' CXXFLAGS='-m32 -msse2 -mfpmath=sse' CFLAGS='-m32 -msse2 -mfpmath=sse' CXXFLAGS='-m32 -msse2 -mfpmath=sse'
- os: linux
compiler: "gcc-6-stxxl"
addons: &gcc6
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-6', 'libbz2-dev', 'libstxxl-dev', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release' ENABLE_STXXL=On
- os: linux - os: linux
compiler: "gcc-4.9-release" compiler: "gcc-4.9-release"
addons: &gcc49 addons: &gcc49
apt: apt:
sources: ['ubuntu-toolchain-r-test'] sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.9', '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'] packages: ['g++-4.9', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev', 'ccache']
env: CCOMPILER='gcc-4.9' CXXCOMPILER='g++-4.9' BUILD_TYPE='Release' env: CCOMPILER='gcc-4.9' CXXCOMPILER='g++-4.9' BUILD_TYPE='Release'
- os: osx - os: osx
@@ -119,7 +155,7 @@ matrix:
#- addons: &clang40 #- addons: &clang40
#- apt: #- apt:
#- sources: ['llvm-toolchain-trusty-4.0', 'ubuntu-toolchain-r-test'] #- sources: ['llvm-toolchain-trusty-4.0', 'ubuntu-toolchain-r-test']
#- packages: ['clang-4.0', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev'] #- packages: ['clang-4.0', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
#- env: CCOMPILER='clang-4.0' CXXCOMPILER='clang++-4.0' BUILD_TYPE='Release' #- env: CCOMPILER='clang-4.0' CXXCOMPILER='clang++-4.0' BUILD_TYPE='Release'
# Shared Library # Shared Library
@@ -128,7 +164,7 @@ matrix:
addons: &gcc6 addons: &gcc6
apt: apt:
sources: ['ubuntu-toolchain-r-test'] sources: ['ubuntu-toolchain-r-test']
packages: ['g++-6', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev'] packages: ['g++-6', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
# Disabled because CI slowness # Disabled because CI slowness
@@ -137,7 +173,7 @@ matrix:
#- addons: &clang40 #- addons: &clang40
#- apt: #- apt:
#- sources: ['llvm-toolchain-trusty-4.0', 'ubuntu-toolchain-r-test'] #- sources: ['llvm-toolchain-trusty-4.0', 'ubuntu-toolchain-r-test']
#- packages: ['clang-4.0', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev'] #- packages: ['clang-4.0', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
#- env: CCOMPILER='clang-4.0' CXXCOMPILER='clang++-4.0' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON #- env: CCOMPILER='clang-4.0' CXXCOMPILER='clang++-4.0' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
# Node build jobs. These skip running the tests. # Node build jobs. These skip running the tests.
@@ -148,7 +184,7 @@ matrix:
apt: apt:
sources: ['ubuntu-toolchain-r-test'] sources: ['ubuntu-toolchain-r-test']
packages: ['libstdc++-5-dev'] packages: ['libstdc++-5-dev']
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON PUBLISH_NODE_BINDINGS=On JOBS=3 env: CLANG_VERSION='4.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3
install: install:
- pushd ${OSRM_BUILD_DIR} - pushd ${OSRM_BUILD_DIR}
- | - |
@@ -171,7 +207,7 @@ matrix:
apt: apt:
sources: ['ubuntu-toolchain-r-test'] sources: ['ubuntu-toolchain-r-test']
packages: ['libstdc++-5-dev'] packages: ['libstdc++-5-dev']
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON PUBLISH_NODE_BINDINGS=On JOBS=3 env: CLANG_VERSION='4.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3
install: install:
- pushd ${OSRM_BUILD_DIR} - pushd ${OSRM_BUILD_DIR}
- | - |
@@ -194,7 +230,7 @@ matrix:
apt: apt:
sources: ['ubuntu-toolchain-r-test'] sources: ['ubuntu-toolchain-r-test']
packages: ['libstdc++-5-dev'] packages: ['libstdc++-5-dev']
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON PUBLISH_NODE_BINDINGS=On JOBS=3 NODE="6" env: CLANG_VERSION='4.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="6"
install: install:
- pushd ${OSRM_BUILD_DIR} - pushd ${OSRM_BUILD_DIR}
- | - |
@@ -217,7 +253,7 @@ matrix:
apt: apt:
sources: ['ubuntu-toolchain-r-test'] sources: ['ubuntu-toolchain-r-test']
packages: ['libstdc++-5-dev'] packages: ['libstdc++-5-dev']
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON PUBLISH_NODE_BINDINGS=On JOBS=3 NODE="6" env: CLANG_VERSION='4.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="6"
install: install:
- pushd ${OSRM_BUILD_DIR} - pushd ${OSRM_BUILD_DIR}
- | - |
@@ -247,10 +283,6 @@ before_install:
export JOBS=$((`sysctl -n hw.ncpu` + 1)) export JOBS=$((`sysctl -n hw.ncpu` + 1))
fi fi
fi fi
- |
if [ -n "${RUN_CLANG_FORMAT}" ]; then
${MASON} install clang-format 3.8.1 && PATH=$(${MASON} prefix clang-format 3.8.1)/bin:${PATH} ./scripts/format.sh
fi
- | - |
if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
sudo mdutil -i off / sudo mdutil -i off /
@@ -263,11 +295,12 @@ before_install:
- export PUBLISH=$([[ "${TRAVIS_TAG:-}" == "v${PACKAGE_JSON_VERSION}" ]] && echo "On" || echo "Off") - export PUBLISH=$([[ "${TRAVIS_TAG:-}" == "v${PACKAGE_JSON_VERSION}" ]] && echo "On" || echo "Off")
- echo "Using ${JOBS} jobs" - echo "Using ${JOBS} jobs"
- yarn install --ignore-scripts - yarn install --ignore-scripts
- yarn check --ignore-scripts --integrity
# Bootstrap cmake to be able to run mason # Bootstrap cmake to be able to run mason
- CMAKE_URL="https://mason-binaries.s3.amazonaws.com/${TRAVIS_OS_NAME}-x86_64/cmake/${CMAKE_VERSION}.tar.gz" - CMAKE_URL="https://mason-binaries.s3.amazonaws.com/${TRAVIS_OS_NAME}-x86_64/cmake/${CMAKE_VERSION}.tar.gz"
- CMAKE_DIR="mason_packages/${TRAVIS_OS_NAME}-x86_64/cmake/${CMAKE_VERSION}" - CMAKE_DIR="mason_packages/${TRAVIS_OS_NAME}-x86_64/cmake/${CMAKE_VERSION}"
- mkdir -p ${CMAKE_DIR} - mkdir -p ${CMAKE_DIR}
- travis_retry wget --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C ${CMAKE_DIR} || exit 1 - travis_retry wget --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C ${CMAKE_DIR} || travis_terminate 1
- export PATH=${CMAKE_DIR}/bin:${PATH} - export PATH=${CMAKE_DIR}/bin:${PATH}
- ${MASON} install tbb 2017_20161128 && export LD_LIBRARY_PATH=$(${MASON} prefix tbb 2017_20161128)/lib/:${LD_LIBRARY_PATH} - ${MASON} install tbb 2017_20161128 && export LD_LIBRARY_PATH=$(${MASON} prefix tbb 2017_20161128)/lib/:${LD_LIBRARY_PATH}
- ${MASON} install ccache ${CCACHE_VERSION} && export PATH=$(${MASON} prefix ccache ${CCACHE_VERSION})/bin:${PATH} - ${MASON} install ccache ${CCACHE_VERSION} && export PATH=$(${MASON} prefix ccache ${CCACHE_VERSION})/bin:${PATH}
@@ -275,12 +308,12 @@ before_install:
if [[ ! -z ${CLANG_VERSION} ]]; then if [[ ! -z ${CLANG_VERSION} ]]; then
export CCOMPILER='clang' export CCOMPILER='clang'
export CXXCOMPILER='clang++' export CXXCOMPILER='clang++'
${MASON} install clang++ ${CLANG_VERSION} && export PATH=$(${MASON} prefix clang++ ${CLANG_VERSION})/bin:${PATH} ${MASON} install clang++ ${CLANG_VERSION} && export PATH=$(${MASON} prefix clang++ ${CLANG_VERSION})/bin:${PATH} || travis_terminate 1
# we only enable lto for release builds # we only enable lto for release builds
# and therefore don't need to us ld.gold or llvm tools for linking # and therefore don't need to us ld.gold or llvm tools for linking
# for debug builds # for debug builds
if [[ ${BUILD_TYPE} == 'Release' ]]; then if [[ ${BUILD_TYPE} == 'Release' ]]; then
${MASON} install binutils 2.27 && export PATH=$(${MASON} prefix binutils 2.27)/bin:${PATH} ${MASON} install binutils 2.27 && export PATH=$(${MASON} prefix binutils 2.27)/bin:${PATH} || travis_terminate 1
fi fi
fi fi
- ccache --max-size=256M # limiting the cache's size to roughly the previous job's object sizes - ccache --max-size=256M # limiting the cache's size to roughly the previous job's object sizes
@@ -290,10 +323,6 @@ before_install:
- mkdir ${OSRM_BUILD_DIR} - mkdir ${OSRM_BUILD_DIR}
install: install:
- |
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
./scripts/check_taginfo.py taginfo.json profiles/car.lua
fi
- pushd ${OSRM_BUILD_DIR} - pushd ${OSRM_BUILD_DIR}
- | - |
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \ cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
@@ -303,6 +332,7 @@ install:
-DENABLE_COVERAGE=${ENABLE_COVERAGE:-OFF} \ -DENABLE_COVERAGE=${ENABLE_COVERAGE:-OFF} \
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \ -DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
-DENABLE_SANITIZER=${ENABLE_SANITIZER:-OFF} \ -DENABLE_SANITIZER=${ENABLE_SANITIZER:-OFF} \
-DENABLE_STXXL=${ENABLE_STXXL:-OFF} \
-DBUILD_TOOLS=ON \ -DBUILD_TOOLS=ON \
-DENABLE_CCACHE=ON \ -DENABLE_CCACHE=ON \
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} -DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR}
@@ -323,8 +353,6 @@ install:
- cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} - cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
- make --jobs=${JOBS} - make --jobs=${JOBS}
- popd - popd
# building docs only works with npm3+ not with yarn or npm2
#- yarn run docs
script: script:
- if [[ $TARGET_ARCH == armhf ]] ; then echo "Skip tests for $TARGET_ARCH" && exit 0 ; fi - if [[ $TARGET_ARCH == armhf ]] ; then echo "Skip tests for $TARGET_ARCH" && exit 0 ; fi
@@ -342,6 +370,6 @@ script:
if [ -z "${ENABLE_SANITIZER}" ] && [ "$TARGET_ARCH" != "i686" ]; then if [ -z "${ENABLE_SANITIZER}" ] && [ "$TARGET_ARCH" != "i686" ]; then
npm run nodejs-tests npm run nodejs-tests
fi fi
- |
- popd - popd
- yarn test - yarn test
+62 -23
View File
@@ -1,32 +1,71 @@
# 5.7.3 # 5.9.1
- Changes from 5.7.2: - Changes from 5.9.0:
- Bug fixes: - #4322: Deprecated `UseLane`. Use the intersections array if you require lanes between steps
- Fixes 4097: .ramIndex files was able to be truncated siliently - #4321: Fixes a potential crash in the MLD alternative code path when not even a shortest path can be found
- #4324: STXXL is not required by default
# 5.7.2 # 5.9.0
- Changes from 5.7.1: - Changes from 5.8:
- Bug fixes: - Algorithm:
- Fixes segmentation fault caused by the fix for 3977 - Multi-Level Dijkstra:
- Plugins supported: `table`
- Adds alternative routes support (see [#4047](https://github.com/Project-OSRM/osrm-backend/pull/4047) and [3905](https://github.com/Project-OSRM/osrm-backend/issues/3905)): provides reasonably looking alternative routes (many, if possible) with reasonable query times.
- API:
- Exposes `alternatives=Number` parameter overload in addition to the boolean flag.
- Support for exits numbers and names. New member `exits` in `RouteStep`, based on `junction:ref` on ways
- `Intersection` now has new parameter `classes` that can be set in the profile on each way.
- Profiles:
- `result.exits` allows you to set a way's exit numbers and names, see [`junction:ref`](http://wiki.openstreetmap.org/wiki/Proposed_features/junction_details)
- `ExtractionWay` now as new property `forward_classes` and `backward_classes` that can set in the `way_function`.
The maximum number of classes is 8.
- We now respect the `construction` tag. If the `construction` tag value is not on our whitelist (`minor`, `widening`, `no`) we will exclude the road.
- Node.js Bindings:
- Exposes `alternatives=Number` parameter overload in addition to the boolean flag
- Expose `EngineConfig` options in the node bindings
- Tools:
- Exposes engine limit on number of alternatives to generate `--max-alternatives` in `osrm-routed` (3 by default)
- Infrastructure
- STXXL is not required to build OSRM and is an optional dependency for back-compatibility (ENABLE_STXXL=On)
- OpenMP is only required when the optional STXXL dependency is used
- Bug fixes:
- #4278: Remove superflous continious instruction on a motorway.
# 5.8.0
- Changes from 5.7
- API:
- polyline6 support in request string
- new parameter `approaches` for `route`, `table`, `trip` and `nearest` requests. This parameter keep waypoints on the curb side.
'approaches' accepts both 'curb' and 'unrestricted' values.
Note : the curb side depend on the `ProfileProperties::left_hand_driving`, it's a global property set once by the profile. If you are working with a planet dataset, the api will be wrong in some countries, and right in others.
- NodeJs Bindings
- new parameter `approaches` for `route`, `table`, `trip` and `nearest` requests.
- Tools
- `osrm-partition` now ensures it is called before `osrm-contract` and removes inconsitent .hsgr files automatically.
- Features
- Added conditional restriction support with `parse-conditional-restrictions=true|false` to osrm-extract. This option saves conditional turn restrictions to the .restrictions file for parsing by contract later. Added `parse-conditionals-from-now=utc time stamp` and `--time-zone-file=/path/to/file` to osrm-contract
- Command-line tools (osrm-extract, osrm-contract, osrm-routed, etc) now return error codes and legible error messages for common problem scenarios, rather than ugly C++ crashes
- Speed up pre-processing by only running the Lua `node_function` for nodes that have tags. Cuts OSM file parsing time in half.
- osrm-extract now performs generation of edge-expanded-edges using all available CPUs, which should make osrm-extract significantly faster on multi-CPU machines
- Files
- .osrm.nodes file was renamed to .nbg_nodes and .ebg_nodes was added
- Guidance
- #4075 Changed counting of exits on service roundabouts
- Debug Tiles
- added support for visualising turn penalties to the MLD plugin
- added support for showing the rate (reciprocal of weight) on each edge when used
- added support for turn weights in addition to turn durations in debug tiles
- Bugfixes
- Fixed a copy/paste issue assigning wrong directions in similar turns (left over right)
- #4074: fixed a bug that would announce entering highway ramps as u-turns
- #4122: osrm-routed/libosrm should throw exception when a dataset incompatible with the requested algorithm is loaded
- Avoid collapsing u-turns into combined turn instructions
# 5.7.1 # 5.7.1
- Changes from 5.7.0: - Bugfixes
- Bug fixes: - #4030 Roundabout edge-case crashes post-processing
- Fixes 3995: Negative duration caused by rounding issues.
- Fixes 3977: Fixes exit number in roundabout if starting inside the roundabout
- Fixes 3981: The NodeJS documentation was outdated and incomplete.
- Fixes 4010: Performance regression while parsing CSV files. Now 5x faster.
- Fixes 3919: Turn penalties on the cyclabilty metric were disabled.
- Fixes 3992: Table plugin not checking for valid phantom nodes
- Fixes 4013: `continue_straight` interaction with bearing constraints
- Fixes 4063: Potential overflow in custom profiles for restricted ways
- Fixes 4030: Roundabout edge-case crashes post-processing
# 5.7.0 # 5.7.0
- Changes from 5.6 - Changes from 5.6
- Bug fixes:
- Fixed 505: Invalid distance value for distance as routing weight.
- Fixed 3958: Fix traffic light penalties for non-turns
- Fixed 3933: crash when collapsing instructions
- Algorithm: - Algorithm:
- OSRM object has new option `algorithm` that allows the selection of a routing algorithm. - OSRM object has new option `algorithm` that allows the selection of a routing algorithm.
- New experimental algorithm: Multi-Level Dijkstra with new toolchain: - New experimental algorithm: Multi-Level Dijkstra with new toolchain:
+45 -25
View File
@@ -21,6 +21,7 @@ option(BUILD_PACKAGE "Build OSRM package" OFF)
option(ENABLE_ASSERTIONS "Use assertions in release mode" OFF) option(ENABLE_ASSERTIONS "Use assertions in release mode" OFF)
option(ENABLE_COVERAGE "Build with coverage instrumentalisation" OFF) option(ENABLE_COVERAGE "Build with coverage instrumentalisation" OFF)
option(ENABLE_SANITIZER "Use memory sanitizer for Debug build" OFF) option(ENABLE_SANITIZER "Use memory sanitizer for Debug build" OFF)
option(ENABLE_STXXL "Use STXXL library" OFF)
option(ENABLE_LTO "Use LTO if available" OFF) option(ENABLE_LTO "Use LTO if available" OFF)
option(ENABLE_FUZZING "Fuzz testing using LLVM's libFuzzer" OFF) option(ENABLE_FUZZING "Fuzz testing using LLVM's libFuzzer" OFF)
option(ENABLE_GOLD_LINKER "Use GNU gold linker if available" ON) option(ENABLE_GOLD_LINKER "Use GNU gold linker if available" ON)
@@ -54,8 +55,8 @@ if (POLICY CMP0048)
endif() endif()
project(OSRM C CXX) project(OSRM C CXX)
set(OSRM_VERSION_MAJOR 5) set(OSRM_VERSION_MAJOR 5)
set(OSRM_VERSION_MINOR 7) set(OSRM_VERSION_MINOR 9)
set(OSRM_VERSION_PATCH 3) set(OSRM_VERSION_PATCH 1)
set(OSRM_VERSION "${OSRM_VERSION_MAJOR}.${OSRM_VERSION_MINOR}.${OSRM_VERSION_PATCH}") set(OSRM_VERSION "${OSRM_VERSION_MAJOR}.${OSRM_VERSION_MINOR}.${OSRM_VERSION_PATCH}")
add_definitions(-DOSRM_PROJECT_DIR="${CMAKE_CURRENT_SOURCE_DIR}") add_definitions(-DOSRM_PROJECT_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
@@ -126,6 +127,7 @@ file(GLOB UpdaterGlob src/updater/*.cpp)
file(GLOB StorageGlob src/storage/*.cpp) file(GLOB StorageGlob src/storage/*.cpp)
file(GLOB ServerGlob src/server/*.cpp src/server/**/*.cpp) file(GLOB ServerGlob src/server/*.cpp src/server/**/*.cpp)
file(GLOB EngineGlob src/engine/*.cpp src/engine/**/*.cpp) file(GLOB EngineGlob src/engine/*.cpp src/engine/**/*.cpp)
file(GLOB ErrorcodesGlob src/osrm/errorcodes.cpp)
add_library(UTIL OBJECT ${UtilGlob}) add_library(UTIL OBJECT ${UtilGlob})
add_library(EXTRACTOR OBJECT ${ExtractorGlob}) add_library(EXTRACTOR OBJECT ${ExtractorGlob})
@@ -427,9 +429,12 @@ if(ENABLE_MASON)
mason_use(boost_libsystem VERSION ${MASON_BOOST_VERSION}) mason_use(boost_libsystem VERSION ${MASON_BOOST_VERSION})
set(Boost_SYSTEM_LIBRARY ${MASON_PACKAGE_boost_libsystem_STATIC_LIBS}) set(Boost_SYSTEM_LIBRARY ${MASON_PACKAGE_boost_libsystem_STATIC_LIBS})
mason_use(stxxl VERSION ${MASON_STXXL_VERSION}) if (ENABLE_STXXL)
add_dependency_includes(${MASON_PACKAGE_stxxl_INCLUDE_DIRS}) mason_use(stxxl VERSION ${MASON_STXXL_VERSION})
set(STXXL_LIBRARY ${MASON_PACKAGE_stxxl_STATIC_LIBS}) add_dependency_includes(${MASON_PACKAGE_stxxl_INCLUDE_DIRS})
set(MAYBE_STXXL_LIBRARY ${MASON_PACKAGE_stxxl_STATIC_LIBS})
add_definitions(-DUSE_STXXL_LIBRARY)
endif()
mason_use(expat VERSION ${MASON_EXPAT_VERSION}) mason_use(expat VERSION ${MASON_EXPAT_VERSION})
add_dependency_includes(${MASON_PACKAGE_expat_INCLUDE_DIRS}) add_dependency_includes(${MASON_PACKAGE_expat_INCLUDE_DIRS})
@@ -447,10 +452,6 @@ if(ENABLE_MASON)
add_dependency_includes(${MASON_PACKAGE_tbb_INCLUDE_DIRS}) add_dependency_includes(${MASON_PACKAGE_tbb_INCLUDE_DIRS})
set(TBB_LIBRARIES ${MASON_PACKAGE_tbb_LDFLAGS}) set(TBB_LIBRARIES ${MASON_PACKAGE_tbb_LDFLAGS})
mason_use(libshp2 VERSION ${MASON_LIBSHP_VERSION})
set(LIBSHAPEFILE_INCLUDE_DIR ${MASON_PACKAGE_libshp2_INCLUDE_DIRS})
set(LIBSHAPEFILE_LIBRARY ${MASON_PACKAGE_libshp2_LDFLAGS})
if(NOT MASON_PACKAGE_tbb_LIBRARY_DIRS) if(NOT MASON_PACKAGE_tbb_LIBRARY_DIRS)
message(FATAL_ERROR "MASON_PACKAGE_tbb_LIBRARY_DIRS is empty, rpath will not work") message(FATAL_ERROR "MASON_PACKAGE_tbb_LIBRARY_DIRS is empty, rpath will not work")
endif() endif()
@@ -477,6 +478,8 @@ if(ENABLE_MASON)
# expat and bzip2 are used from mason rather than the system # expat and bzip2 are used from mason rather than the system
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/libosmium/include) include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/libosmium/include)
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/rapidjson/include)
else() else()
find_package(Boost 1.54 REQUIRED COMPONENTS ${BOOST_COMPONENTS}) find_package(Boost 1.54 REQUIRED COMPONENTS ${BOOST_COMPONENTS})
@@ -494,8 +497,16 @@ else()
find_package(EXPAT REQUIRED) find_package(EXPAT REQUIRED)
add_dependency_includes(${EXPAT_INCLUDE_DIRS}) add_dependency_includes(${EXPAT_INCLUDE_DIRS})
find_package(STXXL REQUIRED) if (ENABLE_STXXL)
add_dependency_includes(${STXXL_INCLUDE_DIR}) find_package(STXXL)
if (STXXL_FOUND)
add_dependency_includes(${STXXL_INCLUDE_DIR})
set(MAYBE_STXXL_LIBRARY ${STXXL_LIBRARY})
add_definitions(-DUSE_STXXL_LIBRARY)
else()
MESSAGE(STATUS "STXXL was requested but not found, default STL will be used")
endif()
endif()
find_package(BZip2 REQUIRED) find_package(BZip2 REQUIRED)
add_dependency_includes(${BZIP2_INCLUDE_DIR}) add_dependency_includes(${BZIP2_INCLUDE_DIR})
@@ -546,6 +557,9 @@ else()
find_package(Osmium REQUIRED COMPONENTS io) find_package(Osmium REQUIRED COMPONENTS io)
include_directories(SYSTEM ${OSMIUM_INCLUDE_DIR}) include_directories(SYSTEM ${OSMIUM_INCLUDE_DIR})
set(RAPIDJSON_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/rapidjson/include")
include_directories(SYSTEM ${RAPIDJSON_INCLUDE_DIR})
endif() endif()
# prefix compilation with ccache by default if available and on clang or gcc # prefix compilation with ccache by default if available and on clang or gcc
@@ -576,11 +590,13 @@ add_dependency_defines(-DBOOST_SPIRIT_USE_PHOENIX_V3)
add_dependency_defines(-DBOOST_RESULT_OF_USE_DECLTYPE) add_dependency_defines(-DBOOST_RESULT_OF_USE_DECLTYPE)
add_dependency_defines(-DBOOST_FILESYSTEM_NO_DEPRECATED) add_dependency_defines(-DBOOST_FILESYSTEM_NO_DEPRECATED)
set(OpenMP_FIND_QUIETLY ON) if (ENABLE_STXXL)
find_package(OpenMP) set(OpenMP_FIND_QUIETLY ON)
if(OPENMP_FOUND) find_package(OpenMP)
message(STATUS "OpenMP support found. Linking just in case for stxxl") if(OPENMP_FOUND)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") message(STATUS "OpenMP support found. Linking just in case for stxxl")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()
endif() endif()
add_definitions(${OSRM_DEFINES}) add_definitions(${OSRM_DEFINES})
@@ -615,7 +631,7 @@ set(EXTRACTOR_LIBRARIES
${EXPAT_LIBRARIES} ${EXPAT_LIBRARIES}
${USED_LUA_LIBRARIES} ${USED_LUA_LIBRARIES}
${OSMIUM_LIBRARIES} ${OSMIUM_LIBRARIES}
${STXXL_LIBRARY} ${MAYBE_STXXL_LIBRARY}
${TBB_LIBRARIES} ${TBB_LIBRARIES}
${ZLIB_LIBRARY} ${ZLIB_LIBRARY}
${MAYBE_COVERAGE_LIBRARIES}) ${MAYBE_COVERAGE_LIBRARIES})
@@ -637,12 +653,13 @@ set(UPDATER_LIBRARIES
${CMAKE_THREAD_LIBS_INIT} ${CMAKE_THREAD_LIBS_INIT}
${TBB_LIBRARIES} ${TBB_LIBRARIES}
${MAYBE_RT_LIBRARY} ${MAYBE_RT_LIBRARY}
${MAYBE_COVERAGE_LIBRARIES}) ${MAYBE_COVERAGE_LIBRARIES}
${ZLIB_LIBRARY})
set(CONTRACTOR_LIBRARIES set(CONTRACTOR_LIBRARIES
${BOOST_BASE_LIBRARIES} ${BOOST_BASE_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT} ${CMAKE_THREAD_LIBS_INIT}
${USED_LUA_LIBRARIES} ${USED_LUA_LIBRARIES}
${STXXL_LIBRARY} ${MAYBE_STXXL_LIBRARY}
${TBB_LIBRARIES} ${TBB_LIBRARIES}
${MAYBE_RT_LIBRARY} ${MAYBE_RT_LIBRARY}
${MAYBE_COVERAGE_LIBRARIES}) ${MAYBE_COVERAGE_LIBRARIES})
@@ -662,9 +679,10 @@ set(STORAGE_LIBRARIES
set(UTIL_LIBRARIES set(UTIL_LIBRARIES
${BOOST_BASE_LIBRARIES} ${BOOST_BASE_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT} ${CMAKE_THREAD_LIBS_INIT}
${STXXL_LIBRARY} ${MAYBE_STXXL_LIBRARY}
${TBB_LIBRARIES} ${TBB_LIBRARIES}
${MAYBE_COVERAGE_LIBRARIES}) ${MAYBE_COVERAGE_LIBRARIES})
# Libraries # Libraries
target_link_libraries(osrm ${ENGINE_LIBRARIES}) target_link_libraries(osrm ${ENGINE_LIBRARIES})
target_link_libraries(osrm_update ${UPDATER_LIBRARIES}) target_link_libraries(osrm_update ${UPDATER_LIBRARIES})
@@ -676,7 +694,7 @@ target_link_libraries(osrm_store ${STORAGE_LIBRARIES})
# BUILD_COMPONENTS # BUILD_COMPONENTS
add_executable(osrm-components src/tools/components.cpp $<TARGET_OBJECTS:UTIL>) add_executable(osrm-components src/tools/components.cpp $<TARGET_OBJECTS:UTIL>)
target_link_libraries(osrm-components ${TBB_LIBRARIES} ${BOOST_BASE_LIBRARIES}) target_link_libraries(osrm-components ${TBB_LIBRARIES} ${BOOST_BASE_LIBRARIES} ${UTIL_LIBRARIES})
install(TARGETS osrm-components DESTINATION bin) install(TARGETS osrm-components DESTINATION bin)
if(BUILD_TOOLS) if(BUILD_TOOLS)
@@ -686,12 +704,12 @@ if(BUILD_TOOLS)
install(TARGETS osrm-io-benchmark DESTINATION bin) install(TARGETS osrm-io-benchmark DESTINATION bin)
find_package(Shapefile) # package libshp-dev find_package(Shapefile)
if(SHAPEFILE_FOUND AND (Boost_VERSION VERSION_GREATER 106000 OR ENABLE_MASON)) if(SHAPEFILE_FOUND AND (Boost_VERSION VERSION_GREATER 106000 OR ENABLE_MASON))
add_executable(osrm-extract-conditionals src/tools/extract-conditionals.cpp $<TARGET_OBJECTS:UTIL>) add_executable(osrm-extract-conditionals src/tools/extract-conditionals.cpp $<TARGET_OBJECTS:UTIL>)
target_include_directories(osrm-extract-conditionals PRIVATE ${LIBSHAPEFILE_INCLUDE_DIR}) target_include_directories(osrm-extract-conditionals PRIVATE ${LIBSHAPEFILE_INCLUDE_DIR})
target_link_libraries(osrm-extract-conditionals ${OSMIUM_LIBRARIES} ${BOOST_BASE_LIBRARIES} ${Boost_PROGRAM_OPTIONS_LIBRARY} target_link_libraries(osrm-extract-conditionals ${OSMIUM_LIBRARIES} ${BOOST_BASE_LIBRARIES} ${Boost_PROGRAM_OPTIONS_LIBRARY}
${LIBSHAPEFILE_LIBRARY} ${BZIP2_LIBRARIES} ${ZLIB_LIBRARY} ${EXPAT_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) ${UTIL_LIBRARIES} ${BZIP2_LIBRARIES} ${ZLIB_LIBRARY} ${EXPAT_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
install(TARGETS osrm-extract-conditionals DESTINATION bin) install(TARGETS osrm-extract-conditionals DESTINATION bin)
endif() endif()
endif() endif()
@@ -713,8 +731,8 @@ set_property(TARGET osrm-routed PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
file(GLOB VariantGlob third_party/variant/include/mapbox/*.hpp) file(GLOB VariantGlob third_party/variant/include/mapbox/*.hpp)
file(GLOB LibraryGlob include/osrm/*.hpp) file(GLOB LibraryGlob include/osrm/*.hpp)
file(GLOB ParametersGlob include/engine/api/*_parameters.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(EngineHeader include/engine/status.hpp include/engine/engine_config.hpp include/engine/hint.hpp include/engine/bearing.hpp include/engine/approach.hpp include/engine/phantom_node.hpp)
set(UtilHeader include/util/coordinate.hpp include/util/json_container.hpp include/util/typedefs.hpp include/util/strong_typedef.hpp include/util/exception.hpp) set(UtilHeader include/util/coordinate.hpp include/util/json_container.hpp include/util/typedefs.hpp include/util/alias.hpp include/util/exception.hpp)
set(ExtractorHeader include/extractor/extractor.hpp include/extractor/extractor_config.hpp include/extractor/travel_mode.hpp) set(ExtractorHeader include/extractor/extractor.hpp include/extractor/extractor_config.hpp include/extractor/travel_mode.hpp)
set(PartitionerHeader include/partition/partitioner.hpp include/partition/partition_config.hpp) set(PartitionerHeader include/partition/partitioner.hpp include/partition/partition_config.hpp)
set(ContractorHeader include/contractor/contractor.hpp include/contractor/contractor_config.hpp) set(ContractorHeader include/contractor/contractor.hpp include/contractor/contractor_config.hpp)
@@ -730,12 +748,14 @@ install(FILES ${ParametersGlob} DESTINATION include/osrm/engine/api)
install(FILES ${VariantGlob} DESTINATION include/mapbox) install(FILES ${VariantGlob} DESTINATION include/mapbox)
install(TARGETS osrm-extract DESTINATION bin) install(TARGETS osrm-extract DESTINATION bin)
install(TARGETS osrm-partition DESTINATION bin) install(TARGETS osrm-partition DESTINATION bin)
install(TARGETS osrm-customize DESTINATION bin)
install(TARGETS osrm-contract DESTINATION bin) install(TARGETS osrm-contract DESTINATION bin)
install(TARGETS osrm-datastore DESTINATION bin) install(TARGETS osrm-datastore DESTINATION bin)
install(TARGETS osrm-routed DESTINATION bin) install(TARGETS osrm-routed DESTINATION bin)
install(TARGETS osrm DESTINATION lib) install(TARGETS osrm DESTINATION lib)
install(TARGETS osrm_extract DESTINATION lib) install(TARGETS osrm_extract DESTINATION lib)
install(TARGETS osrm_partition DESTINATION lib) install(TARGETS osrm_partition DESTINATION lib)
install(TARGETS osrm_customize DESTINATION lib)
install(TARGETS osrm_update DESTINATION lib) install(TARGETS osrm_update DESTINATION lib)
install(TARGETS osrm_contract DESTINATION lib) install(TARGETS osrm_contract DESTINATION lib)
install(TARGETS osrm_store DESTINATION lib) install(TARGETS osrm_store DESTINATION lib)
+41 -3
View File
@@ -16,8 +16,10 @@ The following services are available via HTTP API, C++ library interface and Nod
To quickly try OSRM use our [demo server](http://map.project-osrm.org) which comes with both the backend and a frontend on top. To quickly try OSRM use our [demo server](http://map.project-osrm.org) which comes with both the backend and a frontend on top.
For a quick introduction about how the road network is represented in OpenStreetMap and how to map specific road network features have a look at [this guide about mapping for navigation](https://www.mapbox.com/mapping/mapping-for-navigation/).
Related [Project-OSRM](https://github.com/Project-OSRM) repositories: Related [Project-OSRM](https://github.com/Project-OSRM) repositories:
- [node-osrm](https://github.com/Project-OSRM/node-osrm) - Production-ready NodeJs bindings for the routing engine - [node-osrm](https://www.npmjs.com/package/osrm) - Production-ready NodeJs bindings for the routing engine
- [osrm-frontend](https://github.com/Project-OSRM/osrm-frontend) - User-facing frontend with map. The demo server runs this on top of the backend - [osrm-frontend](https://github.com/Project-OSRM/osrm-frontend) - User-facing frontend with map. The demo server runs this on top of the backend
- [osrm-text-instructions](https://github.com/Project-OSRM/osrm-text-instructions) - Text instructions from OSRM route response - [osrm-text-instructions](https://github.com/Project-OSRM/osrm-text-instructions) - Text instructions from OSRM route response
- [osrm-backend-docker](https://hub.docker.com/r/osrm/osrm-backend/) - Ready to use Docker images - [osrm-backend-docker](https://hub.docker.com/r/osrm/osrm-backend/) - Ready to use Docker images
@@ -69,6 +71,15 @@ In case Docker complains about not being able to connect to the Docker daemon ma
After adding yourself to the `docker` group make sure to log out and back in again with your terminal. After adding yourself to the `docker` group make sure to log out and back in again with your terminal.
We support the following images on Docker Cloud:
Name | Description
-----|------
`latest` | `master` compiled with release flag
`latest-assertions` | `master` compiled with with release flag, assertions enabled and debug symbols
`latest-debug` | `master` compiled with debug flag
`<tag>` | specific tag compiled with release flag
`<tag>-debug` | specific tag compiled with debug flag
### Building from Source ### Building from Source
@@ -110,7 +121,7 @@ osrm-routed berlin-latest.osrm
Running Queries Running Queries
``` ```
curl http://127.0.0.1:5000/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true curl "http://127.0.0.1:5000/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true"
``` ```
### Request Against the Demo Server ### Request Against the Demo Server
@@ -119,9 +130,36 @@ Read the [API usage policy](https://github.com/Project-OSRM/osrm-backend/wiki/Ap
Simple query with instructions and alternatives on Berlin: Simple query with instructions and alternatives on Berlin:
``` ```
curl https://router.project-osrm.org/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true&alternatives=true curl "https://router.project-osrm.org/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true&alternatives=true"
``` ```
### Using the Node.js Bindings
The Node.js bindings provide read-only access to the routing engine.
We provide API documentation and examples [here](docs/nodejs/api.md).
You will need a modern `libstdc++` toolchain (`>= GLIBCXX_3.4.20`) for binary compatibility if you want to use the pre-built binaries.
For older Ubuntu systems you can upgrade your standard library for example with:
```
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update -y
sudo apt-get install -y libstdc++-5-dev
```
You can install the Node.js bindings via `npm install osrm` or from this repository either via
npm install
which will check and use pre-built binaries if they're available for this release and your Node version, or via
npm install --build-from-source
to always force building the Node.js bindings from source.
For usage details have a look [these API docs](docs/nodejs/api.md).
## References in publications ## References in publications
When using the code in a (scientific) publication, please cite When using the code in a (scientific) publication, please cite
-627
View File
@@ -1,627 +0,0 @@
# Vendored NodeJs.cmake to bootstrap our C++ build without
# having the user to install Node modules via `npm install`.
#
# Update via: ../node_modules/.bin/ncmake update
# Defaults for standard Node.js builds
set(NODEJS_DEFAULT_URL https://nodejs.org/download/release)
set(NODEJS_DEFAULT_VERSION installed)
set(NODEJS_VERSION_FALLBACK latest)
set(NODEJS_DEFAULT_NAME node)
set(NODEJS_DEFAULT_CHECKSUM SHASUMS256.txt)
set(NODEJS_DEFAULT_CHECKTYPE SHA256)
include(CMakeParseArguments)
# Find a path by walking upward from a base directory until the path is
# found. Sets the variable ${PATH} to False if the path can't
# be determined
function(find_path_parent NAME BASE PATH)
set(ROOT ${BASE})
set(${PATH} ${ROOT}/${NAME} PARENT_SCOPE)
set(DRIVE "^[A-Za-z]?:?/$")
while(NOT ROOT MATCHES ${DRIVE} AND NOT EXISTS ${ROOT}/${NAME})
get_filename_component(ROOT ${ROOT} DIRECTORY)
set(${PATH} ${ROOT}/${NAME} PARENT_SCOPE)
endwhile()
if(ROOT MATCHES ${DRIVE})
set(${PATH} False PARENT_SCOPE)
endif()
endfunction()
# Shortcut for finding standard node module locations
macro(find_nodejs_module NAME BASE PATH)
find_path_parent(node_modules/${NAME} ${BASE} ${PATH})
endmacro()
# Download with a bit of nice output (without spewing progress)
function(download_file URL)
message(STATUS "Downloading: ${URL}")
file(DOWNLOAD
${URL}
${ARGN}
)
endfunction()
# Embedded win_delay_load_hook file so that this file can be copied
# into projects directly (recommended practice)
function(nodejs_generate_delayload_hook OUTPUT)
file(WRITE ${OUTPUT} "")
file(APPEND ${OUTPUT} "/*\n")
file(APPEND ${OUTPUT} " * When this file is linked to a DLL, it sets up a delay-load hook that\n")
file(APPEND ${OUTPUT} " * intervenes when the DLL is trying to load 'node.exe' or 'iojs.exe'\n")
file(APPEND ${OUTPUT} " * dynamically. Instead of trying to locate the .exe file it'll just return\n")
file(APPEND ${OUTPUT} " * a handle to the process image.\n")
file(APPEND ${OUTPUT} " *\n")
file(APPEND ${OUTPUT} " * This allows compiled addons to work when node.exe or iojs.exe is renamed.\n")
file(APPEND ${OUTPUT} " */\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} "#ifdef _MSC_VER\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} "#ifndef DELAYIMP_INSECURE_WRITABLE_HOOKS\n")
file(APPEND ${OUTPUT} "#define DELAYIMP_INSECURE_WRITABLE_HOOKS\n")
file(APPEND ${OUTPUT} "#endif\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} "#ifndef WIN32_LEAN_AND_MEAN\n")
file(APPEND ${OUTPUT} "#define WIN32_LEAN_AND_MEAN\n")
file(APPEND ${OUTPUT} "#endif\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} "#include <windows.h>\n")
file(APPEND ${OUTPUT} "#include <Shlwapi.h>\n")
file(APPEND ${OUTPUT} "#include <delayimp.h>\n")
file(APPEND ${OUTPUT} "#include <string.h>\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} "static FARPROC WINAPI load_exe_hook(unsigned int event, DelayLoadInfo* info) {\n")
file(APPEND ${OUTPUT} " if (event != dliNotePreLoadLibrary) return NULL;\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} " if (_stricmp(info->szDll, \"iojs.exe\") != 0 &&\n")
file(APPEND ${OUTPUT} " _stricmp(info->szDll, \"node.exe\") != 0 &&\n")
file(APPEND ${OUTPUT} " _stricmp(info->szDll, \"node.dll\") != 0)\n")
file(APPEND ${OUTPUT} " return NULL;\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} " // Get a handle to the current process executable.\n")
file(APPEND ${OUTPUT} " HMODULE processModule = GetModuleHandle(NULL);\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} " // Get the path to the executable.\n")
file(APPEND ${OUTPUT} " TCHAR processPath[_MAX_PATH];\n")
file(APPEND ${OUTPUT} " GetModuleFileName(processModule, processPath, _MAX_PATH);\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} " // Get the name of the current executable.\n")
file(APPEND ${OUTPUT} " LPSTR processName = PathFindFileName(processPath);\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} " // If the current process is node or iojs, then just return the proccess \n")
file(APPEND ${OUTPUT} " // module.\n")
file(APPEND ${OUTPUT} " if (_stricmp(processName, \"node.exe\") == 0 ||\n")
file(APPEND ${OUTPUT} " _stricmp(processName, \"iojs.exe\") == 0) {\n")
file(APPEND ${OUTPUT} " return (FARPROC) processModule;\n")
file(APPEND ${OUTPUT} " }\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} " // If it is another process, attempt to load 'node.dll' from the same \n")
file(APPEND ${OUTPUT} " // directory.\n")
file(APPEND ${OUTPUT} " PathRemoveFileSpec(processPath);\n")
file(APPEND ${OUTPUT} " PathAppend(processPath, \"node.dll\");\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} " HMODULE nodeDllModule = GetModuleHandle(processPath);\n")
file(APPEND ${OUTPUT} " if(nodeDllModule != NULL) {\n")
file(APPEND ${OUTPUT} " // This application has a node.dll in the same directory as the executable,\n")
file(APPEND ${OUTPUT} " // use that.\n")
file(APPEND ${OUTPUT} " return (FARPROC) nodeDllModule;\n")
file(APPEND ${OUTPUT} " }\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} " // Fallback to the current executable, which must statically link to \n")
file(APPEND ${OUTPUT} " // node.lib\n")
file(APPEND ${OUTPUT} " return (FARPROC) processModule;\n")
file(APPEND ${OUTPUT} "}\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} "PfnDliHook __pfnDliNotifyHook2 = load_exe_hook;\n")
file(APPEND ${OUTPUT} "\n")
file(APPEND ${OUTPUT} "#endif\n")
endfunction()
# Sets up a project to build Node.js native modules
# - Downloads required dependencies and unpacks them to the build directory.
# Internet access is required the first invocation but not after (
# provided the download is successful)
# - Sets up several variables for building against the downloaded
# dependencies
# - Guarded to prevent multiple executions, so a single project hierarchy
# will only call this once
function(nodejs_init)
# Prevents this function from executing more than once
if(NODEJS_INIT)
return()
endif()
# Regex patterns used by the init function for component extraction
set(HEADERS_MATCH "^([A-Fa-f0-9]+)[ \t]+([^-]+)-(headers|v?[0-9.]+)-(headers|v?[0-9.]+)([.]tar[.]gz)$")
set(LIB32_MATCH "(^[0-9A-Fa-f]+)[\t ]+(win-x86)?(/)?([^/]*)(.lib)$")
set(LIB64_MATCH "(^[0-9A-Fa-f]+)[\t ]+(win-)?(x64/)(.*)(.lib)$")
# Parse function arguments
cmake_parse_arguments(nodejs_init
"" "URL;NAME;VERSION;CHECKSUM;CHECKTYPE" "" ${ARGN}
)
# Allow the download URL to be overridden by command line argument
# NODEJS_URL
if(NODEJS_URL)
set(URL ${NODEJS_URL})
else()
# Use the argument if specified, falling back to the default
set(URL ${NODEJS_DEFAULT_URL})
if(nodejs_init_URL)
set(URL ${nodejs_init_URL})
endif()
endif()
# Allow name to be overridden by command line argument NODEJS_NAME
if(NODEJS_NAME)
set(NAME ${NODEJS_NAME})
else()
# Use the argument if specified, falling back to the default
set(NAME ${NODEJS_DEFAULT_NAME})
if(nodejs_init_NAME)
set(NAME ${nodejs_init_NAME})
endif()
endif()
# Allow the checksum file to be overridden by command line argument
# NODEJS_CHECKSUM
if(NODEJS_CHECKSUM)
set(CHECKSUM ${NODEJS_CHECKSUM})
else()
# Use the argument if specified, falling back to the default
set(CHECKSUM ${NODEJS_DEFAULT_CHECKSUM})
if(nodejs_init_CHECKSUM)
set(CHECKSUM ${nodejs_init_CHECKSUM})
endif()
endif()
# Allow the checksum type to be overriden by the command line argument
# NODEJS_CHECKTYPE
if(NODEJS_CHECKTYPE)
set(CHECKTYPE ${NODEJS_CHECKTYPE})
else()
# Use the argument if specified, falling back to the default
set(CHECKTYPE ${NODEJS_DEFAULT_CHECKTYPE})
if(nodejs_init_CHECKTYPE)
set(CHECKTYPE ${nodejs_init_CHECKTYPE})
endif()
endif()
# Allow the version to be overridden by the command line argument
# NODEJS_VERSION
if(NODEJS_VERSION)
set(VERSION ${NODEJS_VERSION})
else()
# Use the argument if specified, falling back to the default
set(VERSION ${NODEJS_DEFAULT_VERSION})
if(nodejs_init_VERSION)
set(VERSION ${nodejs_init_VERSION})
endif()
endif()
# "installed" is a special version that tries to use the currently
# installed version (determined by running node)
set(NODEJS_INSTALLED False CACHE BOOL "Node.js install status" FORCE)
if(VERSION STREQUAL "installed")
if(NOT NAME STREQUAL ${NODEJS_DEFAULT_NAME})
message(FATAL_ERROR
"'Installed' version identifier can only be used with"
"the core Node.js library"
)
endif()
# Fall back to the "latest" version if node isn't installed
set(VERSION ${NODEJS_VERSION_FALLBACK})
find_program(NODEJS_BINARY NAMES node nodejs)
if(NODEJS_BINARY)
execute_process(
COMMAND ${NODEJS_BINARY} --version
RESULT_VARIABLE INSTALLED_VERSION_RESULT
OUTPUT_VARIABLE INSTALLED_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(INSTALLED_VERSION_RESULT STREQUAL "0")
set(NODEJS_INSTALLED True CACHE BOOL
"Node.js install status" FORCE
)
set(VERSION ${INSTALLED_VERSION})
endif()
endif()
endif()
# Create a temporary download directory
set(TEMP ${CMAKE_CURRENT_BINARY_DIR}/temp)
if(EXISTS ${TEMP})
file(REMOVE_RECURSE ${TEMP})
endif()
file(MAKE_DIRECTORY ${TEMP})
# Unless the target is special version "latest", the parameters
# necessary to construct the root path are known
if(NOT VERSION STREQUAL "latest")
set(ROOT ${CMAKE_CURRENT_BINARY_DIR}/${NAME}/${VERSION})
# Extract checksums from the existing checksum file
set(CHECKSUM_TARGET ${ROOT}/CHECKSUM)
endif()
# If we're trying to determine the version or we haven't saved the
# checksum file for this version, download it from the specified server
if(VERSION STREQUAL "latest" OR
(DEFINED ROOT AND NOT EXISTS ${ROOT}/CHECKSUM))
if(DEFINED ROOT)
# Clear away the old checksum in case the new one is different
# and/or it fails to download
file(REMOVE ${ROOT}/CHECKSUM)
endif()
file(REMOVE ${TEMP}/CHECKSUM)
download_file(
${URL}/${VERSION}/${CHECKSUM}
${TEMP}/CHECKSUM
INACTIVITY_TIMEOUT 10
STATUS CHECKSUM_STATUS
)
list(GET CHECKSUM_STATUS 0 CHECKSUM_STATUS)
if(CHECKSUM_STATUS GREATER 0)
file(REMOVE ${TEMP}/CHECKSUM)
message(FATAL_ERROR
"Unable to download checksum file"
)
endif()
# Extract checksums from the temporary file
set(CHECKSUM_TARGET ${TEMP}/CHECKSUM)
endif()
# Extract the version, name, header archive and archive checksum
# from the file. This first extract is what defines / specifies the
# actual version number and name.
file(STRINGS
${CHECKSUM_TARGET} HEADERS_CHECKSUM
REGEX ${HEADERS_MATCH}
LIMIT_COUNT 1
)
if(NOT HEADERS_CHECKSUM)
file(REMOVE ${TEMP}/CHECKSUM)
if(DEFINED ROOT)
file(REMOVE ${ROOT}/CHECKSUM)
endif()
message(FATAL_ERROR "Unable to extract header archive checksum")
endif()
string(REGEX MATCH ${HEADERS_MATCH} HEADERS_CHECKSUM ${HEADERS_CHECKSUM})
set(HEADERS_CHECKSUM ${CMAKE_MATCH_1})
set(NAME ${CMAKE_MATCH_2})
if(CMAKE_MATCH_3 STREQUAL "headers")
set(VERSION ${CMAKE_MATCH_4})
else()
set(VERSION ${CMAKE_MATCH_3})
endif()
set(HEADERS_ARCHIVE
${CMAKE_MATCH_2}-${CMAKE_MATCH_3}-${CMAKE_MATCH_4}${CMAKE_MATCH_5}
)
# Make sure that the root directory exists, and that the checksum
# file has been moved over from temp
if(DEFINED ROOT)
set(OLD_ROOT ${ROOT})
endif()
set(ROOT ${CMAKE_CURRENT_BINARY_DIR}/${NAME}/${VERSION})
if(DEFINED OLD_ROOT AND NOT ROOT STREQUAL "${OLD_ROOT}")
file(REMOVE ${TEMP}/CHECKSUM)
file(REMOVE ${ROOT}/CHECKSUM)
message(FATAL_ERROR "Version/Name mismatch")
endif()
file(MAKE_DIRECTORY ${ROOT})
if(EXISTS ${TEMP}/CHECKSUM)
file(REMOVE ${ROOT}/CHECKSUM)
file(RENAME ${TEMP}/CHECKSUM ${ROOT}/CHECKSUM)
endif()
# Now that its fully resolved, report the name and version of Node.js being
# used
message(STATUS "NodeJS: Using ${NAME}, version ${VERSION}")
# Download the headers for the version being used
# Theoretically, these could be found by searching the installed
# system, but in practice, this can be error prone. They're provided
# on the download servers, so just use the ones there.
if(NOT EXISTS ${ROOT}/include)
file(REMOVE ${TEMP}/${HEADERS_ARCHIVE})
download_file(
${URL}/${VERSION}/${HEADERS_ARCHIVE}
${TEMP}/${HEADERS_ARCHIVE}
INACTIVITY_TIMEOUT 10
EXPECTED_HASH ${CHECKTYPE}=${HEADERS_CHECKSUM}
STATUS HEADERS_STATUS
)
list(GET HEADERS_STATUS 0 HEADERS_STATUS)
if(HEADER_STATUS GREATER 0)
file(REMOVE ${TEMP}/${HEADERS_ARCHIVE})
message(FATAL_ERROR "Unable to download Node.js headers")
endif()
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar xfz ${TEMP}/${HEADERS_ARCHIVE}
WORKING_DIRECTORY ${TEMP}
)
# This adapts the header extraction to support a number of different
# header archive contents in addition to the one used by the
# default Node.js library
unset(NODEJS_HEADERS_PATH CACHE)
find_path(NODEJS_HEADERS_PATH
NAMES src include
PATHS
${TEMP}/${NAME}-${VERSION}-headers
${TEMP}/${NAME}-${VERSION}
${TEMP}/${NODEJS_DEFAULT_NAME}-${VERSION}-headers
${TEMP}/${NODEJS_DEFAULT_NAME}-${VERSION}
${TEMP}/${NODEJS_DEFAULT_NAME}
${TEMP}
NO_DEFAULT_PATH
)
if(NOT NODEJS_HEADERS_PATH)
message(FATAL_ERROR "Unable to find extracted headers folder")
endif()
# Move the headers into a standard location with a standard layout
file(REMOVE ${TEMP}/${HEADERS_ARCHIVE})
file(REMOVE_RECURSE ${ROOT}/include)
if(EXISTS ${NODEJS_HEADERS_PATH}/include/node)
file(RENAME ${NODEJS_HEADERS_PATH}/include/node ${ROOT}/include)
elseif(EXISTS ${NODEJS_HEADERS_PATH}/src)
file(MAKE_DIRECTORY ${ROOT}/include)
if(NOT EXISTS ${NODEJS_HEADERS_PATH}/src)
file(REMOVE_RECURSE ${ROOT}/include)
message(FATAL_ERROR "Unable to find core headers")
endif()
file(COPY ${NODEJS_HEADERS_PATH}/src/
DESTINATION ${ROOT}/include
)
if(NOT EXISTS ${NODEJS_HEADERS_PATH}/deps/uv/include)
file(REMOVE_RECURSE ${ROOT}/include)
message(FATAL_ERROR "Unable to find libuv headers")
endif()
file(COPY ${NODEJS_HEADERS_PATH}/deps/uv/include/
DESTINATION ${ROOT}/include
)
if(NOT EXISTS ${NODEJS_HEADERS_PATH}/deps/v8/include)
file(REMOVE_RECURSE ${ROOT}/include)
message(FATAL_ERROR "Unable to find v8 headers")
endif()
file(COPY ${NODEJS_HEADERS_PATH}/deps/v8/include/
DESTINATION ${ROOT}/include
)
if(NOT EXISTS ${NODEJS_HEADERS_PATH}/deps/zlib)
file(REMOVE_RECURSE ${ROOT}/include)
message(FATAL_ERROR "Unable to find zlib headers")
endif()
file(COPY ${NODEJS_HEADERS_PATH}/deps/zlib/
DESTINATION ${ROOT}/include
)
endif()
file(REMOVE_RECURSE ${NODEJS_HEADERS_PATH})
unset(NODEJS_HEADERS_PATH CACHE)
endif()
# Only download the libraries on windows, since its the only place
# its necessary. Note, this requires rerunning CMake if moving
# a module from one platform to another (should happen automatically
# with most generators)
if(WIN32)
# Download the win32 library for linking
file(STRINGS
${ROOT}/CHECKSUM LIB32_CHECKSUM
LIMIT_COUNT 1
REGEX ${LIB32_MATCH}
)
if(NOT LIB32_CHECKSUM)
message(FATAL_ERROR "Unable to extract x86 library checksum")
endif()
string(REGEX MATCH ${LIB32_MATCH} LIB32_CHECKSUM ${LIB32_CHECKSUM})
set(LIB32_CHECKSUM ${CMAKE_MATCH_1})
set(LIB32_PATH win-x86)
set(LIB32_NAME ${CMAKE_MATCH_4}${CMAKE_MATCH_5})
set(LIB32_TARGET ${CMAKE_MATCH_2}${CMAKE_MATCH_3}${LIB32_NAME})
if(NOT EXISTS ${ROOT}/${LIB32_PATH})
file(REMOVE_RECURSE ${TEMP}/${LIB32_PATH})
download_file(
${URL}/${VERSION}/${LIB32_TARGET}
${TEMP}/${LIB32_PATH}/${LIB32_NAME}
INACTIVITY_TIMEOUT 10
EXPECTED_HASH ${CHECKTYPE}=${LIB32_CHECKSUM}
STATUS LIB32_STATUS
)
list(GET LIB32_STATUS 0 LIB32_STATUS)
if(LIB32_STATUS GREATER 0)
message(FATAL_ERROR
"Unable to download Node.js windows library (32-bit)"
)
endif()
file(REMOVE_RECURSE ${ROOT}/${LIB32_PATH})
file(MAKE_DIRECTORY ${ROOT}/${LIB32_PATH})
file(RENAME
${TEMP}/${LIB32_PATH}/${LIB32_NAME}
${ROOT}/${LIB32_PATH}/${LIB32_NAME}
)
file(REMOVE_RECURSE ${TEMP}/${LIB32_PATH})
endif()
# Download the win64 library for linking
file(STRINGS
${ROOT}/CHECKSUM LIB64_CHECKSUM
LIMIT_COUNT 1
REGEX ${LIB64_MATCH}
)
if(NOT LIB64_CHECKSUM)
message(FATAL_ERROR "Unable to extract x64 library checksum")
endif()
string(REGEX MATCH ${LIB64_MATCH} LIB64_CHECKSUM ${LIB64_CHECKSUM})
set(LIB64_CHECKSUM ${CMAKE_MATCH_1})
set(LIB64_PATH win-x64)
set(LIB64_NAME ${CMAKE_MATCH_4}${CMAKE_MATCH_5})
set(LIB64_TARGET ${CMAKE_MATCH_2}${CMAKE_MATCH_3}${LIB64_NAME})
if(NOT EXISTS ${ROOT}/${LIB64_PATH})
file(REMOVE_RECURSE ${TEMP}/${LIB64_PATH})
download_file(
${URL}/${VERSION}/${LIB64_TARGET}
${TEMP}/${LIB64_PATH}/${LIB64_NAME}
INACTIVITY_TIMEOUT 10
EXPECTED_HASH ${CHECKTYPE}=${LIB64_CHECKSUM}
STATUS LIB64_STATUS
)
list(GET LIB64_STATUS 0 LIB64_STATUS)
if(LIB64_STATUS GREATER 0)
message(FATAL_ERROR
"Unable to download Node.js windows library (64-bit)"
)
endif()
file(REMOVE_RECURSE ${ROOT}/${LIB64_PATH})
file(MAKE_DIRECTORY ${ROOT}/${LIB64_PATH})
file(RENAME
${TEMP}/${LIB64_PATH}/${LIB64_NAME}
${ROOT}/${LIB64_PATH}/${LIB64_NAME}
)
file(REMOVE_RECURSE ${TEMP}/${LIB64_PATH})
endif()
endif()
# The downloaded headers should always be set for inclusion
list(APPEND INCLUDE_DIRS ${ROOT}/include)
# Look for the NAN module, and add it to the includes
find_nodejs_module(
nan
${CMAKE_CURRENT_SOURCE_DIR}
NODEJS_NAN_DIR
)
if(NODEJS_NAN_DIR)
list(APPEND INCLUDE_DIRS ${NODEJS_NAN_DIR})
endif()
# Under windows, we need a bunch of libraries (due to the way
# dynamic linking works)
if(WIN32)
# Generate and use a delay load hook to allow the node binary
# name to be changed while still loading native modules
set(DELAY_LOAD_HOOK ${CMAKE_CURRENT_BINARY_DIR}/win_delay_load_hook.c)
nodejs_generate_delayload_hook(${DELAY_LOAD_HOOK})
set(SOURCES ${DELAY_LOAD_HOOK})
# Necessary flags to get delayload working correctly
list(APPEND LINK_FLAGS
"-IGNORE:4199"
"-DELAYLOAD:iojs.exe"
"-DELAYLOAD:node.exe"
"-DELAYLOAD:node.dll"
)
# Core system libraries used by node
list(APPEND LIBRARIES
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib
odbc32.lib Shlwapi.lib DelayImp.lib
)
# Also link to the node stub itself (downloaded above)
if(CMAKE_CL_64)
list(APPEND LIBRARIES ${ROOT}/${LIB64_PATH}/${LIB64_NAME})
else()
list(APPEND LIBRARIES ${ROOT}/${LIB32_PATH}/${LIB32_NAME})
endif()
else()
# Non-windows platforms should use these flags
list(APPEND DEFINITIONS _LARGEFILE_SOURCE _FILE_OFFSET_BITS=64)
endif()
# Special handling for OSX / clang to allow undefined symbols
# Define is required by node on OSX
if(APPLE)
list(APPEND LINK_FLAGS "-undefined dynamic_lookup")
list(APPEND DEFINITIONS _DARWIN_USE_64_BIT_INODE=1)
endif()
# Export all settings for use as arguments in the rest of the build
set(NODEJS_VERSION ${VERSION} PARENT_SCOPE)
set(NODEJS_SOURCES ${SOURCES} PARENT_SCOPE)
set(NODEJS_INCLUDE_DIRS ${INCLUDE_DIRS} PARENT_SCOPE)
set(NODEJS_LIBRARIES ${LIBRARIES} PARENT_SCOPE)
set(NODEJS_LINK_FLAGS ${LINK_FLAGS} PARENT_SCOPE)
set(NODEJS_DEFINITIONS ${DEFINITIONS} PARENT_SCOPE)
# Prevents this function from executing more than once
set(NODEJS_INIT TRUE PARENT_SCOPE)
endfunction()
# Helper function for defining a node module
# After nodejs_init, all of the settings and dependencies necessary to do
# this yourself are defined, but this helps make sure everything is configured
# correctly. Feel free to use it as a model to do this by hand (or to
# tweak this configuration if you need something custom).
function(add_nodejs_module NAME)
# Validate name parameter (must be a valid C identifier)
string(MAKE_C_IDENTIFIER ${NAME} ${NAME}_SYMBOL_CHECK)
if(NOT "${NAME}" STREQUAL "${${NAME}_SYMBOL_CHECK}")
message(FATAL_ERROR
"Module name must be a valid C identifier. "
"Suggested alternative: '${${NAME}_SYMBOL_CHECK}'"
)
endif()
# Make sure node is initialized (variables set) before defining the module
if(NOT NODEJS_INIT)
message(FATAL_ERROR
"Node.js has not been initialized. "
"Call nodejs_init before adding any modules"
)
endif()
# In order to match node-gyp, we need to build into type specific folders
# ncmake takes care of this, but be sure to set CMAKE_BUILD_TYPE yourself
# if invoking CMake directly
if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
message(FATAL_ERROR
"Configuration type must be specified. "
"Set CMAKE_BUILD_TYPE or use a different generator"
)
endif()
# A node module is a shared library
add_library(${NAME} SHARED ${NODEJS_SOURCES} ${ARGN})
# Add compiler defines for the module
# Two helpful ones:
# MODULE_NAME must match the name of the build library, define that here
# ${NAME}_BUILD is for symbol visibility under windows
string(TOUPPER "${NAME}_BUILD" ${NAME}_BUILD_DEF)
target_compile_definitions(${NAME}
PRIVATE MODULE_NAME=${NAME}
PRIVATE ${${NAME}_BUILD_DEF}
PUBLIC ${NODEJS_DEFINITIONS}
)
# This properly defines includes for the module
target_include_directories(${NAME} PUBLIC ${NODEJS_INCLUDE_DIRS})
# Add link flags to the module
target_link_libraries(${NAME} ${NODEJS_LIBRARIES})
# Set required properties for the module to build properly
# Correct naming, symbol visiblity and C++ standard
set_target_properties(${NAME} PROPERTIES
OUTPUT_NAME ${NAME}
PREFIX ""
SUFFIX ".node"
MACOSX_RPATH ON
C_VISIBILITY_PRESET hidden
CXX_VISIBILITY_PRESET hidden
POSITION_INDEPENDENT_CODE TRUE
CMAKE_CXX_STANDARD_REQUIRED TRUE
CXX_STANDARD 11
LINK_FLAGS "${NODEJS_LINK_FLAGS}"
)
# Make sure we're buiilding in a build specific output directory
# Only necessary on single-target generators (Make, Ninja)
# Multi-target generators do this automatically
# This (luckily) mirrors node-gyp conventions
if(NOT CMAKE_CONFIGURATION_TYPES)
set_property(TARGET ${NAME} PROPERTY
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BUILD_TYPE}
)
endif()
endfunction()
+1 -1
View File
@@ -3,5 +3,5 @@ module.exports = {
verify: '--strict --tags ~@stress --tags ~@todo -f progress --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', todo: '--strict --tags @todo --require features/support --require features/step_definitions',
all: '--strict --require features/support --require features/step_definitions', all: '--strict --require features/support --require features/step_definitions',
mld: '--strict --tags ~@stress --tags ~@todo --tags ~@alternative --tags ~@matrix --tags ~@trip --require features/support --require features/step_definitions -f progress' mld: '--strict --tags ~@stress --tags ~@todo --tags ~@alternative --require features/support --require features/step_definitions -f progress'
} }
+18 -11
View File
@@ -1,15 +1,9 @@
FROM alpine:3.5 FROM alpine:3.5
ARG DOCKER_TAG
RUN mkdir /src
COPY . /src
RUN mkdir /opt RUN mkdir /opt
WORKDIR /opt WORKDIR /opt
RUN NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \ RUN NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \
case ${DOCKER_TAG} in *"-debug"*) BUILD_TYPE="Debug";; *) BUILD_TYPE="Release";; esac && \
\
echo "@testing http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories && \ echo "@testing http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories && \
apk update && \ apk update && \
apk upgrade && \ apk upgrade && \
@@ -23,13 +17,26 @@ RUN NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \
cd build && \ cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \ cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j${NPROC} && \ make -j${NPROC} && \
make install && \ make install
\
ARG DOCKER_TAG
RUN mkdir /src
COPY . /src
WORKDIR /src
RUN NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \
echo "Building OSRM ${DOCKER_TAG}" && \ echo "Building OSRM ${DOCKER_TAG}" && \
cd /src && \ git show --format="%H" | head -n1 > /opt/OSRM_GITSHA && \
echo "Building OSRM gitsha $(cat /opt/OSRM_GITSHA)" && \
mkdir build && \ mkdir build && \
cd build && \ cd build && \
cmake -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DENABLE_LTO=On .. && \ BUILD_TYPE="Release" && \
ENABLE_ASSERTIONS="Off" && \
BUILD_TOOLS="Off" && \
case ${DOCKER_TAG} in *"-debug"*) BUILD_TYPE="Debug";; esac && \
case ${DOCKER_TAG} in *"-assertions"*) BUILD_TYPE="RelWithDebInfo" && ENABLE_ASSERTIONS="On" && BUILD_TOOLS="On";; esac && \
echo "Building ${BUILD_TYPE} with ENABLE_ASSERTIONS=${ENABLE_ASSERTIONS} BUILD_TOOLS=${BUILD_TOOLS}" && \
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DENABLE_ASSERTIONS=${ENABLE_ASSERTIONS} -DBUILD_TOOLS=${BUILD_TOOLS} -DENABLE_LTO=On && \
make -j${NPROC} install && \ make -j${NPROC} install && \
cd ../profiles && \ cd ../profiles && \
cp -r * /opt && \ cp -r * /opt && \
+22 -14
View File
@@ -15,7 +15,7 @@ GET /{service}/{version}/{profile}/{coordinates}[.{format}]?option=value&option=
| `service` | One of the following values: [`route`](#route-service), [`nearest`](#nearest-service), [`table`](#table-service), [`match`](#match-service), [`trip`](#trip-service), [`tile`](#tile-service) | | `service` | One of the following values: [`route`](#route-service), [`nearest`](#nearest-service), [`table`](#table-service), [`match`](#match-service), [`trip`](#trip-service), [`tile`](#tile-service) |
| `version` | Version of the protocol implemented by the service. `v1` for all OSRM 5.x installations | | `version` | Version of the protocol implemented by the service. `v1` for all OSRM 5.x installations |
| `profile` | Mode of transportation, is determined statically by the Lua profile that is used to prepare the data using `osrm-extract`. Typically `car`, `bike` or `foot` if using one of the supplied profiles. | | `profile` | Mode of transportation, is determined statically by the Lua profile that is used to prepare the data using `osrm-extract`. Typically `car`, `bike` or `foot` if using one of the supplied profiles. |
| `coordinates`| String of format `{longitude},{latitude};{longitude},{latitude}[;{longitude},{latitude} ...]` or `polyline({polyline})`. | | `coordinates`| String of format `{longitude},{latitude};{longitude},{latitude}[;{longitude},{latitude} ...]` or `polyline({polyline}) or polyline6({polyline6})`. |
| `format`| Only `json` is supported 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 by default and can be generated using [this package](https://www.npmjs.com/package/polyline). Passing any `option=value` is optional. `polyline` follows Google's polyline format with precision 5 by default and can be generated using [this package](https://www.npmjs.com/package/polyline).
@@ -30,6 +30,7 @@ To pass parameters to each location some options support an array like encoding:
|radiuses |`{radius};{radius}[;{radius} ...]` |Limits the search to given radius in meters. | |radiuses |`{radius};{radius}[;{radius} ...]` |Limits the search to given radius in meters. |
|generate\_hints |`true` (default), `false` |Adds a Hint to the response which can be used in subsequent requests, see `hints` parameter. | |generate\_hints |`true` (default), `false` |Adds a Hint to the response which can be used in subsequent requests, see `hints` parameter. |
|hints |`{hint};{hint}[;{hint} ...]` |Hint from previous request to derive position in street network. | |hints |`{hint};{hint}[;{hint} ...]` |Hint from previous request to derive position in street network. |
|approaches |`{approach};{approach}[;{approach} ...]` |Keep waypoints on curb side. |
Where the elements follow the following format: Where the elements follow the following format:
@@ -38,6 +39,7 @@ Where the elements follow the following format:
|bearing |`{value},{range}` `integer 0 .. 360,integer 0 .. 180` | |bearing |`{value},{range}` `integer 0 .. 360,integer 0 .. 180` |
|radius |`double >= 0` or `unlimited` (default) | |radius |`double >= 0` or `unlimited` (default) |
|hint |Base64 `string` | |hint |Base64 `string` |
|approach |`curb` or `unrestricted` (default) |
``` ```
{option}={element};{element}[;{element} ... ] {option}={element};{element}[;{element} ... ]
@@ -163,21 +165,21 @@ curl 'http://router.project-osrm.org/nearest/v1/driving/13.388860,52.517037?numb
Finds the fastest route between coordinates in the supplied order. Finds the fastest route between coordinates in the supplied order.
```endpoint ```endpoint
GET /route/v1/{profile}/{coordinates}?alternatives={true|false}&steps={true|false}&geometries={polyline|polyline6|geojson}&overview={full|simplified|false}&annotations={true|false} GET /route/v1/{profile}/{coordinates}?alternatives={true|false|number}&steps={true|false}&geometries={polyline|polyline6|geojson}&overview={full|simplified|false}&annotations={true|false}
``` ```
In addition to the [general options](#general-options) the following options are supported for this service: In addition to the [general options](#general-options) the following options are supported for this service:
|Option |Values |Description | |Option |Values |Description |
|------------|---------------------------------------------|-------------------------------------------------------------------------------| |------------|---------------------------------------------|-------------------------------------------------------------------------------|
|alternatives|`true`, `false` (default) |Search for alternative routes and return as well.\* | |alternatives|`true`, `false` (default), or Number |Search for alternative routes. Passing a number `alternatives=n` searches for up to `n` alternative routes.\* |
|steps |`true`, `false` (default) |Return route steps for each route leg | |steps |`true`, `false` (default) |Returned route steps for each route leg |
|annotations |`true`, `false` (default), `nodes`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. | |annotations |`true`, `false` (default), `nodes`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. |
|geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) | |geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) |
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.| |overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
|continue\_straight |`default` (default), `true`, `false` |Forces the route to keep going straight at waypoints constraining uturns there even if it would be faster. Default value depends on the profile. | |continue\_straight |`default` (default), `true`, `false` |Forces the route to keep going straight at waypoints constraining uturns there even if it would be faster. Default value depends on the profile. |
\* Please note that even if an alternative route is requested, a result cannot be guaranteed. \* Please note that even if alternative routes are requested, a result cannot be guaranteed.
**Response** **Response**
@@ -273,7 +275,7 @@ In addition to the [general options](#general-options) the following options are
|Option |Values |Description | |Option |Values |Description |
|------------|------------------------------------------------|------------------------------------------------------------------------------------------| |------------|------------------------------------------------|------------------------------------------------------------------------------------------|
|steps |`true`, `false` (default) |Return route steps for each route | |steps |`true`, `false` (default) |Returned route steps for each route |
|geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) | |geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) |
|annotations |`true`, `false` (default), `nodes`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. | |annotations |`true`, `false` (default), `nodes`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. |
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.| |overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
@@ -300,7 +302,7 @@ The area to search is chosen such that the correct candidate should be considere
Each `Waypoint` object has the following additional properties: Each `Waypoint` object has the following additional properties:
- `matchings_index`: Index to the `Route` object in `matchings` the sub-trace was matched to. - `matchings_index`: Index to the `Route` object in `matchings` the sub-trace was matched to.
- `waypoint_index`: Index of the waypoint inside the matched route. - `waypoint_index`: Index of the waypoint inside the matched route.
- `alternatives_count`: number of alternative routes leading to the destination from this trace point. 0 means there are no other routes reaching destination. Greater values mean that there are different routes available and different route can be selected if you provide more coordinates. - `alternatives_count`: Number of probable alternative matchings for this trace point. A value of zero indicate that this point was matched unambiguously. Split the trace at these points for incremental map matching.
- `matchings`: An array of `Route` objects that assemble the trace. Each `Route` object has the following additional properties: - `matchings`: An array of `Route` objects that assemble the trace. Each `Route` object has the following additional properties:
- `confidence`: Confidence of the matching. `float` value between 0 and 1. 1 is very confident that the matching is correct. - `confidence`: Confidence of the matching. `float` value between 0 and 1. 1 is very confident that the matching is correct.
@@ -326,10 +328,10 @@ In addition to the [general options](#general-options) the following options are
|Option |Values |Description | |Option |Values |Description |
|------------|------------------------------------------------|---------------------------------------------------------------------------| |------------|------------------------------------------------|---------------------------------------------------------------------------|
|roundtrip |`true` (default), `false` |Return route is a roundtrip (route returns to first location) | |roundtrip |`true` (default), `false` |Returned route is a roundtrip (route returns to first location) |
|source |`any` (default), `first` |Return route starts at `any` or `first` coordinate | |source |`any` (default), `first` |Returned route starts at `any` or `first` coordinate |
|destination |`any` (default), `last` |Return route ends at `any` or `last` coordinate | |destination |`any` (default), `last` |Returned route ends at `any` or `last` coordinate |
|steps |`true`, `false` (default) |Return route instructions for each trip | |steps |`true`, `false` (default) |Returned route instructions for each trip |
|annotations |`true`, `false` (default), `nodes`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. | |annotations |`true`, `false` (default), `nodes`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. |
|geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) | |geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) |
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.| |overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
@@ -417,8 +419,10 @@ Vector tiles contain two layers:
| `speed` | `integer` | the speed on that road segment, in km/h | | `speed` | `integer` | the speed on that road segment, in km/h |
| `is_small` | `boolean` | whether this segment belongs to a small (< 1000 node) [strongly connected component](https://en.wikipedia.org/wiki/Strongly_connected_component) | | `is_small` | `boolean` | whether this segment belongs to a small (< 1000 node) [strongly connected component](https://en.wikipedia.org/wiki/Strongly_connected_component) |
| `datasource` | `string` | the source for the speed value (normally `lua profile` unless you're using the [traffic update feature](https://github.com/Project-OSRM/osrm-backend/wiki/Traffic), in which case it contains the stem of the filename that supplied the speed value for this segment | | `datasource` | `string` | the source for the speed value (normally `lua profile` unless you're using the [traffic update feature](https://github.com/Project-OSRM/osrm-backend/wiki/Traffic), in which case it contains the stem of the filename that supplied the speed value for this segment |
| `duration` | `float` | how long this segment takes to traverse, in seconds | | `duration` | `float` | how long this segment takes to traverse, in seconds. This value is to calculate the total route ETA. |
| `weight ` | `integer` | how long this segment takes to traverse, in units (may differ from `duration` when artificial biasing is applied in the Lua profiles). ACTUAL ROUTING USES THIS VALUE. |
| `name` | `string` | the name of the road this segment belongs to | | `name` | `string` | the name of the road this segment belongs to |
| `rate` | `float` | the value of `length/weight` - analagous to `speed`, but using the `weight` value rather than `duration`, rounded to the nearest integer |
`turns` layer: `turns` layer:
@@ -427,6 +431,7 @@ Vector tiles contain two layers:
| `bearing_in` | `integer` | the absolute bearing that approaches the intersection. -180 to +180, 0 = North, 90 = East | | `bearing_in` | `integer` | the absolute bearing that approaches the intersection. -180 to +180, 0 = North, 90 = East |
| `turn_angle` | `integer` | the angle of the turn, relative to the `bearing_in`. -180 to +180, 0 = straight ahead, 90 = 90-degrees to the right | | `turn_angle` | `integer` | the angle of the turn, relative to the `bearing_in`. -180 to +180, 0 = straight ahead, 90 = 90-degrees to the right |
| `cost` | `float` | the time we think it takes to make that turn, in seconds. May be negative, depending on how the data model is constructed (some turns get a "bonus"). | | `cost` | `float` | the time we think it takes to make that turn, in seconds. May be negative, depending on how the data model is constructed (some turns get a "bonus"). |
| `weight` | `float` | the weight we think it takes to make that turn. May be negative, depending on how the data model is constructed (some turns get a "bonus"). ACTUAL ROUTING USES THIS VALUE |
## Result objects ## Result objects
@@ -576,6 +581,7 @@ step.
- `ref`: A reference number or code for the way. Optionally included, if ref data is available for the given way. - `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. - `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. - `destinations`: The destinations of the way. Will be `undefined` if there are no destinations.
- `exits`: The exit numbers or names of the way. Will be `undefined` if there are no exit numbers or names.
- `mode`: A string signifying the mode of transportation. - `mode`: A string signifying the mode of transportation.
- `maneuver`: A `StepManeuver` object representing the maneuver. - `maneuver`: A `StepManeuver` object representing the maneuver.
- `intersections`: A list of `Intersection` objects that are passed along the segment, the very first belonging to the StepManeuver - `intersections`: A list of `Intersection` objects that are passed along the segment, the very first belonging to the StepManeuver
@@ -649,12 +655,12 @@ step.
| `off ramp` | take a ramp to exit a highway (direction given my `modifier`) | | `off ramp` | take a ramp to exit a highway (direction given my `modifier`) |
| `fork` | take the left/right side at a fork depending on `modifier` | | `fork` | take the left/right side at a fork depending on `modifier` |
| `end of road` | road ends in a T intersection turn in direction of `modifier`| | `end of road` | road ends in a T intersection turn in direction of `modifier`|
| `use lane` | going straight on a specific lane | | `use lane` | **Deprecated** replaced by lanes on all intersection entries |
| `continue` | Turn in direction of `modifier` to stay on the same road | | `continue` | Turn in direction of `modifier` to stay on the same road |
| `roundabout` | traverse roundabout, has additional property `exit` with NR if the roundabout is left. The modifier specifies the direction of entering the roundabout. | | `roundabout` | traverse roundabout, has additional property `exit` with NR if the roundabout is left. The modifier specifies the direction of entering the roundabout. |
| `rotary` | a traffic circle. While very similar to a larger version of a roundabout, it does not necessarily follow roundabout rules for right of way. It can offer `rotary_name` and/or `rotary_pronunciation` parameters (located in the RouteStep object) in addition to the `exit` parameter (located on the StepManeuver object). | | `rotary` | a traffic circle. While very similar to a larger version of a roundabout, it does not necessarily follow roundabout rules for right of way. It can offer `rotary_name` and/or `rotary_pronunciation` parameters (located in the RouteStep object) in addition to the `exit` parameter (located on the StepManeuver object). |
| `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`. | | `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 | | `notification` | not an actual turn but a change in the driving conditions. For example the travel mode or classes. If the road takes a turn itself, the `modifier` describes the direction |
Please note that even though there are `new name` and `notification` instructions, the `mode` and `name` can change Please note that even though there are `new name` and `notification` instructions, the `mode` and `name` can change
between all instructions. They only offer a fallback in case nothing else is to report. between all instructions. They only offer a fallback in case nothing else is to report.
@@ -727,6 +733,7 @@ location of the StepManeuver. Further intersections are listed for every cross-w
- `location`: A `[longitude, latitude]` pair describing the location of the turn. - `location`: A `[longitude, latitude]` pair describing the location of the turn.
- `bearings`: A list of bearing values (e.g. [0,90,180,270]) that are available at the intersection. The bearings describe all available roads at the intersection. Values are between 0-359 (0=true north) - `bearings`: A list of bearing values (e.g. [0,90,180,270]) that are available at the intersection. The bearings describe all available roads at the intersection. Values are between 0-359 (0=true north)
- `classes`: An array of strings signifying the classes (as specified in the profile) of the road exiting the intersection.
- `entry`: A list of entry flags, corresponding in a 1:1 relationship to the bearings. A value of `true` indicates that the respective road could be entered on a valid route. - `entry`: A list of entry flags, corresponding in a 1:1 relationship to the bearings. A value of `true` indicates that the respective road could be entered on a valid route.
`false` indicates that the turn onto the respective road would violate a restriction. `false` indicates that the turn onto the respective road would violate a restriction.
- `in`: index into bearings/entry array. Used to calculate the bearing just before the turn. Namely, the clockwise angle from true north to the - `in`: index into bearings/entry array. Used to calculate the bearing just before the turn. Namely, the clockwise angle from true north to the
@@ -745,6 +752,7 @@ location of the StepManeuver. Further intersections are listed for every cross-w
"out":2, "out":2,
"bearings":[60,150,240,330], "bearings":[60,150,240,330],
"entry":["false","true","true","true"], "entry":["false","true","true","true"],
"classes": ["toll", "restricted"],
"lanes":{ "lanes":{
"indications": ["left", "straight"], "indications": ["left", "straight"],
"valid": "false" "valid": "false"
+32 -20
View File
@@ -26,6 +26,12 @@ var osrm = new OSRM('network.osrm');
- `options.shared_memory` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Connects to the persistent shared memory datastore. - `options.shared_memory` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Connects to the persistent shared memory datastore.
This requires you to run `osrm-datastore` prior to creating an `OSRM` object. This requires you to run `osrm-datastore` prior to creating an `OSRM` object.
- `options.path` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** The path to the `.osrm` files. This is mutually exclusive with setting {options.shared_memory} to true. - `options.path` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** The path to the `.osrm` files. This is mutually exclusive with setting {options.shared_memory} to true.
- `options.max_locations_trip` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. locations supported in trip query (default: unlimited).
- `options.max_locations_viaroute` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. locations supported in viaroute query 9default: unlimited).
- `options.max_locations_distance_table` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. locations supported in distance table query (default: unlimited).
- `options.max_locations_map_matching` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. locations supported in map matching query (default: unlimited).
- `options.max_results_nearest` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. results supported in nearest query (default: unlimited).
- `options.max_alternatives` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. number of alternative routes supported (default: 3).
### route ### route
@@ -41,12 +47,13 @@ Returns the fastest route between two or more coordinates while visiting the way
- `options.hints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Hints for the coordinate snapping. Array of base64 encoded strings. - `options.hints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Hints for the coordinate snapping. Array of base64 encoded strings.
- `options.alternatives` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Search for alternative routes and return as well. - `options.alternatives` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Search for alternative routes and return as well.
_Please note that even if an alternative route is requested, a result cannot be guaranteed._ (optional, default `false`) _Please note that even if an alternative route is requested, a result cannot be guaranteed._ (optional, default `false`)
- `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route steps for each route leg. (optional, default `false`) - `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Returned route steps for each route leg. (optional, default `false`)
- `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`) - `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`)
- `options.geometries` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route geometry format (influences overview and per step). Can also be `geojson`. (optional, default `polyline`) - `options.geometries` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route geometry format (influences overview and per step). Can also be `geojson`. (optional, default `polyline`)
- `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`). (optional, default `simplified`) - `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`). (optional, default `simplified`)
- `options.continue_straight` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Forces the route to keep going straight at waypoints and don't do a uturn even if it would be faster. Default value depends on the profile. - `options.continue_straight` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Forces the route to keep going straight at waypoints and don't do a uturn even if it would be faster. Default value depends on the profile.
`null`/`true`/`false` `null`/`true`/`false`
- `options.approaches` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`.
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** - `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
**Examples** **Examples**
@@ -78,6 +85,7 @@ Note: `coordinates` in the general options only supports a single `{longitude},{
- `options.hints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Hints for the coordinate snapping. Array of base64 encoded strings. - `options.hints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Hints for the coordinate snapping. Array of base64 encoded strings.
- `options.number` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Number of nearest segments that should be returned. - `options.number` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Number of nearest segments that should be returned.
Must be an integer greater than or equal to `1`. (optional, default `1`) Must be an integer greater than or equal to `1`. (optional, default `1`)
- `options.approaches` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`.
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** - `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
**Examples** **Examples**
@@ -116,6 +124,7 @@ tables.
location with given index as source. Default is to use all. location with given index as source. Default is to use all.
- `options.destinations` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** An array of `index` elements (`0 <= integer < - `options.destinations` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** An array of `index` elements (`0 <= integer <
#coordinates`) to use location with given index as destination. Default is to use all. #coordinates`) to use location with given index as destination. Default is to use all.
- `options.approaches` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`.
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** - `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
**Examples** **Examples**
@@ -185,12 +194,14 @@ if they can not be matched successfully.
- `options.bearings` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the search to segments with given bearing in degrees towards true north in clockwise direction. - `options.bearings` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the search to segments with given bearing in degrees towards true north in clockwise direction.
Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`. Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`.
- `options.hints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Hints for the coordinate snapping. Array of base64 encoded strings. - `options.hints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Hints for the coordinate snapping. Array of base64 encoded strings.
- `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route steps for each route. (optional, default `false`) - `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Returned route steps for each route. (optional, default `false`)
- `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`) - `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`)
- `options.geometries` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route geometry format (influences overview and per step). Can also be `geojson`. (optional, default `polyline`) - `options.geometries` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route geometry format (influences overview and per step). Can also be `geojson`. (optional, default `polyline`)
- `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`). (optional, default `simplified`) - `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`). (optional, default `simplified`)
- `options.timestamps` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>?** Timestamp of the input location (integers, UNIX-like timestamp). - `options.timestamps` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>?** Timestamp of the input location (integers, UNIX-like timestamp).
- `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Standard deviation of GPS precision used for map matching. If applicable use GPS accuracy. Can be `null` for default value `5` meters or `double >= 0`. - `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Standard deviation of GPS precision used for map matching. If applicable use GPS accuracy. Can be `null` for default value `5` meters or `double >= 0`.
- `options.gaps` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Allows the input track splitting based on huge timestamp gaps between points. Either `split` or `ignore`. (optional, default `split`)
- `options.tidy` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Allows the input track modification to obtain better matching quality for noisy tracks. (optional, default `false`)
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** - `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
**Examples** **Examples**
@@ -224,7 +235,25 @@ The trip plugin solves the Traveling Salesman Problem using a greedy heuristic
waypoints. The returned path does not have to be the shortest path, _ as TSP is NP-hard it is waypoints. The returned path does not have to be the shortest path, _ as TSP is NP-hard it is
only an approximation. only an approximation.
Note that all input coordinates have to be connected for the trip service to work. **Parameters**
- `options` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Object literal containing parameters for the trip query.
- `options.coordinates` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** The coordinates this request will use, coordinates as `[{lon},{lat}]` values, in decimal degrees.
- `options.bearings` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the search to segments with given bearing in degrees towards true north in clockwise direction.
Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`.
- `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the coordinate snapping to streets in the given radius in meters. Can be `double >= 0` or `null` (unlimited, default).
- `options.hints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Hints for the coordinate snapping. Array of base64 encoded strings.
- `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Returned route steps for each route. (optional, default `false`)
- `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`)
- `options.geometries` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route geometry format (influences overview and per step). Can also be `geojson`. (optional, default `polyline`)
- `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` (optional, default `simplified`)
- `options.roundtrip` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Returned route is a roundtrip (route returns to first location). (optional, default `true`)
- `options.source` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route starts at `any` or `first` coordinate. (optional, default `any`)
- `options.destination` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route ends at `any` or `last` coordinate. (optional, default `any`)
- `options.approaches` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`.
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
A requirement for computing trips is that all input coordinates are connected.
Currently, not all combinations of `roundtrip`, `source` and `destination` are supported. Currently, not all combinations of `roundtrip`, `source` and `destination` are supported.
Right now, the following combinations are possible: Right now, the following combinations are possible:
@@ -239,23 +268,6 @@ Right now, the following combinations are possible:
| false | any | last | no | | false | any | last | no |
| false | any | any | no | | false | any | any | no |
**Parameters**
- `options` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Object literal containing parameters for the trip query.
- `options.coordinates` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** The coordinates this request will use, coordinates as `[{lon},{lat}]` values, in decimal degrees.
- `options.bearings` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the search to segments with given bearing in degrees towards true north in clockwise direction.
Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`.
- `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the coordinate snapping to streets in the given radius in meters. Can be `double >= 0` or `null` (unlimited, default).
- `options.hints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Hints for the coordinate snapping. Array of base64 encoded strings.
- `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route steps for each route. (optional, default `false`)
- `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`)
- `options.geometries` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route geometry format (influences overview and per step). Can also be `geojson`. (optional, default `polyline`)
- `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` (optional, default `simplified`)
- `options.roundtrip` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route is a roundtrip. (optional, default `true`)
- `options.source` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Return route starts at `any` or `first` coordinate. (optional, default `any`)
- `options.destination` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Return route ends at `any` or `last` coordinate. (optional, default `any`)
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
**Examples** **Examples**
```javascript ```javascript
+31 -27
View File
@@ -27,50 +27,54 @@ As you scroll down the file you'll see local variables, and then local functions
The following global properties can be set in your profile: The following global properties can be set in your profile:
Attribute | Type | Notes Attribute | Type | Notes
------------------------------|----------|---------------------------------------------------------------------------- -------------------------------------|----------|----------------------------------------------------------------------------
weight_name | String | Name used in output for the routing weight property (default 'duration') weight_name | String | Name used in output for the routing weight property (default `'duration'`)
weight_precision | Unsigned | Decimal precision of edge weights (default 1) weight_precision | Unsigned | Decimal precision of edge weights (default `1`)
left_hand_driving | Boolean | Are vehicles assumed to drive on the left? (used in guidance) left_hand_driving | Boolean | Are vehicles assumed to drive on the left? (used in guidance, default `false`)
use_turn_restrictions | Boolean | Are turn instructions followed? use_turn_restrictions | Boolean | Are turn instructions followed? (default `false`)
continue_straight_at_waypoint | Boolean | Must the route continue straight on at a via point, or are U-turns allowed? continue_straight_at_waypoint | Boolean | Must the route continue straight on at a via point, or are U-turns allowed? (default `true`)
max_speed_for_map_matching | Float | Maximum vehicle speed to be assumed in matching (in m/s) max_speed_for_map_matching | Float | Maximum vehicle speed to be assumed in matching (in m/s)
max_turn_weight | Float | Maximum turn penalty weight max_turn_weight | Float | Maximum turn penalty weight
force_split_edges | Boolean | True value forces a split of forward and backward edges of extracted ways and guarantees that segment_function will be called for all segments force_split_edges | Boolean | True value forces a split of forward and backward edges of extracted ways and guarantees that `segment_function` will be called for all segments (default `false`)
## way_function ## way_function
Given an OpenStreetMap way, the way_function will either return nothing (meaning we are not going to route over this way at all), or it will set up a result hash to be returned. The most important thing it will do is set the value of `result.forward_speed` and `result.backward_speed` as a suitable integer value representing the speed for traversing the way. Given an OpenStreetMap way, the `way_function` will either return nothing (meaning we are not going to route over this way at all), or it will set up a result hash to be returned. The most important thing it will do is set the value of `result.forward_speed` and `result.backward_speed` as a suitable integer value representing the speed for traversing the way.
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) 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. 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.
The following attributes can be set on the result in way_function: The following attributes can be set on the result in `way_function`:
Attribute | Type | Notes Attribute | Type | Notes
----------------------------------------|----------|-------------------------------------------------------------------------- ----------------------------------------|----------|--------------------------------------------------------------------------
forward_speed | Float | Speed on this way in km/h forward_speed | Float | Speed on this way in km/h. Mandatory.
backward_speed | Float | " " backward_speed | Float | " "
forward_rate | Float | Routing weight, expressed as meters/*weight* (e.g. for a fastest-route weighting, you would want this to be meters/second, so set it to forward_speed/3.6) forward_rate | Float | Routing weight, expressed as meters/*weight* (e.g. for a fastest-route weighting, you would want this to be meters/second, so set it to forward_speed/3.6)
backward_rate | Float | " " backward_rate | Float | " "
forward_mode | Enum | Mode of travel (e.g. car, ferry). Defined in include/extractor/travel_mode.hpp forward_mode | Enum | Mode of travel (e.g. `car`, `ferry`). Mandatory. Defined in `include/extractor/travel_mode.hpp`.
backward_mode | Enum | " " backward_mode | Enum | " "
forward_classes | Table | Mark this way as being of a specific class, e.g. `result.classes["toll"] = true`. This will be exposed in the API as `classes` on each `RouteStep`.
backward_classes | Table | " "
duration | Float | Alternative setter for duration of the whole way in both directions duration | Float | Alternative setter for duration of the whole way in both directions
weight | Float | Alternative setter for weight of the whole way in both directions weight | Float | Alternative setter for weight of the whole way in both directions
turn_lanes_forward | String | Directions for individual lanes (normalised OSM turn:lanes value) turn_lanes_forward | String | Directions for individual lanes (normalised OSM `turn:lanes` value)
turn_lanes_backward | String | " " turn_lanes_backward | String | " "
forward_restricted | Boolean | Is this a restricted access road? (e.g. private, or deliveries only; used to enable high turn penalty, so that way is only chosen for start/end of route) forward_restricted | Boolean | Is this a restricted access road? (e.g. private, or deliveries only; used to enable high turn penalty, so that way is only chosen for start/end of route)
backward_restricted | Boolean | " " backward_restricted | Boolean | " "
is_startpoint | Boolean | Can a journey start on this way? (e.g. ferry; if false, prevents snapping the start point to this way) is_startpoint | Boolean | Can a journey start on this way? (e.g. ferry; if `false`, prevents snapping the start point to this way)
roundabout | Boolean | Is this part of a roundabout? roundabout | Boolean | Is this part of a roundabout?
circular | Boolean | Is this part of a non-roundabout circular junction? circular | Boolean | Is this part of a non-roundabout circular junction?
name | String | Name of the way name | String | Name of the way
ref | String | Road number ref | String | Road number
destinations | String | The road's destinations
exits | String | The ramp's exit numbers or names
pronunciation | String | Name pronunciation pronunciation | String | Name pronunciation
road_classification.motorway_class | Boolean | Guidance: way is a motorway road_classification.motorway_class | Boolean | Guidance: way is a motorway
road_classification.link_class | Boolean | Guidance: way is a slip/link road road_classification.link_class | Boolean | Guidance: way is a slip/link road
road_classification.road_priority_class | Enum | Guidance: order in priority list. Defined in include/extractor/guidance/road_classification.hpp road_classification.road_priority_class | Enum | Guidance: order in priority list. Defined in `include/extractor/guidance/road_classification.hpp`
road_classification.may_be_ignored | Boolean | Guidance: way is non-highway road_classification.may_be_ignored | Boolean | Guidance: way is non-highway
road_classification.num_lanes | Unsigned | Guidance: total number of lanes in way road_classification.num_lanes | Unsigned | Guidance: total number of lanes in way
@@ -87,16 +91,16 @@ Forks can be emitted between roads of similar priority category only. Obvious ch
## node_function ## node_function
The following attributes can be set on the result in node_function: The following attributes can be set on the result in `node_function`:
Attribute | Type | Notes Attribute | Type | Notes
----------------|---------|------------------------------------------------------- ----------------|---------|-------------------------------------------------------
barrier | Boolean | Is it an impassable barrier? barrier | Boolean | Is it an impassable barrier?
traffic_lights | Boolean | Is it a traffic light (incurs delay in turn_function)? traffic_lights | Boolean | Is it a traffic light (incurs delay in `turn_function`)?
## segment_function ## segment_function
The following attributes can be read and set on the result in segment_function: The following attributes can be read and set on the result in `segment_function`:
Attribute | Read/write? | Type | Notes Attribute | Read/write? | Type | Notes
-------------------|-------------|---------|------------------------------------------------------ -------------------|-------------|---------|------------------------------------------------------
@@ -110,15 +114,15 @@ duration | Read/write | Float | Duration for this segment
## turn_function ## turn_function
The following attributes can be read and set on the result in turn_function: The following attributes can be read and set on the result in `turn_function`:
Attribute | Read/write? | Type | Notes Attribute | Read/write? | Type | Notes
-------------------|-------------|---------|------------------------------------------------------ -------------------|-------------|---------|------------------------------------------------------
direction_modifier | Read | Enum | Geometry of turn. Defined in include/extractor/guidance/turn_instruction.hpp direction_modifier | Read | Enum | Geometry of turn. Defined in `include/extractor/guidance/turn_instruction.hpp`
turn_type | Read | Enum | Priority of turn. Defined in include/extractor/guidance/turn_instruction.hpp turn_type | Read | Enum | Priority of turn. Defined in `include/extractor/guidance/turn_instruction.hpp`
has_traffic_light | Read | Boolean | Is a traffic light present at this turn? has_traffic_light | Read | Boolean | Is a traffic light present at this turn?
source_restricted | Read | Boolean | Is it from a restricted access road? (See definition in way_function) source_restricted | Read | Boolean | Is it from a restricted access road? (See definition in `way_function`)
target_restricted | Read | Boolean | Is it to a restricted access road? (See definition in way_function) target_restricted | Read | Boolean | Is it to a restricted access road? (See definition in `way_function`)
angle | Read | Float | Angle of turn in degrees (0-360: 0=u-turn, 180=straight on) angle | Read | Float | Angle of turn in degrees (`0-360`: `0`=u-turn, `180`=straight on)
duration | Read/write | Float | Penalty to be applied for this turn (duration in deciseconds) duration | Read/write | Float | Penalty to be applied for this turn (duration in deciseconds)
weight | Read/write | Float | Penalty to be applied for this turn (routing weight) weight | Read/write | Float | Penalty to be applied for this turn (routing weight)
+10 -10
View File
@@ -82,16 +82,16 @@ Feature: Bike - Cycle tracks/lanes
Scenario: Bike - Cycleway on oneways, modes Scenario: Bike - Cycleway on oneways, modes
Then routability should be Then routability should be
| highway | cycleway | oneway | forw | backw | | highway | cycleway | oneway | forw | backw |
| motorway | track | yes | cycling | | | motorway | track | yes | cycling | |
| residential | track | yes | cycling | pushing bike | | residential | track | yes | cycling | pushing bike |
| cycleway | track | yes | cycling | pushing bike | | cycleway | track | yes | cycling | pushing bike |
| footway | track | yes | pushing bike | pushing bike | | footway | track | yes | cycling | pushing bike |
Scenario: Bike - Cycleway on oneways, speeds Scenario: Bike - Cycleway on oneways, speeds
Then routability should be Then routability should be
| highway | cycleway | oneway | forw | backw | | highway | cycleway | oneway | forw | backw |
| motorway | track | yes | 15 km/h | | | motorway | track | yes | 15 km/h | |
| residential | track | yes | 15 km/h | 6 km/h | | residential | track | yes | 15 km/h | 6 km/h +-1 |
| cycleway | track | yes | 15 km/h | 6 km/h | | cycleway | track | yes | 15 km/h | 6 km/h +-1 |
| footway | track | yes | 6 km/h +-1 | 6 km/h +-1 | | footway | track | yes | 15 km/h | 6 km/h +-1 |
+1 -2
View File
@@ -53,8 +53,7 @@ Feature: Bike - Handle ferry routes
Scenario: Bike - Ferry duration, multiple nodes Scenario: Bike - Ferry duration, multiple nodes
Given the node map Given the node map
""" """
x y x a b c d y
a b c d
""" """
And the ways And the ways
+9
View File
@@ -134,3 +134,12 @@ Feature: Bike - Oneway streets
When I route I should get When I route I should get
| from | to | route | | from | to | route |
| a | c | ab,bc,bc | | a | c | ab,bc,bc |
Scenario: Bike - Left/right cycleways on oneways
Then routability should be
| highway | oneway | cycleway:left | cycleway:right | forw | backw |
| primary | yes | | | cycling | pushing bike |
| primary | yes | | track | cycling | pushing bike |
| primary | yes | track | | cycling | cycling |
| primary | yes | track | track | cycling | cycling |
+105
View File
@@ -0,0 +1,105 @@
@routing @bicycle @safety
Feature: Bicycle - Adds penalties to unsafe roads
Background:
Given the profile file
"""
require 'bicycle'
properties.weight_name = 'cyclability'
"""
Scenario: Bike - Apply penalties to ways without cycleways
Then routability should be
| highway | cycleway | forw | backw | forw_rate | backw_rate |
| motorway | | | | | |
| primary | | 15 km/h | 15 km/h | 2.9 | 2.9 |
| secondary | | 15 km/h | 15 km/h | 3.1 | 3.1 |
| tertiary | | 15 km/h | 15 km/h | 3.3 | 3.3 |
| primary_link | | 15 km/h | 15 km/h | 2.9 | 2.9 |
| secondary_link | | 15 km/h | 15 km/h | 3.1 | 3.1 |
| tertiary_link | | 15 km/h | 15 km/h | 3.3 | 3.3 |
| residential | | 15 km/h | 15 km/h | 4.2 | 4.2 |
| cycleway | | 15 km/h | 15 km/h | 4.2 | 4.2 |
| footway | | 6 km/h +-1 | 6 km/h +-1 | 1.7 | 1.7 |
Scenario: Bike - Apply no penalties to ways with cycleways
Then routability should be
| highway | cycleway | forw | backw | forw_rate | backw_rate |
| motorway | track | 15 km/h | | 4.2 | |
| primary | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| secondary | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| tertiary | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| primary_link | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| secondary_link | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| tertiary_link | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| residential | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| cycleway | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| footway | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| motorway | lane | 15 km/h | | 4.2 | |
| primary | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| secondary | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| tertiary | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| primary_link | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| secondary_link | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| tertiary_link | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| residential | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| cycleway | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| footway | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| motorway | shared_lane | 15 km/h | | 4.2 | |
| primary | shared_lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
Scenario: Bike - Apply no penalties to ways in direction of cycleways
Then routability should be
| highway | cycleway:right | cycleway:left | forw | backw | forw_rate | backw_rate |
| motorway | track | | 15 km/h | | 4.2 | |
| primary | track | | 15 km/h | 15 km/h | 4.2 | 2.9 |
| secondary | track | | 15 km/h | 15 km/h | 4.2 | 3.1 |
| tertiary | track | | 15 km/h | 15 km/h | 4.2 | 3.3 |
| primary_link | track | | 15 km/h | 15 km/h | 4.2 | 2.9 |
| secondary_link | track | | 15 km/h | 15 km/h | 4.2 | 3.1 |
| tertiary_link | track | | 15 km/h | 15 km/h | 4.2 | 3.3 |
| residential | track | | 15 km/h | 15 km/h | 4.2 | 4.2 |
| cycleway | track | | 15 km/h | 15 km/h | 4.2 | 4.2 |
| footway | track | | 15 km/h | 6 km/h +-1 | 4.2 | 1.7 |
| motorway | | track | | 15 km/h | | 4.2 |
| primary | | track | 15 km/h | 15 km/h | 2.9 | 4.2 |
| secondary | | track | 15 km/h | 15 km/h | 3.1 | 4.2 |
| tertiary | | track | 15 km/h | 15 km/h | 3.3 | 4.2 |
| primary_link | | track | 15 km/h | 15 km/h | 2.9 | 4.2 |
| secondary_link | | track | 15 km/h | 15 km/h | 3.1 | 4.2 |
| tertiary_link | | track | 15 km/h | 15 km/h | 3.3 | 4.2 |
| residential | | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| cycleway | | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| footway | | track | 6 km/h +-1 | 15 km/h | 1.7 | 4.2 |
| motorway | lane | | 15 km/h | | 4.2 | |
| primary | lane | | 15 km/h | 15 km/h | 4.2 | 2.9 |
| secondary | lane | | 15 km/h | 15 km/h | 4.2 | 3.1 |
| tertiary | lane | | 15 km/h | 15 km/h | 4.2 | 3.3 |
| primary_link | lane | | 15 km/h | 15 km/h | 4.2 | 2.9 |
| secondary_link | lane | | 15 km/h | 15 km/h | 4.2 | 3.1 |
| tertiary_link | lane | | 15 km/h | 15 km/h | 4.2 | 3.3 |
| residential | lane | | 15 km/h +-1 | 15 km/h +-1 | 4.2 | 4.2 |
| cycleway | lane | | 15 km/h | 15 km/h | 4.2 | 4.2 |
| footway | lane | | 15 km/h | 6 km/h +-1 | 4.2 | 1.7 |
| motorway | | lane | | 15 km/h | | 4.2 |
| primary | | lane | 15 km/h | 15 km/h | 2.9 | 4.2 |
| secondary | | lane | 15 km/h +-1 | 15 km/h +-1 | 3.1 | 4.2 |
| tertiary | | lane | 15 km/h | 15 km/h | 3.3 | 4.2 |
| primary_link | | lane | 15 km/h | 15 km/h | 2.9 | 4.2 |
| secondary_link | | lane | 15 km/h | 15 km/h | 3.1 | 4.2 |
| tertiary_link | | lane | 15 km/h | 15 km/h | 3.3 | 4.2 |
| residential | | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| cycleway | | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| footway | | lane | 6 km/h +-1 | 15 km/h | 1.7 | 4.2 |
| motorway | shared_lane | | 15 km/h | | 4.2 | |
| primary | shared_lane | | 15 km/h | 15 km/h | 4.2 | 2.9 |
| motorway | | shared_lane | | 15 km/h | | 4.2 |
| primary | | shared_lane | 15 km/h | 15 km/h | 2.9 | 4.2 |
Scenario: Bike - Don't apply penalties for all kind of cycleways
Then routability should be
| highway | cycleway | forw | backw | forw_rate | backw_rate |
| tertiary | shared_lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| tertiary | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| tertiary | opposite | 15 km/h | 15 km/h | 3.3 | 4.2 |
+53
View File
@@ -0,0 +1,53 @@
@routing @bicycle @startpoint
Feature: Bike - Allowed start/end modes
Background:
Given the profile "bicycle"
Scenario: Bike - Don't start/stop on ferries
Given the node map
"""
a 1 b 2 c
"""
And the ways
| nodes | highway | route | bicycle |
| ab | primary | | |
| bc | | ferry | yes |
When I route I should get
| from | to | route | modes |
| 1 | 2 | ab,ab | cycling,cycling |
| 2 | 1 | ab,ab | cycling,cycling |
Scenario: Bike - Don't start/stop on trains
Given the node map
"""
a 1 b 2 c
"""
And the ways
| nodes | highway | railway | bicycle |
| ab | primary | | |
| bc | | train | yes |
When I route I should get
| from | to | route | modes |
| 1 | 2 | ab,ab | cycling,cycling |
| 2 | 1 | ab,ab | cycling,cycling |
Scenario: Bike - OK to start pushing bike
Given the node map
"""
a 1 b 2 c
"""
And the ways
| nodes | highway |
| ab | primary |
| bc | steps |
When I route I should get
| from | to | route | modes |
| 1 | 2 | ab,bc,bc | cycling,pushing bike,pushing bike |
| 2 | 1 | bc,ab,ab | pushing bike,cycling,cycling |
+60 -28
View File
@@ -1,39 +1,71 @@
@routing @bicycle @train @routing @bicycle @train
Feature: Bike - Handle ferry routes Feature: Bike - Handle ferry routes
# Bringing bikes on trains and subways # Bringing bikes on trains and subways
# We cannot currently use a 'routability' type test, since the bike
# profile does not allow starting/stopping on trains, and
# it's not possible to modify the bicycle profile table because it's
# defined as local.
Background: Background:
Given the profile "bicycle" Given the profile "bicycle"
Scenario: Bike - Bringing bikes on trains Scenario: Bike - Bringing bikes on trains
Then routability should be Given the node map
| highway | railway | bicycle | bothw | """
| primary | | | cycling | a 1 b c 2 d e 3 f g 4 h
| (nil) | train | | | """
| (nil) | train | no | |
| (nil) | train | yes | train | And the ways
| (nil) | railway | | | | nodes | highway | railway | bicycle |
| (nil) | railway | no | | | ab | primary | | |
| (nil) | railway | yes | train | | cd | primary | | |
| (nil) | subway | | | | ef | primary | | |
| (nil) | subway | no | | | gh | primary | | |
| (nil) | subway | yes | train | | bc | | train | |
| (nil) | tram | | | | de | | train | yes |
| (nil) | tram | no | | | fg | | train | no |
| (nil) | tram | yes | train |
| (nil) | light_rail | | | When I route I should get
| (nil) | light_rail | no | | | from | to | route |
| (nil) | light_rail | yes | train | | 1 | 2 | |
| (nil) | monorail | | | | 2 | 3 | cd,de,ef,ef |
| (nil) | monorail | no | | | 3 | 4 | |
| (nil) | monorail | yes | train |
| (nil) | some_tag | | | Scenario: Bike - Bringing bikes on trains, invalid railway tag is accepted if access specified
| (nil) | some_tag | no | | Given the node map
| (nil) | some_tag | yes | cycling | """
a 1 b c 2 d e 3 f g 4 h
"""
And the ways
| nodes | highway | railway | bicycle |
| ab | primary | | |
| cd | primary | | |
| ef | primary | | |
| gh | primary | | |
| bc | | invalid_tag | |
| de | | invalid_tag | yes |
| fg | | invalid_tag | no |
When I route I should get
| from | to | route |
| 1 | 2 | |
| 2 | 3 | cd,de,ef|
| 3 | 4 | |
@construction @construction
Scenario: Bike - Don't route on railways under construction Scenario: Bike - Don't route on railways under construction
Then routability should be Given the node map
| highway | railway | bicycle | bothw | """
| primary | | | cycling | a 1 b c 2 d
| (nil) | construction | yes | | """
And the ways
| nodes | highway | railway | bicycle |
| ab | primary | | |
| cd | primary | | |
| bc | | construction | yes |
When I route I should get
| from | to | route |
| 1 | 2 | |
+1 -30
View File
@@ -2,38 +2,9 @@
Feature: Turn Penalties Feature: Turn Penalties
Background: Background:
Given the profile "turnbot" Given the profile "bicycle"
Given a grid size of 200 meters Given a grid size of 200 meters
Scenario: Bike - turns should incur a delay that depend on the angle
Given the node map
"""
c d e
b j f
a s g
"""
And the ways
| nodes |
| sj |
| ja |
| jb |
| jc |
| jd |
| je |
| jf |
| jg |
When I route I should get
| from | to | route | time | distance |
| s | a | sj,ja,ja | 63s +-1 | 483m +-1 |
| s | b | sj,jb,jb | 50s +-1 | 400m +-1 |
| s | c | sj,jc,jc | 54s +-1 | 483m +-1 |
| s | d | sj,jd,jd | 40s +-1 | 400m +-1 |
| s | e | sj,je,je | 53s +-1 | 483m +-1 |
| s | f | sj,jf,jf | 50s +-1 | 400m +-1 |
| s | g | sj,jg,jg | 63s +-1 | 483m +-1 |
Scenario: Bicycle - Turn penalties on cyclability Scenario: Bicycle - Turn penalties on cyclability
Given the profile file Given the profile file
+20 -20
View File
@@ -183,9 +183,9 @@ Feature: Car - Restricted access
Scenario: Car - designated HOV ways are rated low Scenario: Car - designated HOV ways are rated low
Then routability should be Then routability should be
| highway | hov | bothw | forw_rate | backw_rate | | highway | hov | bothw | forw_rate | backw_rate |
| primary | designated | x | 18 | 18 | | primary | designated | x | 18.2 | 18.2 |
| primary | yes | x | 18 | 18 | | primary | yes | x | 18.2 | 18.2 |
| primary | no | x | 18 | 18 | | primary | no | x | 18.2 | 18.2 |
# Models: # Models:
# https://www.openstreetmap.org/way/124891268 # https://www.openstreetmap.org/way/124891268
@@ -201,24 +201,24 @@ Feature: Car - Restricted access
Scenario: Car - a way with all lanes HOV-designated is highly penalized by default (similar to hov=designated) Scenario: Car - a way with all lanes HOV-designated is highly penalized by default (similar to hov=designated)
Then routability should be Then routability should be
| highway | hov:lanes:forward | hov:lanes:backward | hov:lanes | oneway | forw | backw | forw_rate | backw_rate | | highway | hov:lanes:forward | hov:lanes:backward | hov:lanes | oneway | forw | backw | forw_rate | backw_rate |
| primary | designated | designated | | | x | x | 18 | 18 | | primary | designated | designated | | | x | x | 18.2 | 18.2 |
# This test is flaky because non-deterministic turn generation sometimes emits a NoTurn here that is marked as restricted. #3769 # This test is flaky because non-deterministic turn generation sometimes emits a NoTurn here that is marked as restricted. #3769
#| primary | | designated | | | x | x | 18 | 18 | #| primary | | designated | | | x | x | 18.2 | 18.2 |
#| primary | designated | | | | x | x | 18 | 18 | #| primary | designated | | | | x | x | 18.2 | 18.2 |
| primary | designated\|designated | designated\|designated | | | x | x | 18 | 18 | | primary | designated\|designated | designated\|designated | | | x | x | 18.2 | 18.2 |
| primary | designated\|no | designated\|no | | | x | x | 18 | 18 | | primary | designated\|no | designated\|no | | | x | x | 18.2 | 18.2 |
| primary | yes\|no | yes\|no | | | x | x | 18 | 18 | | primary | yes\|no | yes\|no | | | x | x | 18.2 | 18.2 |
| primary | | | | | x | x | 18 | 18 | | primary | | | | | x | x | 18.2 | 18.2 |
| primary | designated | | | -1 | | x | | 18 | | primary | designated | | | -1 | | x | | 18.2 |
| primary | | designated | | -1 | | x | | 18 | | primary | | designated | | -1 | | x | | 18.2 |
| primary | | | designated | yes | x | | 18 | | | primary | | | designated | yes | x | | 18.2 | |
| primary | | | designated | -1 | | x | | 18 | | primary | | | designated | -1 | | x | | 18.2 |
| primary | | | designated\| | yes | x | | 18 | | | primary | | | designated\| | yes | x | | 18.2 | |
| primary | | | designated\| | -1 | | x | | 18 | | primary | | | designated\| | -1 | | x | | 18.2 |
| primary | | | designated\|designated | yes | x | | 18 | | | primary | | | designated\|designated | yes | x | | 18.2 | |
| primary | | | designated\|designated | -1 | | x | | 18 | | primary | | | designated\|designated | -1 | | x | | 18.2 |
| primary | | | designated\|yes | yes | x | | 18 | | | primary | | | designated\|yes | yes | x | | 18.2 | |
| primary | | | designated\|no | -1 | | x | | 18 | | primary | | | designated\|no | -1 | | x | | 18.2 |
Scenario: Car - these toll roads always work Scenario: Car - these toll roads always work
Then routability should be Then routability should be
+127
View File
@@ -0,0 +1,127 @@
@routing @car @mode
Feature: Car - Mode flag
Background:
Given the profile "car"
Scenario: Car - We tag ferries with a class
Given the node map
"""
a b
c d
"""
And the ways
| nodes | highway | route |
| ab | primary | |
| bc | | ferry |
| cd | primary | |
When I route I should get
| from | to | route | turns | classes |
| a | d | ab,bc,cd,cd | depart,notification right,notification left,arrive | [()],[(ferry)],[()],[()] |
| d | a | cd,bc,ab,ab | depart,notification right,notification left,arrive | [()],[(ferry)],[()],[()] |
| c | a | bc,ab,ab | depart,notification left,arrive | [(ferry)],[()],[()] |
| d | b | cd,bc,bc | depart,notification right,arrive | [()],[(ferry)],[()] |
| a | c | ab,bc,bc | depart,notification right,arrive | [()],[(ferry)],[()] |
| b | d | bc,cd,cd | depart,notification left,arrive | [(ferry)],[()],[()] |
Scenario: Car - We tag motorways with a class
Given the node map
"""
a b
c d
"""
And the ways
| nodes | highway |
| ab | primary |
| bc | motorway|
| cd | primary |
When I route I should get
| from | to | route | turns | classes |
| a | d | ab,cd | depart,arrive | [(),(motorway),()],[()] |
| a | c | ab,bc | depart,arrive | [(),(motorway)],[()] |
| b | d | bc,cd | depart,arrive | [(motorway),()],[()] |
Scenario: Car - We tag motorway_link with a class
Given the node map
"""
a b
c d
"""
And the ways
| nodes | highway |
| ab | primary |
| bc | motorway_link |
| cd | primary |
When I route I should get
| from | to | route | turns | classes | # |
| a | d | ab,bc,cd | depart,on ramp right,arrive | [()],[(motorway),()],[()] | on-ramp at class change |
| a | c | ab,bc,bc | depart,on ramp right,arrive | [()],[(motorway)],[()] | " " |
| b | d | bc,cd | depart,arrive | [(motorway),()],[()] | no announcement |
Scenario: Car - We tag restricted with a class
Given the node map
"""
a b
c d
"""
And the ways
| nodes | highway | access |
| ab | primary | private |
| bc | motorway| private |
| cd | primary | |
When I route I should get
| from | to | route | turns | classes |
| a | d | ab,cd | depart,arrive| [(restricted),(motorway,restricted),()],[()] |
Scenario: Car - We toll restricted with a class
Given the node map
"""
a b
c d
"""
And the ways
| nodes | highway | toll |
| ab | primary | yes |
| bc | motorway| yes |
| cd | primary | |
When I route I should get
| from | to | route | turns | classes |
| a | d | ab,cd | depart,arrive | [(toll),(motorway,toll),()],[()] |
Scenario: Car - From roundabout on toll road
Given the node map
"""
c
/ \
a---b d---f
\ /
e
|
g
"""
And the ways
| nodes | oneway | highway | junction | toll |
| ab | yes | primary | | |
| cb | yes | primary | roundabout | |
| dc | yes | primary | roundabout | |
| be | yes | primary | roundabout | |
| ed | yes | motorway| roundabout | |
| eg | yes | primary | | |
| df | yes | motorway| | yes |
When I route I should get
| from | to | route | turns | classes |
| a | f | ab,df,df | depart,roundabout-exit-2,arrive | [()],[(),(motorway),(toll,motorway)],[()] |
@@ -0,0 +1,741 @@
@routing @car @restrictions
Feature: Car - Turn restrictions
# Handle turn restrictions as defined by http://wiki.openstreetmap.org/wiki/Relation:restriction
# Note that if u-turns are allowed, turn restrictions can lead to suprising, but correct, routes.
Background: Use car routing
Given the profile "car"
Given a grid size of 200 meters
Given the origin -9.2972,10.3811
# coordinate in Guinée, a country that observes GMT year round
@no_turning @conditionals
Scenario: Car - ignores unrecognized restriction
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | nj | j | only_right_turn @ (has_pygmies > 10 p) |
When I route I should get
| from | to | route |
| e | s | ej,js,js |
| e | n | ej,nj,nj |
| e | p | ej,jp,jp |
@no_turning @conditionals
Scenario: Car - Restriction would be on, but the restriction was badly tagged
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p |
\ |
j
| \
s m
"""
And the ways
| nodes |
| nj |
| js |
| pjm |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | nj | pjm | j | no_left_turn @ (Mo-Fr 07:00-10:30) |
| restriction | js | pjm | j | no_right_turn @ (Mo-Fr 07:00-10:30) |
When I route I should get
| from | to | route |
| n | m | nj,pjm,pjm |
| s | m | js,pjm,pjm |
@no_turning @conditionals
Scenario: Car - ignores except restriction
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | no |
| jp | no |
And the relations
| type | way:from | way:to | node:via | restriction:conditional | except |
| restriction | ej | nj | j | only_right_turn @ (Mo-Su 08:00-12:00) | motorcar |
| restriction | jp | nj | j | only_left_turn @ (Mo-Su 08:00-12:00) | bus |
When I route I should get
| from | to | route | # |
| e | s | ej,js,js | |
| e | n | ej,nj,nj | restriction does not apply to cars |
| e | p | ej,jp,jp | |
| p | s | jp,nj,nj,js,js | restriction excepting busses still applies to cars |
@no_turning @conditionals
Scenario: Car - only_right_turn
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | nj | j | only_right_turn @ (Mo-Su 07:00-14:00) |
When I route I should get
| from | to | route |
| e | s | ej,nj,nj,js,js |
| e | n | ej,nj,nj |
| e | p | ej,nj,nj,jp,jp |
@no_turning @conditionals
Scenario: Car - No right turn
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | nj | j | no_right_turn @ (Mo-Fr 07:00-13:00) |
When I route I should get
| from | to | route | # |
| e | s | ej,js,js | normal turn |
| e | n | ej,js,js,nj,nj | avoids right turn |
| e | p | ej,jp,jp | normal maneuver |
@only_turning @conditionals
Scenario: Car - only_left_turn
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | js | j | only_left_turn @ (Mo-Fr 07:00-16:00) |
When I route I should get
| from | to | route |
| e | s | ej,js,js |
| e | n | ej,js,js,nj,nj |
| e | p | ej,js,js,jp,jp |
@no_turning @conditionals
Scenario: Car - No left turn
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | js | j | no_left_turn @ (Mo-Su 00:00-23:59) |
When I route I should get
| from | to | route |
| e | s | ej,nj,nj,js,js |
| e | n | ej,nj,nj |
| e | p | ej,jp,jp |
@no_turning @conditionals
Scenario: Car - Conditional restriction is off
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | nj | j | no_right_turn @ (Mo-Su 16:00-20:00) |
When I route I should get
| from | to | route |
| e | s | ej,js,js |
| e | n | ej,nj,nj |
| e | p | ej,jp,jp |
@no_turning @conditionals
Scenario: Car - Conditional restriction is on
Given the extract extra arguments "--parse-conditional-restrictions"
# 10am utc, wed
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493805600"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493805600"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | nj | j | no_right_turn @ (Mo-Fr 07:00-14:00) |
When I route I should get
| from | to | route |
| e | s | ej,js,js |
| e | n | ej,js,js,nj,nj |
| e | p | ej,jp,jp |
@no_turning @conditionals
Scenario: Car - Conditional restriction with multiple time windows
Given the extract extra arguments "--parse-conditional-restrictions"
# 5pm Wed 02 May, 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493744400"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493744400"
Given the node map
"""
n
p |
\ |
j
| \
s m
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| jp | yes |
| mj | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | nj | jp | j | no_right_turn @ (Mo-Fr 07:00-11:00,16:00-18:30) |
When I route I should get
| from | to | route |
| n | p | nj,js,js,jp,jp |
| m | p | mj,jp,jp |
@no_turning @conditionals
Scenario: Car - only_right_turn
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | nj | j | only_right_turn @ (Mo-Su 07:00-14:00) |
When I route I should get
| from | to | route |
| e | s | ej,nj,nj,js,js |
| e | n | ej,nj,nj |
| e | p | ej,nj,nj,jp,jp |
@no_turning @conditionals
Scenario: Car - No right turn
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | nj | j | no_right_turn @ (Mo-Fr 07:00-13:00) |
When I route I should get
| from | to | route | # |
| e | s | ej,js,js | normal turn |
| e | n | ej,js,js,nj,nj | avoids right turn |
| e | p | ej,jp,jp | normal maneuver |
@only_turning @conditionals
Scenario: Car - only_left_turn
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | js | j | only_left_turn @ (Mo-Fr 07:00-16:00) |
When I route I should get
| from | to | route |
| e | s | ej,js,js |
| e | n | ej,js,js,nj,nj |
| e | p | ej,js,js,jp,jp |
@no_turning @conditionals
Scenario: Car - No left turn
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | js | j | no_left_turn @ (Mo-Su 00:00-23:59) |
When I route I should get
| from | to | route |
| e | s | ej,nj,nj,js,js |
| e | n | ej,nj,nj |
| e | p | ej,jp,jp |
@no_turning @conditionals
Scenario: Car - Conditional restriction is off
Given the extract extra arguments "--parse-conditional-restrictions"
# time stamp for 10am on Tues, 02 May 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493719200"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | nj | j | no_right_turn @ (Mo-Su 16:00-20:00) |
When I route I should get
| from | to | route |
| e | s | ej,js,js |
| e | n | ej,nj,nj |
| e | p | ej,jp,jp |
@no_turning @conditionals
Scenario: Car - Conditional restriction is on
Given the extract extra arguments "--parse-conditional-restrictions"
# 10am utc, wed
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493805600"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493805600"
Given the node map
"""
n
p j e
s
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| ej | yes |
| jp | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ej | nj | j | no_right_turn @ (Mo-Fr 07:00-14:00) |
When I route I should get
| from | to | route |
| e | s | ej,js,js |
| e | n | ej,js,js,nj,nj |
| e | p | ej,jp,jp |
@no_turning @conditionals
Scenario: Car - Conditional restriction with multiple time windows
Given the extract extra arguments "--parse-conditional-restrictions"
# 5pm Wed 02 May, 2017 GMT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493744400"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/guinea.geojson --parse-conditionals-from-now=1493744400"
Given the node map
"""
n
p |
\ |
j
| \
s m
"""
And the ways
| nodes | oneway |
| nj | no |
| js | no |
| jp | yes |
| mj | yes |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | nj | jp | j | no_right_turn @ (Mo-Fr 07:00-11:00,16:00-18:30) |
When I route I should get
| from | to | route |
| n | p | nj,js,js,jp,jp |
| m | p | mj,jp,jp |
# https://www.openstreetmap.org/#map=18/38.91099/-77.00888
@no_turning @conditionals
Scenario: Car - DC North capitol situation, two on one off
Given the extract extra arguments "--parse-conditional-restrictions=1"
# 9pm Wed 02 May, 2017 UTC, 5pm EDT
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/dc.geojson --parse-conditionals-from-now=1493845200"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/dc.geojson --parse-conditionals-from-now=1493845200"
# """
# a h
# d
# b g
# e
# c f
# """
Given the node locations
| node | lat | lon |
| a | 38.9113 | -77.0091 |
| b | 38.9108 | -77.0091 |
| c | 38.9104 | -77.0091 |
| d | 38.9110 | -77.0096 |
| e | 38.9106 | -77.0086 |
| f | 38.9105 | -77.0090 |
| g | 38.9108 | -77.0090 |
| h | 38.9113 | -77.0090 |
And the ways
| nodes | oneway | name |
| ab | yes | cap south |
| bc | yes | cap south |
| fg | yes | cap north |
| gh | yes | cap north |
| db | no | florida nw |
| bg | no | florida |
| ge | no | florida ne |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ab | bg | b | no_left_turn @ (Mo-Fr 07:00-09:30,16:00-18:30) |
| restriction | fg | bg | g | no_left_turn @ (Mo-Fr 06:00-10:00) |
| restriction | bg | bc | b | no_left_turn @ (Mo-Fr 07:00-09:30,16:00-18:30) |
When I route I should get
| from | to | route | turns |
| a | e | cap south,florida nw,florida nw,florida ne | depart,turn right,continue uturn,arrive |
| f | d | cap north,florida,florida nw | depart,turn left,arrive |
| e | c | florida ne,florida nw,cap south,cap south | depart,continue uturn,turn right,arrive |
@no_turning @conditionals
Scenario: Car - DC North capitol situation, one on two off
Given the extract extra arguments "--parse-conditional-restrictions=1"
# 10:30am utc, wed, 6:30am est
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/dc.geojson --parse-conditionals-from-now=1493807400"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/dc.geojson --parse-conditionals-from-now=1493807400"
# """
# a h
# d
# b g
# e
# c f
# """
Given the node locations
| node | lat | lon |
| a | 38.9113 | -77.0091 |
| b | 38.9108 | -77.0091 |
| c | 38.9104 | -77.0091 |
| d | 38.9110 | -77.0096 |
| e | 38.9106 | -77.0086 |
| f | 38.9105 | -77.0090 |
| g | 38.9108 | -77.0090 |
| h | 38.9113 | -77.0090 |
And the ways
| nodes | oneway | name |
| ab | yes | cap south |
| bc | yes | cap south |
| fg | yes | cap north |
| gh | yes | cap north |
| db | no | florida nw |
| bg | no | florida |
| ge | no | florida ne |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ab | bg | b | no_left_turn @ (Mo-Fr 07:00-09:30,16:00-18:30) |
| restriction | fg | bg | g | no_left_turn @ (Mo-Fr 06:00-10:00) |
| restriction | bg | bc | b | no_left_turn @ (Mo-Fr 07:00-09:30,16:00-18:30) |
When I route I should get
| from | to | route | turns |
| a | e | cap south,florida,florida ne | depart,turn left,arrive |
| f | d | cap north,florida ne,florida ne,florida nw | depart,turn sharp right,continue uturn,arrive |
| e | c | florida ne,cap south,cap south | depart,turn left,arrive |
@only_turning @conditionals
Scenario: Car - Restriction is always off when point not found in timezone files
# same test as the following one, but given a different time zone file
Given the extract extra arguments "--parse-conditional-restrictions"
# 9am UTC, 10am BST
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/dc.geojson --parse-conditionals-from-now=1493802000"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/dc.geojson --parse-conditionals-from-now=1493802000"
# """
# a
# e
# b
# d
# c
# """
Given the node locations
| node | lat | lon |
| a | 51.5250 | -0.1166 |
| b | 51.5243 | -0.1159 |
| c | 51.5238 | -0.1152 |
| d | 51.5241 | -0.1167 |
| e | 51.5247 | -0.1153 |
And the ways
| nodes | name |
| ab | albic |
| bc | albic |
| db | dobe |
| be | dobe |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ab | be | b | only_left_turn @ (Mo-Fr 07:00-11:00) |
When I route I should get
| from | to | route | turns |
| a | c | albic,albic | depart,arrive |
| a | e | albic,dobe,dobe | depart,turn left,arrive |
@only_turning @conditionals
Scenario: Car - Somewhere in london, the UK, GMT timezone
Given the extract extra arguments "--parse-conditional-restrictions"
# 9am UTC, 10am BST
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/london.geojson --parse-conditionals-from-now=1493802000"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/london.geojson --parse-conditionals-from-now=1493802000"
# """
# a
# e
# b
# d
# c
# """
Given the node locations
| node | lat | lon |
| a | 51.5250 | -0.1166 |
| b | 51.5243 | -0.1159 |
| c | 51.5238 | -0.1152 |
| d | 51.5241 | -0.1167 |
| e | 51.5247 | -0.1153 |
And the ways
| nodes | name |
| ab | albic |
| bc | albic |
| db | dobe |
| be | dobe |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ab | be | b | only_left_turn @ (Mo-Fr 07:00-11:00) |
When I route I should get
| from | to | route | turns |
| a | c | albic,dobe,dobe,albic,albic | depart,turn left,continue uturn,turn left,arrive |
| a | e | albic,dobe,dobe | depart,turn left,arrive |
@only_turning @conditionals
Scenario: Car - Somewhere in London, the UK, GMT timezone
Given the extract extra arguments "--parse-conditional-restrictions=1"
# 9am UTC, 10am BST
Given the contract extra arguments "--time-zone-file=test/data/tz/{timezone_names}/london.geojson --parse-conditionals-from-now=1493802000"
Given the customize extra arguments "--time-zone-file=test/data/tz/{timezone_names}/london.geojson --parse-conditionals-from-now=1493802000"
# """
# a
# e
# b
# d
# c
# """
Given the node locations
| node | lat | lon |
| a | 51.5250 | -0.1166 |
| b | 51.5243 | -0.1159 |
| c | 51.5238 | -0.1152 |
| d | 51.5241 | -0.1167 |
| e | 51.5247 | -0.1153 |
And the ways
| nodes | name |
| ab | albic |
| bc | albic |
| db | dobe |
| be | dobe |
And the relations
| type | way:from | way:to | node:via | restriction:conditional |
| restriction | ab | be | b | only_left_turn @ (Mo-Fr 07:00-11:00) |
When I route I should get
| from | to | route | turns |
| a | c | albic,dobe,dobe,albic,albic | depart,turn left,continue uturn,turn left,arrive |
| a | e | albic,dobe,dobe | depart,turn left,arrive |
+17
View File
@@ -0,0 +1,17 @@
@routing @car @construction
Feature: Car - all construction tags the OpenStreetMap community could think of and then some
Background:
Given the profile "car"
Scenario: Various ways to tag construction and proposed roads
Then routability should be
| highway | construction | proposed | bothw |
| primary | | | x |
| construction | | | |
| proposed | | | |
| primary | yes | | |
| primary | | yes | |
| primary | no | | x |
| primary | widening | | x |
| primary | minor | | x |
+32 -32
View File
@@ -88,18 +88,18 @@ OSRM will use 4/5 of the projected free-flow speed.
| highway | maxspeed | width | maxspeed:forward | maxspeed:backward | forw | backw | forw_rate | backw_rate | | highway | maxspeed | width | maxspeed:forward | maxspeed:backward | forw | backw | forw_rate | backw_rate |
| primary | | | | | 64 km/h | 64 km/h | 18 | 18 | | primary | | | | | 64 km/h | 64 km/h | 18 | 18 |
| primary | | 3 | | | 64 km/h | 64 km/h | 9 | 9 | | primary | | 3 | | | 64 km/h | 64 km/h | 9 | 9 |
| primary | 60 | | | | 47 km/h | 47 km/h | 13 | 13 | | primary | 60 | | | | 47 km/h | 47 km/h | 13.3 | 13.3 |
| primary | 60 | 3 | | | 47 km/h | 47 km/h | 7 | 7 | | primary | 60 | 3 | | | 47 km/h | 47 km/h | 6.7 | 6.7 |
| primary | | | 60 | | 47 km/h | 64 km/h | 13 | 18 | | primary | | | 60 | | 47 km/h | 64 km/h | 13.3 | 18 |
| primary | | 3 | 60 | | 47 km/h | 64 km/h | 7 | 9 | | primary | | 3 | 60 | | 47 km/h | 64 km/h | 6.7 | 9 |
| primary | | | | 60 | 64 km/h | 47 km/h | 18 | 13 | | primary | | | | 60 | 64 km/h | 47 km/h | 18 | 13.3 |
| primary | | 3 | | 60 | 64 km/h | 47 km/h | 9 | 7 | | primary | | 3 | | 60 | 64 km/h | 47 km/h | 9 | 6.7 |
| primary | 15 | | 60 | | 47 km/h | 11 km/h | 13 | 3 | | primary | 15 | | 60 | | 47 km/h | 11 km/h | 13.3 | 3.3 |
| primary | 15 | 3 | 60 | | 48 km/h | 12 km/h | 7 | 2 | | primary | 15 | 3 | 60 | | 48 km/h | 12 km/h | 6.7 | 1.7 |
| primary | 15 | | | 60 | 12 km/h | 47 km/h | 3 | 13 | | primary | 15 | | | 60 | 12 km/h | 47 km/h | 3.3 | 13.3 |
| primary | 15 | 3 | | 60 | 12 km/h | 47 km/h | 2 | 7 | | primary | 15 | 3 | | 60 | 12 km/h | 47 km/h | 1.7 | 6.7 |
| primary | 15 | | 30 | 60 | 23 km/h | 47 km/h | 7 | 13 | | primary | 15 | | 30 | 60 | 23 km/h | 47 km/h | 6.7 | 13.3 |
| primary | 15 | 3 | 30 | 60 | 23 km/h | 47 km/h | 3 | 7 | | primary | 15 | 3 | 30 | 60 | 23 km/h | 47 km/h | 3.3 | 6.7 |
Scenario: Car - Single lane streets be ignored or incur a penalty Scenario: Car - Single lane streets be ignored or incur a penalty
Then routability should be Then routability should be
@@ -107,33 +107,33 @@ OSRM will use 4/5 of the projected free-flow speed.
| highway | maxspeed | lanes | maxspeed:forward | maxspeed:backward | forw | backw | forw_rate | backw_rate | | highway | maxspeed | lanes | maxspeed:forward | maxspeed:backward | forw | backw | forw_rate | backw_rate |
| primary | | | | | 64 km/h | 64 km/h | 18 | 18 | | primary | | | | | 64 km/h | 64 km/h | 18 | 18 |
| primary | | 1 | | | 64 km/h | 64 km/h | 9 | 9 | | primary | | 1 | | | 64 km/h | 64 km/h | 9 | 9 |
| primary | 60 | | | | 47 km/h | 47 km/h | 13 | 13 | | primary | 60 | | | | 47 km/h | 47 km/h | 13.3 | 13.3 |
| primary | 60 | 1 | | | 47 km/h | 47 km/h | 7 | 7 | | primary | 60 | 1 | | | 47 km/h | 47 km/h | 6.7 | 6.7 |
| primary | | | 60 | | 47 km/h | 64 km/h | 13 | 18 | | primary | | | 60 | | 47 km/h | 64 km/h | 13.3 | 18 |
| primary | | 1 | 60 | | 47 km/h | 64 km/h | 7 | 9 | | primary | | 1 | 60 | | 47 km/h | 64 km/h | 6.7 | 9 |
| primary | | | | 60 | 64 km/h | 47 km/h | 18 | 13 | | primary | | | | 60 | 64 km/h | 47 km/h | 18 | 13.3 |
| primary | | 1 | | 60 | 64 km/h | 47 km/h | 9 | 7 | | primary | | 1 | | 60 | 64 km/h | 47 km/h | 9 | 6.7 |
| primary | 15 | | 60 | | 47 km/h | 11 km/h | 13 | 3 | | primary | 15 | | 60 | | 47 km/h | 11 km/h | 13.3 | 3.3 |
| primary | 15 | 1 | 60 | | 48 km/h | 12 km/h | 7 | 2 | | primary | 15 | 1 | 60 | | 48 km/h | 12 km/h | 6.7 | 1.7 |
| primary | 15 | | | 60 | 12 km/h | 47 km/h | 3 | 13 | | primary | 15 | | | 60 | 12 km/h | 47 km/h | 3.3 | 13.3 |
| primary | 15 | 1 | | 60 | 12 km/h | 47 km/h | 2 | 7 | | primary | 15 | 1 | | 60 | 12 km/h | 47 km/h | 1.7 | 6.7 |
| primary | 15 | | 30 | 60 | 23 km/h | 47 km/h | 7 | 13 | | primary | 15 | | 30 | 60 | 23 km/h | 47 km/h | 6.7 | 13.3 |
| primary | 15 | 1 | 30 | 60 | 23 km/h | 47 km/h | 3 | 7 | | primary | 15 | 1 | 30 | 60 | 23 km/h | 47 km/h | 3.3 | 6.7 |
Scenario: Car - Single lane streets only incur a penalty for two-way streets Scenario: Car - Single lane streets only incur a penalty for two-way streets
Then routability should be Then routability should be
| highway | maxspeed | lanes | oneway | forw | backw | forw_rate | backw_rate | | highway | maxspeed | lanes | oneway | forw | backw | forw_rate | backw_rate |
| primary | 30 | 1 | yes | 23 km/h | | 7 | | | primary | 30 | 1 | yes | 23 km/h | | 6.7 | |
| primary | 30 | 1 | -1 | | 23 km/h | | 7 | | primary | 30 | 1 | -1 | | 23 km/h | | 6.7 |
| primary | 30 | 1 | | 23 km/h | 23 km/h | 3 | 3 | | primary | 30 | 1 | | 23 km/h | 23 km/h | 3.3 | 3.3 |
| primary | 30 | 2 | | 23 km/h | 23 km/h | 7 | 7 | | primary | 30 | 2 | | 23 km/h | 23 km/h | 6.7 | 6.7 |
Scenario: Car - Forward/backward maxspeed on reverse oneways Scenario: Car - Forward/backward maxspeed on reverse oneways
Then routability should be Then routability should be
| highway | maxspeed | maxspeed:forward | maxspeed:backward | oneway | forw | backw | forw_rate | backw_rate | | highway | maxspeed | maxspeed:forward | maxspeed:backward | oneway | forw | backw | forw_rate | backw_rate |
| primary | | | | -1 | | 64 km/h | | 18 | | primary | | | | -1 | | 64 km/h | | 18 |
| primary | 30 | | | -1 | | 23 km/h | | 7 | | primary | 30 | | | -1 | | 23 km/h | | 6.7 |
| primary | | 30 | | -1 | | 64 km/h | | 18 | | primary | | 30 | | -1 | | 64 km/h | | 18 |
| primary | | | 30 | -1 | | 23 km/h | | 7 | | primary | | | 30 | -1 | | 23 km/h | | 6.7 |
| primary | 20 | 30 | | -1 | | 15 km/h | | 4 | | primary | 20 | 30 | | -1 | | 15 km/h | | 4.4 |
| primary | 20 | | 30 | -1 | | 23 km/h | | 7 | | primary | 20 | | 30 | -1 | | 23 km/h | | 6.7 |
+4 -4
View File
@@ -7,8 +7,8 @@ Feature: Car - Surfaces
Scenario: Car - Ways tagged service should reduce speed Scenario: Car - Ways tagged service should reduce speed
Then routability should be Then routability should be
| highway | service | forw | backw | forw_rate | | highway | service | forw | backw | forw_rate |
| service | alley | 15 km/h +-1 | 15 km/h +-1 | 2 | | service | alley | 15 km/h +-1 | 15 km/h +-1 | 2.1 |
| service | emergency_access | | | | | service | emergency_access | | | |
| service | driveway | 15 km/h +-1 | 15 km/h +-1 | 2 | | service | driveway | 15 km/h +-1 | 15 km/h +-1 | 2.1 |
| service | drive-through | 15 km/h +-1 | 15 km/h +-1 | 2 | | service | drive-through | 15 km/h +-1 | 15 km/h +-1 | 2.1 |
| service | parking | 15 km/h +-1 | 15 km/h +-1 | 2 | | service | parking | 15 km/h +-1 | 15 km/h +-1 | 2.1 |
+1 -1
View File
@@ -50,4 +50,4 @@ Feature: Car - speeds
Then routability should be Then routability should be
| highway | side_road | forw | backw | forw_rate | backw_rate | | highway | side_road | forw | backw | forw_rate | backw_rate |
| primary | yes | 64 km/h | 64 km/h | 14 | 14 | | primary | yes | 64 km/h | 64 km/h | 14.4 | 14.4 |
+37
View File
@@ -0,0 +1,37 @@
@routing @car @startpoint
Feature: Car - Allowed start/end modes
Background:
Given the profile "car"
Scenario: Car - Don't start/stop on ferries
Given the node map
"""
a 1 b 2 c
"""
And the ways
| nodes | highway | route | bicycle |
| ab | primary | | |
| bc | | ferry | yes |
When I route I should get
| from | to | route | modes |
| 1 | 2 | ab,ab | driving,driving |
| 2 | 1 | ab,ab | driving,driving |
Scenario: Car - Don't start/stop on trains
Given the node map
"""
a 1 b 2 c
"""
And the ways
| nodes | highway | railway | bicycle |
| ab | primary | | |
| bc | | train | yes |
When I route I should get
| from | to | route | modes |
| 1 | 2 | ab,ab | driving,driving |
| 2 | 1 | ab,ab | driving,driving |
+2 -2
View File
@@ -60,8 +60,8 @@ Feature: Basic Routing
| bc | | 101 | | bc | | 101 |
When I route I should get When I route I should get
| waypoints | route | summary | | waypoints | route | summary |
| a,c | road, | road, 101 | | a,c | road,, | road, 101 |
Scenario: Only Refs Scenario: Only Refs
Given the node map Given the node map
+33
View File
@@ -0,0 +1,33 @@
@routing @via
Feature: Via points
Background:
Given the profile "car"
# See issue #1896
Scenario: Via point at a dead end with barrier
Given the profile "car"
Given the node map
"""
a b c
1
d
f e
"""
And the nodes
| node | barrier |
| d | bollard |
And the ways
| nodes |
| abc |
| bd |
| afed |
When I route I should get
| waypoints | route |
| a,1,c | abc,bd,bd,bd,bd,abc,abc |
| c,1,a | abc,bd,bd,bd,bd,abc,abc |
+37
View File
@@ -0,0 +1,37 @@
@routing @foot @startpoint
Feature: Foot - Allowed start/end modes
Background:
Given the profile "foot"
Scenario: Foot - Don't start/stop on ferries
Given the node map
"""
a 1 b 2 c
"""
And the ways
| nodes | highway | route | bicycle |
| ab | primary | | |
| bc | | ferry | yes |
When I route I should get
| from | to | route | modes |
| 1 | 2 | ab,ab | walking,walking |
| 2 | 1 | ab,ab | walking,walking |
Scenario: Foot - Don't start/stop on trains
Given the node map
"""
a 1 b 2 c
"""
And the ways
| nodes | highway | railway | bicycle |
| ab | primary | | |
| bc | | train | yes |
When I route I should get
| from | to | route | modes |
| 1 | 2 | ab,ab | walking,walking |
| 2 | 1 | ab,ab | walking,walking |
+14 -14
View File
@@ -35,10 +35,10 @@ Feature: Turn Lane Guidance
| restriction | bc | cd | c | no_right_turn | | restriction | bc | cd | c | no_right_turn |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,e | in,cross,cross | depart,turn left,arrive | ,left:true straight:false right:false, | | a,e | in,cross,cross | depart,turn left,arrive | ;,left:true straight:false, |
| a,g | in,straight,straight | depart,new name straight,arrive | ,left:false straight:true right:false, | | a,g | in,straight,straight | depart,new name straight,arrive | ;,left:false straight:true, |
| a,f | in,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true, | | a,f | in,cross,cross | depart,continue right,arrive | ,;right:true, |
@sliproads @sliproads
Scenario: Separate Turn Lanes Scenario: Separate Turn Lanes
@@ -68,10 +68,10 @@ Feature: Turn Lane Guidance
| restriction | bc | cd | c | no_right_turn | | restriction | bc | cd | c | no_right_turn |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,e | in,cross,cross | depart,turn left,arrive | ,left:true straight:false right:false, | | 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,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,f | in,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true;left:false straight:false right:true, |
@sliproads @sliproads
@@ -109,12 +109,12 @@ Feature: Turn Lane Guidance
| restriction | bc | cd | c | no_right_turn | | restriction | bc | cd | c | no_right_turn |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,e | in,cross,cross | depart,turn left,arrive | ,left:true straight:false right:false, | | 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,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,f | in,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true;left:false straight:false right:true, |
| a,j | in,turn,other,other | depart,turn right,turn left,arrive | ,,left:true right:false, | | 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, | | a,i | in,turn,other,other | depart,turn right,turn right,arrive | ,,left:false right:true, |
@todo @2654 @none @todo @2654 @none
+48 -86
View File
@@ -3,7 +3,7 @@ Feature: Turn Lane Guidance
Background: Background:
Given the profile "car" Given the profile "car"
Given a grid size of 20 meters Given a grid size of 100 meters
@anticipate @anticipate
Scenario: Anticipate Lane Change for subsequent multi-lane intersections Scenario: Anticipate Lane Change for subsequent multi-lane intersections
@@ -151,9 +151,9 @@ Feature: Turn Lane Guidance
| cj | | 1 | motorway_link | yes | xbcj | | cj | | 1 | motorway_link | yes | xbcj |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,i | ab,ci,ci | depart,turn slight right,arrive | ,none:false slight right:true, | | a,i | ab,ci,ci | depart,turn slight right,arrive | ;,none:false slight right:true, |
| a,j | ab,xbcj | depart,arrive | , | | a,j | ab,xbcj | depart,arrive | ;;none:true slight right:false, |
@anticipate @anticipate
@@ -308,8 +308,8 @@ Feature: Turn Lane Guidance
| di | | off | | yes | | di | | off | | yes |
When I route I should get When I route I should get
| waypoints | route | turns | destinations | lanes | locations | | waypoints | route | turns | destinations | locations | lanes |
| a,e | main,main,main | depart,use lane straight,arrive | One,Two,Three | ,left:false straight:false straight:true straight:false right:false, | a,c,e | | a,e | main,main | depart,arrive | One,Three | a,e | ;left:false straight:false straight:true straight:false right:false;left:false straight:true right:false, |
@anticipate @anticipate
Scenario: Anticipate Lanes for through and collapse multiple use lanes Scenario: Anticipate Lanes for through and collapse multiple use lanes
@@ -335,9 +335,9 @@ Feature: Turn Lane Guidance
| dj | | off | | dj | | off |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,c | main,main | depart,arrive | , | | a,c | main,main | depart,arrive | ;left:false straight:true straight:true right:false, |
| a,d | main,main | depart,arrive | , | | a,d | main,main | depart,arrive | ;left:false straight:true straight:true right:false;left:false straight:true straight:true right:false, |
@anticipate @anticipate
Scenario: Anticipate Lanes for through followed by left/right Scenario: Anticipate Lanes for through followed by left/right
@@ -363,17 +363,17 @@ Feature: Turn Lane Guidance
| ci | | off | | ci | | off |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | 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,d | main,left,left | depart,end of road 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, | | a,e | main,right,right | depart,end of road 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 @anticipate
Scenario: Anticipate Lanes for through with turn before / after Scenario: Anticipate Lanes for through with turn before / after
Given the node map Given the node map
""" """
c g l c g l
b d e h - i b d e h i
a f j a f j
""" """
And the ways And the ways
@@ -390,15 +390,15 @@ Feature: Turn Lane Guidance
| il | | il | | | il | | il | |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | # | | 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,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,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,j | ab,bdehi,ij,ij | depart,turn right,end of road 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 | | a,l | ab,bdehi,il,il | depart,turn right,end of road 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,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,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,l | cb,bdehi,il,il | depart,turn left,end of road 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 | | c,j | cb,bdehi,ij,ij | depart,turn left,end of road 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 @anticipate
Scenario: Anticipate Lanes for turns with through before and after Scenario: Anticipate Lanes for turns with through before and after
@@ -431,11 +431,11 @@ Feature: Turn Lane Guidance
| jk | | bot | primary | yes | | jk | | bot | primary | yes |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | 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,i | top,main,top,top | depart,turn right,turn left,arrive | ,straight:false right:true 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, | | a,k | top,main,bot,bot | depart,turn right,turn right,arrive | ,straight:false right:true right:true right:true;;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,i | bot,main,top,top | depart,turn left,turn left,arrive | ,left:true 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, | | c,k | bot,main,bot,bot | depart,turn left,turn right,arrive | ,left:true left:true left:true straight:false;;left:false straight:false straight:false straight:true straight:true right:false,left:false left:false right:true right:true, |
@anticipate @anticipate
Scenario: Anticipate Lanes for turn between throughs Scenario: Anticipate Lanes for turn between throughs
@@ -462,8 +462,8 @@ Feature: Turn Lane Guidance
| dt | | off | | dt | | off |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | 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, | | a,e | main,main,main | depart,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;left:false straight:true straight:true, |
@anticipate @todo @2661 @anticipate @todo @2661
Scenario: Anticipate with lanes in roundabout: roundabouts as the unit of anticipation Scenario: Anticipate with lanes in roundabout: roundabouts as the unit of anticipation
@@ -520,8 +520,8 @@ Feature: Turn Lane Guidance
| df | | primary | | | df | | primary | |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes | intersection_lanes |
| a,f | ab,df,df | depart,roundabout-exit-1,use lane slight right,arrive | ,,slight left:false slight left:false slight right:true, | | a,f | ab,df,df | depart,roundabout-exit-1,arrive | ,, | |
@anticipate @anticipate
Scenario: No Lanes for Roundabouts, see #2626 Scenario: No Lanes for Roundabouts, see #2626
@@ -553,8 +553,8 @@ Feature: Turn Lane Guidance
| fy | | primary | | | fy | | primary | |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,h | ab,gh,gh | depart,roundabout-exit-5,arrive | ,, | | a,h | ab,gh,gh | depart,roundabout-exit-5,arrive | ,;;;;;, |
@anticipate @anticipate
Scenario: No Lanes for Roundabouts, see #2626 Scenario: No Lanes for Roundabouts, see #2626
@@ -576,9 +576,9 @@ Feature: Turn Lane Guidance
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| x,y | xb,dy,dy | depart,roundabout-exit-1,arrive | ,, | | x,y | xb,dy,dy | depart,roundabout-exit-1,arrive | ,;, |
| x,c | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,, | | x,c | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,, |
| x,a | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,, | | x,a | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,;, |
@anticipate @anticipate
Scenario: No Lanes for Roundabouts, see #2626 Scenario: No Lanes for Roundabouts, see #2626
@@ -614,8 +614,8 @@ Feature: Turn Lane Guidance
| fy | | primary | | | fy | | primary | |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,h | ab,ch,ch | depart,roundabout-exit-5,arrive | ,, | | a,h | ab,ch,ch | depart,roundabout-exit-5,arrive | ,;;;;;, |
@anticipate @anticipate
Scenario: No Lanes for Roundabouts, see #2626 Scenario: No Lanes for Roundabouts, see #2626
@@ -623,40 +623,11 @@ Feature: Turn Lane Guidance
""" """
/a\ /a\
x b d y x b d y
| |
| |
| |
| |
| |
| |
| |
| |
| | | |
| | | |
| | | |
| | | |
| | \ /
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
|
|
|
|
|
|
|
|
|
|
c c
""" """
@@ -671,9 +642,9 @@ Feature: Turn Lane Guidance
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| x,y | xb,dy,dy | depart,roundabout-exit-1,arrive | ,, | | x,y | xb,dy,dy | depart,roundabout-exit-1,arrive | ,;, |
| x,c | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,, | | x,c | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,, |
| x,a | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,, | | x,a | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,;, |
@anticipate @todo @2032 @anticipate @todo @2032
Scenario: No Lanes for Roundabouts, see #2626 Scenario: No Lanes for Roundabouts, see #2626
@@ -789,13 +760,6 @@ Feature: Turn Lane Guidance
Given the node map Given the node map
""" """
a b x a b x
|
|
|
|
|
|
|
| |
| |
| |
@@ -823,11 +787,9 @@ Feature: Turn Lane Guidance
Scenario: Don't Overdo It Scenario: Don't Overdo It
Given the node map Given the node map
""" """
q r s t u v q r s t u v
| | | | | | a - - b - - c - - d - - e - - f - g - h - i
a - - - - - - - - - - b - - - - - - - - - - c - - - - - - - - - - d - - - - - - - - - - e - - - - - - - - - - f - - - - - - - - - - g - h - i p o n m l k j
| | | | | | |
p o n m l k j
""" """
And the ways And the ways
@@ -849,6 +811,6 @@ Feature: Turn Lane Guidance
| hj | 7th | | no | | hj | 7th | | no |
When I route I should get When I route I should get
| waypoints | route | turns | locations | lanes | | waypoints | route | turns | locations | lanes |
| a,i | road,road,road | depart,use lane straight,arrive | a,g,i | ,left:false none:true none:true none:false, | | a,i | road,road | depart,arrive | a,i | ;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:false;none:true none:true right:false, |
| a,j | road,road,7th,7th | depart,use lane straight,turn right,arrive | a,f,h,j | ,left:false none:false none:false none:true,none:false none:false right:true, | | a,j | road,7th,7th | depart,turn right,arrive | a,h,j | ;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:false none:false none:true;left:false none:false none:false none:true,none:false none:false right:true, |
+30 -11
View File
@@ -359,7 +359,7 @@ Feature: Collapse
| a,g | first,second,second | depart,turn left,arrive | a,b,g | | a,g | first,second,second | depart,turn left,arrive | a,b,g |
| d,g | first,second,second | depart,turn right,arrive | d,e,g | | d,g | first,second,second | depart,turn right,arrive | d,e,g |
| g,f | second,first,first | depart,turn right,arrive | g,e,f | | g,f | second,first,first | depart,turn right,arrive | g,e,f |
| g,c | second,first,first | depart,end of road left,arrive | g,b,c | | g,c | second,first,first | depart,turn left,arrive | g,e,c |
Scenario: Do not collapse turning roads Scenario: Do not collapse turning roads
Given the node map Given the node map
@@ -690,9 +690,9 @@ Feature: Collapse
| restriction | bc | dc | c | no_right_turn | | restriction | bc | dc | c | no_right_turn |
When I route I should get When I route I should get
| waypoints | route | turns | locations | | waypoints | route | turns | locations |
| a,g | road,cross,cross | depart,turn left,arrive | a,b,g | | a,g | road,road,cross,cross | depart,continue slight left,turn left,arrive | a,b,c,g |
| a,e | road,road | depart,arrive | a,e | | a,e | road,road | depart,arrive | a,e |
Scenario: On-Off on Highway Scenario: On-Off on Highway
Given the node map Given the node map
@@ -807,8 +807,8 @@ Feature: Collapse
| di | | off | | di | | off |
When I route I should get When I route I should get
| waypoints | route | turns | locations | | waypoints | route | turns | locations | lanes |
| a,e | main,main,main | depart,use lane straight,arrive | a,c,e | | a,e | main,main | depart,arrive | a,e | ;left:false straight:false straight:true straight:false right:false;left:false straight:true right:false, |
Scenario: But _do_ collapse UseLane step when lanes stay the same Scenario: But _do_ collapse UseLane step when lanes stay the same
Given the node map Given the node map
@@ -996,8 +996,8 @@ Feature: Collapse
a . . b .' a . . b .'
` d. ` d.
f e f e
""" """
#Check collapse.detail for a similar case (shorter) that does not classify these turns as a sliproad anymore #Check collapse.detail for a similar case (shorter) that does not classify these turns as a sliproad anymore
And the ways And the ways
| nodes | name | oneway | highway | | nodes | name | oneway | highway |
@@ -1016,9 +1016,9 @@ Feature: Collapse
When I route I should get When I route I should get
| waypoints | route | turns | locations | | waypoints | route | turns | locations |
| a,g | road,cross,cross | depart,fork left,arrive | a,b,g | | a,g | road,road,cross,cross | depart,fork slight left,turn left,arrive | a,b,c,g |
| a,e | road,road,road | depart,fork slight right,arrive | a,b,e | | a,e | road,road,road | depart,fork slight right,arrive | a,b,e |
| a,f | road,road,cross,cross | depart,fork slight right,turn right,arrive | a,b,d,f | | a,f | road,road,cross,cross | depart,fork slight right,turn right,arrive | a,b,d,f |
# http://www.openstreetmap.org/way/92415447 #3933 # http://www.openstreetmap.org/way/92415447 #3933
@@ -1055,3 +1055,22 @@ Feature: Collapse
When I route I should get When I route I should get
| waypoints | route | turns | locations | | waypoints | route | turns | locations |
| a,i | President Avenue,Princes Highway,Princes Highway | depart,turn left,arrive | a,b,i | | a,i | President Avenue,Princes Highway,Princes Highway | depart,turn left,arrive | a,b,i |
Scenario: Don't combine uturns
Given the node map
"""
2 d
a - - b - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - c
1
"""
And the ways
| nodes | highway |
| ab | tertiary |
| bc | tertiary |
| bd | service |
When I route I should get
| waypoints | bearings | route | turns | locations |
| 1,2 | 90 270 | ab,bd,bd,ab,ab | depart,turn left,continue uturn,turn right,arrive | _,b,d,b,_ |
+48
View File
@@ -0,0 +1,48 @@
@driveway @guidance
Feature: Driveways intersections
Background:
Given the profile "car"
Given a grid size of 5 meters
Scenario: Road with a turn to service road
Given the node map
"""
a
~.
b----c----d
|
e
"""
And the ways
| nodes | highway | name | oneway |
| abc | trunk | first | yes |
| cd | trunk | second | yes |
| be | service | parking | yes |
When I route I should get
| waypoints | route | turns | locations |
| a,d | first,second | depart,arrive | a,d |
Scenario: Turn Instead of Ramp
Given the node map
"""
a
~.
b----c----d
|
e
"""
And the ways
| nodes | highway | name | oneway |
| ab | trunk | | yes |
| bc | trunk | | yes |
| cd | trunk | second | yes |
| be | service | parking | yes |
When I route I should get
| waypoints | route | turns | locations |
| a,d | ,second | depart,arrive | a,d |
@@ -0,0 +1,98 @@
@routing @guidance
Feature: Exit Numbers and Names
Background:
Given the profile "car"
Given a grid size of 10 meters
Scenario: Exit number on the way after the motorway junction
Given the node map
"""
a . . b . c . . d
` e . . f
"""
And the nodes
| node | highway |
| b | motorway_junction |
And the ways
| nodes | highway | name | junction:ref |
| abcd | motorway | MainRoad | |
| be | motorway_link | ExitRamp | 3 |
| ef | motorway_link | ExitRamp | |
When I route I should get
| waypoints | route | turns | exits |
| a,f | MainRoad,ExitRamp,ExitRamp | depart,off ramp slight right,arrive | ,3, |
Scenario: Exit number on the way, motorway junction node tag missing, multiple numbers
Given the node map
"""
a . . b . c . . d
` e . . f
"""
And the ways
| nodes | highway | name | junction:ref |
| abcd | motorway | MainRoad | |
| be | motorway_link | ExitRamp | 10;12 |
| ef | motorway_link | ExitRamp | |
When I route I should get
| waypoints | route | turns | exits |
| a,f | MainRoad,ExitRamp,ExitRamp | depart,off ramp slight right,arrive | ,10; 12, |
Scenario: Exit number on the ways after the motorway junction, multiple exits
Given the node map
"""
a . . b . c . . d
` e . . f
` g . . h
"""
And the nodes
| node | highway |
| b | motorway_junction |
And the ways
| nodes | highway | name | junction:ref |
| abcd | motorway | MainRoad | |
| be | motorway_link | ExitRamp | 3 |
| ef | motorway_link | ExitRamp | |
| bg | motorway_link | ExitRamp | 3 |
| gh | motorway_link | ExitRamp | |
When I route I should get
| waypoints | route | turns | exits |
| a,f | MainRoad,ExitRamp,ExitRamp | depart,off ramp slight right,arrive | ,3, |
| a,h | MainRoad,ExitRamp,ExitRamp | depart,off ramp right,arrive | ,3, |
# http://www.openstreetmap.org/way/417524818#map=17/37.38663/-121.97972
Scenario: Exit 393 on Bayshore Freeway
Given the node map
"""
a
` b
` c
. ` d
f ` e
"""
And the nodes
| node | highway |
| c | motorway_junction |
And the ways
| nodes | highway | name | junction:ref | oneway | destination |
| abcde | motorway | Bayshore Freeway | | yes | |
| cf | motorway_link | | 393 | yes | Great America Parkway;Bowers Avenue |
When I route I should get
| waypoints | route | turns | exits | destinations |
| a,e | Bayshore Freeway,Bayshore Freeway | depart,arrive | , | , |
| a,f | Bayshore Freeway,, | depart,off ramp slight right,arrive | ,393,393 | ,Great America Parkway, Bowers Avenue,Great America Parkway, Bowers Avenue |
+20
View File
@@ -261,3 +261,23 @@ Feature: Motorway Guidance
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,d | On,Hwy,Off,Off | depart,merge slight right,off ramp right,arrive | | a,d | On,Hwy,Off,Off | depart,merge slight right,off ramp right,arrive |
#http://0.0.0.0:9966/?z=18&center=38.893323%2C-77.055117&loc=38.893551%2C-77.054833&loc=38.893112%2C-77.055536&hl=en&alt=0
Scenario: Merging with same name
Given the node map
"""
a - - -
> c - d
b
"""
And the ways
| nodes | name | ref | highway | oneway |
| ac | | US 50 | motorway | yes |
| bc | | I 66 | motorway | yes |
| cd | | US 50; I 66 | motorway | yes |
When I route I should get
| waypoints | route | turns |
| a,d | , | depart,arrive |
| b,d | , | depart,arrive |
@@ -37,3 +37,37 @@ Feature: Basic Roundabout
| h,a | gh,ab,ab | depart,roundabout turn left exit-3,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,d | gh,cd,cd | depart,roundabout turn straight exit-2,arrive |
| h,f | gh,ef,ef | depart,roundabout turn right exit-1,arrive | | h,f | gh,ef,ef | depart,roundabout turn right exit-1,arrive |
# https://www.openstreetmap.org/way/223225602
Scenario: Enter and Exit with changing mode
Given the node map
"""
a
b
h g c d
e
f
"""
And the ways
| nodes | junction | highway |
| ab | | residential |
| cd | | residential |
| ef | | footway |
| gh | | footway |
| bgecb | roundabout | residential |
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,ef | depart,roundabout turn left exit-1,notification right,arrive |
| a,h | ab,bgecb,gh,gh | depart,roundabout turn right exit-1,notification right,arrive |
| d,f | cd,ef,ef,ef | depart,roundabout turn sharp left exit-2,notification right,arrive |
| d,h | cd,gh,gh,gh | depart,roundabout turn left exit-2,notification right,arrive |
| d,a | cd,ab,ab | depart,roundabout turn right exit-1,arrive |
| f,h | ef,gh,gh,gh | depart,roundabout turn sharp left exit-3,notification right,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-2,arrive |
| h,d | gh,cd,cd | depart,roundabout turn straight exit-1,arrive |
| h,f | gh,bgecb,ef,ef | depart,roundabout turn right exit-1,notification right,arrive |
+65 -39
View File
@@ -606,11 +606,11 @@ Feature: Basic Roundabout
| ob | trunk | yes | roundabout | Europaplatz | | | ob | trunk | yes | roundabout | Europaplatz | |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns |
| a,d | ,Europastrasse,Europastrasse | depart,Europaplatz-exit-1,arrive | ,, | | a,d | ,Europastrasse,Europastrasse | depart,Europaplatz-exit-1,arrive |
| a,h | ,Allee Cite,Allee Cite | depart,Europaplatz-exit-2,arrive | ,, | | a,h | ,Allee Cite,Allee Cite | depart,Europaplatz-exit-2,arrive |
| a,l | ,Europastrasse,Europastrasse | depart,Europaplatz-exit-3,arrive | ,, | | a,l | ,Europastrasse,Europastrasse | depart,Europaplatz-exit-3,arrive |
| a,p | ,, | depart,Europaplatz-exit-4,arrive | ,, | | a,p | ,, | depart,Europaplatz-exit-4,arrive |
@turboroundabout @turboroundabout
# http://www.openstreetmap.org/?mlat=50.180039&mlon=8.474939&zoom=16#map=19/50.17999/8.47506 # http://www.openstreetmap.org/?mlat=50.180039&mlon=8.474939&zoom=16#map=19/50.17999/8.47506
@@ -658,14 +658,14 @@ Feature: Basic Roundabout
| wb | primary | yes | roundabout | | through\|through;right | | wb | primary | yes | roundabout | | through\|through;right |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns |
| a,w | Le-Cannet-Rocheville-Strasse,, | depart,roundabout-exit-undefined,arrive | ,, | | a,w | Le-Cannet-Rocheville-Strasse,, | depart,roundabout-exit-undefined,arrive |
| a,r | Le-Cannet-Rocheville-Strasse,, | depart,roundabout-exit-4,arrive | ,, | | a,r | Le-Cannet-Rocheville-Strasse,, | depart,roundabout-exit-4,arrive |
| a,f | Le-Cannet-Rocheville-Strasse,Frankfurter Strasse,Frankfurter Strasse | depart,roundabout-exit-1,arrive | ,, | | a,f | Le-Cannet-Rocheville-Strasse,Frankfurter Strasse,Frankfurter Strasse | depart,roundabout-exit-1,arrive |
| a,h | Le-Cannet-Rocheville-Strasse,Bischof-Kaller-Strasse,Bischof-Kaller-Strasse | depart,roundabout-exit-2,arrive | ,, | | a,h | Le-Cannet-Rocheville-Strasse,Bischof-Kaller-Strasse,Bischof-Kaller-Strasse | depart,roundabout-exit-2,arrive |
| u,r | ,, | depart,roundabout-exit-5,arrive | ,, | | u,r | ,, | depart,roundabout-exit-5,arrive |
| j,h | Bischof-Kaller-Strasse,Bischof-Kaller-Strasse,Bischof-Kaller-Strasse | depart,roundabout-exit-5,arrive | ,, | | j,h | Bischof-Kaller-Strasse,Bischof-Kaller-Strasse,Bischof-Kaller-Strasse | depart,roundabout-exit-5,arrive |
| n,m | , | depart,arrive | , | | n,m | , | depart,arrive |
@turboroundabout @turboroundabout
# http://www.openstreetmap.org/?mlat=47.57723&mlon=7.796765&zoom=16#map=19/47.57720/7.79711 # http://www.openstreetmap.org/?mlat=47.57723&mlon=7.796765&zoom=16#map=19/47.57720/7.79711
@@ -769,32 +769,6 @@ Feature: Basic Roundabout
| g,h | 45 135 | gch,gch,gch | depart,roundabout-exit-1,arrive | | g,h | 45 135 | gch,gch,gch | depart,roundabout-exit-1,arrive |
| e,e | 90 270 | edf,edf,edf | depart,roundabout-exit-3,arrive | | e,e | 90 270 | edf,edf,edf | depart,roundabout-exit-3,arrive |
@4030 @4075
Scenario: Service roundabout with service exits
# Counting of service exits must be adjusted in #4075
Given the node map
"""
e
f a d
g b1c
h
"""
And the ways
| nodes | highway | junction |
| abcda | service | roundabout |
| de | service | |
| af | service | |
| bg | tertiary | |
| bh | service | |
When I route I should get
| from | to | route | turns |
| 1 | e | abcda,de,de | depart,roundabout-exit-1,arrive |
| 1 | f | abcda,af,af | depart,roundabout-exit-1,arrive |
| 1 | g | abcda,bg,bg | depart,roundabout-exit-1,arrive |
| 1 | h | abcda,bh,bh | depart,roundabout-exit-1,arrive |
Scenario: CCW and CW roundabouts with overlaps Scenario: CCW and CW roundabouts with overlaps
Given the node map Given the node map
""" """
@@ -820,3 +794,55 @@ Feature: Basic Roundabout
| k | l | kg,hl,hl | depart,roundabout-exit-1,arrive | 80.1m | | k | l | kg,hl,hl | depart,roundabout-exit-1,arrive | 80.1m |
| l | k | hl,kg,kg | depart,roundabout-exit-1,arrive | 120.1m | | l | k | hl,kg,kg | depart,roundabout-exit-1,arrive | 120.1m |
@4030 @4075
Scenario: Service roundabout with service exits
Given the node map
"""
g a d f
h b1c e
"""
And the ways
| nodes | highway | junction |
| abcda | service | roundabout |
| ce | service | |
| df | service | |
| ag | tertiary | |
| bh | service | |
When I route I should get
| from | to | route | turns |
| 1 | e | abcda,ce,ce | depart,roundabout-exit-1,arrive |
| 1 | f | abcda,df,df | depart,roundabout-exit-2,arrive |
| 1 | g | abcda,ag,ag | depart,roundabout-exit-3,arrive |
| 1 | h | abcda,bh,bh | depart,roundabout-exit-4,arrive |
Scenario: Collapsing a sliproad step after roundabouts
Given the node map
"""
a r j
eb1ds ufghl
`i
c t
m v k
"""
And the ways
| nodes | highway | junction | oneway | # |
| abcda | tertiary | roundabout | | circle |
| ebds | tertiary | | | road |
| cm | tertiary | | | |
| ds | tertiary | | | road |
| rstur | tertiary | roundabout | | circle2 |
| ufghl | tertiary | | | road |
| tv | tertiary | | | |
| gi | tertiary | | yes | sliproad |
| jhik | tertiary | | | crossroad |
When I route I should get
| from | to | route | turns | distance |
| e | k | ebds,ebds,ds,ufghl,jhik,jhik | depart,rotary-exit-1,rotary-exit-1,rstur-exit-2,turn right,arrive | 189.1m |
| 1 | k | ebds,ds,ufghl,jhik,jhik | depart,rotary-exit-1,rstur-exit-2,turn right,arrive | 159.1m |
+83 -10
View File
@@ -201,14 +201,14 @@ Feature: Simple Turns
| ef | residential | road | 2 | yes | | ef | residential | road | 2 | yes |
When I route I should get When I route I should get
| waypoints | route | turns | locations | | waypoints | route | turns | locations |
| a,c | road,road | depart,arrive | a,c | | a,c | road,road | depart,arrive | a,c |
| c,a | road,road | depart,arrive | c,a | | c,a | road,road | depart,arrive | c,a |
| g,a | turn,road,road | depart,turn left,arrive | g,b,a | | g,a | turn,road,road | depart,turn left,arrive | g,b,a |
| g,c | turn,road,road | depart,turn right,arrive | g,b,c | | g,c | turn,road,road | depart,turn right,arrive | g,b,c |
| g,f | turn,road,road | depart,turn left,arrive | g,e,f | | g,f | turn,road,road | depart,end of road left,arrive | g,e,f |
| c,f | road,road,road | depart,continue right,arrive | c,b,f | | c,f | road,road,road | depart,turn right,arrive | c,b,f |
| a,f | road,road,road | depart,continue uturn,arrive | a,b,f | | a,f | road,road,road | depart,continue uturn,arrive | a,b,f |
# http://www.openstreetmap.org/#map=19/52.48753/13.52838 # http://www.openstreetmap.org/#map=19/52.48753/13.52838
Scenario: Traffic Circle Scenario: Traffic Circle
@@ -1312,8 +1312,8 @@ Feature: Simple Turns
# we don't care for turn instructions, this is a coordinate extraction bug check # we don't care for turn instructions, this is a coordinate extraction bug check
When I route I should get When I route I should get
| waypoints | route | intersections | | waypoints | route | intersections |
| a,g | ab,bcdefgh | true:90,true:45 false:180 false:270;true:180 | | a,g | ab,bcdefgh,bcdefgh | true:90;true:45 false:180 false:270;true:180 |
#https://github.com/Project-OSRM/osrm-backend/pull/3469#issuecomment-270806580 #https://github.com/Project-OSRM/osrm-backend/pull/3469#issuecomment-270806580
Scenario: Oszillating Lower Priority Road Scenario: Oszillating Lower Priority Road
@@ -1371,3 +1371,76 @@ Feature: Simple Turns
When I route I should get When I route I should get
| waypoints | route | | waypoints | route |
| g,e | abcde,abcde | | g,e | abcde,abcde |
# 4205
# https://www.openstreetmap.org/node/36153635#map=19/51.97548/7.61795
Scenario: merging onto a through street
Given the node map
"""
e
`
`
`
`
d
c
a - - - - - - - b``
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
f
"""
And the ways
| nodes | oneway | name |
| abc | yes | fww |
| fcde | no | jahn |
When I route I should get
| waypoints | route | turns |
| a,f | fww,jahn,jahn | depart,turn right,arrive |
| a,e | fww,jahn,jahn | depart,turn left,arrive |
+103 -74
View File
@@ -134,7 +134,7 @@ Feature: Turn Lane Guidance
| a | c | 180,180 180,180 | in,straight,straight | depart,new name straight,arrive | ,left;uturn:false straight;right:true, | a,b,c | | a | c | 180,180 180,180 | in,straight,straight | depart,new name straight,arrive | ,left;uturn:false straight;right:true, | a,b,c |
| a | d | 180,180 180,180 | in,right,right | depart,turn right,arrive | ,left;uturn:false straight;right:true, | a,b,d | | a | d | 180,180 180,180 | in,right,right | depart,turn right,arrive | ,left;uturn:false straight;right:true, | a,b,d |
| a | e | 180,180 180,180 | in,left,left | depart,turn left,arrive | ,left;uturn:true straight;right:false, | a,b,e | | a | e | 180,180 180,180 | in,left,left | depart,turn left,arrive | ,left;uturn:true straight;right:false, | a,b,e |
| 1 | a | 90,2 270,2 | in,in,in | depart,turn uturn,arrive | ,left;uturn:true straight;right:false, | _,b,a | | 1 | a | 90,2 270,2 | in,in,in | depart,continue uturn,arrive | ,left;uturn:true straight;right:false, | _,b,a |
#this next test requires decision on how to announce lanes for going straight if there is no turn #this next test requires decision on how to announce lanes for going straight if there is no turn
@@ -156,7 +156,7 @@ Feature: Turn Lane Guidance
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,d | road,turn,turn | depart,turn right,arrive | ,straight:false right:true, | | a,d | road,turn,turn | depart,turn right,arrive | ,straight:false right:true, |
| a,c | road,road | depart,arrive | , | | a,c | road,road | depart,arrive | ;straight:true right:false, |
Scenario: Turn with Bus-Lane Left Scenario: Turn with Bus-Lane Left
Given the node map Given the node map
@@ -178,7 +178,7 @@ Feature: Turn Lane Guidance
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,d | road,turn,turn | depart,turn left,arrive | ,left:true straight:false, | | a,d | road,turn,turn | depart,turn left,arrive | ,left:true straight:false, |
| a,c | road,road | depart,arrive | , | | a,c | road,road | depart,arrive | ;left:false straight:true, |
# This tests whether empty/invalid PSV tags cause osrm-extract to crash # This tests whether empty/invalid PSV tags cause osrm-extract to crash
Scenario: Turn with Bus-Lane Scenario: Turn with Bus-Lane
@@ -248,23 +248,23 @@ Feature: Turn Lane Guidance
| fl | cross | | yes | | fl | cross | | yes |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes | intersection_lanes |
| a,j | road,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true | | a,j | road,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true | ,left:false straight:false right:true |
| a,d | road,road,road | depart,use lane straight,arrive | ,left:false straight:true right:false, | | a,d | road,road | depart,arrive | , | left:false straight:true right:false, |
| a,l | road,cross,cross | depart,turn left,arrive | ,left:true straight:false right:false, | | a,l | road,cross,cross | depart,turn left,arrive | ,left:true straight:false right:false, | ,left:true straight:false right:false, |
| a,h | road,road,road | depart,continue uturn,arrive | ,left:true straight:false right:false, | | a,h | road,road,road | depart,continue uturn,arrive | ,left:true straight:false right:false, | ,left:true straight:false right:false |
| k,d | cross,road,road | depart,turn right,arrive | ,left:false straight;right:true, | | k,d | cross,road,road | depart,turn right,arrive | ,left:false straight;right:true, | ,left:false straight;right:true, |
| k,l | cross,cross,cross | depart,use lane straight,arrive | ,left:false straight;right:true, | | k,l | cross,cross | depart,arrive | , | left:false straight;right:true, |
| k,h | cross,road,road | depart,turn left,arrive | ,left:true straight;right:false, | | k,h | cross,road,road | depart,turn left,arrive | ,left:true straight;right:false, | ,left:true straight;right:false, |
| k,j | cross,cross,cross | depart,continue uturn,arrive | ,left:true straight;right:false, | | k,j | cross,cross,cross | depart,continue uturn,arrive | ,left:true straight;right:false, | ,left:true straight;right:false, |
| e,l | road,cross,cross | depart,turn right,arrive | ,none:false straight:false straight;right:true, | | e,l | road,cross,cross | depart,turn right,arrive | ,none:false straight:false straight;right:true, | ,none:false straight:false straight;right:true, |
| e,h | road,road | depart,arrive | ,none:false straight:true straight;right:true | | e,h | road,road | depart,arrive | , | none:false straight:true straight;right:true, |
| e,j | road,cross,cross | depart,turn left,arrive | ,none:true straight:false straight;right:false, | | e,j | road,cross,cross | depart,turn left,arrive | ,none:true straight:false straight;right:false, | ,none:true straight:false straight;right:false, |
| e,d | road,road,road | depart,continue uturn,arrive | ,none:true straight:false straight;right:false, | | e,d | road,road,road | depart,continue uturn,arrive | ,none:true straight:false straight;right:false, | ,none:true straight:false straight;right:false, |
| i,h | cross,road,road | depart,turn right,arrive | ,, | | i,h | cross,road,road | depart,turn right,arrive | ,, | |
| i,j | cross,cross,cross | depart,use lane straight,arrive | ,left:false straight:true, | | i,j | cross,cross | depart,arrive | | left:false straight:true, |
| i,d | cross,road,road | depart,turn left,arrive | ,left:true straight:false, | | i,d | cross,road,road | depart,turn left,arrive | ,left:true straight:false, | ,left:true straight:false, |
| i,l | cross,cross,cross | depart,continue uturn,arrive | ,left:true straight:false, | | i,l | cross,cross,cross | depart,continue uturn,arrive | ,left:true straight:false, | ,left:true straight:false, |
#copy of former case to prevent further regression #copy of former case to prevent further regression
@collapse @partition-lanes @collapse @partition-lanes
@@ -295,13 +295,13 @@ Feature: Turn Lane Guidance
| fl | cross | | yes | | fl | cross | | yes |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,j | road,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true, | | a,j | road,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true, |
| k,d | cross,road,road | depart,turn right,arrive | ,left:false straight;right:true, | | k,d | cross,road,road | depart,turn right,arrive | ,left:false straight;right:true, |
| e,l | road,cross,cross | depart,turn right,arrive | ,none:false straight:false straight;right:true, | | e,l | road,cross,cross | depart,turn right,arrive | ,none:false straight:false straight;right:true, |
| i,h | cross,road,road | depart,turn right,arrive | ,, | | i,h | cross,road,road | depart,turn right,arrive | ,, |
| i,j | cross,cross | depart,arrive | , | | i,j | cross,cross | depart,arrive | ;;left:false straight:true, |
| i,l | cross,cross,cross | depart,continue uturn,arrive | ,left:true straight:false, | | i,l | cross,cross,cross | depart,continue uturn,arrive | ;,left:true straight:false;left:true straight:false;left:false straight:true, |
@partition-lanes @partition-lanes
Scenario: Turn Lanes at Segregated Road Scenario: Turn Lanes at Segregated Road
@@ -347,7 +347,7 @@ Feature: Turn Lane Guidance
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,e | road,turn,turn | depart,turn right,arrive | ,none:false right:true, | | a,e | road,turn,turn | depart,turn right,arrive | ,none:false right:true, |
| a,d | road,road | depart,arrive | , | | a,d | road,road | depart,arrive | ;none:true right:false, |
@2654 @previous-lanes @2654 @previous-lanes
Scenario: Turn Lanes Given earlier than actual turn Scenario: Turn Lanes Given earlier than actual turn
@@ -368,11 +368,11 @@ Feature: Turn Lane Guidance
| hk | second-turn | | | | hk | second-turn | | |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,k | road,second-turn,second-turn | depart,turn right,arrive | ,none:false right:true, | | a,k | road,second-turn,second-turn | depart,turn right,arrive | ;,none:false right:true, |
| a,i | road,road | depart,arrive | , | | a,i | road,road | depart,arrive | ;;none:true right:false, |
| i,j | road,first-turn,first-turn | depart,turn left,arrive | ,left:true none:false, | | i,j | road,first-turn,first-turn | depart,turn left,arrive | ;,left:true none:false, |
| i,a | road,road | depart,arrive | , | | i,a | road,road | depart,arrive | ;;left:false none:true, |
@previous-lanes @previous-lanes
Scenario: Passing a one-way street Scenario: Passing a one-way street
@@ -390,8 +390,8 @@ Feature: Turn Lane Guidance
| cf | turn | | | | cf | turn | | |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,f | road,turn,turn | depart,turn left,arrive | ,left:true straight:false, | | a,f | road,turn,turn | depart,turn left,arrive | ;left:true straight:false,left:true straight:false, |
@partition-lanes @partition-lanes
Scenario: Passing a one-way street, partly pulled back lanes Scenario: Passing a one-way street, partly pulled back lanes
@@ -411,10 +411,10 @@ Feature: Turn Lane Guidance
| bg | right | | no | | bg | right | | no |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,f | road,turn,turn | depart,turn left,arrive | ,left:true straight;right:false, | | a,f | road,turn,turn | depart,turn left,arrive | ;left:true straight;right:false,left:true straight;right:false, |
| a,d | road,road | depart,arrive | , | | a,d | road,road | depart,arrive | ;left:false straight;right:true;left:false straight;right:true, |
| a,g | road,right,right | depart,turn right,arrive | ,left:false straight;right:true, | | a,g | road,right,right | depart,turn right,arrive | ,left:false straight;right:true, |
@partition-lanes @previous-lanes @partition-lanes @previous-lanes
Scenario: Passing a one-way street, partly pulled back lanes, no through Scenario: Passing a one-way street, partly pulled back lanes, no through
@@ -434,9 +434,9 @@ Feature: Turn Lane Guidance
| bg | right | | no | | bg | right | | no |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,f | road,turn,turn | depart,turn left,arrive | ,left:true right:false, | | a,f | road,turn,turn | depart,turn left,arrive | ,left:true right:false;left:true right:false, |
| a,g | road,right,right | depart,turn right,arrive | ,left:false right:true, | | a,g | road,right,right | depart,turn right,arrive | ,left:false right:true, |
@todo @partition-lanes @previous-lanes @todo @partition-lanes @previous-lanes
Scenario: Narrowing Turn Lanes Scenario: Narrowing Turn Lanes
@@ -484,7 +484,7 @@ Feature: Turn Lane Guidance
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,d | road,road | depart,arrive | , | | a,d | road,road | depart,arrive | ;straight:true right:false, |
| a,e | road,turn,turn | depart,turn right,arrive | ,straight:false right:true, | | a,e | road,turn,turn | depart,turn right,arrive | ,straight:false right:true, |
@todo @roundabout @todo @roundabout
@@ -554,9 +554,9 @@ Feature: Turn Lane Guidance
| restriction | bc | dc | c | no_right_turn | | restriction | bc | dc | c | no_right_turn |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,g | road,cross,cross | depart,turn left,arrive | ,left:true left:true straight:false straight:false right:false, | | a,g | road,cross,cross | depart,turn left,arrive | ,left:true left:true straight:false straight:false right:false;left:true left:true straight:false straight:false right:false, |
| a,e | road,road | depart,arrive | , | | a,e | road,road | depart,arrive | ;left:false left:false straight:true straight:true right:false;left:false left:false straight:true straight:true right:false, |
#NEEDS TO BE INVESTIGATED. Turn restriction shouldn't be here. See #2867 #NEEDS TO BE INVESTIGATED. Turn restriction shouldn't be here. See #2867
@reverse @previous-lanes @reverse @previous-lanes
@@ -589,11 +589,11 @@ Feature: Turn Lane Guidance
| restriction | de | ef | e | no_left_turn | | restriction | de | ef | e | no_left_turn |
When I route I should get When I route I should get
| from | to | bearings | route | turns | lanes | | 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 | g | 180,180 180,180 | road,cross,cross | depart,turn right,arrive | ;none:false straight:false right:true,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 | h | 180,180 180,180 | road,cross,cross | depart,turn left,arrive | ;none:true straight:false right:false,none:true straight:false right:false;, |
| a | i | 180,180 180,180 | road,road | depart,arrive | , | | a | i | 180,180 180,180 | road,road | depart,arrive | ;none:true straight:true right:false;none:true straight:true right:false, |
| b | a | 90,2 270,2 | road,road,road | depart,continue uturn,arrive | ,none:true straight:false right:false, | | b | a | 90,2 270,2 | road,road,road | depart,continue uturn,arrive | ,none:true straight:false right:false;, |
@reverse @reverse
Scenario: Segregated Intersection Merges With Lanes Scenario: Segregated Intersection Merges With Lanes
@@ -629,7 +629,7 @@ Feature: Turn Lane Guidance
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,f | road,left,left | depart,turn left,arrive | ,left:true left:true left:true straight:false straight:false, | | a,f | road,left,left | depart,turn left,arrive | ,left:true left:true left:true straight:false straight:false, |
| a,e | road,road,road | depart,turn uturn,arrive | ,left:true left:false left:false straight:false straight:false, | | a,e | road,road,road | depart,continue 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, | | a,g | road,straight,straight | depart,new name straight,arrive | ,left:false left:false left:false straight:true straight:true, |
@todo @roundabout @todo @roundabout
@@ -681,7 +681,7 @@ Feature: Turn Lane Guidance
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,d | road,road | depart,arrive | , | | a,d | road,road | depart,arrive | ;straight:true straight:true straight;slight right:true slight right:false, |
| a,e | road,cross,cross | depart,turn slight right,arrive | ,straight:false straight:false straight;slight right:true slight right:true, | | a,e | road,cross,cross | depart,turn slight right,arrive | ,straight:false straight:false straight;slight right:true slight right:true, |
@ramp @ramp
@@ -700,7 +700,7 @@ Feature: Turn Lane Guidance
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,d | hwy,hwy | depart,arrive | , | | a,d | hwy,hwy | depart,arrive | ;straight:true straight:true straight;slight right:true slight right:false, |
| a,e | hwy,ramp,ramp | depart,off ramp slight right,arrive | ,straight:false straight:false straight;slight right:true slight right:true, | | a,e | hwy,ramp,ramp | depart,off ramp slight right,arrive | ,straight:false straight:false straight;slight right:true slight right:true, |
@todo @todo
@@ -745,7 +745,7 @@ Feature: Turn Lane Guidance
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,c | hwy,hwy | depart,arrive | , | | a,c | hwy,hwy | depart,arrive | ;straight:true straight:true slight right:false, |
| a,d | hwy,ramp,ramp | depart,off ramp slight right,arrive | ,straight:false straight:false slight right:true, | | a,d | hwy,ramp,ramp | depart,off ramp slight right,arrive | ,straight:false straight:false slight right:true, |
@reverse @reverse
@@ -766,8 +766,8 @@ Feature: Turn Lane Guidance
| fgh | road | | primary | yes | | fgh | road | | primary | yes |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,h | road,road,road | depart,continue uturn,arrive | ,uturn:true straight:false straight:false,| | a,h | road,road,road | depart,continue uturn,arrive | ,uturn:true straight:false straight:false;,|
@reverse @reverse
Scenario: Reverse Lane in Segregated Road with none Scenario: Reverse Lane in Segregated Road with none
@@ -787,8 +787,8 @@ Feature: Turn Lane Guidance
| fgh | road | | primary | yes | | fgh | road | | primary | yes |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,h | road,road,road | depart,continue uturn,arrive | ,uturn:true straight:false none:false, | | a,h | road,road,road | depart,continue uturn,arrive | ,uturn:true straight:false none:false;, |
@reverse @reverse
Scenario: Reverse Lane in Segregated Road with none, Service Turn Prior Scenario: Reverse Lane in Segregated Road with none, Service Turn Prior
@@ -810,8 +810,8 @@ Feature: Turn Lane Guidance
| ji | park | | service | no | | ji | park | | service | no |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,h | road,road,road | depart,continue uturn,arrive | ,uturn:true straight:false none:false, | | a,h | road,road,road | depart,continue uturn,arrive | ,uturn:true straight:false none:false;, |
@simple @simple
Scenario: Don't collapse everything to u-turn / too wide Scenario: Don't collapse everything to u-turn / too wide
@@ -873,9 +873,9 @@ Feature: Turn Lane Guidance
| ab | on | motorway_link | | | ab | on | motorway_link | |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,j | on,xbcj | depart,arrive | , | | a,j | on,xbcj | depart,arrive | ;;none:true slight right:false, |
| a,i | on,off,off | depart,turn right,arrive | ,none:false slight right:true, | | a,i | on,off,off | depart,turn right,arrive | ;,none:false slight right:true, |
#http://www.openstreetmap.org/#map=17/52.47414/13.35712 #http://www.openstreetmap.org/#map=17/52.47414/13.35712
@todo @ramp @2645 @todo @ramp @2645
@@ -929,8 +929,8 @@ Feature: Turn Lane Guidance
| cf | turn | primary | | | cf | turn | primary | |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| x,d | road,road | depart,arrive | , | | x,d | road,road | depart,arrive | ;straight;right:true;straight;right:true, |
@partition-lanes @partition-lanes
Scenario: Partitioned turn, Slight Curve - maxspeed Scenario: Partitioned turn, Slight Curve - maxspeed
@@ -952,9 +952,9 @@ Feature: Turn Lane Guidance
| dce | cross | primary | yes | | 1 | | dce | cross | primary | yes | | 1 |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | locations | | waypoints | route | turns | lanes | locations |
| a,g | road,cross,cross | depart,turn right,arrive | ,left:false right:true, | a,b,g | | a,g | road,cross,cross | depart,turn right,arrive | ,left:false right:true, | a,b,g |
| a,e | road,cross,cross | depart,end of road left,arrive | ,left:true right:false, | a,c,e | | a,e | road,cross,cross | depart,end of road left,arrive | ;left:true right:false,left:true right:false, | a,c,e |
Scenario: Partitioned turn, Slight Curve Scenario: Partitioned turn, Slight Curve
Given the node map Given the node map
@@ -975,9 +975,9 @@ Feature: Turn Lane Guidance
| dce | cross | primary | yes | | | dce | cross | primary | yes | |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | locations | | waypoints | route | turns | lanes | locations |
| a,g | road,cross,cross | depart,turn right,arrive | ,left:false right:true, | a,b,g | | a,g | road,cross,cross | depart,turn right,arrive | ,left:false right:true, | a,b,g |
| a,e | road,cross,cross | depart,end of road left,arrive | ,left:true right:false, | a,c,e | | a,e | road,cross,cross | depart,end of road left,arrive | ;left:true right:false,left:true right:false, | a,c,e |
Scenario: Lane Parsing Issue #2694 Scenario: Lane Parsing Issue #2694
Given the node map Given the node map
@@ -1193,7 +1193,7 @@ Feature: Turn Lane Guidance
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,e | road,cross,cross | depart,turn right,arrive | ,left:false none:false none:true, | | a,e | road,cross,cross | depart,turn right,arrive | ,left:false none:false none:true, |
| a,c | road,road | depart,arrive | , | | a,c | road,road | depart,arrive | ;left:false none:true none:true, |
@3379 @3379
Scenario: Don't Turn through potential through lanes Scenario: Don't Turn through potential through lanes
@@ -1214,4 +1214,33 @@ Feature: Turn Lane Guidance
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,d | road,cross,cross | depart,turn left,arrive | ,none:true none:false right:false, | | a,d | road,cross,cross | depart,turn left,arrive | ,none:true none:false right:false, |
| a,c | road,road | depart,arrive | , | | a,c | road,road | depart,arrive | ;none:true none:true right:false, |
@4189
Scenario: U-turn after a traffic light
Given the node map
"""
j k
: :
f---g-h-i
: :
a-b-c-d-e
: :
l m
"""
And the nodes
| node | highway |
| b | traffic_signals |
And the ways
| nodes | name | lanes | turn:lanes | oneway |
| ab | road1 | 3 | left\|through\|through;right | yes |
| bcde | road1 | 2 | | yes |
| ihgf | road1 | 2 | | yes |
| jgcl | road2 | 2 | | yes |
| mdhk | road2 | 2 | | yes |
When I route I should get
| waypoints | route | turns | lanes | locations |
| a,f | road1,road1,road1 | depart,continue uturn,arrive | ;left:false straight:true straight;right:false,left:true straight:false straight;right:false;;, | a,d,f |
+89
View File
@@ -1260,3 +1260,92 @@ Feature: Simple Turns
| waypoints | route | turns | | waypoints | route | turns |
| a,d | Goethe,Fried,Fried | depart,continue left,arrive | | a,d | Goethe,Fried,Fried | depart,continue left,arrive |
| a,g | Goethe,Fried,Fried | depart,turn right,arrive | | a,g | Goethe,Fried,Fried | depart,turn right,arrive |
# Conflicting roads (https://www.openstreetmap.org/export#map=19/37.57805/-77.46049)
Scenario: Turning at forklike structure
Given the node map
"""
c d
- - - b - - - a
-
e
"""
And the ways
| nodes | name | oneway | highway |
| abc | foo | no | residential |
| bd | bar | yes | residential |
| eb | some | yes | tertiary_link |
When I route I should get
| waypoints | route | turns |
| a,d | foo,bar,bar | depart,turn slight right,arrive |
Scenario: UTurn onto ramp
Given the node map
"""
a - - - b - c
.|
_________________ de
h-g-----------------------f
"""
And the ways
| nodes | name | ref | oneway | highway |
| abc | Road | | yes | primary |
| ce | other | | yes | primary |
| cdg | | | yes | motorway_link |
| fgh | | C 42 | yes | motorway |
When I route I should get
| waypoints | route | ref | turns |
| a,h | Road,,, | ,,C 42,C 42 | depart,on ramp right,merge slight left,arrive |
Scenario: UTurn onto ramp (same ref)
Given the node map
"""
a - - - b - c
.|
_________________ de
h-g-----------------------f
"""
And the ways
| nodes | name | ref | oneway | highway |
| abc | Road | C 42 | yes | primary |
| ce | other | | yes | primary |
| cdg | | | yes | motorway_link |
| fgh | | C 42 | yes | motorway |
When I route I should get
| waypoints | route | ref | turns |
| a,h | Road,,, | C 42,,C 42,C 42 | depart,on ramp right,merge slight left,arrive |
Scenario: End of road, T-intersection, no obvious turn, only one road allowed
Given the node map
"""
d
.
a . b . . c
' .
'e
.
f
"""
And the ways
| nodes | highway | oneway | ref |
| ab | primary | | B 191 |
| bc | primary | | B 191 |
| be | primary_link | yes | |
| dc | primary | | B 4;B 191 |
| ce | primary | | B 4 |
| ef | primary | | B 4 |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | bc | ce | c | no_right_turn |
| restriction | be | ef | e | only_right_turn |
When I route I should get
| waypoints | route | turns |
| a,d | ab,dc,dc | depart,turn left,arrive |
@@ -21,6 +21,7 @@ Feature: osrm-contract command line option: edge-weight-updates-over-factor
Scenario: Logging weight with updates over factor of 2, long segment Scenario: Logging weight with updates over factor of 2, long segment
When I run "osrm-extract --profile {profile_file} {osm_file}" When I run "osrm-extract --profile {profile_file} {osm_file}"
And the data has been partitioned
When I run "osrm-contract --edge-weight-updates-over-factor 2 --segment-speed-file {speeds_file} {processed_file}" When I run "osrm-contract --edge-weight-updates-over-factor 2 --segment-speed-file {speeds_file} {processed_file}"
Then stderr should not contain "Speed values were used to update 2 segment(s)" Then stderr should not contain "Speed values were used to update 2 segment(s)"
And stderr should contain "Segment: 1,2" And stderr should contain "Segment: 1,2"
+1 -1
View File
@@ -14,5 +14,5 @@ Feature: osrm-routed command line options: invalid options
Scenario: osrm-routed - Missing file Scenario: osrm-routed - Missing file
When I try to 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" Then stderr should contain "over-the-rainbow.osrm"
And stderr should contain "not found" And stderr should contain "Required files are missing"
And it should exit with an error And it should exit with an error
+3 -11
View File
@@ -32,9 +32,7 @@ Feature: Raster - weights
Scenario: Weighting not based on raster sources Scenario: Weighting not based on raster sources
Given the profile "testbot" Given the profile "testbot"
When I run "osrm-extract {osm_file} -p {profile_file}" When I route I should get
And I run "osrm-contract {processed_file}"
And I route I should get
| from | to | route | speed | | from | to | route | speed |
| a | b | ab,ab | 36 km/h | | a | b | ab,ab | 36 km/h |
| a | c | ab,bc,bc | 36 km/h | | a | c | ab,bc,bc | 36 km/h |
@@ -44,10 +42,7 @@ Feature: Raster - weights
Scenario: Weighting based on raster sources Scenario: Weighting based on raster sources
Given the profile "rasterbot" Given the profile "rasterbot"
When I run "osrm-extract {osm_file} -p {profile_file}" When I route I should get
Then stdout should contain "evaluating segment"
And I run "osrm-contract {processed_file}"
And I route I should get
| from | to | route | speed | | from | to | route | speed |
| a | b | ab,ab | 8 km/h | | a | b | ab,ab | 8 km/h |
| b | a | ab,ab | 22 km/h | | b | a | ab,ab | 22 km/h |
@@ -63,10 +58,7 @@ Feature: Raster - weights
Scenario: Weighting based on raster sources Scenario: Weighting based on raster sources
Given the profile "rasterbotinterp" Given the profile "rasterbotinterp"
When I run "osrm-extract {osm_file} -p {profile_file}" When I route I should get
Then stdout should contain "evaluating segment"
And I run "osrm-contract {processed_file}"
And I route I should get
| from | to | route | speed | | from | to | route | speed |
| a | b | ab,ab | 8 km/h | | a | b | ab,ab | 8 km/h |
| a | c | ad,dc,dc | 15 km/h | | a | c | ad,dc,dc | 15 km/h |
+7 -7
View File
@@ -38,7 +38,7 @@ module.exports = function () {
callback(); callback();
}); });
this.Given(/^the origin ([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)$/, (lat, lon, callback) => { this.Given(/^the origin ([-+]?[0-9]*\.?[0-9]+),([-+]?[0-9]*\.?[0-9]+)$/, (lon, lat, callback) => {
this.setOrigin([parseFloat(lon), parseFloat(lat)]); this.setOrigin([parseFloat(lon), parseFloat(lat)]);
callback(); callback();
}); });
@@ -67,7 +67,7 @@ module.exports = function () {
if (this.nameNodeHash[name]) throw new Error(util.format('*** duplicate node %s', name)); if (this.nameNodeHash[name]) throw new Error(util.format('*** duplicate node %s', name));
this.addOSMNode(name, lonLat[0], lonLat[1], null); this.addOSMNode(name, lonLat[0], lonLat[1], null);
} else if (name.match(/[0-9]/) ) { } else if (name.match(/[0-9]/) ) {
if (this.locationHash[name]) throw new Error(util.format('*** duplicate node %s'), name); if (this.locationHash[name]) throw new Error(util.format('*** duplicate node %s', name));
this.addLocation(name, lonLat[0], lonLat[1], null); this.addLocation(name, lonLat[0], lonLat[1], null);
} }
cb(); cb();
@@ -89,7 +89,7 @@ module.exports = function () {
let addNodeLocations = (row, cb) => { let addNodeLocations = (row, cb) => {
let name = row.node; let name = row.node;
if (this.findNodeByName(name)) throw new Error(util.format('*** duplicate node %s'), name); if (this.findNodeByName(name)) throw new Error(util.format('*** duplicate node %s', name));
if (name.match(/[a-z]/)) { if (name.match(/[a-z]/)) {
let id = row.id && parseInt(row.id); let id = row.id && parseInt(row.id);
@@ -194,19 +194,19 @@ module.exports = function () {
isColonSeparated = key.match(/^(.*):(.*)/); isColonSeparated = key.match(/^(.*):(.*)/);
if (isNode) { if (isNode) {
row[key].split(',').map(function(v) { return v.trim(); }).forEach((nodeName) => { row[key].split(',').map(function(v) { return v.trim(); }).forEach((nodeName) => {
if (nodeName.length !== 1) throw new Error(util.format('*** invalid relation node member "%s"'), nodeName); if (nodeName.length !== 1) throw new Error(util.format('*** invalid relation node member "%s"', nodeName));
let node = this.findNodeByName(nodeName); let node = this.findNodeByName(nodeName);
if (!node) throw new Error(util.format('*** unknown relation node member "%s"'), nodeName); if (!node) throw new Error(util.format('*** unknown relation node member "%s"', nodeName));
relation.addMember('node', node.id, isNode[1]); relation.addMember('node', node.id, isNode[1]);
}); });
} else if (isWay) { } else if (isWay) {
row[key].split(',').map(function(v) { return v.trim(); }).forEach((wayName) => { row[key].split(',').map(function(v) { return v.trim(); }).forEach((wayName) => {
let way = this.findWayByName(wayName); let way = this.findWayByName(wayName);
if (!way) throw new Error(util.format('*** unknown relation way member "%s"'), wayName); if (!way) throw new Error(util.format('*** unknown relation way member "%s"', wayName));
relation.addMember('way', way.id, isWay[1]); relation.addMember('way', way.id, isWay[1]);
}); });
} else if (isColonSeparated && isColonSeparated[1] !== 'restriction') { } else if (isColonSeparated && isColonSeparated[1] !== 'restriction') {
throw new Error(util.format('*** unknown relation member type "%s:%s", must be either "node" or "way"'), isColonSeparated[1], isColonSeparated[2]); throw new Error(util.format('*** unknown relation member type "%s:%s", must be either "node" or "way"', isColonSeparated[1], isColonSeparated[2]));
} else { } else {
relation.addTag(key, row[key]); relation.addTag(key, row[key]);
} }
+1 -1
View File
@@ -228,7 +228,7 @@ module.exports = function () {
for (var i=0; i<row.trace.length; i++) { for (var i=0; i<row.trace.length; i++) {
var n = row.trace[i], var n = row.trace[i],
node = this.findNodeByName(n); node = this.findNodeByName(n);
if (!node) throw new Error(util.format('*** unknown waypoint node "%s"'), n); if (!node) throw new Error(util.format('*** unknown waypoint node "%s"', n));
trace.push(node); trace.push(node);
} }
if (row.timestamps) { if (row.timestamps) {
+2 -2
View File
@@ -6,10 +6,10 @@ module.exports = function () {
if (e) return callback(e); if (e) return callback(e);
var testRow = (row, ri, cb) => { var testRow = (row, ri, cb) => {
var inNode = this.findNodeByName(row.in); var inNode = this.findNodeByName(row.in);
if (!inNode) throw new Error(util.format('*** unknown in-node "%s"'), row.in); if (!inNode) throw new Error(util.format('*** unknown in-node "%s"', row.in));
var outNode = this.findNodeByName(row.out); var outNode = this.findNodeByName(row.out);
if (!outNode) throw new Error(util.format('*** unknown out-node "%s"'), row.out); if (!outNode) throw new Error(util.format('*** unknown out-node "%s"', row.out));
this.requestNearest(inNode, this.queryParams, (err, response) => { this.requestNearest(inNode, this.queryParams, (err, response) => {
if (err) return cb(err); if (err) return cb(err);
+3 -3
View File
@@ -34,7 +34,7 @@ module.exports = function () {
outputRow[rate] = result[direction].status ? outputRow[rate] = result[direction].status ?
result[direction].status.toString() : ''; result[direction].status.toString() : '';
break; break;
case /^\d+$/.test(want): case /^\d+(\.\d+){0,1}$/.test(want):
if (result[direction].rate !== undefined && !isNaN(result[direction].rate)) { if (result[direction].rate !== undefined && !isNaN(result[direction].rate)) {
outputRow[rate] = result[direction].rate.toString(); outputRow[rate] = result[direction].rate.toString();
} else { } else {
@@ -121,7 +121,7 @@ module.exports = function () {
r.which = dir; r.which = dir;
this.requestRoute((dir === 'forw' ? [a, b] : [b, a]), [], this.queryParams, (err, res, body) => { this.requestRoute((dir === 'forw' ? [a, b] : [b, a]), [], [], this.queryParams, (err, res, body) => {
if (err) return callback(err); if (err) return callback(err);
r.query = this.query; r.query = this.query;
@@ -135,7 +135,7 @@ module.exports = function () {
if (r.route.split(',')[0] === util.format('w%d', i)) { if (r.route.split(',')[0] === util.format('w%d', i)) {
r.time = r.json.routes[0].duration; r.time = r.json.routes[0].duration;
r.distance = r.json.routes[0].distance; r.distance = r.json.routes[0].distance;
r.rate = Math.round(r.distance / r.json.routes[0].weight); r.rate = Math.round(r.distance / r.json.routes[0].weight * 10) / 10.;
r.speed = r.time > 0 ? parseInt(3.6 * r.distance / r.time) : null; r.speed = r.time > 0 ? parseInt(3.6 * r.distance / r.time) : null;
// use the mode of the first step of the route // use the mode of the first step of the route
+1 -4
View File
@@ -85,8 +85,7 @@ module.exports = function () {
} }
var ok = true, var ok = true,
encodedResult = '', encodedResult = '';
extendedTarget = '';
if (json.trips) row.trips.split(',').forEach((sub, si) => { if (json.trips) row.trips.split(',').forEach((sub, si) => {
if (si >= subTrips.length) { if (si >= subTrips.length) {
@@ -98,11 +97,9 @@ module.exports = function () {
outNode = subTrips[si][ni]; outNode = subTrips[si][ni];
if (this.FuzzyMatch.matchLocation(outNode, node)) { if (this.FuzzyMatch.matchLocation(outNode, node)) {
encodedResult += sub[ni]; encodedResult += sub[ni];
extendedTarget += sub[ni];
} else { } else {
ok = false; ok = false;
encodedResult += util.format('? [%s,%s]', outNode[0], outNode[1]); encodedResult += util.format('? [%s,%s]', outNode[0], outNode[1]);
extendedTarget += util.format('%s [%d,%d]', sub[ni], node.lat, node.lon);
} }
} }
} }
+4 -4
View File
@@ -238,13 +238,13 @@ module.exports = function () {
// a shallow copy of scenario parameters to avoid data inconsistency // a shallow copy of scenario parameters to avoid data inconsistency
// if a cucumber timeout occurs during deferred jobs // if a cucumber timeout occurs during deferred jobs
let p = {extractArgs: this.extractArgs, contractArgs: this.contractArgs, let p = {extractArgs: this.extractArgs, contractArgs: this.contractArgs,
partitionArgs: this.partitionArgs, customizeArgs: this.customizeArgs, partitionArgs: this.partitionArgs, customizeArgs: this.customizeArgs,
profileFile: this.profileFile, inputCacheFile: this.inputCacheFile, profileFile: this.profileFile, inputCacheFile: this.inputCacheFile,
processedCacheFile: this.processedCacheFile, environment: this.environment}; processedCacheFile: this.processedCacheFile, environment: this.environment};
let queue = d3.queue(1); let queue = d3.queue(1);
queue.defer(this.extractData.bind(this), p); queue.defer(this.extractData.bind(this), p);
queue.defer(this.contractData.bind(this), p);
queue.defer(this.partitionData.bind(this), p); queue.defer(this.partitionData.bind(this), p);
queue.defer(this.contractData.bind(this), p);
queue.defer(this.customizeData.bind(this), p); queue.defer(this.customizeData.bind(this), p);
queue.awaitAll(callback); queue.awaitAll(callback);
}; };
+2 -1
View File
@@ -39,7 +39,8 @@ module.exports = function () {
this.WAY_SPACING = 100; this.WAY_SPACING = 100;
this.DEFAULT_GRID_SIZE = 100; // meters this.DEFAULT_GRID_SIZE = 100; // meters
// get algorithm name from the command line profile argument // get algorithm name from the command line profile argument
this.ROUTING_ALGORITHM = process.argv[process.argv.indexOf('-p') + 1] === 'mld' ? 'MLD' : 'CH'; this.ROUTING_ALGORITHM = process.argv[process.argv.indexOf('-p') + 1].match('mld') ? 'MLD' : 'CH';
this.TIMEZONE_NAMES = this.PLATFORM_WINDOWS ? 'win' : 'iana';
this.OSRM_PORT = process.env.OSRM_PORT && parseInt(process.env.OSRM_PORT) || 5000; this.OSRM_PORT = process.env.OSRM_PORT && parseInt(process.env.OSRM_PORT) || 5000;
this.HOST = 'http://127.0.0.1:' + this.OSRM_PORT; this.HOST = 'http://127.0.0.1:' + this.OSRM_PORT;
+35 -12
View File
@@ -46,8 +46,9 @@ module.exports = function () {
return waypoints.map(w => [w.lon, w.lat].map(ensureDecimal).join(',')); return waypoints.map(w => [w.lon, w.lat].map(ensureDecimal).join(','));
}; };
this.requestRoute = (waypoints, bearings, userParams, callback) => { this.requestRoute = (waypoints, bearings, approaches, userParams, callback) => {
if (bearings.length && bearings.length !== waypoints.length) throw new Error('*** number of bearings does not equal the number of waypoints'); if (bearings.length && bearings.length !== waypoints.length) throw new Error('*** number of bearings does not equal the number of waypoints');
if (approaches.length && approaches.length !== waypoints.length) throw new Error('*** number of approaches does not equal the number of waypoints');
var defaults = { var defaults = {
output: 'json', output: 'json',
@@ -67,6 +68,9 @@ module.exports = function () {
}).join(';'); }).join(';');
} }
if (approaches.length) {
params.approaches = approaches.join(';');
}
return this.requestPath('route', params, callback); return this.requestPath('route', params, callback);
}; };
@@ -151,6 +155,10 @@ module.exports = function () {
return this.extractInstructionList(instructions, s => s.destinations || ''); return this.extractInstructionList(instructions, s => s.destinations || '');
}; };
this.exitsList = (instructions) => {
return this.extractInstructionList(instructions, s => s.exits || '');
};
this.reverseBearing = (bearing) => { this.reverseBearing = (bearing) => {
if (bearing >= 180) if (bearing >= 180)
return bearing - 180.; return bearing - 180.;
@@ -163,6 +171,28 @@ module.exports = function () {
('out' in s.intersections[0] ? s.intersections[0].bearings[s.intersections[0].out] : 0)); ('out' in s.intersections[0] ? s.intersections[0].bearings[s.intersections[0].out] : 0));
}; };
this.lanesList = (instructions) => {
return this.extractInstructionList(instructions, s => {
return s.intersections.map( i => {
if(i.lanes)
{
return i.lanes.map( l => {
let indications = l.indications.join(';');
return indications + ':' + (l.valid ? 'true' : 'false');
}).join(' ');
}
else
{
return '';
}
}).join(';');
});
};
this.approachList = (instructions) => {
return this.extractInstructionList(instructions, s => s.approaches || '');
};
this.annotationList = (instructions) => { this.annotationList = (instructions) => {
if (!('annotation' in instructions.legs[0])) if (!('annotation' in instructions.legs[0]))
return ''; return '';
@@ -185,17 +215,6 @@ module.exports = function () {
return instructions.tracepoints.map(t => t.alternatives_count.toString()).join(','); return instructions.tracepoints.map(t => t.alternatives_count.toString()).join(',');
}; };
this.lanesList = (instructions) => {
return this.extractInstructionList(instructions, instruction => {
if( 'lanes' in instruction.intersections[0] )
{
return instruction.intersections[0].lanes.map( p => { return (p.indications).join(';') + ':' + p.valid; } ).join(' ');
} else
{
return '';
}});
};
this.turnList = (instructions) => { this.turnList = (instructions) => {
return instructions.legs.reduce((m, v) => m.concat(v.steps), []) return instructions.legs.reduce((m, v) => m.concat(v.steps), [])
.map(v => { .map(v => {
@@ -248,6 +267,10 @@ module.exports = function () {
return this.extractInstructionList(instructions, s => s.mode); return this.extractInstructionList(instructions, s => s.mode);
}; };
this.classesList = (instructions) => {
return this.extractInstructionList(instructions, s => '[' + s.intersections.map(i => '(' + (i.classes ? i.classes.join(',') : '') + ')').join(',') + ']');
};
this.timeList = (instructions) => { this.timeList = (instructions) => {
return this.extractInstructionList(instructions, s => s.duration + 's'); return this.extractInstructionList(instructions, s => s.duration + 's');
}; };
+2 -1
View File
@@ -15,7 +15,8 @@ module.exports = function () {
'{profile_file}': this.profileFile, '{profile_file}': this.profileFile,
'{rastersource_file}': this.rasterCacheFile, '{rastersource_file}': this.rasterCacheFile,
'{speeds_file}': this.speedsCacheFile, '{speeds_file}': this.speedsCacheFile,
'{penalties_file}': this.penaltiesCacheFile '{penalties_file}': this.penaltiesCacheFile,
'{timezone_names}': this.TIMEZONE_NAMES
}; };
for (let k in table) { for (let k in table) {
+24 -9
View File
@@ -34,8 +34,8 @@ module.exports = function () {
var afterRequest = (err, res, body) => { var afterRequest = (err, res, body) => {
if (err) return cb(err); if (err) return cb(err);
if (body && body.length) { if (body && body.length) {
let destinations, pronunciations, instructions, refs, bearings, turns, modes, times, let destinations, exits, pronunciations, instructions, refs, bearings, turns, modes, times, classes,
distances, summary, intersections, lanes, locations, annotation, weight_name, weights; distances, summary, intersections, lanes, locations, annotation, weight_name, weights, approaches;
let json = JSON.parse(body); let json = JSON.parse(body);
@@ -48,10 +48,12 @@ module.exports = function () {
pronunciations = this.pronunciationList(json.routes[0]); pronunciations = this.pronunciationList(json.routes[0]);
refs = this.refList(json.routes[0]); refs = this.refList(json.routes[0]);
destinations = this.destinationsList(json.routes[0]); destinations = this.destinationsList(json.routes[0]);
exits = this.exitsList(json.routes[0]);
bearings = this.bearingList(json.routes[0]); bearings = this.bearingList(json.routes[0]);
turns = this.turnList(json.routes[0]); turns = this.turnList(json.routes[0]);
intersections = this.intersectionList(json.routes[0]); intersections = this.intersectionList(json.routes[0]);
modes = this.modeList(json.routes[0]); modes = this.modeList(json.routes[0]);
classes = this.classesList(json.routes[0]);
times = this.timeList(json.routes[0]); times = this.timeList(json.routes[0]);
distances = this.distanceList(json.routes[0]); distances = this.distanceList(json.routes[0]);
lanes = this.lanesList(json.routes[0]); lanes = this.lanesList(json.routes[0]);
@@ -60,6 +62,7 @@ module.exports = function () {
annotation = this.annotationList(json.routes[0]); annotation = this.annotationList(json.routes[0]);
weight_name = this.weightName(json.routes[0]); weight_name = this.weightName(json.routes[0]);
weights = this.weightList(json.routes[0]); weights = this.weightList(json.routes[0]);
approaches = this.approachList(json.routes[0]);
} }
if (headers.has('status')) { if (headers.has('status')) {
@@ -146,7 +149,10 @@ module.exports = function () {
if (headers.has('locations')){ if (headers.has('locations')){
got.locations = (locations || '').trim(); got.locations = (locations || '').trim();
} }
/*
if (headers.has('approaches')){
got.approaches = (approaches || '').trim();
}*/
// if header matches 'a:*', parse out the values for * // if header matches 'a:*', parse out the values for *
// and return in that header // and return in that header
headers.forEach((k) => { headers.forEach((k) => {
@@ -169,13 +175,16 @@ module.exports = function () {
putValue('bearing', bearings); putValue('bearing', bearings);
putValue('turns', turns); putValue('turns', turns);
putValue('modes', modes); putValue('modes', modes);
putValue('classes', classes);
putValue('times', times); putValue('times', times);
putValue('distances', distances); putValue('distances', distances);
putValue('pronunciations', pronunciations); putValue('pronunciations', pronunciations);
putValue('destinations', destinations); putValue('destinations', destinations);
putValue('exits', exits);
putValue('weight_name', weight_name); putValue('weight_name', weight_name);
putValue('weights', weights); putValue('weights', weights);
putValue('weight', weight); putValue('weight', weight);
putValue('approach', approaches);
for (var key in row) { for (var key in row) {
if (this.FuzzyMatch.match(got[key], row[key])) { if (this.FuzzyMatch.match(got[key], row[key])) {
@@ -210,33 +219,39 @@ module.exports = function () {
var params = this.overwriteParams(defaultParams, userParams), var params = this.overwriteParams(defaultParams, userParams),
waypoints = [], waypoints = [],
bearings = []; bearings = [],
approaches = [];
if (row.bearings) { if (row.bearings) {
got.bearings = row.bearings; got.bearings = row.bearings;
bearings = row.bearings.split(' ').filter(b => !!b); bearings = row.bearings.split(' ').filter(b => !!b);
} }
if (row.approaches) {
got.approaches = row.approaches;
approaches = row.approaches.split(' ').filter(b => !!b);
}
if (row.from && row.to) { if (row.from && row.to) {
var fromNode = this.findNodeByName(row.from); var fromNode = this.findNodeByName(row.from);
if (!fromNode) return cb(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); waypoints.push(fromNode);
var toNode = this.findNodeByName(row.to); var toNode = this.findNodeByName(row.to);
if (!toNode) return cb(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); waypoints.push(toNode);
got.from = row.from; got.from = row.from;
got.to = row.to; got.to = row.to;
this.requestRoute(waypoints, bearings, params, afterRequest); this.requestRoute(waypoints, bearings, approaches, params, afterRequest);
} else if (row.waypoints) { } else if (row.waypoints) {
row.waypoints.split(',').forEach((n) => { row.waypoints.split(',').forEach((n) => {
var node = this.findNodeByName(n.trim()); var node = this.findNodeByName(n.trim());
if (!node) return cb(new Error('*** unknown waypoint node "%s"', n.trim())); if (!node) return cb(new Error(util.format('*** unknown waypoint node "%s"', n.trim())));
waypoints.push(node); waypoints.push(node);
}); });
got.waypoints = row.waypoints; got.waypoints = row.waypoints;
this.requestRoute(waypoints, bearings, params, afterRequest); this.requestRoute(waypoints, bearings, approaches, params, afterRequest);
} else { } else {
return cb(new Error('*** no waypoints')); return cb(new Error('*** no waypoints'));
} }
+35
View File
@@ -30,3 +30,38 @@ Feature: Alternative route
| 3 | 4 | bd,dc,ca,ab,bd,bd | | | 3 | 4 | bd,dc,ca,ab,bd,bd | |
| 5 | 6 | dc,ca,ab,bd,dc,dc | | | 5 | 6 | dc,ca,ab,bd,dc,dc | |
| 7 | 8 | ca,ab,bd,dc,ca,ca | | | 7 | 8 | ca,ab,bd,dc,ca,ca | |
@4111
Scenario: Alternative Loop Paths with single node path
Given the node map
"""
a1b2c3d
e f
"""
And the ways
| nodes | maxspeed |
| ab | 30 |
| bc | 3 |
| cd | 30 |
| ae | 30 |
| ef | 30 |
| fd | 30 |
And the query options
| alternatives | true |
When I route I should get
| from | to | route | alternative |
| b | c | bc,bc | ab,ae,ef,fd,cd,cd |
#| c | b | bc,bc | cd,fd,ef,ae,ab,ab | # alternative path depends on phantom snapping order
| 1 | c | ab,bc,bc | ab,ae,ef,fd,cd,cd |
#| c | 1 | bc,ab | cd,fd,ef,ae,ab | # alternative path depends on phantom snapping order
| 2 | c | bc,bc | |
| c | 2 | bc,bc | |
| 1 | 3 | ab,ae,ef,fd,cd | ab,bc,cd |
#| 3 | 1 | cd,fd,ef,ae,ab | cd,bc,ab | # alternative path depends on phantom snapping order
| b | 3 | bc,cd | ab,ae,ef,fd,cd |
#| 3 | b | cd,bc,bc | cd,fd,ef,ae,ab,ab | # alternative path depends on phantom snapping order
+192
View File
@@ -0,0 +1,192 @@
@routing @approach @testbot
Feature: Approach parameter
Background:
Given the profile "testbot"
And a grid size of 10 meters
Scenario: Start End same approach, option unrestricted for Start and End
Given the node map
"""
s e
a------b------c
"""
And the ways
| nodes |
| ab |
| bc |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted unrestricted | ab,bc |
Scenario: Start End same approach, option unrestricted for Start and curb for End
Given the node map
"""
s e
a------b------c
"""
And the ways
| nodes |
| ab |
| bc |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted curb | ab,bc,bc |
Scenario: Start End opposite approach, option unrestricted for Start and End
Given the node map
"""
s
a------b------c
e
"""
And the ways
| nodes |
| ab |
| bc |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted unrestricted | ab,bc |
Scenario: Start End opposite approach, option unrestricted for Start and curb for End
Given the node map
"""
s
a------b------c
e
"""
And the ways
| nodes |
| ab |
| bc |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted curb | ab,bc |
###############
# Oneway Test #
###############
Scenario: Test on oneway segment, Start End same approach, option unrestricted for Start and End
Given the node map
"""
s e
a------b------c
"""
And the ways
| nodes | oneway |
| ab | yes |
| bc | yes |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted unrestricted | ab,bc |
Scenario: Test on oneway segment, Start End same approach, option unrestricted for Start and curb for End
Given the node map
"""
s e
a------b------c
"""
And the ways
| nodes | oneway |
| ab | yes |
| bc | yes |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted curb | ab,bc |
Scenario: Test on oneway segment, Start End opposite approach, option unrestricted for Start and End
Given the node map
"""
s
a------b------c
e
"""
And the ways
| nodes | oneway |
| ab | yes |
| bc | yes |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted unrestricted | ab,bc |
Scenario: Test on oneway segment, Start End opposite approach, option unrestricted for Start and curb for End
Given the node map
"""
s
a------b------c
e
"""
And the ways
| nodes | oneway |
| ab | yes |
| bc | yes |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted curb | ab,bc |
##############
# UTurn Test #
##############
Scenario: UTurn test, router can't found a route because uturn unauthorized on the segment selected
Given the node map
"""
s e
a------b------c
"""
And the ways
| nodes |
| ab |
| bc |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | bc | bc | c | no_u_turn |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted curb | |
Scenario: UTurn test, router can found a route because he can use the roundabout
Given the node map
"""
h
s e / \
a------b------c g
\ /
f
"""
And the ways
| nodes | junction |
| ab | |
| bc | |
| cfghc | roundabout |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | bc | bc | c | no_u_turn |
When I route I should get
| from | to | approaches | route |
| s | e | unrestricted curb | ab,bc,bc |
+5
View File
@@ -12,6 +12,7 @@ Feature: Testbot - Handle ferry routes
i j k l i j k l
m n o p m n o p
q r s t q r s t
u v w x
""" """
And the ways And the ways
@@ -26,11 +27,14 @@ Feature: Testbot - Handle ferry routes
| op | primary | | | | op | primary | | |
| qr | primary | | | | qr | primary | | |
| st | primary | | | | st | primary | | |
| uv | primary | | |
| wx | primary | | |
| bc | | ferry | 0:01 | | bc | | ferry | 0:01 |
| fg | | ferry | 0:10 | | fg | | ferry | 0:10 |
| jk | | ferry | 1:00 | | jk | | ferry | 1:00 |
| no | | ferry | 24:00 | | no | | ferry | 24:00 |
| rs | | ferry | 96:00 | | rs | | ferry | 96:00 |
| vw | | ferry | P5D |
When I route I should get When I route I should get
| from | to | route | time | | from | to | route | time |
@@ -39,6 +43,7 @@ Feature: Testbot - Handle ferry routes
| j | k | jk,jk | 3600s +-1 | | j | k | jk,jk | 3600s +-1 |
| n | o | no,no | 86400s +-1 | | n | o | no,no | 86400s +-1 |
| r | s | rs,rs | 345600s +-1 | | r | s | rs,rs | 345600s +-1 |
| v | w | vw,vw | 419430s +-1|
@todo @todo
Scenario: Testbot - Week long ferry routes Scenario: Testbot - Week long ferry routes
+26 -4
View File
@@ -358,8 +358,8 @@ Feature: Basic Map Matching
| trace | matchings | alternatives | | trace | matchings | alternatives |
| abcdef | abcde | 0,0,0,0,1,1 | | abcdef | abcde | 0,0,0,0,1,1 |
Scenario: Testbot - Speed greater than speed threshhold Scenario: Testbot - Speed greater than speed threshold
Given a grid size of 10 meters Given a grid size of 100 meters
Given the query options Given the query options
| geometries | geojson | | geometries | geojson |
@@ -379,8 +379,8 @@ Feature: Basic Map Matching
| trace | timestamps | matchings | | trace | timestamps | matchings |
| abcd | 0 1 2 3 | ab,cd | | abcd | 0 1 2 3 | ab,cd |
Scenario: Testbot - Speed less than speed threshhold Scenario: Testbot - Speed less than speed threshold
Given a grid size of 10 meters Given a grid size of 100 meters
Given the query options Given the query options
| geometries | geojson | | geometries | geojson |
@@ -397,6 +397,28 @@ Feature: Basic Map Matching
| trace | timestamps | matchings | | trace | timestamps | matchings |
| abcd | 0 1 2 3 | abcd | | abcd | 0 1 2 3 | abcd |
Scenario: Testbot - Huge gap in the coordinates
Given a grid size of 100 meters
Given the query options
| geometries | geojson |
| gaps | ignore |
Given the node map
"""
a b c d ---- x
|
|
y ---- z ---- efjk
"""
And the ways
| nodes | oneway |
| abcdxyzefjk | no |
When I match I should get
| trace | timestamps | matchings |
| abcdefjk | 0 1 2 3 50 51 52 53 | abcdefjk |
# Regression test 1 for issue 3176 # Regression test 1 for issue 3176
Scenario: Testbot - multiple segments: properly expose OSM IDs Scenario: Testbot - multiple segments: properly expose OSM IDs
Given the query options Given the query options
+65 -5
View File
@@ -48,21 +48,40 @@ Feature: Multi level routing
lkpo lkpo
""" """
And the nodes
| node | highway |
| i | traffic_signals |
| n | traffic_signals |
And the ways And the ways
| nodes | highway | | nodes | highway |
| abcda | primary | | abcda | primary |
| efghe | primary | | efghe | primary |
| ijkli | primary | | ijkli | primary |
| nmop | primary | | mnopm | primary |
| cm | primary | | cm | primary |
| hj | primary | | hj | primary |
| kp | primary | | kp | primary |
When I route I should get When I route I should get
| from | to | route | time | | from | to | route | time |
| a | b | abcda,abcda | 20s | | a | b | abcda,abcda | 20s |
| a | f | abcda,cm,nmop,kp,ijkli,hj,efghe,efghe | 257.7s | | a | f | abcda,cm,mnopm,kp,ijkli,hj,efghe,efghe | 229.4s |
| c | m | cm,cm | 44.7s | | a | l | abcda,cm,mnopm,kp,ijkli,ijkli | 144.7s |
| a | o | abcda,cm,mnopm,mnopm,mnopm | 124.7s |
| f | l | efghe,hj,ijkli,ijkli,ijkli | 124.7s |
| f | o | efghe,hj,ijkli,kp,mnopm,mnopm | 144.7s |
| l | o | ijkli,kp,mnopm,mnopm | 60s |
| c | m | cm,cm | 44.7s |
When I request a travel time matrix I should get
| | a | f | l | o |
| a | 0 | 229.4 | 144.7 | 124.7 |
| f | 229.4 | 0 | 124.7 | 144.7 |
| l | 144.7 | 124.7 | 0 | 60 |
| o | 124.7 | 144.7 | 60 | 0 |
Scenario: Testbot - Multi level routing: horizontal road Scenario: Testbot - Multi level routing: horizontal road
Given the node map Given the node map
@@ -127,3 +146,44 @@ Feature: Multi level routing
When I route I should get When I route I should get
| from | to | route | time | | from | to | route | time |
| a | k | abcda,ch,hf,fi,ijkli,ijkli | 724.3s | | a | k | abcda,ch,hf,fi,ijkli,ijkli | 724.3s |
Scenario: Testbot - Edge case for matrix plugin with
Given the node map
"""
ab
dc
e f
h gi
"""
And the partition extra arguments "--small-component-size 1 --max-cell-sizes 5,16,64"
And the nodes
| node | highway |
| e | traffic_signals |
| g | traffic_signals |
And the ways
| nodes | highway | maxspeed |
| abcda | primary | |
| ac | primary | |
| db | primary | |
| deh | primary | |
| cfg | primary | |
| ef | primary | 1 |
| eg | primary | 1 |
| hf | primary | 1 |
| hg | primary | 1 |
| gi | primary | |
When I route I should get
| from | to | route | time |
| h | i | deh,abcda,cfg,gi,gi | 134s |
When I request a travel time matrix I should get
| | h | i |
| h | 0 | 134 |
| i | 134 | 0 |
+1
View File
@@ -14,6 +14,7 @@ Feature: Testbot - Check assigning nil values
result.name = nil result.name = nil
result.ref = nil result.ref = nil
result.destinations = nil result.destinations = nil
result.exits = nil
result.pronunciation = nil result.pronunciation = nil
result.turn_lanes_forward = nil result.turn_lanes_forward = nil
result.turn_lanes_backward = nil result.turn_lanes_backward = nil
+26 -18
View File
@@ -2,15 +2,22 @@
Feature: Traffic - speeds Feature: Traffic - speeds
Background: Use specific speeds Background: Use specific speeds
# __ a
# / /
#c----b / g
# \ |\/
# \ e/\_.f
# \ | /
# d./
Given the node locations Given the node locations
| node | lat | lon | | node | lat | lon | id |
| a | 0.1 | 0.1 | | a | 0.1 | 0.1 | 1 |
| b | 0.05 | 0.1 | | b | 0.05 | 0.1 | 2 |
| c | 0.0 | 0.1 | | c | 0.0 | 0.1 | 3 |
| d | 0.05 | 0.03 | | d | 0.05 | 0.03 | 4 |
| e | 0.05 | 0.066 | | e | 0.05 | 0.066 | 5 |
| f | 0.075 | 0.066 | | f | 0.075 | 0.066 | 6 |
| g | 0.075 | 0.1 | | g | 0.075 | 0.1 | 7 |
And the ways And the ways
| nodes | highway | | nodes | highway |
| ab | primary | | ab | primary |
@@ -82,7 +89,7 @@ Feature: Traffic - speeds
api_version = 1 api_version = 1
properties.traffic_signal_penalty = 0 properties.traffic_signal_penalty = 0
properties.u_turn_penalty = 0 properties.u_turn_penalty = 0
properties.weight_precision = 3 properties.weight_precision = 2
""" """
And the contract extra arguments "--segment-speed-file {speeds_file}" And the contract extra arguments "--segment-speed-file {speeds_file}"
And the customize extra arguments "--segment-speed-file {speeds_file}" And the customize extra arguments "--segment-speed-file {speeds_file}"
@@ -99,15 +106,15 @@ Feature: Traffic - speeds
| annotations | datasources | | annotations | datasources |
When I route I should get When I route I should get
| from | to | route | speed | weights | a:datasources | | from | to | route | speed | weights | a:datasources |
| a | b | ab,ab | 1 km/h | 20020.735,0 | 1:0 | | a | b | ab,ab | 1 km/h | 20020.73,0 | 1:0 |
| a | c | ab,bc,bc | 2 km/h | 20020.735,741.509,0 | 1:1:0 | | a | c | ab,bc,bc | 2 km/h | 20020.73,741.51,0 | 1:1:0 |
| b | c | bc,bc | 27 km/h | 741.509,0 | 1:0 | | b | c | bc,bc | 27 km/h | 741.51,0 | 1:0 |
| a | d | ab,eb,de,de | 2 km/h | 20020.735,378.169,400.415,0 | 1:0:0 | | a | d | ab,eb,de,de | 2 km/h | 20020.73,378.17,400.41,0 | 1:0:0 |
| d | c | dc,dc | 36 km/h | 956.805,0 | 0 | | d | c | dc,dc | 36 km/h | 956.8,0 | 0 |
| g | b | ab,ab | 1 km/h | 10010.365,0 | 1:0 | | g | b | ab,ab | 1 km/h | 10010.37,0 | 1:0 |
| a | g | ab,ab | 1 km/h | 10010.37,0 | 1 | | a | g | ab,ab | 1 km/h | 10010.36,0 | 1 |
| g | a | ab,ab | 1 km/h | 10010.37,0 | 1:1 | | g | a | ab,ab | 1 km/h | 10010.36,0 | 1:1 |
Scenario: Speeds that isolate a single node (a) Scenario: Speeds that isolate a single node (a)
@@ -161,3 +168,4 @@ Feature: Traffic - speeds
And the data has been extracted And the data has been extracted
When I try to run "osrm-contract --segment-speed-file {speeds_file} {processed_file}" When I try to run "osrm-contract --segment-speed-file {speeds_file} {processed_file}"
And it should exit successfully And it should exit successfully
@@ -0,0 +1,30 @@
@routing @speed @traffic
Feature: Traffic - speeds edge cases
Scenario: Weighting based on speed file weights that cause segment weight overflows
Given the node map
"""
a-----b
"""
And the ways
| nodes | highway |
| ab | primary |
And the profile file "testbot" extended with
"""
api_version = 1
properties.traffic_signal_penalty = 0
properties.u_turn_penalty = 0
properties.weight_precision = 2
"""
And the contract extra arguments "--segment-speed-file {speeds_file}"
And the customize extra arguments "--segment-speed-file {speeds_file}"
And the speed file
"""
1,2,1,0.001
2,1,1,0.001
"""
And the query options
| annotations | datasources |
When I route I should get
| from | to | route | speed | weights | a:datasources |
| a | b | ab,ab | 1 km/h | 41943.02,0 | 1 |
+36
View File
@@ -0,0 +1,36 @@
@routing @testbot @turn_penalty
Feature: Turn Penalties
Background:
Given the profile "turnbot"
Given a grid size of 200 meters
Scenario: Turns should incur a delay that depend on the angle
Given the node map
"""
c d e
b j f
a s g
"""
And the ways
| nodes |
| sj |
| ja |
| jb |
| jc |
| jd |
| je |
| jf |
| jg |
When I route I should get
| from | to | route | time | distance |
| s | a | sj,ja,ja | 63s +-1 | 483m +-1 |
| s | b | sj,jb,jb | 50s +-1 | 400m +-1 |
| s | c | sj,jc,jc | 54s +-1 | 483m +-1 |
| s | d | sj,jd,jd | 40s +-1 | 400m +-1 |
| s | e | sj,je,je | 53s +-1 | 483m +-1 |
| s | f | sj,jf,jf | 50s +-1 | 400m +-1 |
| s | g | sj,jg,jg | 63s +-1 | 483m +-1 |
+3 -31
View File
@@ -224,34 +224,6 @@ Feature: Via points
| a,d,c | abc,bd,bd,bd,abc,abc | | a,d,c | abc,bd,bd,bd,abc,abc |
| c,d,a | abc,bd,bd,bd,abc,abc | | c,d,a | abc,bd,bd,bd,abc,abc |
# See issue #1896
Scenario: Via point at a dead end with barrier
Given the profile "car"
Given the node map
"""
a b c
1
d
f e
"""
And the nodes
| node | barrier |
| d | bollard |
And the ways
| nodes |
| abc |
| bd |
| afed |
When I route I should get
| waypoints | route |
| a,1,c | abc,bd,bd,bd,bd,abc,abc |
| c,1,a | abc,bd,bd,bd,bd,abc,abc |
Scenario: Via points on ring on the same oneway, forces one of the vertices to be top node Scenario: Via points on ring on the same oneway, forces one of the vertices to be top node
Given the node map Given the node map
""" """
@@ -349,9 +321,9 @@ Feature: Via points
| ab | | ab |
When I route I should get When I route I should get
| waypoints | bearings | route | turns | | waypoints | bearings | route | turns |
| 1,a | 90,2 270,2 | ab,ab,ab | depart,turn uturn,arrive | | 1,a | 90,2 270,2 | ab,ab,ab | depart,continue uturn,arrive |
| 1,b | 270,2 90,2 | ab,ab,ab | depart,turn uturn,arrive | | 1,b | 270,2 90,2 | ab,ab,ab | depart,continue uturn,arrive |
Scenario: Continue Straight in presence of Bearings Scenario: Continue Straight in presence of Bearings
Given the node map Given the node map
+5 -2
View File
@@ -1,5 +1,8 @@
Feature: Check zero speed updates Feature: Check zero speed updates
Background:
Given the profile "testbot"
Scenario: Matching on restricted way, single segment Scenario: Matching on restricted way, single segment
Given the query options Given the query options
| geometries | geojson | | geometries | geojson |
@@ -108,8 +111,8 @@ Feature: Check zero speed updates
""" """
When I route I should get When I route I should get
| from | to | bearings | code | | from | to | bearings | code |
| 1 | 2 | 270 270 | NoRoute | | 1 | 2 | 270 270 | NoSegment |
Scenario: Via routing on restricted oneway Scenario: Via routing on restricted oneway
+1 -13
View File
@@ -31,7 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "contractor/contractor_config.hpp" #include "contractor/contractor_config.hpp"
#include "contractor/query_edge.hpp" #include "contractor/query_edge.hpp"
#include "extractor/edge_based_edge.hpp" #include "extractor/edge_based_edge.hpp"
#include "extractor/edge_based_node.hpp" #include "extractor/edge_based_node_segment.hpp"
#include "util/deallocating_vector.hpp" #include "util/deallocating_vector.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
@@ -65,21 +65,9 @@ class Contractor
std::vector<EdgeWeight> &&node_weights, std::vector<EdgeWeight> &&node_weights,
std::vector<bool> &is_core_node, std::vector<bool> &is_core_node,
std::vector<float> &inout_node_levels) const; std::vector<float> &inout_node_levels) const;
void WriteCoreNodeMarker(std::vector<bool> &&is_core_node) const;
void WriteNodeLevels(std::vector<float> &&node_levels) const;
void ReadNodeLevels(std::vector<float> &contraction_order) const;
void WriteContractedGraph(unsigned number_of_edge_based_nodes,
util::DeallocatingVector<QueryEdge> contracted_edge_list);
void FindComponents(unsigned max_edge_id,
const util::DeallocatingVector<extractor::EdgeBasedEdge> &edges,
std::vector<extractor::EdgeBasedNode> &nodes) const;
private: private:
ContractorConfig config; ContractorConfig config;
EdgeID LoadEdgeExpandedGraph(const ContractorConfig &config,
std::vector<extractor::EdgeBasedEdge> &edge_based_edge_list,
std::vector<EdgeWeight> &node_weights);
}; };
} }
} }
+6 -6
View File
@@ -1,7 +1,7 @@
#ifndef OSRM_CONTRACTOR_CONTRACTOR_HEAP_HPP_ #ifndef OSRM_CONTRACTOR_CONTRACTOR_HEAP_HPP_
#define OSRM_CONTRACTOR_CONTRACTOR_HEAP_HPP_ #define OSRM_CONTRACTOR_CONTRACTOR_HEAP_HPP_
#include "util/binary_heap.hpp" #include "util/query_heap.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include "util/xor_fast_hash_storage.hpp" #include "util/xor_fast_hash_storage.hpp"
@@ -18,11 +18,11 @@ struct ContractorHeapData
bool target = false; bool target = false;
}; };
using ContractorHeap = util::BinaryHeap<NodeID, using ContractorHeap = util::QueryHeap<NodeID,
NodeID, NodeID,
EdgeWeight, EdgeWeight,
ContractorHeapData, ContractorHeapData,
util::XORFastHashStorage<NodeID, NodeID>>; util::XORFastHashStorage<NodeID, NodeID>>;
} // namespace contractor } // namespace contractor
} // namespace osrm } // namespace osrm
+40
View File
@@ -6,6 +6,7 @@
#include "util/serialization.hpp" #include "util/serialization.hpp"
#include "storage/io.hpp" #include "storage/io.hpp"
#include "storage/serialization.hpp"
namespace osrm namespace osrm
{ {
@@ -13,6 +14,27 @@ namespace contractor
{ {
namespace files namespace files
{ {
// reads .osrm.core
template <typename CoreVectorT>
void readCoreMarker(const boost::filesystem::path &path, CoreVectorT &is_core_node)
{
static_assert(util::is_view_or_vector<bool, CoreVectorT>::value,
"is_core_node must be a vector");
storage::io::FileReader reader(path, storage::io::FileReader::VerifyFingerprint);
storage::serialization::read(reader, is_core_node);
}
// writes .osrm.core
template <typename CoreVectorT>
void writeCoreMarker(const boost::filesystem::path &path, const CoreVectorT &is_core_node)
{
static_assert(util::is_view_or_vector<bool, CoreVectorT>::value,
"is_core_node must be a vector");
storage::io::FileWriter writer(path, storage::io::FileWriter::GenerateFingerprint);
storage::serialization::write(writer, is_core_node);
}
// reads .osrm.hsgr file // reads .osrm.hsgr file
template <typename QueryGraphT> template <typename QueryGraphT>
@@ -43,6 +65,24 @@ writeGraph(const boost::filesystem::path &path, unsigned checksum, const QueryGr
writer.WriteOne(checksum); writer.WriteOne(checksum);
util::serialization::write(writer, graph); util::serialization::write(writer, graph);
} }
// reads .levels file
inline void readLevels(const boost::filesystem::path &path, std::vector<float> &node_levels)
{
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
storage::io::FileReader reader{path, fingerprint};
storage::serialization::read(reader, node_levels);
}
// writes .levels file
inline void writeLevels(const boost::filesystem::path &path, const std::vector<float> &node_levels)
{
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint;
storage::io::FileWriter writer{path, fingerprint};
storage::serialization::write(writer, node_levels);
}
} }
} }
} }
+25 -8
View File
@@ -14,8 +14,6 @@
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <stxxl/vector>
#include <tbb/enumerable_thread_specific.h> #include <tbb/enumerable_thread_specific.h>
#include <tbb/parallel_for.h> #include <tbb/parallel_for.h>
#include <tbb/parallel_sort.h> #include <tbb/parallel_sort.h>
@@ -25,6 +23,10 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#if USE_STXXL_LIBRARY
#include <stxxl/vector>
#endif
namespace osrm namespace osrm
{ {
namespace contractor namespace contractor
@@ -33,6 +35,12 @@ namespace contractor
class GraphContractor class GraphContractor
{ {
private: private:
#if USE_STXXL_LIBRARY
template <typename T> using ExternalVector = stxxl::vector<T>;
#else
template <typename T> using ExternalVector = std::vector<T>;
#endif
struct ContractorThreadData struct ContractorThreadData
{ {
ContractorDijkstra dijkstra; ContractorDijkstra dijkstra;
@@ -91,8 +99,8 @@ class GraphContractor
GraphContractor(int nodes, GraphContractor(int nodes,
std::vector<ContractorEdge> edges, std::vector<ContractorEdge> edges,
std::vector<float> &&node_levels_, std::vector<float> node_levels_,
std::vector<EdgeWeight> &&node_weights_); std::vector<EdgeWeight> node_weights_);
/* Flush all data from the contraction to disc and reorder stuff for better locality */ /* Flush all data from the contraction to disc and reorder stuff for better locality */
void FlushDataAndRebuildContractorGraph(ThreadDataContainer &thread_data_list, void FlushDataAndRebuildContractorGraph(ThreadDataContainer &thread_data_list,
@@ -101,12 +109,14 @@ class GraphContractor
void Run(double core_factor = 1.0); void Run(double core_factor = 1.0);
void GetCoreMarker(std::vector<bool> &out_is_core_node); std::vector<bool> GetCoreMarker();
void GetNodeLevels(std::vector<float> &out_node_levels); std::vector<float> GetNodeLevels();
template <class Edge> inline void GetEdges(util::DeallocatingVector<Edge> &edges) template <class Edge> inline util::DeallocatingVector<Edge> GetEdges()
{ {
util::DeallocatingVector<Edge> edges;
util::UnbufferedLog log; util::UnbufferedLog log;
log << "Getting edges of minimized graph "; log << "Getting edges of minimized graph ";
util::Percent p(log, contractor_graph->GetNumberOfNodes()); util::Percent p(log, contractor_graph->GetNumberOfNodes());
@@ -161,6 +171,13 @@ class GraphContractor
edges.append(external_edge_list.begin(), external_edge_list.end()); edges.append(external_edge_list.begin(), external_edge_list.end());
external_edge_list.clear(); external_edge_list.clear();
// sort and remove duplicates
tbb::parallel_sort(edges.begin(), edges.end());
auto new_end = std::unique(edges.begin(), edges.end());
edges.resize(new_end - edges.begin());
return edges;
} }
private: private:
@@ -392,7 +409,7 @@ class GraphContractor
bool Bias(const NodeID a, const NodeID b) const; bool Bias(const NodeID a, const NodeID b) const;
std::shared_ptr<ContractorGraph> contractor_graph; std::shared_ptr<ContractorGraph> contractor_graph;
stxxl::vector<QueryEdge> external_edge_list; ExternalVector<QueryEdge> external_edge_list;
std::vector<NodeID> orig_node_id_from_new_node_id_map; std::vector<NodeID> orig_node_id_from_new_node_id_map;
std::vector<float> node_levels; std::vector<float> node_levels;
+32 -18
View File
@@ -3,7 +3,7 @@
#include "partition/cell_storage.hpp" #include "partition/cell_storage.hpp"
#include "partition/multi_level_partition.hpp" #include "partition/multi_level_partition.hpp"
#include "util/binary_heap.hpp" #include "util/query_heap.hpp"
#include <tbb/enumerable_thread_specific.h> #include <tbb/enumerable_thread_specific.h>
@@ -20,11 +20,12 @@ class CellCustomizer
struct HeapData struct HeapData
{ {
bool from_clique; bool from_clique;
EdgeDuration duration;
}; };
public: public:
using Heap = using Heap =
util::BinaryHeap<NodeID, NodeID, EdgeWeight, HeapData, util::ArrayStorage<NodeID, int>>; util::QueryHeap<NodeID, NodeID, EdgeWeight, HeapData, util::ArrayStorage<NodeID, int>>;
using HeapPtr = tbb::enumerable_thread_specific<Heap>; using HeapPtr = tbb::enumerable_thread_specific<Heap>;
CellCustomizer(const partition::MultiLevelPartition &partition) : partition(partition) {} CellCustomizer(const partition::MultiLevelPartition &partition) : partition(partition) {}
@@ -41,31 +42,41 @@ class CellCustomizer
{ {
std::unordered_set<NodeID> destinations_set(destinations.begin(), destinations.end()); std::unordered_set<NodeID> destinations_set(destinations.begin(), destinations.end());
heap.Clear(); heap.Clear();
heap.Insert(source, 0, {false}); heap.Insert(source, 0, {false, 0});
// explore search space // explore search space
while (!heap.Empty() && !destinations_set.empty()) while (!heap.Empty() && !destinations_set.empty())
{ {
const NodeID node = heap.DeleteMin(); const NodeID node = heap.DeleteMin();
const EdgeWeight weight = heap.GetKey(node); const EdgeWeight weight = heap.GetKey(node);
const EdgeDuration duration = heap.GetData(node).duration;
if (level == 1) if (level == 1)
RelaxNode<true>(graph, cells, heap, level, node, weight); RelaxNode<true>(graph, cells, heap, level, node, weight, duration);
else else
RelaxNode<false>(graph, cells, heap, level, node, weight); RelaxNode<false>(graph, cells, heap, level, node, weight, duration);
destinations_set.erase(node); destinations_set.erase(node);
} }
// fill a map of destination nodes to placeholder pointers // fill a map of destination nodes to placeholder pointers
auto destination_iter = destinations.begin(); auto weights = cell.GetOutWeight(source);
for (auto &weight : cell.GetOutWeight(source)) auto durations = cell.GetOutDuration(source);
for (auto &destination : destinations)
{ {
BOOST_ASSERT(destination_iter != destinations.end()); BOOST_ASSERT(!weights.empty());
const auto destination = *destination_iter++; BOOST_ASSERT(!durations.empty());
weight =
heap.WasInserted(destination) ? heap.GetKey(destination) : INVALID_EDGE_WEIGHT; const bool inserted = heap.WasInserted(destination);
weights.front() = inserted ? heap.GetKey(destination) : INVALID_EDGE_WEIGHT;
durations.front() =
inserted ? heap.GetData(destination).duration : MAXIMAL_EDGE_DURATION;
weights.advance_begin(1);
durations.advance_begin(1);
} }
BOOST_ASSERT(weights.empty());
BOOST_ASSERT(durations.empty());
} }
} }
@@ -94,7 +105,8 @@ class CellCustomizer
Heap &heap, Heap &heap,
LevelID level, LevelID level,
NodeID node, NodeID node,
EdgeWeight weight) const EdgeWeight weight,
EdgeDuration duration) const
{ {
BOOST_ASSERT(heap.WasInserted(node)); BOOST_ASSERT(heap.WasInserted(node));
@@ -113,24 +125,26 @@ class CellCustomizer
auto subcell_id = partition.GetCell(level - 1, node); auto subcell_id = partition.GetCell(level - 1, node);
auto subcell = cells.GetCell(level - 1, subcell_id); auto subcell = cells.GetCell(level - 1, subcell_id);
auto subcell_destination = subcell.GetDestinationNodes().begin(); auto subcell_destination = subcell.GetDestinationNodes().begin();
auto subcell_duration = subcell.GetOutDuration(node).begin();
for (auto subcell_weight : subcell.GetOutWeight(node)) for (auto subcell_weight : subcell.GetOutWeight(node))
{ {
if (subcell_weight != INVALID_EDGE_WEIGHT) if (subcell_weight != INVALID_EDGE_WEIGHT)
{ {
const NodeID to = *subcell_destination; const NodeID to = *subcell_destination;
const EdgeWeight to_weight = subcell_weight + weight; const EdgeWeight to_weight = weight + subcell_weight;
if (!heap.WasInserted(to)) if (!heap.WasInserted(to))
{ {
heap.Insert(to, to_weight, {true}); heap.Insert(to, to_weight, {true, duration + *subcell_duration});
} }
else if (to_weight < heap.GetKey(to)) else if (to_weight < heap.GetKey(to))
{ {
heap.DecreaseKey(to, to_weight); heap.DecreaseKey(to, to_weight);
heap.GetData(to).from_clique = true; heap.GetData(to) = {true, duration + *subcell_duration};
} }
} }
++subcell_destination; ++subcell_destination;
++subcell_duration;
} }
} }
} }
@@ -144,15 +158,15 @@ class CellCustomizer
(first_level || (first_level ||
partition.GetCell(level - 1, node) != partition.GetCell(level - 1, to))) partition.GetCell(level - 1, node) != partition.GetCell(level - 1, to)))
{ {
const EdgeWeight to_weight = data.weight + weight; const EdgeWeight to_weight = weight + data.weight;
if (!heap.WasInserted(to)) if (!heap.WasInserted(to))
{ {
heap.Insert(to, to_weight, {false}); heap.Insert(to, to_weight, {false, duration + data.duration});
} }
else if (to_weight < heap.GetKey(to)) else if (to_weight < heap.GetKey(to))
{ {
heap.DecreaseKey(to, to_weight); heap.DecreaseKey(to, to_weight);
heap.GetData(to).from_clique = false; heap.GetData(to) = {false, duration + data.duration};
} }
} }
} }
+9
View File
@@ -93,6 +93,9 @@ template <> struct HasGetTileTurns<corech::Algorithm> final : std::true_type
}; };
// Algorithms supported by Multi-Level Dijkstra // Algorithms supported by Multi-Level Dijkstra
template <> struct HasAlternativePathSearch<mld::Algorithm> final : std::true_type
{
};
template <> struct HasDirectShortestPathSearch<mld::Algorithm> final : std::true_type template <> struct HasDirectShortestPathSearch<mld::Algorithm> final : std::true_type
{ {
}; };
@@ -102,6 +105,12 @@ template <> struct HasShortestPathSearch<mld::Algorithm> final : std::true_type
template <> struct HasMapMatching<mld::Algorithm> final : std::true_type template <> struct HasMapMatching<mld::Algorithm> final : std::true_type
{ {
}; };
template <> struct HasManyToManySearch<mld::Algorithm> final : std::true_type
{
};
template <> struct HasGetTileTurns<mld::Algorithm> final : std::true_type
{
};
} }
} }
} }
+10 -5
View File
@@ -50,14 +50,19 @@ class BaseAPI
{ {
if (parameters.generate_hints) if (parameters.generate_hints)
{ {
return json::makeWaypoint(phantom.location, // TODO: check forward/reverse
facade.GetNameForID(phantom.name_id).to_string(), return json::makeWaypoint(
Hint{phantom, facade.GetCheckSum()}); phantom.location,
facade.GetNameForID(facade.GetNameIndex(phantom.forward_segment_id.id)).to_string(),
Hint{phantom, facade.GetCheckSum()});
} }
else else
{ {
return json::makeWaypoint(phantom.location, // TODO: check forward/reverse
facade.GetNameForID(phantom.name_id).to_string()); return json::makeWaypoint(
phantom.location,
facade.GetNameForID(facade.GetNameIndex(phantom.forward_segment_id.id))
.to_string());
} }
} }
+6 -1
View File
@@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ENGINE_API_BASE_PARAMETERS_HPP #ifndef ENGINE_API_BASE_PARAMETERS_HPP
#define ENGINE_API_BASE_PARAMETERS_HPP #define ENGINE_API_BASE_PARAMETERS_HPP
#include "engine/approach.hpp"
#include "engine/bearing.hpp" #include "engine/bearing.hpp"
#include "engine/hint.hpp" #include "engine/hint.hpp"
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
@@ -55,6 +56,7 @@ namespace api
* optional per coordinate * optional per coordinate
* - bearings: limits the search for segments in the road network to given bearing(s) in degree * - bearings: limits the search for segments in the road network to given bearing(s) in degree
* towards true north in clockwise direction, optional per coordinate * towards true north in clockwise direction, optional per coordinate
* - approaches: force the phantom node to start towards the node with the road country side.
* *
* \see OSRM, Coordinate, Hint, Bearing, RouteParame, RouteParameters, TableParameters, * \see OSRM, Coordinate, Hint, Bearing, RouteParame, RouteParameters, TableParameters,
* NearestParameters, TripParameters, MatchParameters and TileParameters * NearestParameters, TripParameters, MatchParameters and TileParameters
@@ -65,6 +67,7 @@ struct BaseParameters
std::vector<boost::optional<Hint>> hints; std::vector<boost::optional<Hint>> hints;
std::vector<boost::optional<double>> radiuses; std::vector<boost::optional<double>> radiuses;
std::vector<boost::optional<Bearing>> bearings; std::vector<boost::optional<Bearing>> bearings;
std::vector<boost::optional<Approach>> approaches;
// Adds hints to response which can be included in subsequent requests, see `hints` above. // Adds hints to response which can be included in subsequent requests, see `hints` above.
bool generate_hints = true; bool generate_hints = true;
@@ -73,9 +76,10 @@ struct BaseParameters
const std::vector<boost::optional<Hint>> hints_ = {}, const std::vector<boost::optional<Hint>> hints_ = {},
std::vector<boost::optional<double>> radiuses_ = {}, std::vector<boost::optional<double>> radiuses_ = {},
std::vector<boost::optional<Bearing>> bearings_ = {}, std::vector<boost::optional<Bearing>> bearings_ = {},
std::vector<boost::optional<Approach>> approaches_ = {},
bool generate_hints_ = true) bool generate_hints_ = true)
: coordinates(coordinates_), hints(hints_), radiuses(radiuses_), bearings(bearings_), : coordinates(coordinates_), hints(hints_), radiuses(radiuses_), bearings(bearings_),
generate_hints(generate_hints_) approaches(approaches_), generate_hints(generate_hints_)
{ {
} }
@@ -85,6 +89,7 @@ struct BaseParameters
return (hints.empty() || hints.size() == coordinates.size()) && return (hints.empty() || hints.size() == coordinates.size()) &&
(bearings.empty() || bearings.size() == coordinates.size()) && (bearings.empty() || bearings.size() == coordinates.size()) &&
(radiuses.empty() || radiuses.size() == coordinates.size()) && (radiuses.empty() || radiuses.size() == coordinates.size()) &&
(approaches.empty() || approaches.size() == coordinates.size()) &&
std::all_of(bearings.begin(), std::all_of(bearings.begin(),
bearings.end(), bearings.end(),
[](const boost::optional<Bearing> bearing_and_range) { [](const boost::optional<Bearing> bearing_and_range) {
+23 -19
View File
@@ -41,26 +41,27 @@ class RouteAPI : public BaseAPI
{ {
} }
void MakeResponse(const InternalRouteResult &raw_route, util::json::Object &response) const void MakeResponse(const InternalManyRoutesResult &raw_routes,
util::json::Object &response) const
{ {
auto number_of_routes = raw_route.has_alternative() ? 2UL : 1UL; BOOST_ASSERT(!raw_routes.routes.empty());
util::json::Array routes;
routes.values.resize(number_of_routes); util::json::Array jsRoutes;
routes.values[0] = MakeRoute(raw_route.segment_end_coordinates,
raw_route.unpacked_path_segments, for (const auto &route : raw_routes.routes)
raw_route.source_traversed_in_reverse,
raw_route.target_traversed_in_reverse);
if (raw_route.has_alternative())
{ {
std::vector<std::vector<PathData>> wrapped_leg(1); if (!route.is_valid())
wrapped_leg.front() = std::move(raw_route.unpacked_alternative); continue;
routes.values[1] = MakeRoute(raw_route.segment_end_coordinates,
wrapped_leg, jsRoutes.values.push_back(MakeRoute(route.segment_end_coordinates,
raw_route.alt_source_traversed_in_reverse, route.unpacked_path_segments,
raw_route.alt_target_traversed_in_reverse); route.source_traversed_in_reverse,
route.target_traversed_in_reverse));
} }
response.values["waypoints"] = BaseAPI::MakeWaypoints(raw_route.segment_end_coordinates);
response.values["routes"] = std::move(routes); response.values["waypoints"] =
BaseAPI::MakeWaypoints(raw_routes.routes[0].segment_end_coordinates);
response.values["routes"] = std::move(jsRoutes);
response.values["code"] = "Ok"; response.values["code"] = "Ok";
} }
@@ -164,19 +165,22 @@ class RouteAPI : public BaseAPI
* to find a via point. * to find a via point.
* The same exit will be emitted, though, if we should start routing at S, making * The same exit will be emitted, though, if we should start routing at S, making
* the overall response consistent. * the overall response consistent.
*
* CAUTION: order of post-processing steps is important
* - postProcess must be called before collapseTurnInstructions that expects
* post-processed roundabouts without Exit instructions
*/ */
guidance::trimShortSegments(steps, leg_geometry); guidance::trimShortSegments(steps, leg_geometry);
leg.steps = guidance::postProcess(std::move(steps)); leg.steps = guidance::postProcess(std::move(steps));
leg.steps = guidance::collapseTurnInstructions(std::move(leg.steps)); leg.steps = guidance::collapseTurnInstructions(std::move(leg.steps));
leg.steps = guidance::anticipateLaneChange(std::move(leg.steps));
leg.steps = guidance::buildIntersections(std::move(leg.steps)); leg.steps = guidance::buildIntersections(std::move(leg.steps));
leg.steps = guidance::suppressShortNameSegments(std::move(leg.steps)); leg.steps = guidance::suppressShortNameSegments(std::move(leg.steps));
leg.steps = guidance::assignRelativeLocations(std::move(leg.steps), leg.steps = guidance::assignRelativeLocations(std::move(leg.steps),
leg_geometry, leg_geometry,
phantoms.source_phantom, phantoms.source_phantom,
phantoms.target_phantom); phantoms.target_phantom);
leg.steps = guidance::anticipateLaneChange(std::move(leg.steps));
leg.steps = guidance::collapseUseLane(std::move(leg.steps));
leg_geometry = guidance::resyncGeometry(std::move(leg_geometry), leg.steps); leg_geometry = guidance::resyncGeometry(std::move(leg_geometry), leg.steps);
} }
+13 -4
View File
@@ -89,8 +89,9 @@ struct RouteParameters : public BaseParameters
const boost::optional<bool> continue_straight_, const boost::optional<bool> continue_straight_,
Args... args_) Args... args_)
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_}, : BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
annotations{false}, annotations_type{AnnotationsType::None}, geometries{geometries_}, number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{false},
overview{overview_}, continue_straight{continue_straight_} annotations_type{AnnotationsType::None}, geometries{geometries_}, overview{overview_},
continue_straight{continue_straight_}
// Once we perfectly-forward `args` (see #2990) this constructor can delegate to the one below. // Once we perfectly-forward `args` (see #2990) this constructor can delegate to the one below.
{ {
} }
@@ -105,7 +106,7 @@ struct RouteParameters : public BaseParameters
const boost::optional<bool> continue_straight_, const boost::optional<bool> continue_straight_,
Args... args_) Args... args_)
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_}, : BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
annotations{annotations_}, number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{annotations_},
annotations_type{annotations_ ? AnnotationsType::All : AnnotationsType::None}, annotations_type{annotations_ ? AnnotationsType::All : AnnotationsType::None},
geometries{geometries_}, overview{overview_}, continue_straight{continue_straight_} geometries{geometries_}, overview{overview_}, continue_straight{continue_straight_}
{ {
@@ -121,6 +122,7 @@ struct RouteParameters : public BaseParameters
const boost::optional<bool> continue_straight_, const boost::optional<bool> continue_straight_,
Args... args_) Args... args_)
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_}, : BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
number_of_alternatives{alternatives_ ? 1u : 0u},
annotations{annotations_ == AnnotationsType::None ? false : true}, annotations{annotations_ == AnnotationsType::None ? false : true},
annotations_type{annotations_}, geometries{geometries_}, overview{overview_}, annotations_type{annotations_}, geometries{geometries_}, overview{overview_},
continue_straight{continue_straight_} continue_straight{continue_straight_}
@@ -128,14 +130,21 @@ struct RouteParameters : public BaseParameters
} }
bool steps = false; bool steps = false;
// TODO: in v6 we should remove the boolean and only keep the number parameter; for compat.
bool alternatives = false; bool alternatives = false;
unsigned number_of_alternatives = 0;
bool annotations = false; bool annotations = false;
AnnotationsType annotations_type = AnnotationsType::None; AnnotationsType annotations_type = AnnotationsType::None;
GeometriesType geometries = GeometriesType::Polyline; GeometriesType geometries = GeometriesType::Polyline;
OverviewType overview = OverviewType::Simplified; OverviewType overview = OverviewType::Simplified;
boost::optional<bool> continue_straight; boost::optional<bool> continue_straight;
bool IsValid() const { return coordinates.size() >= 2 && BaseParameters::IsValid(); } bool IsValid() const
{
const auto coordinates_ok = coordinates.size() >= 2;
const auto base_params_ok = BaseParameters::IsValid();
return coordinates_ok && base_params_ok;
}
}; };
inline bool operator&(RouteParameters::AnnotationsType lhs, RouteParameters::AnnotationsType rhs) inline bool operator&(RouteParameters::AnnotationsType lhs, RouteParameters::AnnotationsType rhs)
-1
View File
@@ -42,7 +42,6 @@ class TableAPI final : public BaseAPI
{ {
auto number_of_sources = parameters.sources.size(); auto number_of_sources = parameters.sources.size();
auto number_of_destinations = parameters.destinations.size(); auto number_of_destinations = parameters.destinations.size();
;
// symmetric case // symmetric case
if (parameters.sources.empty()) if (parameters.sources.empty())
+46
View File
@@ -0,0 +1,46 @@
/*
Copyright (c) 2016, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OSRM_ENGINE_APPROACH_HPP
#define OSRM_ENGINE_APPROACH_HPP
#include <cstdint>
namespace osrm
{
namespace engine
{
enum class Approach : std::uint8_t
{
CURB = 0,
UNRESTRICTED = 1
};
}
}
#endif
@@ -6,6 +6,7 @@
#include "engine/datafacade/datafacade_base.hpp" #include "engine/datafacade/datafacade_base.hpp"
#include "engine/algorithm.hpp" #include "engine/algorithm.hpp"
#include "engine/approach.hpp"
#include "engine/geospatial_query.hpp" #include "engine/geospatial_query.hpp"
#include "customizer/edge_based_graph.hpp" #include "customizer/edge_based_graph.hpp"
@@ -13,6 +14,9 @@
#include "extractor/datasources.hpp" #include "extractor/datasources.hpp"
#include "extractor/guidance/turn_instruction.hpp" #include "extractor/guidance/turn_instruction.hpp"
#include "extractor/guidance/turn_lane_types.hpp" #include "extractor/guidance/turn_lane_types.hpp"
#include "extractor/intersection_bearings_container.hpp"
#include "extractor/node_data_container.hpp"
#include "extractor/packed_osm_ids.hpp"
#include "extractor/profile_properties.hpp" #include "extractor/profile_properties.hpp"
#include "extractor/segment_data_container.hpp" #include "extractor/segment_data_container.hpp"
#include "extractor/turn_data_container.hpp" #include "extractor/turn_data_container.hpp"
@@ -214,14 +218,14 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
unsigned m_check_sum; unsigned m_check_sum;
util::vector_view<util::Coordinate> m_coordinate_list; util::vector_view<util::Coordinate> m_coordinate_list;
util::PackedVectorView<OSMNodeID> m_osmnodeid_list; extractor::PackedOSMIDsView m_osmnodeid_list;
util::NameTable m_names_table;
util::vector_view<std::uint32_t> m_lane_description_offsets; util::vector_view<std::uint32_t> m_lane_description_offsets;
util::vector_view<extractor::guidance::TurnLaneType::Mask> m_lane_description_masks; util::vector_view<extractor::guidance::TurnLaneType::Mask> m_lane_description_masks;
util::vector_view<TurnPenalty> m_turn_weight_penalties; util::vector_view<TurnPenalty> m_turn_weight_penalties;
util::vector_view<TurnPenalty> m_turn_duration_penalties; util::vector_view<TurnPenalty> m_turn_duration_penalties;
extractor::SegmentDataView segment_data; extractor::SegmentDataView segment_data;
extractor::TurnDataView turn_data; extractor::TurnDataView turn_data;
extractor::EdgeBasedNodeDataView edge_based_node_data;
util::vector_view<char> m_datasource_name_data; util::vector_view<char> m_datasource_name_data;
util::vector_view<std::size_t> m_datasource_name_offsets; util::vector_view<std::size_t> m_datasource_name_offsets;
@@ -232,19 +236,12 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
std::unique_ptr<SharedGeospatialQuery> m_geospatial_query; std::unique_ptr<SharedGeospatialQuery> m_geospatial_query;
boost::filesystem::path file_index_path; boost::filesystem::path file_index_path;
util::NameTable m_name_table; extractor::IntersectionBearingsView intersection_bearings_view;
// bearing classes by node based node
util::vector_view<BearingClassID> m_bearing_class_id_table;
// entry class IDs
util::vector_view<EntryClassID> m_entry_class_id_list;
util::NameTable m_name_table;
// the look-up table for entry classes. An entry class lists the possibility of entry for all // the look-up table for entry classes. An entry class lists the possibility of entry for all
// available turns. Such a class id is stored with every edge. // available turns. Such a class id is stored with every edge.
util::vector_view<util::guidance::EntryClass> m_entry_class_table; util::vector_view<util::guidance::EntryClass> m_entry_class_table;
// the look-up table for distinct bearing classes. A bearing class lists the available bearings
// at an intersection
std::shared_ptr<util::RangeTable<16, storage::Ownership::View>> m_bearing_ranges_table;
util::vector_view<DiscreteBearing> m_bearing_values_table;
// allocator that keeps the allocation data // allocator that keeps the allocation data
std::shared_ptr<ContiguousBlockAllocator> allocator; std::shared_ptr<ContiguousBlockAllocator> allocator;
@@ -286,50 +283,75 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
"Is any data loaded into shared memory?" + SOURCE_REF); "Is any data loaded into shared memory?" + SOURCE_REF);
} }
auto tree_ptr = auto tree_nodes_ptr =
data_layout.GetBlockPtr<RTreeNode>(memory_block, storage::DataLayout::R_SEARCH_TREE); data_layout.GetBlockPtr<RTreeNode>(memory_block, storage::DataLayout::R_SEARCH_TREE);
auto tree_level_sizes_ptr = data_layout.GetBlockPtr<std::uint64_t>(
memory_block, storage::DataLayout::R_SEARCH_TREE_LEVELS);
m_static_rtree.reset( m_static_rtree.reset(
new SharedRTree(tree_ptr, new SharedRTree(tree_nodes_ptr,
data_layout.num_entries[storage::DataLayout::R_SEARCH_TREE], data_layout.num_entries[storage::DataLayout::R_SEARCH_TREE],
tree_level_sizes_ptr,
data_layout.num_entries[storage::DataLayout::R_SEARCH_TREE_LEVELS],
file_index_path, file_index_path,
m_coordinate_list)); m_coordinate_list));
m_geospatial_query.reset( m_geospatial_query.reset(
new SharedGeospatialQuery(*m_static_rtree, m_coordinate_list, *this)); new SharedGeospatialQuery(*m_static_rtree, m_coordinate_list, *this));
} }
void InitializeNodeInformationPointers(storage::DataLayout &data_layout, char *memory_block) void InitializeNodeInformationPointers(storage::DataLayout &layout, char *memory_ptr)
{ {
const auto coordinate_list_ptr = data_layout.GetBlockPtr<util::Coordinate>( const auto coordinate_list_ptr =
memory_block, storage::DataLayout::COORDINATE_LIST); layout.GetBlockPtr<util::Coordinate>(memory_ptr, storage::DataLayout::COORDINATE_LIST);
m_coordinate_list.reset(coordinate_list_ptr, m_coordinate_list.reset(coordinate_list_ptr,
data_layout.num_entries[storage::DataLayout::COORDINATE_LIST]); layout.num_entries[storage::DataLayout::COORDINATE_LIST]);
for (unsigned i = 0; i < m_coordinate_list.size(); ++i) const auto osmnodeid_ptr = layout.GetBlockPtr<extractor::PackedOSMIDsView::block_type>(
{ memory_ptr, storage::DataLayout::OSM_NODE_ID_LIST);
BOOST_ASSERT(GetCoordinateOfNode(i).IsValid()); m_osmnodeid_list = extractor::PackedOSMIDsView(
} util::vector_view<extractor::PackedOSMIDsView::block_type>(
osmnodeid_ptr, layout.num_entries[storage::DataLayout::OSM_NODE_ID_LIST]),
// We (ab)use the number of coordinates here because we know we have the same amount of
// ids
layout.num_entries[storage::DataLayout::COORDINATE_LIST]);
}
const auto osmnodeid_list_ptr = data_layout.GetBlockPtr<std::uint64_t>( void InitializeEdgeBasedNodeDataInformationPointers(storage::DataLayout &layout,
memory_block, storage::DataLayout::OSM_NODE_ID_LIST); char *memory_ptr)
m_osmnodeid_list.reset(osmnodeid_list_ptr, {
data_layout.num_entries[storage::DataLayout::OSM_NODE_ID_LIST]); const auto via_geometry_list_ptr =
// We (ab)use the number of coordinates here because we know we have the same amount of ids layout.GetBlockPtr<GeometryID>(memory_ptr, storage::DataLayout::GEOMETRY_ID_LIST);
m_osmnodeid_list.set_number_of_entries( util::vector_view<GeometryID> geometry_ids(
data_layout.num_entries[storage::DataLayout::COORDINATE_LIST]); via_geometry_list_ptr, layout.num_entries[storage::DataLayout::GEOMETRY_ID_LIST]);
const auto name_id_list_ptr =
layout.GetBlockPtr<NameID>(memory_ptr, storage::DataLayout::NAME_ID_LIST);
util::vector_view<NameID> name_ids(name_id_list_ptr,
layout.num_entries[storage::DataLayout::NAME_ID_LIST]);
const auto component_id_list_ptr =
layout.GetBlockPtr<ComponentID>(memory_ptr, storage::DataLayout::COMPONENT_ID_LIST);
util::vector_view<ComponentID> component_ids(
component_id_list_ptr, layout.num_entries[storage::DataLayout::COMPONENT_ID_LIST]);
const auto travel_mode_list_ptr = layout.GetBlockPtr<extractor::TravelMode>(
memory_ptr, storage::DataLayout::TRAVEL_MODE_LIST);
util::vector_view<extractor::TravelMode> travel_modes(
travel_mode_list_ptr, layout.num_entries[storage::DataLayout::TRAVEL_MODE_LIST]);
const auto classes_list_ptr =
layout.GetBlockPtr<extractor::ClassData>(memory_ptr, storage::DataLayout::CLASSES_LIST);
util::vector_view<extractor::ClassData> classes(
classes_list_ptr, layout.num_entries[storage::DataLayout::CLASSES_LIST]);
edge_based_node_data = extractor::EdgeBasedNodeDataView(std::move(geometry_ids),
std::move(name_ids),
std::move(component_ids),
std::move(travel_modes),
std::move(classes));
} }
void InitializeEdgeInformationPointers(storage::DataLayout &layout, char *memory_ptr) void InitializeEdgeInformationPointers(storage::DataLayout &layout, char *memory_ptr)
{ {
auto via_geometry_list_ptr =
layout.GetBlockPtr<GeometryID>(memory_ptr, storage::DataLayout::VIA_NODE_LIST);
util::vector_view<GeometryID> geometry_ids(
via_geometry_list_ptr, layout.num_entries[storage::DataLayout::VIA_NODE_LIST]);
const auto travel_mode_list_ptr =
layout.GetBlockPtr<extractor::TravelMode>(memory_ptr, storage::DataLayout::TRAVEL_MODE);
util::vector_view<extractor::TravelMode> travel_modes(
travel_mode_list_ptr, layout.num_entries[storage::DataLayout::TRAVEL_MODE]);
const auto lane_data_id_ptr = const auto lane_data_id_ptr =
layout.GetBlockPtr<LaneDataID>(memory_ptr, storage::DataLayout::LANE_DATA_ID); layout.GetBlockPtr<LaneDataID>(memory_ptr, storage::DataLayout::LANE_DATA_ID);
util::vector_view<LaneDataID> lane_data_ids( util::vector_view<LaneDataID> lane_data_ids(
@@ -341,11 +363,6 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
util::vector_view<extractor::guidance::TurnInstruction> turn_instructions( util::vector_view<extractor::guidance::TurnInstruction> turn_instructions(
turn_instruction_list_ptr, layout.num_entries[storage::DataLayout::TURN_INSTRUCTION]); turn_instruction_list_ptr, layout.num_entries[storage::DataLayout::TURN_INSTRUCTION]);
const auto name_id_list_ptr =
layout.GetBlockPtr<NameID>(memory_ptr, storage::DataLayout::NAME_ID_LIST);
util::vector_view<NameID> name_ids(name_id_list_ptr,
layout.num_entries[storage::DataLayout::NAME_ID_LIST]);
const auto entry_class_id_list_ptr = const auto entry_class_id_list_ptr =
layout.GetBlockPtr<EntryClassID>(memory_ptr, storage::DataLayout::ENTRY_CLASSID); layout.GetBlockPtr<EntryClassID>(memory_ptr, storage::DataLayout::ENTRY_CLASSID);
util::vector_view<EntryClassID> entry_class_ids( util::vector_view<EntryClassID> entry_class_ids(
@@ -361,11 +378,8 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
util::vector_view<util::guidance::TurnBearing> post_turn_bearings( util::vector_view<util::guidance::TurnBearing> post_turn_bearings(
post_turn_bearing_ptr, layout.num_entries[storage::DataLayout::POST_TURN_BEARING]); post_turn_bearing_ptr, layout.num_entries[storage::DataLayout::POST_TURN_BEARING]);
turn_data = extractor::TurnDataView(std::move(geometry_ids), turn_data = extractor::TurnDataView(std::move(turn_instructions),
std::move(name_ids),
std::move(turn_instructions),
std::move(lane_data_ids), std::move(lane_data_ids),
std::move(travel_modes),
std::move(entry_class_ids), std::move(entry_class_ids),
std::move(pre_turn_bearings), std::move(pre_turn_bearings),
std::move(post_turn_bearings)); std::move(post_turn_bearings));
@@ -424,35 +438,47 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
util::vector_view<unsigned> geometry_begin_indices( util::vector_view<unsigned> geometry_begin_indices(
geometries_index_ptr, data_layout.num_entries[storage::DataLayout::GEOMETRIES_INDEX]); geometries_index_ptr, data_layout.num_entries[storage::DataLayout::GEOMETRIES_INDEX]);
auto num_entries = data_layout.num_entries[storage::DataLayout::GEOMETRIES_NODE_LIST];
auto geometries_node_list_ptr = data_layout.GetBlockPtr<NodeID>( auto geometries_node_list_ptr = data_layout.GetBlockPtr<NodeID>(
memory_block, storage::DataLayout::GEOMETRIES_NODE_LIST); memory_block, storage::DataLayout::GEOMETRIES_NODE_LIST);
util::vector_view<NodeID> geometry_node_list( util::vector_view<NodeID> geometry_node_list(geometries_node_list_ptr, num_entries);
geometries_node_list_ptr,
data_layout.num_entries[storage::DataLayout::GEOMETRIES_NODE_LIST]);
auto geometries_fwd_weight_list_ptr = data_layout.GetBlockPtr<EdgeWeight>( auto geometries_fwd_weight_list_ptr =
memory_block, storage::DataLayout::GEOMETRIES_FWD_WEIGHT_LIST); data_layout.GetBlockPtr<extractor::SegmentDataView::SegmentWeightVector::block_type>(
util::vector_view<EdgeWeight> geometry_fwd_weight_list( memory_block, storage::DataLayout::GEOMETRIES_FWD_WEIGHT_LIST);
geometries_fwd_weight_list_ptr, extractor::SegmentDataView::SegmentWeightVector geometry_fwd_weight_list(
data_layout.num_entries[storage::DataLayout::GEOMETRIES_FWD_WEIGHT_LIST]); util::vector_view<extractor::SegmentDataView::SegmentWeightVector::block_type>(
geometries_fwd_weight_list_ptr,
data_layout.num_entries[storage::DataLayout::GEOMETRIES_FWD_WEIGHT_LIST]),
num_entries);
auto geometries_rev_weight_list_ptr = data_layout.GetBlockPtr<EdgeWeight>( auto geometries_rev_weight_list_ptr =
memory_block, storage::DataLayout::GEOMETRIES_REV_WEIGHT_LIST); data_layout.GetBlockPtr<extractor::SegmentDataView::SegmentWeightVector::block_type>(
util::vector_view<EdgeWeight> geometry_rev_weight_list( memory_block, storage::DataLayout::GEOMETRIES_REV_WEIGHT_LIST);
geometries_rev_weight_list_ptr, extractor::SegmentDataView::SegmentWeightVector geometry_rev_weight_list(
data_layout.num_entries[storage::DataLayout::GEOMETRIES_REV_WEIGHT_LIST]); util::vector_view<extractor::SegmentDataView::SegmentWeightVector::block_type>(
geometries_rev_weight_list_ptr,
data_layout.num_entries[storage::DataLayout::GEOMETRIES_REV_WEIGHT_LIST]),
num_entries);
auto geometries_fwd_duration_list_ptr = data_layout.GetBlockPtr<EdgeWeight>( auto geometries_fwd_duration_list_ptr =
memory_block, storage::DataLayout::GEOMETRIES_FWD_DURATION_LIST); data_layout.GetBlockPtr<extractor::SegmentDataView::SegmentDurationVector::block_type>(
util::vector_view<EdgeWeight> geometry_fwd_duration_list( memory_block, storage::DataLayout::GEOMETRIES_FWD_DURATION_LIST);
geometries_fwd_duration_list_ptr, extractor::SegmentDataView::SegmentDurationVector geometry_fwd_duration_list(
data_layout.num_entries[storage::DataLayout::GEOMETRIES_FWD_DURATION_LIST]); util::vector_view<extractor::SegmentDataView::SegmentDurationVector::block_type>(
geometries_fwd_duration_list_ptr,
data_layout.num_entries[storage::DataLayout::GEOMETRIES_FWD_DURATION_LIST]),
num_entries);
auto geometries_rev_duration_list_ptr = data_layout.GetBlockPtr<EdgeWeight>( auto geometries_rev_duration_list_ptr =
memory_block, storage::DataLayout::GEOMETRIES_REV_DURATION_LIST); data_layout.GetBlockPtr<extractor::SegmentDataView::SegmentDurationVector::block_type>(
util::vector_view<EdgeWeight> geometry_rev_duration_list( memory_block, storage::DataLayout::GEOMETRIES_REV_DURATION_LIST);
geometries_rev_duration_list_ptr, extractor::SegmentDataView::SegmentDurationVector geometry_rev_duration_list(
data_layout.num_entries[storage::DataLayout::GEOMETRIES_REV_DURATION_LIST]); util::vector_view<extractor::SegmentDataView::SegmentDurationVector::block_type>(
geometries_rev_duration_list_ptr,
data_layout.num_entries[storage::DataLayout::GEOMETRIES_REV_DURATION_LIST]),
num_entries);
auto datasources_list_ptr = data_layout.GetBlockPtr<DatasourceID>( auto datasources_list_ptr = data_layout.GetBlockPtr<DatasourceID>(
memory_block, storage::DataLayout::DATASOURCES_LIST); memory_block, storage::DataLayout::DATASOURCES_LIST);
@@ -475,15 +501,13 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
{ {
auto bearing_class_id_ptr = data_layout.GetBlockPtr<BearingClassID>( auto bearing_class_id_ptr = data_layout.GetBlockPtr<BearingClassID>(
memory_block, storage::DataLayout::BEARING_CLASSID); memory_block, storage::DataLayout::BEARING_CLASSID);
typename util::vector_view<BearingClassID> bearing_class_id_table( util::vector_view<BearingClassID> bearing_class_id(
bearing_class_id_ptr, data_layout.num_entries[storage::DataLayout::BEARING_CLASSID]); bearing_class_id_ptr, data_layout.num_entries[storage::DataLayout::BEARING_CLASSID]);
m_bearing_class_id_table = std::move(bearing_class_id_table);
auto bearing_class_ptr = data_layout.GetBlockPtr<DiscreteBearing>( auto bearing_values_ptr = data_layout.GetBlockPtr<DiscreteBearing>(
memory_block, storage::DataLayout::BEARING_VALUES); memory_block, storage::DataLayout::BEARING_VALUES);
typename util::vector_view<DiscreteBearing> bearing_class_table( util::vector_view<DiscreteBearing> bearing_values(
bearing_class_ptr, data_layout.num_entries[storage::DataLayout::BEARING_VALUES]); bearing_values_ptr, data_layout.num_entries[storage::DataLayout::BEARING_VALUES]);
m_bearing_values_table = std::move(bearing_class_table);
auto offsets_ptr = auto offsets_ptr =
data_layout.GetBlockPtr<unsigned>(memory_block, storage::DataLayout::BEARING_OFFSETS); data_layout.GetBlockPtr<unsigned>(memory_block, storage::DataLayout::BEARING_OFFSETS);
@@ -494,12 +518,15 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
util::vector_view<IndexBlock> bearing_blocks( util::vector_view<IndexBlock> bearing_blocks(
blocks_ptr, data_layout.num_entries[storage::DataLayout::BEARING_BLOCKS]); blocks_ptr, data_layout.num_entries[storage::DataLayout::BEARING_BLOCKS]);
m_bearing_ranges_table = std::make_unique<util::RangeTable<16, storage::Ownership::View>>( util::RangeTable<16, storage::Ownership::View> bearing_range_table(
bearing_offsets, bearing_blocks, static_cast<unsigned>(m_bearing_values_table.size())); bearing_offsets, bearing_blocks, static_cast<unsigned>(bearing_values.size()));
intersection_bearings_view = extractor::IntersectionBearingsView{
std::move(bearing_values), std::move(bearing_class_id), std::move(bearing_range_table)};
auto entry_class_ptr = data_layout.GetBlockPtr<util::guidance::EntryClass>( auto entry_class_ptr = data_layout.GetBlockPtr<util::guidance::EntryClass>(
memory_block, storage::DataLayout::ENTRY_CLASS); memory_block, storage::DataLayout::ENTRY_CLASS);
typename util::vector_view<util::guidance::EntryClass> entry_class_table( util::vector_view<util::guidance::EntryClass> entry_class_table(
entry_class_ptr, data_layout.num_entries[storage::DataLayout::ENTRY_CLASS]); entry_class_ptr, data_layout.num_entries[storage::DataLayout::ENTRY_CLASS]);
m_entry_class_table = std::move(entry_class_table); m_entry_class_table = std::move(entry_class_table);
} }
@@ -508,6 +535,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
{ {
InitializeChecksumPointer(data_layout, memory_block); InitializeChecksumPointer(data_layout, memory_block);
InitializeNodeInformationPointers(data_layout, memory_block); InitializeNodeInformationPointers(data_layout, memory_block);
InitializeEdgeBasedNodeDataInformationPointers(data_layout, memory_block);
InitializeEdgeInformationPointers(data_layout, memory_block); InitializeEdgeInformationPointers(data_layout, memory_block);
InitializeTurnPenalties(data_layout, memory_block); InitializeTurnPenalties(data_layout, memory_block);
InitializeGeometryPointers(data_layout, memory_block); InitializeGeometryPointers(data_layout, memory_block);
@@ -536,10 +564,10 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
OSMNodeID GetOSMNodeIDOfNode(const NodeID id) const override final OSMNodeID GetOSMNodeIDOfNode(const NodeID id) const override final
{ {
return m_osmnodeid_list.at(id); return m_osmnodeid_list[id];
} }
virtual std::vector<NodeID> GetUncompressedForwardGeometry(const EdgeID id) const override final std::vector<NodeID> GetUncompressedForwardGeometry(const EdgeID id) const override final
{ {
auto range = segment_data.GetForwardGeometry(id); auto range = segment_data.GetForwardGeometry(id);
@@ -598,11 +626,6 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
return std::vector<DatasourceID>{range.begin(), range.end()}; return std::vector<DatasourceID>{range.begin(), range.end()};
} }
virtual GeometryID GetGeometryIndexForEdgeID(const EdgeID id) const override final
{
return turn_data.GetGeometryID(id);
}
virtual TurnPenalty GetWeightPenaltyForEdgeID(const unsigned id) const override final virtual TurnPenalty GetWeightPenaltyForEdgeID(const unsigned id) const override final
{ {
BOOST_ASSERT(m_turn_weight_penalties.size() > id); BOOST_ASSERT(m_turn_weight_penalties.size() > id);
@@ -621,11 +644,6 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
return turn_data.GetTurnInstruction(id); return turn_data.GetTurnInstruction(id);
} }
extractor::TravelMode GetTravelModeForEdgeID(const EdgeID id) const override final
{
return turn_data.GetTravelMode(id);
}
std::vector<RTreeLeaf> GetEdgesInBox(const util::Coordinate south_west, std::vector<RTreeLeaf> GetEdgesInBox(const util::Coordinate south_west,
const util::Coordinate north_east) const override final const util::Coordinate north_east) const override final
{ {
@@ -637,54 +655,61 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float max_distance) const override final const float max_distance,
const Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodesInRange(input_coordinate, max_distance); return m_geospatial_query->NearestPhantomNodesInRange(
input_coordinate, max_distance, approach);
} }
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float max_distance, const float max_distance,
const int bearing, const int bearing,
const int bearing_range) const override final const int bearing_range,
const Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodesInRange( return m_geospatial_query->NearestPhantomNodesInRange(
input_coordinate, max_distance, bearing, bearing_range); input_coordinate, max_distance, bearing, bearing_range, approach);
}
std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results) const override final
{
BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results);
} }
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results, const unsigned max_results,
const double max_distance) const override final const Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, max_distance); return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, approach);
}
std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results,
const double max_distance,
const Approach approach) const override final
{
BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodes(
input_coordinate, max_results, max_distance, approach);
} }
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results, const unsigned max_results,
const int bearing, const int bearing,
const int bearing_range) const override final const int bearing_range,
const Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodes( return m_geospatial_query->NearestPhantomNodes(
input_coordinate, max_results, bearing, bearing_range); input_coordinate, max_results, bearing, bearing_range, approach);
} }
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
@@ -692,60 +717,97 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
const unsigned max_results, const unsigned max_results,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range) const override final const int bearing_range,
const Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodes( return m_geospatial_query->NearestPhantomNodes(
input_coordinate, max_results, max_distance, bearing, bearing_range); input_coordinate, max_results, max_distance, bearing, bearing_range, approach);
} }
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent( std::pair<PhantomNode, PhantomNode>
const util::Coordinate input_coordinate) const override final NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent( return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate); input_coordinate, approach);
} }
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent( std::pair<PhantomNode, PhantomNode>
const util::Coordinate input_coordinate, const double max_distance) const override final NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance,
const Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent( return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, max_distance); input_coordinate, max_distance, approach);
} }
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range) const override final const int bearing_range,
const Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent( return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, max_distance, bearing, bearing_range); input_coordinate, max_distance, bearing, bearing_range, approach);
} }
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const int bearing, const int bearing,
const int bearing_range) const override final const int bearing_range,
const Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent( return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, bearing, bearing_range); input_coordinate, bearing, bearing_range, approach);
} }
unsigned GetCheckSum() const override final { return m_check_sum; } unsigned GetCheckSum() const override final { return m_check_sum; }
NameID GetNameIndexFromEdgeID(const EdgeID id) const override final GeometryID GetGeometryIndex(const NodeID id) const override final
{ {
return turn_data.GetNameID(id); return edge_based_node_data.GetGeometryID(id);
}
ComponentID GetComponentID(const NodeID id) const override final
{
return edge_based_node_data.GetComponentID(id);
}
extractor::TravelMode GetTravelMode(const NodeID id) const override final
{
return edge_based_node_data.GetTravelMode(id);
}
extractor::ClassData GetClassData(const NodeID id) const override final
{
return edge_based_node_data.GetClassData(id);
}
std::vector<std::string> GetClasses(const extractor::ClassData class_data) const override final
{
auto indexes = extractor::getClassIndexes(class_data);
std::vector<std::string> classes(indexes.size());
std::transform(indexes.begin(), indexes.end(), classes.begin(), [this](const auto index) {
return m_profile_properties->GetClassName(index);
});
return classes;
}
NameID GetNameIndex(const NodeID id) const override final
{
return edge_based_node_data.GetNameID(id);
} }
StringView GetNameForID(const NameID id) const override final StringView GetNameForID(const NameID id) const override final
@@ -768,6 +830,11 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
return m_name_table.GetDestinationsForID(id); return m_name_table.GetDestinationsForID(id);
} }
StringView GetExitsForID(const NameID id) const override final
{
return m_name_table.GetExitsForID(id);
}
StringView GetDatasourceName(const DatasourceID id) const override final StringView GetDatasourceName(const DatasourceID id) const override final
{ {
return m_datasources->GetSourceName(id); return m_datasources->GetSourceName(id);
@@ -797,27 +864,9 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
return m_profile_properties->GetWeightMultiplier(); return m_profile_properties->GetWeightMultiplier();
} }
BearingClassID GetBearingClassID(const NodeID id) const override final util::guidance::BearingClass GetBearingClass(const NodeID node) const override final
{ {
return m_bearing_class_id_table.at(id); return intersection_bearings_view.GetBearingClass(node);
}
util::guidance::BearingClass
GetBearingClass(const BearingClassID bearing_class_id) const override final
{
BOOST_ASSERT(bearing_class_id != INVALID_BEARING_CLASSID);
auto range = m_bearing_ranges_table->GetRange(bearing_class_id);
util::guidance::BearingClass result;
for (auto itr = m_bearing_values_table.begin() + range.front();
itr != m_bearing_values_table.begin() + range.back() + 1;
++itr)
result.add(*itr);
return result;
}
EntryClassID GetEntryClassID(const EdgeID eid) const override final
{
return turn_data.GetEntryClassID(eid);
} }
util::guidance::TurnBearing PreTurnBearing(const EdgeID eid) const override final util::guidance::TurnBearing PreTurnBearing(const EdgeID eid) const override final
@@ -829,8 +878,9 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
return turn_data.GetPostTurnBearing(eid); return turn_data.GetPostTurnBearing(eid);
} }
util::guidance::EntryClass GetEntryClass(const EntryClassID entry_class_id) const override final util::guidance::EntryClass GetEntryClass(const EdgeID turn_id) const override final
{ {
auto entry_class_id = turn_data.GetEntryClassID(turn_id);
return m_entry_class_table.at(entry_class_id); return m_entry_class_table.at(entry_class_id);
} }
@@ -853,6 +903,11 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
m_lane_description_masks.begin() + m_lane_description_masks.begin() +
m_lane_description_offsets[lane_description_id + 1]); m_lane_description_offsets[lane_description_id + 1]);
} }
bool IsLeftHandDriving() const override final
{
return m_profile_properties->left_hand_driving;
}
}; };
template <typename AlgorithmT> class ContiguousInternalMemoryDataFacade; template <typename AlgorithmT> class ContiguousInternalMemoryDataFacade;
@@ -936,6 +991,8 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
auto mld_cell_weights_ptr = data_layout.GetBlockPtr<EdgeWeight>( auto mld_cell_weights_ptr = data_layout.GetBlockPtr<EdgeWeight>(
memory_block, storage::DataLayout::MLD_CELL_WEIGHTS); memory_block, storage::DataLayout::MLD_CELL_WEIGHTS);
auto mld_cell_durations_ptr = data_layout.GetBlockPtr<EdgeDuration>(
memory_block, storage::DataLayout::MLD_CELL_DURATIONS);
auto mld_source_boundary_ptr = data_layout.GetBlockPtr<NodeID>( auto mld_source_boundary_ptr = data_layout.GetBlockPtr<NodeID>(
memory_block, storage::DataLayout::MLD_CELL_SOURCE_BOUNDARY); memory_block, storage::DataLayout::MLD_CELL_SOURCE_BOUNDARY);
auto mld_destination_boundary_ptr = data_layout.GetBlockPtr<NodeID>( auto mld_destination_boundary_ptr = data_layout.GetBlockPtr<NodeID>(
@@ -947,6 +1004,8 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
auto weight_entries_count = auto weight_entries_count =
data_layout.GetBlockEntries(storage::DataLayout::MLD_CELL_WEIGHTS); data_layout.GetBlockEntries(storage::DataLayout::MLD_CELL_WEIGHTS);
auto duration_entries_count =
data_layout.GetBlockEntries(storage::DataLayout::MLD_CELL_DURATIONS);
auto source_boundary_entries_count = auto source_boundary_entries_count =
data_layout.GetBlockEntries(storage::DataLayout::MLD_CELL_SOURCE_BOUNDARY); data_layout.GetBlockEntries(storage::DataLayout::MLD_CELL_SOURCE_BOUNDARY);
auto destination_boundary_entries_count = auto destination_boundary_entries_count =
@@ -955,7 +1014,11 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
auto cell_level_offsets_entries_count = auto cell_level_offsets_entries_count =
data_layout.GetBlockEntries(storage::DataLayout::MLD_CELL_LEVEL_OFFSETS); data_layout.GetBlockEntries(storage::DataLayout::MLD_CELL_LEVEL_OFFSETS);
BOOST_ASSERT(weight_entries_count == duration_entries_count);
util::vector_view<EdgeWeight> weights(mld_cell_weights_ptr, weight_entries_count); util::vector_view<EdgeWeight> weights(mld_cell_weights_ptr, weight_entries_count);
util::vector_view<EdgeDuration> durations(mld_cell_durations_ptr,
duration_entries_count);
util::vector_view<NodeID> source_boundary(mld_source_boundary_ptr, util::vector_view<NodeID> source_boundary(mld_source_boundary_ptr,
source_boundary_entries_count); source_boundary_entries_count);
util::vector_view<NodeID> destination_boundary(mld_destination_boundary_ptr, util::vector_view<NodeID> destination_boundary(mld_destination_boundary_ptr,
@@ -966,6 +1029,7 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
cell_level_offsets_entries_count); cell_level_offsets_entries_count);
mld_cell_storage = partition::CellStorageView{std::move(weights), mld_cell_storage = partition::CellStorageView{std::move(weights),
std::move(durations),
std::move(source_boundary), std::move(source_boundary),
std::move(destination_boundary), std::move(destination_boundary),
std::move(cells), std::move(cells),
+47 -26
View File
@@ -3,13 +3,19 @@
// Exposes all data access interfaces to the algorithms via base class ptr // Exposes all data access interfaces to the algorithms via base class ptr
#include "engine/approach.hpp"
#include "engine/phantom_node.hpp"
#include "contractor/query_edge.hpp" #include "contractor/query_edge.hpp"
#include "extractor/edge_based_node.hpp"
#include "extractor/external_memory_node.hpp" #include "extractor/class_data.hpp"
#include "extractor/edge_based_node_segment.hpp"
#include "extractor/guidance/turn_instruction.hpp" #include "extractor/guidance/turn_instruction.hpp"
#include "extractor/guidance/turn_lane_types.hpp" #include "extractor/guidance/turn_lane_types.hpp"
#include "extractor/original_edge_data.hpp" #include "extractor/original_edge_data.hpp"
#include "engine/phantom_node.hpp" #include "extractor/query_node.hpp"
#include "extractor/travel_mode.hpp"
#include "util/exception.hpp" #include "util/exception.hpp"
#include "util/guidance/bearing_class.hpp" #include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp" #include "util/guidance/entry_class.hpp"
@@ -40,7 +46,7 @@ using StringView = util::StringView;
class BaseDataFacade class BaseDataFacade
{ {
public: public:
using RTreeLeaf = extractor::EdgeBasedNode; using RTreeLeaf = extractor::EdgeBasedNodeSegment;
BaseDataFacade() {} BaseDataFacade() {}
virtual ~BaseDataFacade() {} virtual ~BaseDataFacade() {}
@@ -51,7 +57,9 @@ class BaseDataFacade
virtual OSMNodeID GetOSMNodeIDOfNode(const NodeID id) const = 0; virtual OSMNodeID GetOSMNodeIDOfNode(const NodeID id) const = 0;
virtual GeometryID GetGeometryIndexForEdgeID(const EdgeID id) const = 0; virtual GeometryID GetGeometryIndex(const NodeID id) const = 0;
virtual ComponentID GetComponentID(const NodeID id) const = 0;
virtual std::vector<NodeID> GetUncompressedForwardGeometry(const EdgeID id) const = 0; virtual std::vector<NodeID> GetUncompressedForwardGeometry(const EdgeID id) const = 0;
@@ -82,7 +90,11 @@ class BaseDataFacade
virtual extractor::guidance::TurnInstruction virtual extractor::guidance::TurnInstruction
GetTurnInstructionForEdgeID(const EdgeID id) const = 0; GetTurnInstructionForEdgeID(const EdgeID id) const = 0;
virtual extractor::TravelMode GetTravelModeForEdgeID(const EdgeID id) const = 0; virtual extractor::TravelMode GetTravelMode(const NodeID id) const = 0;
virtual extractor::ClassData GetClassData(const NodeID id) const = 0;
virtual std::vector<std::string> GetClasses(const extractor::ClassData class_data) const = 0;
virtual std::vector<RTreeLeaf> GetEdgesInBox(const util::Coordinate south_west, virtual std::vector<RTreeLeaf> GetEdgesInBox(const util::Coordinate south_west,
const util::Coordinate north_east) const = 0; const util::Coordinate north_east) const = 0;
@@ -91,51 +103,61 @@ class BaseDataFacade
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float max_distance, const float max_distance,
const int bearing, const int bearing,
const int bearing_range) const = 0; const int bearing_range,
const Approach approach) const = 0;
virtual std::vector<PhantomNodeWithDistance> virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float max_distance) const = 0; const float max_distance,
const Approach approach) const = 0;
virtual std::vector<PhantomNodeWithDistance> virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results, const unsigned max_results,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range) const = 0; const int bearing_range,
const Approach approach) const = 0;
virtual std::vector<PhantomNodeWithDistance> virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results, const unsigned max_results,
const int bearing, const int bearing,
const int bearing_range) const = 0; const int bearing_range,
virtual std::vector<PhantomNodeWithDistance> const Approach approach) const = 0;
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results) const = 0;
virtual std::vector<PhantomNodeWithDistance> virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results, const unsigned max_results,
const double max_distance) const = 0; const Approach approach) const = 0;
virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results,
const double max_distance,
const Approach approach) const = 0;
virtual std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
const util::Coordinate input_coordinate) const = 0;
virtual std::pair<PhantomNode, PhantomNode> virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance) const = 0; const Approach approach) const = 0;
virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance,
const Approach approach) const = 0;
virtual std::pair<PhantomNode, PhantomNode> virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range) const = 0; const int bearing_range,
const Approach approach) const = 0;
virtual std::pair<PhantomNode, PhantomNode> virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const int bearing, const int bearing,
const int bearing_range) const = 0; const int bearing_range,
const Approach approach) const = 0;
virtual bool HasLaneData(const EdgeID id) const = 0; virtual bool HasLaneData(const EdgeID id) const = 0;
virtual util::guidance::LaneTupleIdPair GetLaneData(const EdgeID id) const = 0; virtual util::guidance::LaneTupleIdPair GetLaneData(const EdgeID id) const = 0;
virtual extractor::guidance::TurnLaneDescription virtual extractor::guidance::TurnLaneDescription
GetTurnDescription(const LaneDescriptionID lane_description_id) const = 0; GetTurnDescription(const LaneDescriptionID lane_description_id) const = 0;
virtual NameID GetNameIndexFromEdgeID(const EdgeID id) const = 0; virtual NameID GetNameIndex(const NodeID id) const = 0;
virtual StringView GetNameForID(const NameID id) const = 0; virtual StringView GetNameForID(const NameID id) const = 0;
@@ -145,6 +167,8 @@ class BaseDataFacade
virtual StringView GetDestinationsForID(const NameID id) const = 0; virtual StringView GetDestinationsForID(const NameID id) const = 0;
virtual StringView GetExitsForID(const NameID id) const = 0;
virtual std::string GetTimestamp() const = 0; virtual std::string GetTimestamp() const = 0;
virtual bool GetContinueStraightDefault() const = 0; virtual bool GetContinueStraightDefault() const = 0;
@@ -157,17 +181,14 @@ class BaseDataFacade
virtual double GetWeightMultiplier() const = 0; virtual double GetWeightMultiplier() const = 0;
virtual BearingClassID GetBearingClassID(const NodeID id) const = 0;
virtual util::guidance::TurnBearing PreTurnBearing(const EdgeID eid) const = 0; virtual util::guidance::TurnBearing PreTurnBearing(const EdgeID eid) const = 0;
virtual util::guidance::TurnBearing PostTurnBearing(const EdgeID eid) const = 0; virtual util::guidance::TurnBearing PostTurnBearing(const EdgeID eid) const = 0;
virtual util::guidance::BearingClass virtual util::guidance::BearingClass GetBearingClass(const NodeID node) const = 0;
GetBearingClass(const BearingClassID bearing_class_id) const = 0;
virtual EntryClassID GetEntryClassID(const EdgeID eid) const = 0; virtual util::guidance::EntryClass GetEntryClass(const EdgeID turn_id) const = 0;
virtual util::guidance::EntryClass GetEntryClass(const EntryClassID entry_class_id) const = 0; virtual bool IsLeftHandDriving() const = 0;
}; };
} }
} }
+43 -18
View File
@@ -11,7 +11,6 @@
#include "engine/datafacade/contiguous_block_allocator.hpp" #include "engine/datafacade/contiguous_block_allocator.hpp"
#include "engine/datafacade_provider.hpp" #include "engine/datafacade_provider.hpp"
#include "engine/engine_config.hpp" #include "engine/engine_config.hpp"
#include "engine/engine_config.hpp"
#include "engine/plugins/match.hpp" #include "engine/plugins/match.hpp"
#include "engine/plugins/nearest.hpp" #include "engine/plugins/nearest.hpp"
#include "engine/plugins/table.hpp" #include "engine/plugins/table.hpp"
@@ -22,6 +21,7 @@
#include "engine/status.hpp" #include "engine/status.hpp"
#include "util/exception.hpp" #include "util/exception.hpp"
#include "util/exception_utils.hpp" #include "util/exception_utils.hpp"
#include "util/fingerprint.hpp"
#include "util/json_container.hpp" #include "util/json_container.hpp"
#include <memory> #include <memory>
@@ -53,12 +53,12 @@ template <typename Algorithm> class Engine final : public EngineInterface
{ {
public: public:
explicit Engine(const EngineConfig &config) explicit Engine(const EngineConfig &config)
: route_plugin(config.max_locations_viaroute), // : route_plugin(config.max_locations_viaroute, config.max_alternatives), //
table_plugin(config.max_locations_distance_table), // table_plugin(config.max_locations_distance_table), //
nearest_plugin(config.max_results_nearest), // nearest_plugin(config.max_results_nearest), //
trip_plugin(config.max_locations_trip), // trip_plugin(config.max_locations_trip), //
match_plugin(config.max_locations_map_matching), // match_plugin(config.max_locations_map_matching), //
tile_plugin() // tile_plugin() //
{ {
if (config.use_shared_memory) if (config.use_shared_memory)
@@ -158,12 +158,12 @@ bool Engine<routing_algorithms::ch::Algorithm>::CheckCompability(const EngineCon
} }
else else
{ {
std::ifstream in(config.storage_config.hsgr_data_path.string().c_str()); if (!boost::filesystem::exists(config.storage_config.hsgr_data_path))
if (!in)
return false; return false;
storage::io::FileReader in(config.storage_config.hsgr_data_path,
storage::io::FileReader::VerifyFingerprint);
in.seekg(0, std::ios::end); auto size = in.GetSize();
auto size = in.tellg();
return size > 0; return size > 0;
} }
} }
@@ -184,18 +184,43 @@ bool Engine<routing_algorithms::corech::Algorithm>::CheckCompability(const Engin
auto mem = storage::makeSharedMemory(barrier.data().region); auto mem = storage::makeSharedMemory(barrier.data().region);
auto layout = reinterpret_cast<storage::DataLayout *>(mem->Ptr()); auto layout = reinterpret_cast<storage::DataLayout *>(mem->Ptr());
return layout->GetBlockSize(storage::DataLayout::CH_CORE_MARKER) > 4; return layout->GetBlockSize(storage::DataLayout::CH_CORE_MARKER) >
sizeof(std::uint64_t) + sizeof(util::FingerPrint);
} }
else else
{ {
std::ifstream in(config.storage_config.core_data_path.string().c_str()); if (!boost::filesystem::exists(config.storage_config.core_data_path))
if (!in)
return false; return false;
storage::io::FileReader in(config.storage_config.core_data_path,
storage::io::FileReader::VerifyFingerprint);
in.seekg(0, std::ios::end); auto size = in.GetSize();
std::size_t size = in.tellg(); return size > sizeof(std::uint64_t);
// An empty core files is only the 4 byte size header. }
return size > sizeof(std::uint32_t); }
template <>
bool Engine<routing_algorithms::mld::Algorithm>::CheckCompability(const EngineConfig &config)
{
if (config.use_shared_memory)
{
storage::SharedMonitor<storage::SharedDataTimestamp> barrier;
using mutex_type = typename decltype(barrier)::mutex_type;
boost::interprocess::scoped_lock<mutex_type> current_region_lock(barrier.get_mutex());
auto mem = storage::makeSharedMemory(barrier.data().region);
auto layout = reinterpret_cast<storage::DataLayout *>(mem->Ptr());
return layout->GetBlockSize(storage::DataLayout::MLD_PARTITION) > 0;
}
else
{
if (!boost::filesystem::exists(config.storage_config.mld_partition_path))
return false;
storage::io::FileReader in(config.storage_config.mld_partition_path,
storage::io::FileReader::VerifyFingerprint);
auto size = in.GetSize();
return size > 0;
} }
} }
} }
+1
View File
@@ -87,6 +87,7 @@ struct EngineConfig final
int max_locations_distance_table = -1; int max_locations_distance_table = -1;
int max_locations_map_matching = -1; int max_locations_map_matching = -1;
int max_results_nearest = -1; int max_results_nearest = -1;
int max_alternatives = 3; // set an arbitrary upper bound; can be adjusted by user
bool use_shared_memory = true; bool use_shared_memory = true;
Algorithm algorithm = Algorithm::CH; Algorithm algorithm = Algorithm::CH;
}; };
+191 -90
View File
@@ -1,6 +1,7 @@
#ifndef GEOSPATIAL_QUERY_HPP #ifndef GEOSPATIAL_QUERY_HPP
#define GEOSPATIAL_QUERY_HPP #define GEOSPATIAL_QUERY_HPP
#include "engine/approach.hpp"
#include "engine/phantom_node.hpp" #include "engine/phantom_node.hpp"
#include "util/bearing.hpp" #include "util/bearing.hpp"
#include "util/coordinate_calculation.hpp" #include "util/coordinate_calculation.hpp"
@@ -50,15 +51,19 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// Does not filter by small/big component! // Does not filter by small/big component!
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const double max_distance) const const double max_distance,
const Approach approach) const
{ {
auto results = auto results = rtree.Nearest(
rtree.Nearest(input_coordinate, input_coordinate,
[this](const CandidateSegment &segment) { return HasValidEdge(segment); }, [this, approach, &input_coordinate](const CandidateSegment &segment) {
[this, max_distance, input_coordinate](const std::size_t, return boolPairAnd(HasValidEdge(segment),
const CandidateSegment &segment) { CheckApproach(input_coordinate, segment, approach));
return CheckSegmentDistance(input_coordinate, segment, max_distance); },
}); [this, max_distance, input_coordinate](const std::size_t,
const CandidateSegment &segment) {
return CheckSegmentDistance(input_coordinate, segment, max_distance);
});
return MakePhantomNodes(input_coordinate, results); return MakePhantomNodes(input_coordinate, results);
} }
@@ -69,13 +74,18 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range) const const int bearing_range,
const Approach approach) const
{ {
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, bearing, bearing_range, max_distance](const CandidateSegment &segment) { [this, approach, &input_coordinate, bearing, bearing_range, max_distance](
return boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range), const CandidateSegment &segment) {
HasValidEdge(segment)); auto use_direction = boolPairAnd(
CheckSegmentBearing(segment, bearing, bearing_range), HasValidEdge(segment));
use_direction =
boolPairAnd(use_direction, CheckApproach(input_coordinate, segment, approach));
return use_direction;
}, },
[this, max_distance, input_coordinate](const std::size_t, [this, max_distance, input_coordinate](const std::size_t,
const CandidateSegment &segment) { const CandidateSegment &segment) {
@@ -91,13 +101,17 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
NearestPhantomNodes(const util::Coordinate input_coordinate, NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results, const unsigned max_results,
const int bearing, const int bearing,
const int bearing_range) const const int bearing_range,
const Approach approach) const
{ {
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, bearing, bearing_range](const CandidateSegment &segment) { [this, approach, &input_coordinate, bearing, bearing_range](
return boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range), const CandidateSegment &segment) {
HasValidEdge(segment)); auto use_direction = boolPairAnd(
CheckSegmentBearing(segment, bearing, bearing_range), HasValidEdge(segment));
return boolPairAnd(use_direction,
CheckApproach(input_coordinate, segment, approach));
}, },
[max_results](const std::size_t num_results, const CandidateSegment &) { [max_results](const std::size_t num_results, const CandidateSegment &) {
return num_results >= max_results; return num_results >= max_results;
@@ -114,13 +128,17 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
const unsigned max_results, const unsigned max_results,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range) const const int bearing_range,
const Approach approach) const
{ {
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, bearing, bearing_range](const CandidateSegment &segment) { [this, approach, &input_coordinate, bearing, bearing_range](
return boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range), const CandidateSegment &segment) {
HasValidEdge(segment)); auto use_direction = boolPairAnd(
CheckSegmentBearing(segment, bearing, bearing_range), HasValidEdge(segment));
return boolPairAnd(use_direction,
CheckApproach(input_coordinate, segment, approach));
}, },
[this, max_distance, max_results, input_coordinate](const std::size_t num_results, [this, max_distance, max_results, input_coordinate](const std::size_t num_results,
const CandidateSegment &segment) { const CandidateSegment &segment) {
@@ -134,14 +152,19 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// Returns max_results nearest PhantomNodes. // Returns max_results nearest PhantomNodes.
// Does not filter by small/big component! // Does not filter by small/big component!
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, const unsigned max_results) const NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results,
const Approach approach) const
{ {
auto results = auto results = rtree.Nearest(
rtree.Nearest(input_coordinate, input_coordinate,
[this](const CandidateSegment &segment) { return HasValidEdge(segment); }, [this, approach, &input_coordinate](const CandidateSegment &segment) {
[max_results](const std::size_t num_results, const CandidateSegment &) { return boolPairAnd(HasValidEdge(segment),
return num_results >= max_results; CheckApproach(input_coordinate, segment, approach));
}); },
[max_results](const std::size_t num_results, const CandidateSegment &) {
return num_results >= max_results;
});
return MakePhantomNodes(input_coordinate, results); return MakePhantomNodes(input_coordinate, results);
} }
@@ -151,16 +174,20 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results, const unsigned max_results,
const double max_distance) const const double max_distance,
const Approach approach) const
{ {
auto results = auto results = rtree.Nearest(
rtree.Nearest(input_coordinate, input_coordinate,
[this](const CandidateSegment &segment) { return HasValidEdge(segment); }, [this, approach, &input_coordinate](const CandidateSegment &segment) {
[this, max_distance, max_results, input_coordinate]( return boolPairAnd(HasValidEdge(segment),
const std::size_t num_results, const CandidateSegment &segment) { CheckApproach(input_coordinate, segment, approach));
return num_results >= max_results || },
CheckSegmentDistance(input_coordinate, segment, max_distance); [this, max_distance, max_results, input_coordinate](const std::size_t num_results,
}); const CandidateSegment &segment) {
return num_results >= max_results ||
CheckSegmentDistance(input_coordinate, segment, max_distance);
});
return MakePhantomNodes(input_coordinate, results); return MakePhantomNodes(input_coordinate, results);
} }
@@ -169,24 +196,29 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// a second phantom node is return that is the nearest coordinate in a big component. // a second phantom node is return that is the nearest coordinate in a big component.
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance) const const double max_distance,
const Approach approach) const
{ {
bool has_small_component = false; bool has_small_component = false;
bool has_big_component = false; bool has_big_component = false;
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, &has_big_component, &has_small_component](const CandidateSegment &segment) { [this, approach, &input_coordinate, &has_big_component, &has_small_component](
auto use_segment = (!has_small_component || const CandidateSegment &segment) {
(!has_big_component && !segment.data.component.is_tiny)); auto use_segment =
(!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
auto use_directions = std::make_pair(use_segment, use_segment); auto use_directions = std::make_pair(use_segment, use_segment);
const auto valid_edges = HasValidEdge(segment); const auto valid_edges = HasValidEdge(segment);
if (valid_edges.first || valid_edges.second)
{
has_big_component = has_big_component || !segment.data.component.is_tiny;
has_small_component = has_small_component || segment.data.component.is_tiny;
}
use_directions = boolPairAnd(use_directions, valid_edges); use_directions = boolPairAnd(use_directions, valid_edges);
use_directions =
boolPairAnd(use_directions, CheckApproach(input_coordinate, segment, approach));
if (use_directions.first || use_directions.second)
{
has_big_component = has_big_component || !IsTinyComponent(segment);
has_small_component = has_small_component || IsTinyComponent(segment);
}
return use_directions; return use_directions;
}, },
[this, &has_big_component, max_distance, input_coordinate]( [this, &has_big_component, max_distance, input_coordinate](
@@ -208,28 +240,30 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// Returns the nearest phantom node. If this phantom node is not from a big component // Returns the nearest phantom node. If this phantom node is not from a big component
// a second phantom node is return that is the nearest coordinate in a big component. // a second phantom node is return that is the nearest coordinate in a big component.
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate) const NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const Approach approach) const
{ {
bool has_small_component = false; bool has_small_component = false;
bool has_big_component = false; bool has_big_component = false;
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, &has_big_component, &has_small_component](const CandidateSegment &segment) { [this, approach, &input_coordinate, &has_big_component, &has_small_component](
auto use_segment = (!has_small_component || const CandidateSegment &segment) {
(!has_big_component && !segment.data.component.is_tiny)); auto use_segment =
(!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
auto use_directions = std::make_pair(use_segment, use_segment); auto use_directions = std::make_pair(use_segment, use_segment);
if (!use_directions.first && !use_directions.second)
return use_directions;
const auto valid_edges = HasValidEdge(segment); const auto valid_edges = HasValidEdge(segment);
use_directions = boolPairAnd(use_directions, valid_edges);
use_directions =
boolPairAnd(use_directions, CheckApproach(input_coordinate, segment, approach));
if (valid_edges.first || valid_edges.second) if (use_directions.first || use_directions.second)
{ {
has_big_component = has_big_component || !IsTinyComponent(segment);
has_big_component = has_big_component || !segment.data.component.is_tiny; has_small_component = has_small_component || IsTinyComponent(segment);
has_small_component = has_small_component || segment.data.component.is_tiny;
} }
use_directions = boolPairAnd(use_directions, valid_edges);
return use_directions; return use_directions;
}, },
[&has_big_component](const std::size_t num_results, const CandidateSegment &) { [&has_big_component](const std::size_t num_results, const CandidateSegment &) {
@@ -248,17 +282,25 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// Returns the nearest phantom node. If this phantom node is not from a big component // Returns the nearest phantom node. If this phantom node is not from a big component
// a second phantom node is return that is the nearest coordinate in a big component. // a second phantom node is return that is the nearest coordinate in a big component.
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent( std::pair<PhantomNode, PhantomNode>
const util::Coordinate input_coordinate, const int bearing, const int bearing_range) const NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const int bearing,
const int bearing_range,
const Approach approach) const
{ {
bool has_small_component = false; bool has_small_component = false;
bool has_big_component = false; bool has_big_component = false;
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, bearing, bearing_range, &has_big_component, &has_small_component]( [this,
const CandidateSegment &segment) { approach,
auto use_segment = (!has_small_component || &input_coordinate,
(!has_big_component && !segment.data.component.is_tiny)); bearing,
bearing_range,
&has_big_component,
&has_small_component](const CandidateSegment &segment) {
auto use_segment =
(!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
auto use_directions = std::make_pair(use_segment, use_segment); auto use_directions = std::make_pair(use_segment, use_segment);
use_directions = boolPairAnd(use_directions, HasValidEdge(segment)); use_directions = boolPairAnd(use_directions, HasValidEdge(segment));
@@ -267,10 +309,13 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
use_directions = use_directions =
boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range), boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range),
HasValidEdge(segment)); HasValidEdge(segment));
use_directions = boolPairAnd(
use_directions, CheckApproach(input_coordinate, segment, approach));
if (use_directions.first || use_directions.second) if (use_directions.first || use_directions.second)
{ {
has_big_component = has_big_component || !segment.data.component.is_tiny; has_big_component = has_big_component || !IsTinyComponent(segment);
has_small_component = has_small_component || segment.data.component.is_tiny; has_small_component = has_small_component || IsTinyComponent(segment);
} }
} }
@@ -296,16 +341,22 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range) const const int bearing_range,
const Approach approach) const
{ {
bool has_small_component = false; bool has_small_component = false;
bool has_big_component = false; bool has_big_component = false;
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, bearing, bearing_range, &has_big_component, &has_small_component]( [this,
const CandidateSegment &segment) { approach,
auto use_segment = (!has_small_component || &input_coordinate,
(!has_big_component && !segment.data.component.is_tiny)); bearing,
bearing_range,
&has_big_component,
&has_small_component](const CandidateSegment &segment) {
auto use_segment =
(!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
auto use_directions = std::make_pair(use_segment, use_segment); auto use_directions = std::make_pair(use_segment, use_segment);
use_directions = boolPairAnd(use_directions, HasValidEdge(segment)); use_directions = boolPairAnd(use_directions, HasValidEdge(segment));
@@ -314,10 +365,13 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
use_directions = use_directions =
boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range), boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range),
HasValidEdge(segment)); HasValidEdge(segment));
use_directions = boolPairAnd(
use_directions, CheckApproach(input_coordinate, segment, approach));
if (use_directions.first || use_directions.second) if (use_directions.first || use_directions.second)
{ {
has_big_component = has_big_component || !segment.data.component.is_tiny; has_big_component = has_big_component || !IsTinyComponent(segment);
has_small_component = has_small_component || segment.data.component.is_tiny; has_small_component = has_small_component || IsTinyComponent(segment);
} }
} }
@@ -371,17 +425,24 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
EdgeWeight forward_weight_offset = 0, forward_weight = 0; EdgeWeight forward_weight_offset = 0, forward_weight = 0;
EdgeWeight reverse_weight_offset = 0, reverse_weight = 0; EdgeWeight reverse_weight_offset = 0, reverse_weight = 0;
EdgeWeight forward_duration_offset = 0, forward_duration = 0; EdgeDuration forward_duration_offset = 0, forward_duration = 0;
EdgeWeight reverse_duration_offset = 0, reverse_duration = 0; EdgeDuration reverse_duration_offset = 0, reverse_duration = 0;
BOOST_ASSERT(data.forward_segment_id.enabled || data.reverse_segment_id.enabled);
BOOST_ASSERT(!data.reverse_segment_id.enabled ||
datafacade.GetGeometryIndex(data.forward_segment_id.id).id ==
datafacade.GetGeometryIndex(data.reverse_segment_id.id).id);
const auto geometry_id = datafacade.GetGeometryIndex(data.forward_segment_id.id).id;
const auto component_id = datafacade.GetComponentID(data.forward_segment_id.id);
const std::vector<EdgeWeight> forward_weight_vector = const std::vector<EdgeWeight> forward_weight_vector =
datafacade.GetUncompressedForwardWeights(data.packed_geometry_id); datafacade.GetUncompressedForwardWeights(geometry_id);
const std::vector<EdgeWeight> reverse_weight_vector = const std::vector<EdgeWeight> reverse_weight_vector =
datafacade.GetUncompressedReverseWeights(data.packed_geometry_id); datafacade.GetUncompressedReverseWeights(geometry_id);
const std::vector<EdgeWeight> forward_duration_vector = const std::vector<EdgeWeight> forward_duration_vector =
datafacade.GetUncompressedForwardDurations(data.packed_geometry_id); datafacade.GetUncompressedForwardDurations(geometry_id);
const std::vector<EdgeWeight> reverse_duration_vector = const std::vector<EdgeWeight> reverse_duration_vector =
datafacade.GetUncompressedReverseDurations(data.packed_geometry_id); datafacade.GetUncompressedReverseDurations(geometry_id);
for (std::size_t i = 0; i < data.fwd_segment_position; i++) for (std::size_t i = 0; i < data.fwd_segment_position; i++)
{ {
@@ -408,17 +469,17 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
if (data.forward_segment_id.id != SPECIAL_SEGMENTID) if (data.forward_segment_id.id != SPECIAL_SEGMENTID)
{ {
forward_weight = static_cast<EdgeWeight>(forward_weight * ratio); forward_weight = static_cast<EdgeWeight>(forward_weight * ratio);
forward_duration = static_cast<EdgeWeight>(forward_duration * ratio); forward_duration = static_cast<EdgeDuration>(forward_duration * ratio);
} }
if (data.reverse_segment_id.id != SPECIAL_SEGMENTID) if (data.reverse_segment_id.id != SPECIAL_SEGMENTID)
{ {
reverse_weight -= static_cast<EdgeWeight>(reverse_weight * ratio); reverse_weight -= static_cast<EdgeWeight>(reverse_weight * ratio);
reverse_duration -= static_cast<EdgeWeight>(reverse_duration * ratio); reverse_duration -= static_cast<EdgeDuration>(reverse_duration * ratio);
} }
// check phantom node segments validity // check phantom node segments validity
auto areSegmentsValid = [](auto first, auto last) -> bool { auto areSegmentsValid = [](auto first, auto last) -> bool {
return std::find(first, last, INVALID_EDGE_WEIGHT) == last; return std::find(first, last, INVALID_SEGMENT_WEIGHT) == last;
}; };
bool is_forward_valid_source = bool is_forward_valid_source =
areSegmentsValid(forward_weight_vector.begin(), forward_weight_vector.end()); areSegmentsValid(forward_weight_vector.begin(), forward_weight_vector.end());
@@ -431,6 +492,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
reverse_weight_vector.begin(), reverse_weight_vector.end() - data.fwd_segment_position); reverse_weight_vector.begin(), reverse_weight_vector.end() - data.fwd_segment_position);
auto transformed = PhantomNodeWithDistance{PhantomNode{data, auto transformed = PhantomNodeWithDistance{PhantomNode{data,
component_id,
forward_weight, forward_weight,
reverse_weight, reverse_weight,
forward_weight_offset, forward_weight_offset,
@@ -495,7 +557,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
/** /**
* Checks to see if the edge weights are valid. We might have an edge, * Checks to see if the edge weights are valid. We might have an edge,
* but a traffic update might set the speed to 0 (weight == INVALID_EDGE_WEIGHT). * but a traffic update might set the speed to 0 (weight == INVALID_SEGMENT_WEIGHT).
* which means that this edge is not currently traversible. If this is the case, * which means that this edge is not currently traversible. If this is the case,
* then we shouldn't snap to this edge. * then we shouldn't snap to this edge.
*/ */
@@ -505,25 +567,64 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
bool forward_edge_valid = false; bool forward_edge_valid = false;
bool reverse_edge_valid = false; bool reverse_edge_valid = false;
const std::vector<EdgeWeight> forward_weight_vector = const auto &data = segment.data;
datafacade.GetUncompressedForwardWeights(segment.data.packed_geometry_id); BOOST_ASSERT(data.forward_segment_id.enabled);
BOOST_ASSERT(data.forward_segment_id.id != SPECIAL_NODEID);
const auto geometry_id = datafacade.GetGeometryIndex(data.forward_segment_id.id).id;
if (forward_weight_vector[segment.data.fwd_segment_position] != INVALID_EDGE_WEIGHT) const std::vector<EdgeWeight> forward_weight_vector =
datafacade.GetUncompressedForwardWeights(geometry_id);
if (forward_weight_vector[data.fwd_segment_position] != INVALID_SEGMENT_WEIGHT)
{ {
forward_edge_valid = segment.data.forward_segment_id.enabled; forward_edge_valid = data.forward_segment_id.enabled;
} }
const std::vector<EdgeWeight> reverse_weight_vector = const std::vector<EdgeWeight> reverse_weight_vector =
datafacade.GetUncompressedReverseWeights(segment.data.packed_geometry_id); datafacade.GetUncompressedReverseWeights(geometry_id);
if (reverse_weight_vector[reverse_weight_vector.size() - segment.data.fwd_segment_position - if (reverse_weight_vector[reverse_weight_vector.size() - data.fwd_segment_position - 1] !=
1] != INVALID_EDGE_WEIGHT) INVALID_SEGMENT_WEIGHT)
{ {
reverse_edge_valid = segment.data.reverse_segment_id.enabled; reverse_edge_valid = data.reverse_segment_id.enabled;
} }
return std::make_pair(forward_edge_valid, reverse_edge_valid); return std::make_pair(forward_edge_valid, reverse_edge_valid);
} }
bool IsTinyComponent(const CandidateSegment &segment) const
{
const auto &data = segment.data;
BOOST_ASSERT(data.forward_segment_id.enabled);
BOOST_ASSERT(data.forward_segment_id.id != SPECIAL_NODEID);
return datafacade.GetComponentID(data.forward_segment_id.id).is_tiny;
}
std::pair<bool, bool> CheckApproach(const util::Coordinate &input_coordinate,
const CandidateSegment &segment,
const Approach approach) const
{
bool isOnewaySegment =
!(segment.data.forward_segment_id.enabled && segment.data.reverse_segment_id.enabled);
if (!isOnewaySegment && approach == Approach::CURB)
{
// Check the counter clockwise
//
// input_coordinate
// |
// |
// segment.data.u ---------------- segment.data.v
bool input_coordinate_is_at_right = !util::coordinate_calculation::isCCW(
coordinates[segment.data.u], coordinates[segment.data.v], input_coordinate);
if (datafacade.IsLeftHandDriving())
input_coordinate_is_at_right = !input_coordinate_is_at_right;
return std::make_pair(input_coordinate_is_at_right, (!input_coordinate_is_at_right));
}
return std::make_pair(true, true);
}
const RTreeT &rtree; const RTreeT &rtree;
const CoordinateList &coordinates; const CoordinateList &coordinates;
DataFacadeT &datafacade; DataFacadeT &datafacade;
@@ -51,8 +51,11 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
// source node rev: 2 0 <- 1 <- 2 // source node rev: 2 0 <- 1 <- 2
const auto source_segment_start_coordinate = const auto source_segment_start_coordinate =
source_node.fwd_segment_position + (reversed_source ? 1 : 0); source_node.fwd_segment_position + (reversed_source ? 1 : 0);
const auto source_node_id =
reversed_source ? source_node.reverse_segment_id.id : source_node.forward_segment_id.id;
const auto source_gemetry_id = facade.GetGeometryIndex(source_node_id).id;
const std::vector<NodeID> source_geometry = const std::vector<NodeID> source_geometry =
facade.GetUncompressedForwardGeometry(source_node.packed_geometry_id); facade.GetUncompressedForwardGeometry(source_gemetry_id);
geometry.osm_node_ids.push_back( geometry.osm_node_ids.push_back(
facade.GetOSMNodeIDOfNode(source_geometry[source_segment_start_coordinate])); facade.GetOSMNodeIDOfNode(source_geometry[source_segment_start_coordinate]));
@@ -89,8 +92,11 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
// segment leading to the target node // segment leading to the target node
geometry.segment_distances.push_back(cumulative_distance); geometry.segment_distances.push_back(cumulative_distance);
const auto target_node_id =
reversed_target ? target_node.reverse_segment_id.id : target_node.forward_segment_id.id;
const auto target_gemetry_id = facade.GetGeometryIndex(target_node_id).id;
const std::vector<DatasourceID> forward_datasources = const std::vector<DatasourceID> forward_datasources =
facade.GetUncompressedForwardDatasources(target_node.packed_geometry_id); facade.GetUncompressedForwardDatasources(target_gemetry_id);
// FIXME if source and target phantoms are on the same segment then duration and weight // FIXME if source and target phantoms are on the same segment then duration and weight
// will be from one projected point till end of segment // will be from one projected point till end of segment
@@ -113,7 +119,7 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
const auto target_segment_end_coordinate = const auto target_segment_end_coordinate =
target_node.fwd_segment_position + (reversed_target ? 0 : 1); target_node.fwd_segment_position + (reversed_target ? 0 : 1);
const std::vector<NodeID> target_geometry = const std::vector<NodeID> target_geometry =
facade.GetUncompressedForwardGeometry(target_node.packed_geometry_id); facade.GetUncompressedForwardGeometry(target_gemetry_id);
geometry.osm_node_ids.push_back( geometry.osm_node_ids.push_back(
facade.GetOSMNodeIDOfNode(target_geometry[target_segment_end_coordinate])); facade.GetOSMNodeIDOfNode(target_geometry[target_segment_end_coordinate]));
+6 -3
View File
@@ -40,7 +40,8 @@ struct NamedSegment
template <std::size_t SegmentNumber> template <std::size_t SegmentNumber>
std::array<std::uint32_t, SegmentNumber> summarizeRoute(const std::vector<PathData> &route_data, std::array<std::uint32_t, SegmentNumber> summarizeRoute(const datafacade::BaseDataFacade &facade,
const std::vector<PathData> &route_data,
const PhantomNode &target_node, const PhantomNode &target_node,
const bool target_traversed_in_reverse) const bool target_traversed_in_reverse)
{ {
@@ -80,8 +81,10 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const std::vector<PathDa
}); });
const auto target_duration = const auto target_duration =
target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration; target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration;
const auto target_node_id = target_traversed_in_reverse ? target_node.reverse_segment_id.id
: target_node.forward_segment_id.id;
if (target_duration > 1) if (target_duration > 1)
segments.push_back({target_duration, index++, target_node.name_id}); segments.push_back({target_duration, index++, facade.GetNameIndex(target_node_id)});
// this makes sure that the segment with the lowest position comes first // this makes sure that the segment with the lowest position comes first
std::sort( std::sort(
segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs) { segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs) {
@@ -183,7 +186,7 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
if (needs_summary) if (needs_summary)
{ {
auto summary_array = detail::summarizeRoute<detail::MAX_USED_SEGMENTS>( auto summary_array = detail::summarizeRoute<detail::MAX_USED_SEGMENTS>(
route_data, target_node, target_traversed_in_reverse); facade, route_data, target_node, target_traversed_in_reverse);
BOOST_ASSERT(detail::MAX_USED_SEGMENTS > 0); BOOST_ASSERT(detail::MAX_USED_SEGMENTS > 0);
BOOST_ASSERT(summary_array.begin() != summary_array.end()); BOOST_ASSERT(summary_array.begin() != summary_array.end());
+35 -21
View File
@@ -49,15 +49,20 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
source_traversed_in_reverse ? source_node.reverse_weight : source_node.forward_weight; source_traversed_in_reverse ? source_node.reverse_weight : source_node.forward_weight;
const EdgeWeight source_duration = const EdgeWeight source_duration =
source_traversed_in_reverse ? source_node.reverse_duration : source_node.forward_duration; source_traversed_in_reverse ? source_node.reverse_duration : source_node.forward_duration;
const auto source_mode = source_traversed_in_reverse ? source_node.backward_travel_mode const auto source_node_id = source_traversed_in_reverse ? source_node.reverse_segment_id.id
: source_node.forward_travel_mode; : source_node.forward_segment_id.id;
const auto source_name_id = facade.GetNameIndex(source_node_id);
const auto source_mode = facade.GetTravelMode(source_node_id);
auto source_classes = facade.GetClasses(facade.GetClassData(source_node_id));
const EdgeWeight target_duration = const EdgeWeight target_duration =
target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration; target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration;
const EdgeWeight target_weight = const EdgeWeight target_weight =
target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight; target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight;
const auto target_mode = target_traversed_in_reverse ? target_node.backward_travel_mode const auto target_node_id = target_traversed_in_reverse ? target_node.reverse_segment_id.id
: target_node.forward_travel_mode; : target_node.forward_segment_id.id;
const auto target_name_id = facade.GetNameIndex(target_node_id);
const auto target_mode = facade.GetTravelMode(target_node_id);
const auto number_of_segments = leg_geometry.GetNumberOfSegments(); const auto number_of_segments = leg_geometry.GetNumberOfSegments();
@@ -82,7 +87,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
IntermediateIntersection::NO_INDEX, IntermediateIntersection::NO_INDEX,
0, 0,
util::guidance::LaneTuple(), util::guidance::LaneTuple(),
{}}; {},
source_classes};
if (leg_data.size() > 0) if (leg_data.size() > 0)
{ {
@@ -95,7 +101,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
// some name changes are not announced in our processing. For these, we have to keep the // some name changes are not announced in our processing. For these, we have to keep the
// first name on the segment // first name on the segment
auto step_name_id = source_node.name_id; auto step_name_id = source_name_id;
for (std::size_t leg_data_index = 0; leg_data_index < leg_data.size(); ++leg_data_index) for (std::size_t leg_data_index = 0; leg_data_index < leg_data.size(); ++leg_data_index)
{ {
const auto &path_point = leg_data[leg_data_index]; const auto &path_point = leg_data[leg_data_index];
@@ -110,13 +116,17 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
const auto ref = facade.GetRefForID(step_name_id); const auto ref = facade.GetRefForID(step_name_id);
const auto pronunciation = facade.GetPronunciationForID(step_name_id); const auto pronunciation = facade.GetPronunciationForID(step_name_id);
const auto destinations = facade.GetDestinationsForID(step_name_id); const auto destinations = facade.GetDestinationsForID(step_name_id);
const auto exits = facade.GetExitsForID(step_name_id);
const auto distance = leg_geometry.segment_distances[segment_index]; const auto distance = leg_geometry.segment_distances[segment_index];
// intersections contain the classes of exiting road
intersection.classes = facade.GetClasses(path_point.classes);
steps.push_back(RouteStep{step_name_id, steps.push_back(RouteStep{step_name_id,
name.to_string(), name.to_string(),
ref.to_string(), ref.to_string(),
pronunciation.to_string(), pronunciation.to_string(),
destinations.to_string(), destinations.to_string(),
exits.to_string(),
NO_ROTARY_NAME, NO_ROTARY_NAME,
NO_ROTARY_NAME, NO_ROTARY_NAME,
segment_duration / 10., segment_duration / 10.,
@@ -134,15 +144,13 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
} }
else else
{ {
step_name_id = target_node.name_id; step_name_id = facade.GetNameIndex(target_node_id);
} }
// extract bearings // extract bearings
bearings = std::make_pair<std::uint16_t, std::uint16_t>( bearings = std::make_pair<std::uint16_t, std::uint16_t>(
path_point.pre_turn_bearing.Get(), path_point.post_turn_bearing.Get()); path_point.pre_turn_bearing.Get(), path_point.post_turn_bearing.Get());
const auto entry_class = facade.GetEntryClass(path_point.entry_classid); const auto bearing_class = facade.GetBearingClass(path_point.turn_via_node);
const auto bearing_class =
facade.GetBearingClass(facade.GetBearingClassID(path_point.turn_via_node));
auto bearing_data = bearing_class.getAvailableBearings(); auto bearing_data = bearing_class.getAvailableBearings();
intersection.in = bearing_class.findMatchingBearing(bearings.first); intersection.in = bearing_class.findMatchingBearing(bearings.first);
intersection.out = bearing_class.findMatchingBearing(bearings.second); intersection.out = bearing_class.findMatchingBearing(bearings.second);
@@ -170,7 +178,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
intersection.entry.clear(); intersection.entry.clear();
for (auto idx : util::irange<std::size_t>(0, intersection.bearings.size())) for (auto idx : util::irange<std::size_t>(0, intersection.bearings.size()))
{ {
intersection.entry.push_back(entry_class.allowsEntry(idx)); intersection.entry.push_back(path_point.entry_class.allowsEntry(idx));
} }
std::int16_t bearing_in_driving_direction = std::int16_t bearing_in_driving_direction =
util::bearing::reverse(std::round(bearings.first)); util::bearing::reverse(std::round(bearings.first));
@@ -188,12 +196,15 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
const auto distance = leg_geometry.segment_distances[segment_index]; const auto distance = leg_geometry.segment_distances[segment_index];
const EdgeWeight duration = segment_duration + target_duration; const EdgeWeight duration = segment_duration + target_duration;
const EdgeWeight weight = segment_weight + target_weight; const EdgeWeight weight = segment_weight + target_weight;
// intersections contain the classes of exiting road
intersection.classes = facade.GetClasses(facade.GetClassData(target_node_id));
BOOST_ASSERT(duration >= 0); BOOST_ASSERT(duration >= 0);
steps.push_back(RouteStep{step_name_id, steps.push_back(RouteStep{step_name_id,
facade.GetNameForID(step_name_id).to_string(), facade.GetNameForID(step_name_id).to_string(),
facade.GetRefForID(step_name_id).to_string(), facade.GetRefForID(step_name_id).to_string(),
facade.GetPronunciationForID(step_name_id).to_string(), facade.GetPronunciationForID(step_name_id).to_string(),
facade.GetDestinationsForID(step_name_id).to_string(), facade.GetDestinationsForID(step_name_id).to_string(),
facade.GetExitsForID(step_name_id).to_string(),
NO_ROTARY_NAME, NO_ROTARY_NAME,
NO_ROTARY_NAME, NO_ROTARY_NAME,
duration / 10., duration / 10.,
@@ -230,11 +241,12 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
BOOST_ASSERT(target_duration >= source_duration || weight == 0); BOOST_ASSERT(target_duration >= source_duration || weight == 0);
const EdgeWeight duration = std::max(0, target_duration - source_duration); const EdgeWeight duration = std::max(0, target_duration - source_duration);
steps.push_back(RouteStep{source_node.name_id, steps.push_back(RouteStep{source_name_id,
facade.GetNameForID(source_node.name_id).to_string(), facade.GetNameForID(source_name_id).to_string(),
facade.GetRefForID(source_node.name_id).to_string(), facade.GetRefForID(source_name_id).to_string(),
facade.GetPronunciationForID(source_node.name_id).to_string(), facade.GetPronunciationForID(source_name_id).to_string(),
facade.GetDestinationsForID(source_node.name_id).to_string(), facade.GetDestinationsForID(source_name_id).to_string(),
facade.GetExitsForID(source_name_id).to_string(),
NO_ROTARY_NAME, NO_ROTARY_NAME,
NO_ROTARY_NAME, NO_ROTARY_NAME,
duration / 10., duration / 10.,
@@ -257,6 +269,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
0, 0,
IntermediateIntersection::NO_INDEX, IntermediateIntersection::NO_INDEX,
util::guidance::LaneTuple(), util::guidance::LaneTuple(),
{},
{}}; {}};
// This step has length zero, the only reason we need it is the target location // This step has length zero, the only reason we need it is the target location
@@ -268,11 +281,12 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
0}; 0};
BOOST_ASSERT(!leg_geometry.locations.empty()); BOOST_ASSERT(!leg_geometry.locations.empty());
steps.push_back(RouteStep{target_node.name_id, steps.push_back(RouteStep{target_name_id,
facade.GetNameForID(target_node.name_id).to_string(), facade.GetNameForID(target_name_id).to_string(),
facade.GetRefForID(target_node.name_id).to_string(), facade.GetRefForID(target_name_id).to_string(),
facade.GetPronunciationForID(target_node.name_id).to_string(), facade.GetPronunciationForID(target_name_id).to_string(),
facade.GetDestinationsForID(target_node.name_id).to_string(), facade.GetDestinationsForID(target_name_id).to_string(),
facade.GetExitsForID(target_name_id).to_string(),
NO_ROTARY_NAME, NO_ROTARY_NAME,
NO_ROTARY_NAME, NO_ROTARY_NAME,
ZERO_DURATION, ZERO_DURATION,
@@ -130,8 +130,14 @@ inline bool haveSameName(const RouteStep &lhs, const RouteStep &rhs)
// ok, bite the sour grape and check the strings already // ok, bite the sour grape and check the strings already
else else
return !util::guidance::requiresNameAnnounced( return !util::guidance::requiresNameAnnounced(lhs.name,
lhs.name, lhs.ref, lhs.pronunciation, rhs.name, rhs.ref, rhs.pronunciation); lhs.ref,
lhs.pronunciation,
lhs.exits,
rhs.name,
rhs.ref,
rhs.pronunciation,
rhs.exits);
} }
// alias for readability, both turn right | left // alias for readability, both turn right | left
+1 -1
View File
@@ -20,7 +20,7 @@ namespace guidance
// as separate maneuvers. // as separate maneuvers.
OSRM_ATTR_WARN_UNUSED OSRM_ATTR_WARN_UNUSED
std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps, std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
const double min_duration_needed_for_lane_change = 10); const double min_distance_needed_for_lane_change = 200);
} // namespace guidance } // namespace guidance
} // namespace engine } // namespace engine
+5
View File
@@ -42,6 +42,7 @@ struct IntermediateIntersection
// turn lane information // turn lane information
util::guidance::LaneTuple lanes; util::guidance::LaneTuple lanes;
extractor::guidance::TurnLaneDescription lane_description; extractor::guidance::TurnLaneDescription lane_description;
std::vector<std::string> classes;
}; };
inline IntermediateIntersection getInvalidIntersection() inline IntermediateIntersection getInvalidIntersection()
@@ -52,6 +53,7 @@ inline IntermediateIntersection getInvalidIntersection()
IntermediateIntersection::NO_INDEX, IntermediateIntersection::NO_INDEX,
IntermediateIntersection::NO_INDEX, IntermediateIntersection::NO_INDEX,
util::guidance::LaneTuple(), util::guidance::LaneTuple(),
{},
{}}; {}};
} }
@@ -62,6 +64,7 @@ struct RouteStep
std::string ref; std::string ref;
std::string pronunciation; std::string pronunciation;
std::string destinations; std::string destinations;
std::string exits;
std::string rotary_name; std::string rotary_name;
std::string rotary_pronunciation; std::string rotary_pronunciation;
double duration; // duration in seconds double duration; // duration in seconds
@@ -114,6 +117,7 @@ inline void RouteStep::Invalidate()
ref.clear(); ref.clear();
pronunciation.clear(); pronunciation.clear();
destinations.clear(); destinations.clear();
exits.clear();
rotary_name.clear(); rotary_name.clear();
rotary_pronunciation.clear(); rotary_pronunciation.clear();
duration = 0; duration = 0;
@@ -178,6 +182,7 @@ inline RouteStep &RouteStep::AdaptStepSignage(const RouteStep &origin)
name = origin.name; name = origin.name;
pronunciation = origin.pronunciation; pronunciation = origin.pronunciation;
destinations = origin.destinations; destinations = origin.destinations;
exits = origin.exits;
ref = origin.ref; ref = origin.ref;
return *this; return *this;
@@ -20,16 +20,6 @@ namespace guidance
OSRM_ATTR_WARN_UNUSED OSRM_ATTR_WARN_UNUSED
std::vector<RouteStep> suppressShortNameSegments(std::vector<RouteStep> steps); std::vector<RouteStep> suppressShortNameSegments(std::vector<RouteStep> steps);
// remove use lane information that is not actually a turn. For post-processing, we need to
// associate lanes with every turn. Some of these use-lane instructions are not required after lane
// anticipation anymore. This function removes all use lane instructions that are not actually used
// anymore since all lanes going straight are used anyhow.
// FIXME this is currently only a heuristic. We need knowledge on which lanes actually might become
// turn lanes. If a straight lane becomes a turn lane, this might be something to consider. Right
// now we bet on lane-anticipation to catch this.
OSRM_ATTR_WARN_UNUSED
std::vector<RouteStep> collapseUseLane(std::vector<RouteStep> steps);
} // namespace guidance } // namespace guidance
} // namespace engine } // namespace engine
} // namespace osrm } // namespace osrm
+2 -2
View File
@@ -63,8 +63,8 @@ struct Hint
friend std::ostream &operator<<(std::ostream &, const Hint &); friend std::ostream &operator<<(std::ostream &, const Hint &);
}; };
static_assert(sizeof(Hint) == 72 + 4, "Hint is bigger than expected"); static_assert(sizeof(Hint) == 64 + 4, "Hint is bigger than expected");
constexpr std::size_t ENCODED_HINT_SIZE = 104; constexpr std::size_t ENCODED_HINT_SIZE = 92;
static_assert(ENCODED_HINT_SIZE / 4 * 3 >= sizeof(Hint), static_assert(ENCODED_HINT_SIZE / 4 * 3 >= sizeof(Hint),
"ENCODED_HINT_SIZE does not match size of Hint"); "ENCODED_HINT_SIZE does not match size of Hint");
} }
+26 -13
View File
@@ -5,6 +5,7 @@
#include "extractor/travel_mode.hpp" #include "extractor/travel_mode.hpp"
#include "engine/phantom_node.hpp" #include "engine/phantom_node.hpp"
#include "osrm/coordinate.hpp" #include "osrm/coordinate.hpp"
#include "util/guidance/entry_class.hpp"
#include "util/guidance/turn_bearing.hpp" #include "util/guidance/turn_bearing.hpp"
#include "util/guidance/turn_lanes.hpp" #include "util/guidance/turn_lanes.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
@@ -16,8 +17,6 @@ namespace osrm
namespace engine namespace engine
{ {
const constexpr unsigned INVALID_EXIT_NR = 0;
struct PathData struct PathData
{ {
// id of via node of the turn // id of via node of the turn
@@ -34,8 +33,10 @@ struct PathData
util::guidance::LaneTupleIdPair lane_data; util::guidance::LaneTupleIdPair lane_data;
// travel mode of the street that leads to the turn // travel mode of the street that leads to the turn
extractor::TravelMode travel_mode : 4; extractor::TravelMode travel_mode : 4;
// user defined classed of the street that leads to the turn
extractor::ClassData classes;
// entry class of the turn, indicating possibility of turns // entry class of the turn, indicating possibility of turns
EntryClassID entry_classid; util::guidance::EntryClass entry_class;
// Source of the speed value on this road segment // Source of the speed value on this road segment
DatasourceID datasource_id; DatasourceID datasource_id;
@@ -49,28 +50,40 @@ struct PathData
struct InternalRouteResult struct InternalRouteResult
{ {
std::vector<std::vector<PathData>> unpacked_path_segments; std::vector<std::vector<PathData>> unpacked_path_segments;
std::vector<PathData> unpacked_alternative;
std::vector<PhantomNodes> segment_end_coordinates; std::vector<PhantomNodes> segment_end_coordinates;
std::vector<bool> source_traversed_in_reverse; std::vector<bool> source_traversed_in_reverse;
std::vector<bool> target_traversed_in_reverse; std::vector<bool> target_traversed_in_reverse;
std::vector<bool> alt_source_traversed_in_reverse; EdgeWeight shortest_path_weight = INVALID_EDGE_WEIGHT;
std::vector<bool> alt_target_traversed_in_reverse;
int shortest_path_length;
int alternative_path_length;
bool is_valid() const { return INVALID_EDGE_WEIGHT != shortest_path_length; } bool is_valid() const { return INVALID_EDGE_WEIGHT != shortest_path_weight; }
bool has_alternative() const { return INVALID_EDGE_WEIGHT != alternative_path_length; }
bool is_via_leg(const std::size_t leg) const bool is_via_leg(const std::size_t leg) const
{ {
return (leg != unpacked_path_segments.size() - 1); return (leg != unpacked_path_segments.size() - 1);
} }
InternalRouteResult() // Note: includes duration for turns, except for at start and end node.
: shortest_path_length(INVALID_EDGE_WEIGHT), alternative_path_length(INVALID_EDGE_WEIGHT) EdgeWeight duration() const
{
EdgeWeight ret{0};
for (const auto &leg : unpacked_path_segments)
for (const auto &segment : leg)
ret += segment.duration_until_turn;
return ret;
}
};
struct InternalManyRoutesResult
{
InternalManyRoutesResult() = default;
InternalManyRoutesResult(InternalRouteResult route) : routes{std::move(route)} {}
InternalManyRoutesResult(std::vector<InternalRouteResult> routes_) : routes{std::move(routes_)}
{ {
} }
std::vector<InternalRouteResult> routes;
}; };
} }
} }
+17 -36
View File
@@ -48,16 +48,12 @@ struct PhantomNode
{ {
PhantomNode() PhantomNode()
: forward_segment_id{SPECIAL_SEGMENTID, false}, : forward_segment_id{SPECIAL_SEGMENTID, false},
reverse_segment_id{SPECIAL_SEGMENTID, false}, reverse_segment_id{SPECIAL_SEGMENTID, false}, forward_weight(INVALID_EDGE_WEIGHT),
name_id(std::numeric_limits<unsigned>::max()), forward_weight(INVALID_EDGE_WEIGHT),
reverse_weight(INVALID_EDGE_WEIGHT), forward_weight_offset(0), reverse_weight_offset(0), reverse_weight(INVALID_EDGE_WEIGHT), forward_weight_offset(0), reverse_weight_offset(0),
forward_duration(MAXIMAL_EDGE_DURATION), reverse_duration(MAXIMAL_EDGE_DURATION), forward_duration(MAXIMAL_EDGE_DURATION), reverse_duration(MAXIMAL_EDGE_DURATION),
forward_duration_offset(0), reverse_duration_offset(0), forward_duration_offset(0), reverse_duration_offset(0), fwd_segment_position(0),
packed_geometry_id(SPECIAL_GEOMETRYID), component{INVALID_COMPONENTID, false}, is_valid_forward_source{false}, is_valid_forward_target{false},
fwd_segment_position(0), forward_travel_mode(TRAVEL_MODE_INACCESSIBLE), is_valid_reverse_source{false}, is_valid_reverse_target{false}
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE), is_valid_forward_source(false),
is_valid_forward_target(false), is_valid_reverse_source(false),
is_valid_reverse_target(false)
{ {
} }
@@ -95,7 +91,7 @@ struct PhantomNode
(reverse_weight != INVALID_EDGE_WEIGHT)) && (reverse_weight != INVALID_EDGE_WEIGHT)) &&
((forward_duration != MAXIMAL_EDGE_DURATION) || ((forward_duration != MAXIMAL_EDGE_DURATION) ||
(reverse_duration != MAXIMAL_EDGE_DURATION)) && (reverse_duration != MAXIMAL_EDGE_DURATION)) &&
(component.id != INVALID_COMPONENTID) && (name_id != INVALID_NAMEID); (component.id != INVALID_COMPONENTID);
} }
bool IsValid(const unsigned number_of_nodes, const util::Coordinate queried_coordinate) const bool IsValid(const unsigned number_of_nodes, const util::Coordinate queried_coordinate) const
@@ -103,7 +99,7 @@ struct PhantomNode
return queried_coordinate == input_location && IsValid(number_of_nodes); return queried_coordinate == input_location && IsValid(number_of_nodes);
} }
bool IsValid() const { return location.IsValid() && (name_id != INVALID_NAMEID); } bool IsValid() const { return location.IsValid(); }
bool IsValidForwardSource() const bool IsValidForwardSource() const
{ {
@@ -126,6 +122,7 @@ struct PhantomNode
template <class OtherT> template <class OtherT>
explicit PhantomNode(const OtherT &other, explicit PhantomNode(const OtherT &other,
ComponentID component,
EdgeWeight forward_weight, EdgeWeight forward_weight,
EdgeWeight reverse_weight, EdgeWeight reverse_weight,
EdgeWeight forward_weight_offset, EdgeWeight forward_weight_offset,
@@ -141,17 +138,13 @@ struct PhantomNode
const util::Coordinate location, const util::Coordinate location,
const util::Coordinate input_location) const util::Coordinate input_location)
: forward_segment_id{other.forward_segment_id}, : forward_segment_id{other.forward_segment_id},
reverse_segment_id{other.reverse_segment_id}, name_id{other.name_id}, reverse_segment_id{other.reverse_segment_id}, forward_weight{forward_weight},
forward_weight{forward_weight}, reverse_weight{reverse_weight}, reverse_weight{reverse_weight}, forward_weight_offset{forward_weight_offset},
forward_weight_offset{forward_weight_offset},
reverse_weight_offset{reverse_weight_offset}, forward_duration{forward_duration}, reverse_weight_offset{reverse_weight_offset}, forward_duration{forward_duration},
reverse_duration{reverse_duration}, forward_duration_offset{forward_duration_offset}, reverse_duration{reverse_duration}, forward_duration_offset{forward_duration_offset},
reverse_duration_offset{reverse_duration_offset}, reverse_duration_offset{reverse_duration_offset},
packed_geometry_id{other.packed_geometry_id}, component{component.id, component.is_tiny}, location{location},
component{other.component.id, other.component.is_tiny}, location{location},
input_location{input_location}, fwd_segment_position{other.fwd_segment_position}, input_location{input_location}, fwd_segment_position{other.fwd_segment_position},
forward_travel_mode{other.forward_travel_mode},
backward_travel_mode{other.backward_travel_mode},
is_valid_forward_source{is_valid_forward_source}, is_valid_forward_source{is_valid_forward_source},
is_valid_forward_target{is_valid_forward_target}, is_valid_forward_target{is_valid_forward_target},
is_valid_reverse_source{is_valid_reverse_source}, is_valid_reverse_source{is_valid_reverse_source},
@@ -161,7 +154,6 @@ struct PhantomNode
SegmentID forward_segment_id; SegmentID forward_segment_id;
SegmentID reverse_segment_id; SegmentID reverse_segment_id;
unsigned name_id;
EdgeWeight forward_weight; EdgeWeight forward_weight;
EdgeWeight reverse_weight; EdgeWeight reverse_weight;
EdgeWeight forward_weight_offset; // TODO: try to remove -> requires path unpacking changes EdgeWeight forward_weight_offset; // TODO: try to remove -> requires path unpacking changes
@@ -170,30 +162,21 @@ struct PhantomNode
EdgeWeight reverse_duration; EdgeWeight reverse_duration;
EdgeWeight forward_duration_offset; // TODO: try to remove -> requires path unpacking changes EdgeWeight forward_duration_offset; // TODO: try to remove -> requires path unpacking changes
EdgeWeight reverse_duration_offset; // TODO: try to remove -> requires path unpacking changes EdgeWeight reverse_duration_offset; // TODO: try to remove -> requires path unpacking changes
unsigned packed_geometry_id; ComponentID component;
struct ComponentType
{
std::uint32_t id : 31;
std::uint32_t is_tiny : 1;
} component;
static_assert(sizeof(ComponentType) == 4, "ComponentType needs to be 4 bytes big");
util::Coordinate location; util::Coordinate location;
util::Coordinate input_location; util::Coordinate input_location;
unsigned short fwd_segment_position; unsigned short fwd_segment_position;
// note 4 bits would suffice for each,
// but the saved byte would be padding anyway
extractor::TravelMode forward_travel_mode : 4;
extractor::TravelMode backward_travel_mode : 4;
// is phantom node valid to be used as source or target // is phantom node valid to be used as source or target
private: private:
bool is_valid_forward_source : 1; unsigned short is_valid_forward_source : 1;
bool is_valid_forward_target : 1; unsigned short is_valid_forward_target : 1;
bool is_valid_reverse_source : 1; unsigned short is_valid_reverse_source : 1;
bool is_valid_reverse_target : 1; unsigned short is_valid_reverse_target : 1;
unsigned short : 12; // Unused padding out to 16 bits (2 bytes)
}; };
static_assert(sizeof(PhantomNode) == 72, "PhantomNode has more padding then expected"); static_assert(sizeof(PhantomNode) == 64, "PhantomNode has more padding then expected");
using PhantomNodePair = std::pair<PhantomNode, PhantomNode>; using PhantomNodePair = std::pair<PhantomNode, PhantomNode>;
@@ -220,7 +203,6 @@ inline std::ostream &operator<<(std::ostream &out, const PhantomNode &pn)
{ {
out << "node1: " << pn.forward_segment_id.id << ", " out << "node1: " << pn.forward_segment_id.id << ", "
<< "node2: " << pn.reverse_segment_id.id << ", " << "node2: " << pn.reverse_segment_id.id << ", "
<< "name: " << pn.name_id << ", "
<< "fwd-w: " << pn.forward_weight << ", " << "fwd-w: " << pn.forward_weight << ", "
<< "rev-w: " << pn.reverse_weight << ", " << "rev-w: " << pn.reverse_weight << ", "
<< "fwd-o: " << pn.forward_weight_offset << ", " << "fwd-o: " << pn.forward_weight_offset << ", "
@@ -229,7 +211,6 @@ inline std::ostream &operator<<(std::ostream &out, const PhantomNode &pn)
<< "rev-d: " << pn.reverse_duration << ", " << "rev-d: " << pn.reverse_duration << ", "
<< "fwd-do: " << pn.forward_duration_offset << ", " << "fwd-do: " << pn.forward_duration_offset << ", "
<< "rev-do: " << pn.reverse_duration_offset << ", " << "rev-do: " << pn.reverse_duration_offset << ", "
<< "geom: " << pn.packed_geometry_id << ", "
<< "comp: " << pn.component.is_tiny << " / " << pn.component.id << ", " << "comp: " << pn.component.is_tiny << " / " << pn.component.id << ", "
<< "pos: " << pn.fwd_segment_position << ", " << "pos: " << pn.fwd_segment_position << ", "
<< "loc: " << pn.location; << "loc: " << pn.location;
+37 -13
View File
@@ -16,6 +16,8 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <util/log.hpp>
namespace osrm namespace osrm
{ {
namespace engine namespace engine
@@ -118,9 +120,14 @@ class BasePlugin
const bool use_hints = !parameters.hints.empty(); const bool use_hints = !parameters.hints.empty();
const bool use_bearings = !parameters.bearings.empty(); const bool use_bearings = !parameters.bearings.empty();
const bool use_approaches = !parameters.approaches.empty();
for (const auto i : util::irange<std::size_t>(0UL, parameters.coordinates.size())) for (const auto i : util::irange<std::size_t>(0UL, parameters.coordinates.size()))
{ {
Approach approach = engine::Approach::UNRESTRICTED;
if (use_approaches && parameters.approaches[i])
approach = parameters.approaches[i].get();
if (use_hints && parameters.hints[i] && if (use_hints && parameters.hints[i] &&
parameters.hints[i]->IsValid(parameters.coordinates[i], facade)) parameters.hints[i]->IsValid(parameters.coordinates[i], facade))
{ {
@@ -137,12 +144,13 @@ class BasePlugin
facade.NearestPhantomNodesInRange(parameters.coordinates[i], facade.NearestPhantomNodesInRange(parameters.coordinates[i],
radiuses[i], radiuses[i],
parameters.bearings[i]->bearing, parameters.bearings[i]->bearing,
parameters.bearings[i]->range); parameters.bearings[i]->range,
approach);
} }
else else
{ {
phantom_nodes[i] = phantom_nodes[i] = facade.NearestPhantomNodesInRange(
facade.NearestPhantomNodesInRange(parameters.coordinates[i], radiuses[i]); parameters.coordinates[i], radiuses[i], approach);
} }
} }
@@ -160,10 +168,15 @@ class BasePlugin
const bool use_hints = !parameters.hints.empty(); const bool use_hints = !parameters.hints.empty();
const bool use_bearings = !parameters.bearings.empty(); const bool use_bearings = !parameters.bearings.empty();
const bool use_radiuses = !parameters.radiuses.empty(); const bool use_radiuses = !parameters.radiuses.empty();
const bool use_approaches = !parameters.approaches.empty();
BOOST_ASSERT(parameters.IsValid()); BOOST_ASSERT(parameters.IsValid());
for (const auto i : util::irange<std::size_t>(0UL, parameters.coordinates.size())) for (const auto i : util::irange<std::size_t>(0UL, parameters.coordinates.size()))
{ {
Approach approach = engine::Approach::UNRESTRICTED;
if (use_approaches && parameters.approaches[i])
approach = parameters.approaches[i].get();
if (use_hints && parameters.hints[i] && if (use_hints && parameters.hints[i] &&
parameters.hints[i]->IsValid(parameters.coordinates[i], facade)) parameters.hints[i]->IsValid(parameters.coordinates[i], facade))
{ {
@@ -183,27 +196,31 @@ class BasePlugin
number_of_results, number_of_results,
*parameters.radiuses[i], *parameters.radiuses[i],
parameters.bearings[i]->bearing, parameters.bearings[i]->bearing,
parameters.bearings[i]->range); parameters.bearings[i]->range,
approach);
} }
else else
{ {
phantom_nodes[i] = facade.NearestPhantomNodes(parameters.coordinates[i], phantom_nodes[i] = facade.NearestPhantomNodes(parameters.coordinates[i],
number_of_results, number_of_results,
parameters.bearings[i]->bearing, parameters.bearings[i]->bearing,
parameters.bearings[i]->range); parameters.bearings[i]->range,
approach);
} }
} }
else else
{ {
if (use_radiuses && parameters.radiuses[i]) if (use_radiuses && parameters.radiuses[i])
{ {
phantom_nodes[i] = facade.NearestPhantomNodes( phantom_nodes[i] = facade.NearestPhantomNodes(parameters.coordinates[i],
parameters.coordinates[i], number_of_results, *parameters.radiuses[i]); number_of_results,
*parameters.radiuses[i],
approach);
} }
else else
{ {
phantom_nodes[i] = phantom_nodes[i] = facade.NearestPhantomNodes(
facade.NearestPhantomNodes(parameters.coordinates[i], number_of_results); parameters.coordinates[i], number_of_results, approach);
} }
} }
@@ -224,10 +241,15 @@ class BasePlugin
const bool use_hints = !parameters.hints.empty(); const bool use_hints = !parameters.hints.empty();
const bool use_bearings = !parameters.bearings.empty(); const bool use_bearings = !parameters.bearings.empty();
const bool use_radiuses = !parameters.radiuses.empty(); const bool use_radiuses = !parameters.radiuses.empty();
const bool use_approaches = !parameters.approaches.empty();
BOOST_ASSERT(parameters.IsValid()); BOOST_ASSERT(parameters.IsValid());
for (const auto i : util::irange<std::size_t>(0UL, parameters.coordinates.size())) for (const auto i : util::irange<std::size_t>(0UL, parameters.coordinates.size()))
{ {
Approach approach = engine::Approach::UNRESTRICTED;
if (use_approaches && parameters.approaches[i])
approach = parameters.approaches[i].get();
if (use_hints && parameters.hints[i] && if (use_hints && parameters.hints[i] &&
parameters.hints[i]->IsValid(parameters.coordinates[i], facade)) parameters.hints[i]->IsValid(parameters.coordinates[i], facade))
{ {
@@ -245,7 +267,8 @@ class BasePlugin
parameters.coordinates[i], parameters.coordinates[i],
*parameters.radiuses[i], *parameters.radiuses[i],
parameters.bearings[i]->bearing, parameters.bearings[i]->bearing,
parameters.bearings[i]->range); parameters.bearings[i]->range,
approach);
} }
else else
{ {
@@ -253,7 +276,8 @@ class BasePlugin
facade.NearestPhantomNodeWithAlternativeFromBigComponent( facade.NearestPhantomNodeWithAlternativeFromBigComponent(
parameters.coordinates[i], parameters.coordinates[i],
parameters.bearings[i]->bearing, parameters.bearings[i]->bearing,
parameters.bearings[i]->range); parameters.bearings[i]->range,
approach);
} }
} }
else else
@@ -262,13 +286,13 @@ class BasePlugin
{ {
phantom_node_pairs[i] = phantom_node_pairs[i] =
facade.NearestPhantomNodeWithAlternativeFromBigComponent( facade.NearestPhantomNodeWithAlternativeFromBigComponent(
parameters.coordinates[i], *parameters.radiuses[i]); parameters.coordinates[i], *parameters.radiuses[i], approach);
} }
else else
{ {
phantom_node_pairs[i] = phantom_node_pairs[i] =
facade.NearestPhantomNodeWithAlternativeFromBigComponent( facade.NearestPhantomNodeWithAlternativeFromBigComponent(
parameters.coordinates[i]); parameters.coordinates[i], approach);
} }
} }
+2 -1
View File
@@ -27,9 +27,10 @@ class ViaRoutePlugin final : public BasePlugin
{ {
private: private:
const int max_locations_viaroute; const int max_locations_viaroute;
const int max_alternatives;
public: public:
explicit ViaRoutePlugin(int max_locations_viaroute); explicit ViaRoutePlugin(int max_locations_viaroute, int max_alternatives);
Status HandleRequest(const datafacade::ContiguousInternalMemoryDataFacadeBase &facade, Status HandleRequest(const datafacade::ContiguousInternalMemoryDataFacadeBase &facade,
const RoutingAlgorithmsInterface &algorithms, const RoutingAlgorithmsInterface &algorithms,
+26 -4
View File
@@ -14,10 +14,9 @@ namespace engine
{ {
namespace detail namespace detail
{ {
constexpr double POLYLINE_DECODING_PRECISION = 1e5;
constexpr double POLYLINE_TO_COORDINATE = COORDINATE_PRECISION / POLYLINE_DECODING_PRECISION;
std::string encode(std::vector<int> &numbers); std::string encode(std::vector<int> &numbers);
std::int32_t decode_polyline_integer(std::string::const_iterator &first,
std::string::const_iterator last);
} }
using CoordVectorForwardIter = std::vector<util::Coordinate>::const_iterator; using CoordVectorForwardIter = std::vector<util::Coordinate>::const_iterator;
// Encodes geometry into polyline format. // Encodes geometry into polyline format.
@@ -57,7 +56,30 @@ std::string encodePolyline(CoordVectorForwardIter begin, CoordVectorForwardIter
// Decodes geometry from polyline format // Decodes geometry from polyline format
// See: https://developers.google.com/maps/documentation/utilities/polylinealgorithm // See: https://developers.google.com/maps/documentation/utilities/polylinealgorithm
std::vector<util::Coordinate> decodePolyline(const std::string &polyline);
template <unsigned POLYLINE_PRECISION = 100000>
std::vector<util::Coordinate> decodePolyline(const std::string &polyline)
{
double polyline_to_coordinate = COORDINATE_PRECISION / POLYLINE_PRECISION;
std::vector<util::Coordinate> coordinates;
std::int32_t latitude = 0, longitude = 0;
std::string::const_iterator first = polyline.begin();
const std::string::const_iterator last = polyline.end();
while (first != last)
{
const auto dlat = detail::decode_polyline_integer(first, last);
const auto dlon = detail::decode_polyline_integer(first, last);
latitude += dlat;
longitude += dlon;
coordinates.emplace_back(util::Coordinate{
util::FixedLongitude{static_cast<std::int32_t>(longitude * polyline_to_coordinate)},
util::FixedLatitude{static_cast<std::int32_t>(latitude * polyline_to_coordinate)}});
}
return coordinates;
}
} }
} }
+17 -39
View File
@@ -19,8 +19,9 @@ namespace engine
class RoutingAlgorithmsInterface class RoutingAlgorithmsInterface
{ {
public: public:
virtual InternalRouteResult virtual InternalManyRoutesResult
AlternativePathSearch(const PhantomNodes &phantom_node_pair) const = 0; AlternativePathSearch(const PhantomNodes &phantom_node_pair,
unsigned number_of_alternatives) const = 0;
virtual InternalRouteResult virtual InternalRouteResult
ShortestPathSearch(const std::vector<PhantomNodes> &phantom_node_pair, ShortestPathSearch(const std::vector<PhantomNodes> &phantom_node_pair,
@@ -65,8 +66,9 @@ template <typename Algorithm> class RoutingAlgorithms final : public RoutingAlgo
virtual ~RoutingAlgorithms() = default; virtual ~RoutingAlgorithms() = default;
InternalRouteResult InternalManyRoutesResult
AlternativePathSearch(const PhantomNodes &phantom_node_pair) const final override; AlternativePathSearch(const PhantomNodes &phantom_node_pair,
unsigned number_of_alternatives) const final override;
InternalRouteResult ShortestPathSearch( InternalRouteResult ShortestPathSearch(
const std::vector<PhantomNodes> &phantom_node_pair, const std::vector<PhantomNodes> &phantom_node_pair,
@@ -129,10 +131,12 @@ template <typename Algorithm> class RoutingAlgorithms final : public RoutingAlgo
}; };
template <typename Algorithm> template <typename Algorithm>
InternalRouteResult InternalManyRoutesResult
RoutingAlgorithms<Algorithm>::AlternativePathSearch(const PhantomNodes &phantom_node_pair) const RoutingAlgorithms<Algorithm>::AlternativePathSearch(const PhantomNodes &phantom_node_pair,
unsigned number_of_alternatives) const
{ {
return routing_algorithms::ch::alternativePathSearch(heaps, facade, phantom_node_pair); return routing_algorithms::alternativePathSearch(
heaps, facade, phantom_node_pair, number_of_alternatives);
} }
template <typename Algorithm> template <typename Algorithm>
@@ -157,7 +161,7 @@ RoutingAlgorithms<Algorithm>::ManyToManySearch(const std::vector<PhantomNode> &p
const std::vector<std::size_t> &source_indices, const std::vector<std::size_t> &source_indices,
const std::vector<std::size_t> &target_indices) const const std::vector<std::size_t> &target_indices) const
{ {
return routing_algorithms::ch::manyToManySearch( return routing_algorithms::manyToManySearch(
heaps, facade, phantom_nodes, source_indices, target_indices); heaps, facade, phantom_nodes, source_indices, target_indices);
} }
@@ -188,8 +192,9 @@ inline std::vector<routing_algorithms::TurnData> RoutingAlgorithms<Algorithm>::G
// CoreCH overrides // CoreCH overrides
template <> template <>
InternalRouteResult inline RoutingAlgorithms< InternalManyRoutesResult inline RoutingAlgorithms<
routing_algorithms::corech::Algorithm>::AlternativePathSearch(const PhantomNodes &) const routing_algorithms::corech::Algorithm>::AlternativePathSearch(const PhantomNodes &,
unsigned) const
{ {
throw util::exception("AlternativePathSearch is disabled due to performance reasons"); throw util::exception("AlternativePathSearch is disabled due to performance reasons");
} }
@@ -203,34 +208,7 @@ RoutingAlgorithms<routing_algorithms::corech::Algorithm>::ManyToManySearch(
{ {
throw util::exception("ManyToManySearch is disabled due to performance reasons"); throw util::exception("ManyToManySearch is disabled due to performance reasons");
} }
} // ns engine
// MLD overrides for not implemented } // ns osrm
template <>
InternalRouteResult inline RoutingAlgorithms<
routing_algorithms::mld::Algorithm>::AlternativePathSearch(const PhantomNodes &) const
{
throw util::exception("AlternativePathSearch is not implemented");
}
template <>
inline std::vector<EdgeWeight>
RoutingAlgorithms<routing_algorithms::mld::Algorithm>::ManyToManySearch(
const std::vector<PhantomNode> &,
const std::vector<std::size_t> &,
const std::vector<std::size_t> &) const
{
throw util::exception("ManyToManySearch is not implemented");
}
template <>
inline std::vector<routing_algorithms::TurnData>
RoutingAlgorithms<routing_algorithms::mld::Algorithm>::GetTileTurns(
const std::vector<datafacade::BaseDataFacade::RTreeLeaf> &,
const std::vector<std::size_t> &) const
{
throw util::exception("GetTileTurns is not implemented");
}
}
}
#endif #endif
@@ -15,13 +15,19 @@ namespace engine
{ {
namespace routing_algorithms namespace routing_algorithms
{ {
namespace ch
{ InternalManyRoutesResult
InternalRouteResult alternativePathSearch(SearchEngineData<ch::Algorithm> &search_engine_data,
alternativePathSearch(SearchEngineData<Algorithm> &search_engine_data, const datafacade::ContiguousInternalMemoryDataFacade<ch::Algorithm> &facade,
const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade, const PhantomNodes &phantom_node_pair,
const PhantomNodes &phantom_node_pair); unsigned number_of_alternatives);
} // namespace ch
InternalManyRoutesResult
alternativePathSearch(SearchEngineData<mld::Algorithm> &search_engine_data,
const datafacade::ContiguousInternalMemoryDataFacade<mld::Algorithm> &facade,
const PhantomNodes &phantom_node_pair,
unsigned number_of_alternatives);
} // namespace routing_algorithms } // namespace routing_algorithms
} // namespace engine } // namespace engine
} // namespace osrm } // namespace osrm
@@ -21,20 +21,11 @@ namespace routing_algorithms
/// by the previous route. /// by the previous route.
/// This variation is only an optimazation for graphs with slow queries, for example /// This variation is only an optimazation for graphs with slow queries, for example
/// not fully contracted graphs. /// not fully contracted graphs.
InternalRouteResult directShortestPathSearch( template <typename Algorithm>
SearchEngineData<ch::Algorithm> &engine_working_data, InternalRouteResult
const datafacade::ContiguousInternalMemoryDataFacade<ch::Algorithm> &facade, directShortestPathSearch(SearchEngineData<Algorithm> &engine_working_data,
const PhantomNodes &phantom_nodes); const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
const PhantomNodes &phantom_nodes);
InternalRouteResult directShortestPathSearch(
SearchEngineData<corech::Algorithm> &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<corech::Algorithm> &facade,
const PhantomNodes &phantom_nodes);
InternalRouteResult directShortestPathSearch(
SearchEngineData<mld::Algorithm> &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<mld::Algorithm> &facade,
const PhantomNodes &phantom_nodes);
} // namespace routing_algorithms } // namespace routing_algorithms
} // namespace engine } // namespace engine
@@ -16,15 +16,13 @@ namespace engine
namespace routing_algorithms namespace routing_algorithms
{ {
namespace ch template <typename Algorithm>
{
std::vector<EdgeWeight> std::vector<EdgeWeight>
manyToManySearch(SearchEngineData<Algorithm> &engine_working_data, manyToManySearch(SearchEngineData<Algorithm> &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade, const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
const std::vector<PhantomNode> &phantom_nodes, const std::vector<PhantomNode> &phantom_nodes,
const std::vector<std::size_t> &source_indices, const std::vector<std::size_t> &source_indices,
const std::vector<std::size_t> &target_indices); const std::vector<std::size_t> &target_indices);
} // namespace ch
} // namespace routing_algorithms } // namespace routing_algorithms
} // namespace engine } // namespace engine
@@ -6,6 +6,7 @@
#include "engine/algorithm.hpp" #include "engine/algorithm.hpp"
#include "engine/datafacade/contiguous_internalmem_datafacade.hpp" #include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
#include "engine/internal_route_result.hpp" #include "engine/internal_route_result.hpp"
#include "engine/phantom_node.hpp"
#include "engine/search_engine_data.hpp" #include "engine/search_engine_data.hpp"
#include "util/coordinate_calculation.hpp" #include "util/coordinate_calculation.hpp"
@@ -38,14 +39,10 @@ static constexpr bool REVERSE_DIRECTION = false;
static constexpr bool DO_NOT_FORCE_LOOPS = false; static constexpr bool DO_NOT_FORCE_LOOPS = false;
bool needsLoopForward(const PhantomNode &source_phantom, const PhantomNode &target_phantom); bool needsLoopForward(const PhantomNode &source_phantom, const PhantomNode &target_phantom);
bool needsLoopBackwards(const PhantomNode &source_phantom, const PhantomNode &target_phantom); bool needsLoopBackwards(const PhantomNode &source_phantom, const PhantomNode &target_phantom);
void insertSourceInHeap(SearchEngineData<ch::Algorithm>::ManyToManyQueryHeap &heap, bool needsLoopForward(const PhantomNodes &phantoms);
const PhantomNode &phantom_node); bool needsLoopBackwards(const PhantomNodes &phantoms);
void insertTargetInHeap(SearchEngineData<ch::Algorithm>::ManyToManyQueryHeap &heap,
const PhantomNode &phantom_node);
template <typename Heap> template <typename Heap>
void insertNodesInHeaps(Heap &forward_heap, Heap &reverse_heap, const PhantomNodes &nodes) void insertNodesInHeaps(Heap &forward_heap, Heap &reverse_heap, const PhantomNodes &nodes)
@@ -81,39 +78,74 @@ void insertNodesInHeaps(Heap &forward_heap, Heap &reverse_heap, const PhantomNod
} }
} }
template <typename ManyToManyQueryHeap>
void insertSourceInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_node)
{
if (phantom_node.IsValidForwardSource())
{
heap.Insert(phantom_node.forward_segment_id.id,
-phantom_node.GetForwardWeightPlusOffset(),
{phantom_node.forward_segment_id.id, -phantom_node.GetForwardDuration()});
}
if (phantom_node.IsValidReverseSource())
{
heap.Insert(phantom_node.reverse_segment_id.id,
-phantom_node.GetReverseWeightPlusOffset(),
{phantom_node.reverse_segment_id.id, -phantom_node.GetReverseDuration()});
}
}
template <typename ManyToManyQueryHeap>
void insertTargetInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_node)
{
if (phantom_node.IsValidForwardTarget())
{
heap.Insert(phantom_node.forward_segment_id.id,
phantom_node.GetForwardWeightPlusOffset(),
{phantom_node.forward_segment_id.id, phantom_node.GetForwardDuration()});
}
if (phantom_node.IsValidReverseTarget())
{
heap.Insert(phantom_node.reverse_segment_id.id,
phantom_node.GetReverseWeightPlusOffset(),
{phantom_node.reverse_segment_id.id, phantom_node.GetReverseDuration()});
}
}
template <typename FacadeT> template <typename FacadeT>
void annotatePath(const FacadeT &facade, void annotatePath(const FacadeT &facade,
const NodeID source_node,
const NodeID target_node,
const std::vector<EdgeID> &unpacked_edges,
const PhantomNodes &phantom_node_pair, const PhantomNodes &phantom_node_pair,
const std::vector<NodeID> &unpacked_nodes,
const std::vector<EdgeID> &unpacked_edges,
std::vector<PathData> &unpacked_path) std::vector<PathData> &unpacked_path)
{ {
BOOST_ASSERT(source_node != SPECIAL_NODEID && target_node != SPECIAL_NODEID); BOOST_ASSERT(!unpacked_nodes.empty());
BOOST_ASSERT(!unpacked_edges.empty() || source_node == target_node); BOOST_ASSERT(unpacked_nodes.size() == unpacked_edges.size() + 1);
const auto source_node_id = unpacked_nodes.front();
const auto target_node_id = unpacked_nodes.back();
const bool start_traversed_in_reverse = const bool start_traversed_in_reverse =
phantom_node_pair.source_phantom.forward_segment_id.id != source_node; phantom_node_pair.source_phantom.forward_segment_id.id != source_node_id;
const bool target_traversed_in_reverse = const bool target_traversed_in_reverse =
phantom_node_pair.target_phantom.forward_segment_id.id != target_node; phantom_node_pair.target_phantom.forward_segment_id.id != target_node_id;
BOOST_ASSERT(phantom_node_pair.source_phantom.forward_segment_id.id == source_node || BOOST_ASSERT(phantom_node_pair.source_phantom.forward_segment_id.id == source_node_id ||
phantom_node_pair.source_phantom.reverse_segment_id.id == source_node); phantom_node_pair.source_phantom.reverse_segment_id.id == source_node_id);
BOOST_ASSERT(phantom_node_pair.target_phantom.forward_segment_id.id == target_node || BOOST_ASSERT(phantom_node_pair.target_phantom.forward_segment_id.id == target_node_id ||
phantom_node_pair.target_phantom.reverse_segment_id.id == target_node); phantom_node_pair.target_phantom.reverse_segment_id.id == target_node_id);
for (auto edge_id : unpacked_edges) auto node_from = unpacked_nodes.begin(), node_last = std::prev(unpacked_nodes.end());
for (auto edge = unpacked_edges.begin(); node_from != node_last; ++node_from, ++edge)
{ {
const auto &edge_data = facade.GetEdgeData(edge_id); const auto &edge_data = facade.GetEdgeData(*edge);
const auto turn_id = edge_data.turn_id; // edge-based node ID const auto turn_id = edge_data.turn_id; // edge-based graph edge index
const auto name_index = facade.GetNameIndexFromEdgeID(turn_id); const auto node_id = *node_from; // edge-based graph node index
const auto name_index = facade.GetNameIndex(node_id);
const auto turn_instruction = facade.GetTurnInstructionForEdgeID(turn_id); const auto turn_instruction = facade.GetTurnInstructionForEdgeID(turn_id);
const extractor::TravelMode travel_mode = const extractor::TravelMode travel_mode = facade.GetTravelMode(node_id);
(unpacked_path.empty() && start_traversed_in_reverse) const auto classes = facade.GetClassData(node_id);
? phantom_node_pair.source_phantom.backward_travel_mode
: facade.GetTravelModeForEdgeID(turn_id);
const auto geometry_index = facade.GetGeometryIndexForEdgeID(turn_id); const auto geometry_index = facade.GetGeometryIndex(node_id);
std::vector<NodeID> id_vector; std::vector<NodeID> id_vector;
std::vector<EdgeWeight> weight_vector; std::vector<EdgeWeight> weight_vector;
@@ -158,7 +190,8 @@ void annotatePath(const FacadeT &facade,
extractor::guidance::TurnInstruction::NO_TURN(), extractor::guidance::TurnInstruction::NO_TURN(),
{{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID}, {{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID},
travel_mode, travel_mode,
INVALID_ENTRY_CLASSID, classes,
EMPTY_ENTRY_CLASS,
datasource_vector[segment_idx], datasource_vector[segment_idx],
util::guidance::TurnBearing(0), util::guidance::TurnBearing(0),
util::guidance::TurnBearing(0)}); util::guidance::TurnBearing(0)});
@@ -167,7 +200,7 @@ void annotatePath(const FacadeT &facade,
if (facade.HasLaneData(turn_id)) if (facade.HasLaneData(turn_id))
unpacked_path.back().lane_data = facade.GetLaneData(turn_id); unpacked_path.back().lane_data = facade.GetLaneData(turn_id);
unpacked_path.back().entry_classid = facade.GetEntryClassID(turn_id); unpacked_path.back().entry_class = facade.GetEntryClass(turn_id);
unpacked_path.back().turn_instruction = turn_instruction; unpacked_path.back().turn_instruction = turn_instruction;
unpacked_path.back().duration_until_turn += facade.GetDurationPenaltyForEdgeID(turn_id); unpacked_path.back().duration_until_turn += facade.GetDurationPenaltyForEdgeID(turn_id);
unpacked_path.back().weight_until_turn += facade.GetWeightPenaltyForEdgeID(turn_id); unpacked_path.back().weight_until_turn += facade.GetWeightPenaltyForEdgeID(turn_id);
@@ -180,23 +213,16 @@ void annotatePath(const FacadeT &facade,
std::vector<EdgeWeight> weight_vector; std::vector<EdgeWeight> weight_vector;
std::vector<EdgeWeight> duration_vector; std::vector<EdgeWeight> duration_vector;
std::vector<DatasourceID> datasource_vector; std::vector<DatasourceID> datasource_vector;
const bool is_local_path = (phantom_node_pair.source_phantom.packed_geometry_id == const auto source_geometry_id = facade.GetGeometryIndex(source_node_id).id;
phantom_node_pair.target_phantom.packed_geometry_id) && const auto target_geometry_id = facade.GetGeometryIndex(target_node_id).id;
unpacked_path.empty(); const auto is_local_path = source_geometry_id == target_geometry_id && unpacked_path.empty();
if (target_traversed_in_reverse) if (target_traversed_in_reverse)
{ {
id_vector = facade.GetUncompressedReverseGeometry( id_vector = facade.GetUncompressedReverseGeometry(target_geometry_id);
phantom_node_pair.target_phantom.packed_geometry_id); weight_vector = facade.GetUncompressedReverseWeights(target_geometry_id);
duration_vector = facade.GetUncompressedReverseDurations(target_geometry_id);
weight_vector = facade.GetUncompressedReverseWeights( datasource_vector = facade.GetUncompressedReverseDatasources(target_geometry_id);
phantom_node_pair.target_phantom.packed_geometry_id);
duration_vector = facade.GetUncompressedReverseDurations(
phantom_node_pair.target_phantom.packed_geometry_id);
datasource_vector = facade.GetUncompressedReverseDatasources(
phantom_node_pair.target_phantom.packed_geometry_id);
if (is_local_path) if (is_local_path)
{ {
@@ -214,17 +240,10 @@ void annotatePath(const FacadeT &facade,
} }
end_index = phantom_node_pair.target_phantom.fwd_segment_position; end_index = phantom_node_pair.target_phantom.fwd_segment_position;
id_vector = facade.GetUncompressedForwardGeometry( id_vector = facade.GetUncompressedForwardGeometry(target_geometry_id);
phantom_node_pair.target_phantom.packed_geometry_id); weight_vector = facade.GetUncompressedForwardWeights(target_geometry_id);
duration_vector = facade.GetUncompressedForwardDurations(target_geometry_id);
weight_vector = facade.GetUncompressedForwardWeights( datasource_vector = facade.GetUncompressedForwardDatasources(target_geometry_id);
phantom_node_pair.target_phantom.packed_geometry_id);
duration_vector = facade.GetUncompressedForwardDurations(
phantom_node_pair.target_phantom.packed_geometry_id);
datasource_vector = facade.GetUncompressedForwardDatasources(
phantom_node_pair.target_phantom.packed_geometry_id);
} }
// Given the following compressed geometry: // Given the following compressed geometry:
@@ -238,20 +257,20 @@ void annotatePath(const FacadeT &facade,
(start_index < end_index ? ++segment_idx : --segment_idx)) (start_index < end_index ? ++segment_idx : --segment_idx))
{ {
BOOST_ASSERT(segment_idx < id_vector.size() - 1); BOOST_ASSERT(segment_idx < id_vector.size() - 1);
BOOST_ASSERT(phantom_node_pair.target_phantom.forward_travel_mode > 0); BOOST_ASSERT(facade.GetTravelMode(target_node_id) > 0);
unpacked_path.push_back(PathData{ unpacked_path.push_back(
id_vector[start_index < end_index ? segment_idx + 1 : segment_idx - 1], PathData{id_vector[start_index < end_index ? segment_idx + 1 : segment_idx - 1],
phantom_node_pair.target_phantom.name_id, facade.GetNameIndex(target_node_id),
weight_vector[segment_idx], weight_vector[segment_idx],
duration_vector[segment_idx], duration_vector[segment_idx],
extractor::guidance::TurnInstruction::NO_TURN(), extractor::guidance::TurnInstruction::NO_TURN(),
{{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID}, {{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID},
target_traversed_in_reverse ? phantom_node_pair.target_phantom.backward_travel_mode facade.GetTravelMode(target_node_id),
: phantom_node_pair.target_phantom.forward_travel_mode, facade.GetClassData(target_node_id),
INVALID_ENTRY_CLASSID, EMPTY_ENTRY_CLASS,
datasource_vector[segment_idx], datasource_vector[segment_idx],
util::guidance::TurnBearing(0), util::guidance::TurnBearing(0),
util::guidance::TurnBearing(0)}); util::guidance::TurnBearing(0)});
} }
if (unpacked_path.size() > 0) if (unpacked_path.size() > 0)
@@ -310,17 +329,19 @@ double getPathDistance(const datafacade::ContiguousInternalMemoryDataFacade<Algo
using util::coordinate_calculation::detail::EARTH_RADIUS; using util::coordinate_calculation::detail::EARTH_RADIUS;
double distance = 0; double distance = 0;
double prev_lat = static_cast<double>(toFloating(source_phantom.location.lat)) * DEGREE_TO_RAD; double prev_lat =
double prev_lon = static_cast<double>(toFloating(source_phantom.location.lon)) * DEGREE_TO_RAD; static_cast<double>(util::toFloating(source_phantom.location.lat)) * DEGREE_TO_RAD;
double prev_lon =
static_cast<double>(util::toFloating(source_phantom.location.lon)) * DEGREE_TO_RAD;
double prev_cos = std::cos(prev_lat); double prev_cos = std::cos(prev_lat);
for (const auto &p : unpacked_path) for (const auto &p : unpacked_path)
{ {
const auto current_coordinate = facade.GetCoordinateOfNode(p.turn_via_node); const auto current_coordinate = facade.GetCoordinateOfNode(p.turn_via_node);
const double current_lat = const double current_lat =
static_cast<double>(toFloating(current_coordinate.lat)) * DEGREE_TO_RAD; static_cast<double>(util::toFloating(current_coordinate.lat)) * DEGREE_TO_RAD;
const double current_lon = const double current_lon =
static_cast<double>(toFloating(current_coordinate.lon)) * DEGREE_TO_RAD; static_cast<double>(util::toFloating(current_coordinate.lon)) * DEGREE_TO_RAD;
const double current_cos = std::cos(current_lat); const double current_cos = std::cos(current_lat);
const double sin_dlon = std::sin((prev_lon - current_lon) / 2.0); const double sin_dlon = std::sin((prev_lon - current_lon) / 2.0);
@@ -336,9 +357,9 @@ double getPathDistance(const datafacade::ContiguousInternalMemoryDataFacade<Algo
} }
const double current_lat = const double current_lat =
static_cast<double>(toFloating(target_phantom.location.lat)) * DEGREE_TO_RAD; static_cast<double>(util::toFloating(target_phantom.location.lat)) * DEGREE_TO_RAD;
const double current_lon = const double current_lon =
static_cast<double>(toFloating(target_phantom.location.lon)) * DEGREE_TO_RAD; static_cast<double>(util::toFloating(target_phantom.location.lon)) * DEGREE_TO_RAD;
const double current_cos = std::cos(current_lat); const double current_cos = std::cos(current_lat);
const double sin_dlon = std::sin((prev_lon - current_lon) / 2.0); const double sin_dlon = std::sin((prev_lon - current_lon) / 2.0);
@@ -351,6 +372,39 @@ double getPathDistance(const datafacade::ContiguousInternalMemoryDataFacade<Algo
return distance; return distance;
} }
template <typename AlgorithmT>
InternalRouteResult
extractRoute(const datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT> &facade,
const EdgeWeight weight,
const PhantomNodes &phantom_nodes,
const std::vector<NodeID> &unpacked_nodes,
const std::vector<EdgeID> &unpacked_edges)
{
InternalRouteResult raw_route_data;
raw_route_data.segment_end_coordinates = {phantom_nodes};
// No path found for both target nodes?
if (INVALID_EDGE_WEIGHT == weight)
{
return raw_route_data;
}
raw_route_data.shortest_path_weight = weight;
raw_route_data.unpacked_path_segments.resize(1);
raw_route_data.source_traversed_in_reverse.push_back(
(unpacked_nodes.front() != phantom_nodes.source_phantom.forward_segment_id.id));
raw_route_data.target_traversed_in_reverse.push_back(
(unpacked_nodes.back() != phantom_nodes.target_phantom.forward_segment_id.id));
annotatePath(facade,
phantom_nodes,
unpacked_nodes,
unpacked_edges,
raw_route_data.unpacked_path_segments.front());
return raw_route_data;
}
} // namespace routing_algorithms } // namespace routing_algorithms
} // namespace engine } // namespace engine
} // namespace osrm } // namespace osrm

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