Compare commits

..

571 Commits

Author SHA1 Message Date
Patrick Niklaus 300d901618 Merge branch 'develop' 2015-06-22 13:06:50 +02:00
Patrick Niklaus 1cb72acd27 Remove unused header 2015-06-22 08:36:21 +02:00
Patrick Niklaus a17776cb5f Check if FingerPrint is trivial. TODO: Add this for all other data that is going to be serialized 2015-06-19 18:10:49 +02:00
Patrick Niklaus 94b749ab00 Fix magic number check for fingerprint 2015-06-19 17:51:35 +02:00
Patrick Niklaus 5fc0d284cb Revert "Simplify offeset calculation logic a little bit"
This reverts commit 8ade26b4a4.
One of the assertions triggers when run on an extract of Serok. Since
this code does not fix any bugs, I'll just revert this for now.
This definetly needs investigation.
2015-06-19 16:50:48 +02:00
Patrick Niklaus bbe1211451 Merge pull request #1534 from Project-OSRM/profile/lane-penalty
Profile/lane penalty
2015-06-19 00:25:32 +02:00
Patrick Niklaus ce152b205f Merge pull request #1535 from Project-OSRM/develop-vs2015
make AppVeyor green again
2015-06-19 00:25:11 +02:00
bergwerkgis a5fd7cf4e9 make AppVeyor green again 2015-06-18 18:16:51 +02:00
Dane Springmeyer da38a1367a try building with vs2015 as CTP_Nov2013 appears broken now on appveyor 2015-06-18 18:15:34 +02:00
Patrick Niklaus 1445f11c19 Add test for lane penalty 2015-06-18 17:35:39 +02:00
Patrick Niklaus 86df55f5cc Add penalty if there is only one lane for both directions 2015-06-18 17:31:49 +02:00
Patrick Niklaus cf294c938e Merge pull request #1508 from agruss/geometry_string
Polyline string as parameter
2015-06-18 16:29:29 +02:00
Patrick Niklaus ebff45f803 Add new regression test for looping bugs 2015-06-18 00:18:54 +02:00
Patrick Niklaus 7b8021a36e Merge pull request #1531 from Project-OSRM/fix/poland-motorway-bug
Fix/poland motorway bug
2015-06-17 23:25:41 +02:00
Patrick Niklaus 5c77bb7c67 Fix inversion of sign 2015-06-17 23:25:16 +02:00
Patrick Niklaus 8ade26b4a4 Simplify offeset calculation logic a little bit 2015-06-17 23:25:16 +02:00
Patrick Niklaus bdbc60b4f7 Fix comments in edge based graph factory 2015-06-17 23:25:16 +02:00
Patrick Niklaus 373fa7a7d9 Merge pull request #1502 from agruss/develop
Accepting HTTP Post Request
2015-06-17 23:24:41 +02:00
Lauren Budorick eec4f173a7 Fix tag misspellings in profiles + tests: forestry, pebblestone 2015-06-09 20:16:58 -07:00
Andreas Gruß d726ce6340 removed send_simple_request 2015-06-07 12:20:03 +02:00
Andreas Gruß b406844c96 rearranged send_request parameters 2015-06-07 11:06:37 +02:00
Andreas Gruß 153d38f10c post/get handler added, background section for HTTP request 2015-06-05 13:26:27 +02:00
Andreas Gruß dce917eb74 post tests via query options available 2015-06-04 17:39:54 +02:00
Andreas Gruß eb711787ae tests added 2015-06-03 15:31:20 +02:00
Patrick Niklaus 9967dbbaa9 Don't remove small segments at start/begin if they are vias 2015-06-02 17:51:17 +02:00
Patrick Niklaus 71dc10ebea Add failing test case 2015-06-02 16:59:30 +02:00
Andreas Gruß 782fba2ce7 updated to 1E6 based polyline format 2015-06-02 13:15:31 +02:00
Andreas Gruß 4d73f98050 made geometry_string a const reference 2015-06-02 13:06:06 +02:00
Andreas Gruß 79d2083a00 changed parameter from geometry_string to locs 2015-06-02 12:10:28 +02:00
Andreas Gruß ee3b296a99 fixed values of test 2015-06-02 12:10:13 +02:00
Andreas Gruß 8b62d04453 test added 2015-06-02 12:09:59 +02:00
Andreas Gruß 9b0d3dfaeb polyline string as parameter added 2015-06-02 12:09:46 +02:00
Patrick Niklaus b1ef4cfee9 Remove debugging code 2015-06-01 17:22:12 +02:00
Patrick Niklaus f12f6a56ba Fix debug message 2015-06-01 17:22:12 +02:00
Patrick Niklaus 2777d53a12 Direct edges in contractor correctly and add better graph validation. 2015-06-01 17:22:12 +02:00
Patrick Niklaus aba3ec692f Verify graph before compression 2015-06-01 17:22:12 +02:00
Patrick Niklaus b7c8fcd062 Also print edge source/target for suspicious edge weights 2015-06-01 17:22:12 +02:00
Patrick Niklaus 3065de63dd Move renumbering and edge deduplication in extractor 2015-06-01 17:22:12 +02:00
Patrick Niklaus a57fb4f1ab First step into overhauling the edge storage 2015-06-01 17:22:12 +02:00
Patrick Niklaus c493a22765 Add test case for leisure=track 2015-06-01 11:20:17 +02:00
Patrick Niklaus d85e5def5d Add running tracks to foot profile 2015-06-01 11:20:17 +02:00
Patrick Niklaus 0aba499c8e Use spaces instead of tabs 2015-06-01 11:20:17 +02:00
Patrick Niklaus 4146695f34 Add test to check new way naming convention 2015-06-01 11:19:27 +02:00
Patrick Niklaus 4e57e10ba8 Use 'name (ref)' if both are present 2015-06-01 11:19:27 +02:00
Andreas Gruß daa6d02887 Content Type validation added 2015-06-01 09:42:22 +02:00
Daniel Patterson a87d89302f Handle POST request when spanning multiple packets 2015-05-31 21:34:38 +02:00
Patrick Niklaus 2a9b1311d3 Add test for ignoring crossing nodes 2015-05-30 19:30:33 +02:00
Patrick Niklaus 7d73501b87 Update bicycle profile to ignore crossing nodes 2015-05-30 19:26:56 +02:00
Daniel Patterson 039d6acd3e Fix test case, it was missing 'via' instructions 2015-05-29 16:52:08 +02:00
Daniel Patterson 405fcdc483 We really need to run these tests. 2015-05-29 16:52:08 +02:00
Daniel Patterson f52abc1a62 When replacing packed_path1/2, also need to replace distance1/2 to properly track. 2015-05-29 16:52:08 +02:00
Daniel Patterson e763953562 Address #1424 by using the original fix 2015-05-29 16:52:08 +02:00
Patrick Niklaus 4cab617c25 Fix Coverity issue by initializing member 2015-05-29 09:13:28 +02:00
Patrick Niklaus 0190b5e5af Merge pull request #1501 from Project-OSRM/refactor/contractor
First part of the contractor refactor
2015-05-29 01:08:55 +02:00
Patrick Niklaus abc0952247 Fix accessing DeallocatingVector 2015-05-28 22:22:02 +02:00
Patrick Niklaus 6ce2726a87 Fix return codes for osrm-prepare 2015-05-28 15:18:48 +02:00
Patrick Niklaus 17a4463f59 More assertions 2015-05-28 15:18:48 +02:00
Patrick Niklaus e76d8df246 Fix tools to build with new graph reader interface 2015-05-28 15:18:48 +02:00
Patrick Niklaus a46bcf45d5 Move option parsing to own class 2015-05-28 15:18:48 +02:00
Patrick Niklaus 1f985d04a2 Move writing graph to an own function 2015-05-28 15:18:48 +02:00
Patrick Niklaus d64e6e6c1f Move more function from Run in subfunctions 2015-05-28 15:18:48 +02:00
Patrick Niklaus 1164a65df8 Refactor processing_chain by splitting into sub functions 2015-05-28 15:18:48 +02:00
Patrick Niklaus d57f07d57e Merge pull request #1500 from Project-OSRM/fix/scc-only-barrier
Enable barrier check for TarjanSCC
2015-05-28 15:17:36 +02:00
Patrick Niklaus 5c0a964321 Remove unused code SimpleNodeBasedDynamicGraph 2015-05-28 12:43:55 +02:00
Patrick Niklaus cf3b8d09d9 Also run the algorithm tests on travis 2015-05-28 12:43:27 +02:00
Patrick Niklaus 1c7397fb21 Enable barrier check for TarjanSCC
Re-enabling turn restrictions as well requires some further work to
extend the algorithm.
2015-05-28 12:31:59 +02:00
Andreas Gruß 6a08d93e2c http post requests implemented 2015-05-27 15:40:10 +02:00
Patrick Niklaus 4c03ace9eb Remove pruning in IncrementalFindPhantomNode 2015-05-25 02:07:01 +02:00
Patrick Niklaus 2cd616dd30 Merge pull request #1485 from danpat/fix/lua_err_display
Return error message when lua error occurs.
2015-05-22 09:45:26 +02:00
Daniel Patterson eab87c0827 Return error message when lua error occurs.
The error may not be the first item in the stack while we're inside the error handler.  ::from_stack() works OK outside the error callback, but not inside.
2015-05-21 15:39:23 -07:00
Patrick Niklaus 8b8188710e Merge pull request #1481 from Project-OSRM/fix/no-big-cc-pruning
Only activate pruning for big cc after one was found
2015-05-18 16:18:17 +02:00
Patrick Niklaus fd9bb3ac43 Only activate pruning for big cc after one was found 2015-05-18 09:41:41 +02:00
Patrick Niklaus 6d9c3bca33 Merge pull request #1478 from Project-OSRM/fix/profiles-cleanup
Cleanup the profiles
2015-05-18 00:09:45 +02:00
Patrick Niklaus dd33a45644 Revert "fix incorrect behavior when via point was on same one-way street as destination but should have been reached before, closes #1424"
This reopens #1424 but potentially fixes #1429.

This reverts commit 11c671354b.
2015-05-17 23:35:31 +02:00
Patrick Niklaus 074c7a9c40 Fix access module 2015-05-17 17:26:10 +02:00
Patrick Niklaus de2f06970d Fix missing values and activate fallback names by default 2015-05-16 14:39:49 +02:00
Patrick Niklaus 6166d946f7 Fix access tag check 2015-05-16 14:39:49 +02:00
Patrick Niklaus c778ab9622 Make bicycle profile backwards compatible 2015-05-16 14:39:49 +02:00
Patrick Niklaus aad846b968 Fix call to function and transportation if clause 2015-05-16 14:39:49 +02:00
Patrick Niklaus f04a3e3d2e Fix bicycle profile syntax 2015-05-16 14:39:49 +02:00
Patrick Niklaus 7ad52de2b1 Cleanup the profiles 2015-05-16 14:39:49 +02:00
Patrick Niklaus 0706ba9bec Merge pull request #1457 from Project-OSRM/develop-lua52
Modify profiles to use Lua 5.2+ without needing compatibility flags
2015-05-16 14:29:32 +02:00
Patrick Niklaus ed53888fce Follow symlinks 2015-05-15 15:30:41 +02:00
Lauren Budorick fd76fba235 Keep apt-get 5.1 for now 2015-05-15 15:02:23 +02:00
Patrick Niklaus 95088a785a Make using profile.lua work again.
Symbolic links are a _bad_ idea with lua script. Lua will search at the
place of the symbolic link for modules _not_ at the actual location of
the script.
2015-05-15 15:02:23 +02:00
Lauren Budorick f46b600ec0 Upgrade lua to 5.2 on travis 2015-05-15 15:02:23 +02:00
Lauren Budorick 566ab993df Use lua 5.2+ without needing compatibility flags. 2015-05-15 15:02:23 +02:00
Patrick Niklaus 407036e215 Merge pull request #1476 from Project-OSRM/fix/distance-based-radius
Use distance based search radius
2015-05-15 10:49:19 +02:00
Patrick Niklaus 7b1a5566fb Move nodes inside the search radius 2015-05-15 00:34:53 +02:00
Patrick Niklaus 1b0d8739c1 Increase max distance to 1100 to fix unrelated test cases 2015-05-15 00:34:34 +02:00
Patrick Niklaus 266feea397 Merge pull request #1465 from alex85k/develop
fix cucumber tests running on Windows
2015-05-14 22:25:52 +02:00
Patrick Niklaus c4c6ab2494 Use distance based search radius
This limits the nearest neighbour search to a maximum distance
of 1000 meters, but will also work in dense areas.
2015-05-14 22:24:07 +02:00
Emil Tin 079eea3f2b add test for route duration formats 2015-05-10 20:09:09 +02:00
alex85k a457d69034 fix cucumber tests running on Windows 2015-05-09 19:22:16 +05:00
Patrick Niklaus d0175798bf Add link to documentation in the wiki 2015-05-02 15:18:13 +02:00
Patrick Niklaus 80e07943ee Make README more meaningful 2015-05-02 01:30:44 +02:00
Will White e2954211ec Fix travis links. 2015-05-01 20:04:05 +02:00
Patrick Niklaus 337bed8176 Merge pull request #1455 from Project-OSRM/fix/cucumber2.0
upgrade to cucumber 2.0
2015-05-01 18:32:26 +02:00
Emil Tin 71197e1c89 remove last use of routing_diff 2015-04-30 18:29:56 +02:00
Emil Tin e1a13f5ce8 remove obsolete cucumber patch 2015-04-30 18:15:46 +02:00
Emil Tin 1ed2c16a51 upgrade to cucumber 2.0 2015-04-30 18:15:46 +02:00
Patrick Niklaus 12e1bd80b3 Send travis mails to me 2015-04-29 14:00:17 +02:00
Patrick Niklaus fd6daa580a Merge branch 'develop' 2015-04-22 10:34:56 +02:00
Patrick Niklaus d2a19ec8ec Merge pull request #1446 from Project-OSRM/fix/sharedmemory-default
Fix/sharedmemory default
2015-04-22 09:50:46 +02:00
Patrick Niklaus 8f3feac916 Ensure routed is backwards compatible 2015-04-22 09:49:08 +02:00
Patrick Niklaus c0e066440c Use shared memory if no server paths are provided.
This caused a bug in the node bindings that would invoke the constructor
without parameters.
2015-04-22 09:49:08 +02:00
Patrick Niklaus fbb4e9078a Updated restriction parser doc 2015-04-21 20:00:58 +02:00
Patrick Niklaus d96e90c6f4 Add documentation to ExtractionContainer 2015-04-21 20:00:58 +02:00
Patrick Niklaus 3b435d8956 Add documentation to ScriptingEnvironment 2015-04-21 20:00:58 +02:00
Patrick Niklaus 345dd2481b Add documentation to InputRestrictionContainer 2015-04-21 20:00:58 +02:00
Patrick Niklaus 006bcc0fc8 Add some documentation to the restriction parser 2015-04-21 20:00:58 +02:00
Patrick Niklaus c25d14e454 Remove unnecessary header include 2015-04-21 20:00:58 +02:00
Patrick Niklaus 5ff95dc32d Move string_map inside external_callbacks
It is not referenced outside this calls, thus the lifetime
can be safely handled by it.
2015-04-21 20:00:58 +02:00
Patrick Niklaus 34031aab1b Add further documentation to ExtractorCallbacks 2015-04-21 20:00:57 +02:00
Patrick Niklaus 3035219212 Add further documentation 2015-04-21 20:00:57 +02:00
Patrick Niklaus 8a608eb930 Add some doc to the extractor 2015-04-21 20:00:57 +02:00
Patrick Niklaus c2fc47df34 Merge branch 'develop' 2015-04-17 22:51:40 +02:00
Dennis Luxen d4065774ce Merge pull request #1440 from Project-OSRM/feature/check_graph_implementations
fix incorrect SCC generation
2015-04-17 09:50:46 +02:00
Patrick Niklaus 6d43d9f2b6 Add unit test for dynamic graph
Also simplify the unit tests.
2015-04-17 00:38:09 +02:00
Patrick Niklaus 94d7fd9112 Adapt osrm-components to new FindEdge interface 2015-04-17 00:25:01 +02:00
Patrick Niklaus 04b5833e98 Adapt EdgeBasedGraphFactory to new FindEdge behaviour 2015-04-17 00:23:58 +02:00
Patrick Niklaus 52592b84fd Add functions to find reverse edge to DynamicGraph 2015-04-17 00:22:51 +02:00
Patrick Niklaus f2cd68e3ec Return SPECIAL_EDGEID if no edge was found 2015-04-17 00:21:57 +02:00
Dennis Luxen aff590a44d make implementation of FindEdge consistent among graph implementations, introduce FindSmallestEdge() function to return the edge with smallest weight if there are multiple, fixes #1427 2015-04-16 16:12:08 +02:00
Dennis Luxen 0d432f6377 fix comparison to recognize small components in a static graph 2015-04-16 16:11:06 +02:00
Dennis Luxen 59bceee258 make sure GetNumberOfNodes() is only called once 2015-04-16 16:08:10 +02:00
Dennis Luxen 4a0a0bac1d clear right edge list after graph instantiation 2015-04-16 14:38:42 +02:00
Dennis Luxen c7bd96ea8b fix unintended signed/unsigned comparison 2015-04-16 14:31:13 +02:00
Dennis Luxen 0eb2106067 reorder includes, add tuple include 2015-04-16 14:30:52 +02:00
Dennis Luxen c03aec364c add comparison tool for graph classes 2015-04-16 11:25:43 +02:00
Patrick Niklaus f2cdb97867 Change max distance delta to 200m 2015-04-13 22:39:55 +02:00
Patrick Niklaus 727e284ed0 Reduce map beta, as it fits better to the intended sample rate 2015-04-13 22:39:55 +02:00
Patrick Niklaus 3248977e02 Update classifier parameters 2015-04-13 22:39:55 +02:00
Patrick Niklaus 7ee8776165 Remove second stage classifier: obsolete with trace splitting 2015-04-13 22:39:55 +02:00
Patrick Niklaus f89f4bd20b Add option to enable json logging 2015-04-13 22:39:55 +02:00
Patrick Niklaus a372ade7ce Mark suspicious transitions 2015-04-13 22:39:55 +02:00
Patrick Niklaus 61dca4a35e Merge pull request #1433 from Project-OSRM/feature/node-location
Make node location accessible
2015-04-13 16:53:02 +02:00
Dennis Luxen 9cc68b26e2 pull in latest osmcode/libosmium changes 2015-04-13 15:44:38 +02:00
Dennis Luxen c0402345f7 Squashed 'third_party/libosmium/' changes from f074d94..8bcd4ea
8bcd4ea Add explicit cast operator from osmium::Timestamp to uint32_t.
0b24814 Fixed the full_queue_sleep_duration const (again).
5e19dd2 Try different workaround for windows...
df5d6c9 Fix build error on Windows.
1553adf Workaround for missing support for u8 string literals on Windows.
aa5e44a Do not build benchmarks in Appveyor to speed up build.
2b22b31 Remove warning generated by assert by casting to largest type.
148c5e3 Fix inclusion of our own css file into doxygen documentation.
13bce6f Split out test thats fails on Windows and do not run it on appveyor.
ca04757 Make CMake add_unit_test() function more flexible.
6c04a63 Tell CMake to output json file with compile commands.
c0dd848 Fix indentation in some tests.
dfa7e4b Formatting: Consistently use spaces around equal signs.
08fe6db Add change log, release version 2.1.0.
667192e Add XML tests.
28acfc7 Make sorting the PBF stringtables optional.
8184781 Fix PBFInputFormat. Use member variable instead of static variable.
2b48945 Fix comment.
6d37054 Rename m_done to m_quit_input_thread to clarify what it is for.
bc23083 Fix race condition in PBF reader.
7fc380e Add various docs, noexcepts, asserts, and tests.
aeaf4d7 Not a good idea to how overbroad patterns in .gitignore.
c1ef2f9 Bugfix: Multipolygon collector was accessing non-existent NodeRef.
0ef9a13 Add noexcept and docs to some functions in NodeRefList class.
da4d764 Workaround for Doxygen bug.
e67d5d9 use absolute paths to osmium in YouCompleteMe configuration
38abeac remove template parameter from NodeRefList
c47adf0 Add check that osm xml file has <osm> or <osmChange> as top-level element.
5e4af90 Updated version number to 2.0.0.
5b2bc3e Workaround in cmake test for sparsehash size.

git-subtree-dir: third_party/libosmium
git-subtree-split: 8bcd4ea771696812bbb08ebc58e3ee22d0538070
2015-04-13 15:44:38 +02:00
Dennis Luxen 27c9230a82 pull latest mapbox/variant changes in 2015-04-13 15:37:43 +02:00
Dennis Luxen e985c9714b Squashed 'third_party/variant/' changes from 3b02ca0..bf485df
bf485df Revert "pass F (functor) by ref/const ref"
e031c53 Revert "pass by const ref in 'apply_const'"
a3014f5 pass by const ref in 'apply_const'
2e0ce4a pass F (functor) by ref/const ref
5875195 add support for 'unwrapping' std::reference_wrapper<T> and accessing std::reference_wrapper<T>::type through get<T>() + update test
c53422f remove boost variant header
5a2d5c5 add reference_wrapper test

git-subtree-dir: third_party/variant
git-subtree-split: bf485dfb59aef26f3ef2183d7c8c1111ad97062b
2015-04-13 15:37:43 +02:00
Dennis Luxen 6c5015811e do not build concurrently on Travis, also build (but not run) benchmarks 2015-04-13 14:43:35 +02:00
Dennis Luxen 86e7de4d62 Merge branch 'revert-1375-master' into develop 2015-04-13 10:07:29 +02:00
Dennis Luxen 147d35e40d Revert "added lua binding for osmium::Way::id()" 2015-04-13 10:04:23 +02:00
Dennis Luxen b76fc724fd make node id available thru Lua bindings 2015-04-13 09:58:59 +02:00
Dennis Luxen 1bfab4e279 Merge pull request #1375 from bjtaylor1/master
added lua binding for osmium::Way::id()
2015-04-13 09:52:56 +02:00
Dennis Luxen 11bdfba37e traffic signal penalty ignored on white-listed barriers, cf. #1365 2015-04-13 09:47:12 +02:00
Patrick Niklaus 405f08b807 Make node location accessible 2015-04-10 11:45:24 +02:00
Dennis Luxen 592211cecd activate __get_cpuid on all non X64 platform, fixes #1193 2015-04-07 14:45:21 +02:00
Dennis Luxen a4f31001e8 MSVC doesnt properly support the noexcept operator 2015-04-02 15:11:23 +02:00
Dennis Luxen c2deedac8b sprinkle a number of noexcepts into the code 2015-04-02 11:36:04 +02:00
Dennis Luxen 9a61f8b894 add more const keywords, avoid implicit type conversions 2015-04-02 11:27:51 +02:00
Dennis Luxen 3a291f5c8e fix escaping of double quote in JSON response, fixes #1410 and also adds a unit test for that case. 2015-04-02 10:34:40 +02:00
Dennis Luxen 559a2dcec7 move shared lib testing to distinct port on travis 2015-03-31 17:33:56 +02:00
Dennis Luxen b7f003c4aa Merge branch 'opengisch-sharedlib' into develop 2015-03-31 17:33:36 +02:00
Matthias Kuhn d11c0bbd5c Do not compile Coordinate sources directly into the OSRM library
It is already included in the COORDINATES "OBJECT" target to which the OSRM
library is linked.
This fixes the possibility to build OSRM as a shared library.
2015-03-31 16:57:41 +02:00
Matthias Kuhn c2f775fcaa Add test for building as shared library 2015-03-31 16:57:41 +02:00
Dennis Luxen 19ac831c2e remove another quoted compare 2015-03-31 12:59:56 +02:00
Dennis Luxen 23b413a398 remove quotes from string compares against variable in CMakeLists 2015-03-31 12:35:20 +02:00
Dennis Luxen 098de196e2 reactivate profiling flags for debug build 2015-03-31 11:21:36 +02:00
Dennis Luxen 27d2c31f28 add (new) fingerprint.cpp that includes the generated headers 2015-03-31 10:47:21 +02:00
Dennis Luxen c9c9edeb23 deleted: util/fingerprint.cpp.in 2015-03-31 10:46:55 +02:00
Dennis Luxen 5adf792fad fix build issue where cmake does not pick up generated output of a custom target
renamed:    ../util/fingerprint.cpp.in -> ../util/fingerprint_impl.hpp.in
2015-03-31 10:45:35 +02:00
Dennis Luxen 81af7d73a6 make FINGERPRINT a global dependency 2015-03-30 15:55:23 +02:00
Dennis Luxen 23e4e0786d also enable C as a project language 2015-03-30 13:26:06 +02:00
Dennis Luxen 0640ce9632 set project and fingerprint target language to CXX explicitly, fixes AppVeyor build. Potentially Travis, too. 2015-03-30 13:21:03 +02:00
Dennis Luxen 3e49bf4f42 add const keywords where possible 2015-03-30 13:16:22 +02:00
Dennis Luxen 66b038a010 reorder includes 2015-03-30 13:14:13 +02:00
Dennis Luxen 9bbbebf31d use empty() instead of 1>size() to make intent more clear 2015-03-30 13:13:13 +02:00
Dennis Luxen 19765cfa14 remove unneeded include 2015-03-30 13:10:03 +02:00
Dennis Luxen d6badca610 use lamda function to do complex initialization with a (wanted) side-effect 2015-03-30 13:09:10 +02:00
Dennis Luxen 6933804aa4 remove unused html en/decoding entities, we use JSON now 2015-03-30 12:40:54 +02:00
Dennis Luxen 5bed7f292f add test for printInt() sign correctness 2015-03-30 12:37:39 +02:00
Dennis Luxen f553896e2d printInt(): fix sign issue when outputting 0, use postfix in/decrement 2015-03-30 12:36:39 +02:00
Dennis Luxen 60663b5433 reorder build dependencies 2015-03-30 11:09:41 +02:00
Dennis Luxen 1851a31e66 add unit tests for functions escape_JSON, printInt and replaceAll in string_util.hpp 2015-03-27 18:15:58 +01:00
Dennis Luxen d853310bee use range-based for in escape_JSON() function 2015-03-27 18:15:13 +01:00
Dennis Luxen 11c671354b fix incorrect behavior when via point was on same one-way street as destination but should have been reached before, closes #1424 2015-03-27 12:29:29 +01:00
Dennis Luxen b15599f01e simplify logic to compute edge offset 2015-03-27 12:28:01 +01:00
Dennis Luxen 4b957abc0c fix rounding error/uncertainty on some systems 2015-03-27 12:27:15 +01:00
Dennis Luxen 8ee82d1e03 replace old-style typefs with using 2015-03-23 17:06:10 +01:00
Dennis Luxen 5565662d87 fix compilation with CMake 3.2, closes #1422
CMake 3.2 changed the behavior of add_custom_command and ungenerated dependencies. Replaced with add_custom_target that works on version 2.8+
2015-03-23 16:14:24 +01:00
Patrick Niklaus 78735fae6b Fix match test by using the new threshold 2015-03-18 00:21:04 +01:00
Patrick Niklaus d3b9911445 Fix match geometry output 2015-03-17 23:50:59 +01:00
Patrick Niklaus 7813dafc96 Increase the time split threshold to a more reasonable value 2015-03-17 23:50:47 +01:00
Patrick Niklaus 02b561edd2 Pass route leg by reference, not by value 2015-03-17 23:24:31 +01:00
Dennis Luxen 272a1fda54 Merge pull request #1407 from Project-OSRM/feature/matching
Map Matching
2015-03-10 06:08:11 -07:00
Patrick Niklaus bc8666df83 Add tests for matching 2015-03-08 01:32:13 +01:00
Patrick Niklaus 028fad94af Fix overflows when handling size_t 2015-03-08 00:53:15 +01:00
Patrick Niklaus 0c735953c9 Make uturn detection a little less sensitive. 2015-03-08 00:51:07 +01:00
Patrick Niklaus 736bc87480 Fix inverted operator in maximum check 2015-03-07 23:02:14 +01:00
Dennis Luxen dd94a64048 remove lint from #1409
- fix copyright header
- remove dead code
2015-03-05 14:03:35 +01:00
Dennis Luxen cf9f88f8ce Merge pull request #1409 from RockLobster/develop
FIX: Moved the GeometryCompressor's free_list_maximum into a member variable of the class.
2015-03-05 14:02:34 +01:00
RockLobster 5694aeda5f FIX:
Moved the GeometryCompressor's free_list_maximum into a member variable of the class.
(+UniqueNumber() commented out since it is not being used anywhere in all of OSRM)

There was absolutely no need for free_list_maximum to be a static variable and it caused major issues in my code.
Short description:
- I ran osrm-prepare's Prepare().Process(..) function in my own code multiple times for multiple files
	=> After the first file is done, free_list_maximum is still on the same size, but a new GeometryCompressor will start at a size of 100 again.
	=> Indices broken.
2015-03-05 11:30:52 +01:00
Patrick Niklaus 7829e3c132 Add step definition and support code for matching 2015-03-05 00:12:26 +01:00
Dennis Luxen 2ce0d60db1 Squashed 'third_party/libosmium/' changes from 6522da5..f074d94
f074d94 Use shorter path names in Doxygen doc.
5117d5a Make Doxygen-generated HTML docs work better on small screens.
41607ac Appveyor config: Use lowercase command names everywhere. Filter 7z output.
9e77a39 Remove debug output.
3416c4b Revert "Comment out test to see if there are dependencies between tests."
fa49dde Comment out test to see if there are dependencies between tests.
5add75d Fix typo in appveyor conf: nul.
53b3778 Use different file names for tests.
1091c0b Fix Windows munmap() to return the same as the posix one.
14fdc4e Revert "CMake: Remove unneeded build type setting."
0270087 Workaround for MSVC.
56c2120 Another try...
8e96a6f Trying to fix test on Windows...
11a64c2 CMake workaround: Set CMAKE_CONFIGURATION_TYPES before project(). As per http://www.cmake.org/pipermail/cmake/2012-January/048856.html
3847e7a CMake: Remove unneeded build type setting.
a1bcaf1 CMake: Make CMAKE_CONFIGURATION_TYPES a cache variable.
ddab3e3 Create test file in test_typed_mmap in current dir instead of tmp.
ce1d3bd Build "RelWithDebInfo" on appveyor instead of "Release".
b6db34f Add README showing source of FindGem.cmake.
2c86c55 Better error message and some comments in CMake for sparsetable check.
b16a5a3 Fix ctest on Windows.
2203bc8 Fix FindGem.cmake.
5d1f81d Another try to fix travis build.
ddd3f5e Hopefully fix problem where travis doesn't find osm-testdata.
0e673ea More debug output to find travis problem.
eb01107 Updated data-tests README.
8a971c8 Remove special case of the multipolygon test in travis/appveyor config.
dce792c CMake: Check dependencies of multipolygon test and run as CMake script.
b967677 Add tests for thread pool.
400e9b3 Bugfix: Handle exception in one pool threads properly.
a1ba489 More detailed error reporting from zlib.
95cf621 Disable SparseMemTable if sparsetable size_type is smaller than 8.
7b601b5 Add missing overload to cast_with_assert() function.
60a7d86 Giving up on trying to remove LNK4221 warning.
35ed5df Try another way to get rid of MSV warning...
f9c7d92 Disable a warning about changed behaviour on MSVC.
c3c6b2d CTest: Only output failed tests.
9c99996 Try setting option in a different way for getting rid of LNK4221 on MSVC.
4ac563c Another ssize_t fix for Windows.
11db84f Fix mmap for windows. Convert macro to function.
95d8f75 Fix test on Windows (which doesn't have ssize_t).
df51aa4 Do not write huge files in one system call.
9c4f772 Change mmap() implementation for Windows.
5be817c Rewrote function to work on Windows without warnings.
ea84f73 Fix warnings on Windows.
572d692 Fixed the static_cast_with_assert function and added tests.
89ef86b Use SparseMemArray instead of SparseMemTable in examples.

git-subtree-dir: third_party/libosmium
git-subtree-split: f074d949a5585a81578d682035f2163de971beb3
2015-03-04 12:50:42 +01:00
Dennis Luxen 68e66dad06 upgrade libosmium dependency 2015-03-04 12:50:42 +01:00
Dennis Luxen 80db907857 upgrade variant dependency 2015-03-04 12:48:19 +01:00
Dennis Luxen 76674a3594 Squashed 'third_party/variant/' changes from 24dcab2..3b02ca0
3b02ca0 add which() method returning zero based index of stored T in Types... for boost::variant() compatibility
c117592 update unit test to match c64c74775a80474f2012c1a49ab2865e3666107a
36f1e12 add get<T>() overloads for when T is stored in recursive_wrapper<T> also makes get<T>() a compile time error where T is not in Types... (ref #24)
7dfdfa2 clean up coverage files in test directory too [skip ci]
89f8a41 add coverage report

git-subtree-dir: third_party/variant
git-subtree-split: 3b02ca0e3ab1a36dd6ec9138e7f93eb3176ae5f7
2015-03-04 12:48:18 +01:00
Patrick Niklaus 98dba11c5e Address some of the remaining issues of the code review 2015-03-04 01:34:45 +01:00
Dennis Luxen de261d28ef add override specifier 2015-03-03 18:26:38 +01:00
Dennis Luxen d43716612b several copyedits to brush up code
- remove unneeded includes
- replace size() <==> 0 comparisions with calls to empty()
- use fp instead of integer literals
- use range-based for loops with integer ranges
- add a couple of consts
2015-03-03 18:17:12 +01:00
Dennis Luxen cfaacf7cb2 put util/compute_angle.cpp into OBJECT library to avoid repetetive compiles 2015-03-03 17:58:17 +01:00
Dennis Luxen b9922bc90b replace C-style comments 2015-03-03 17:43:37 +01:00
Dennis Luxen 31cae8f05f several copy edits to brush up the code
- fix copyright header
- rename probabilityDensityFunction -> density_function
- use double-precision fp literal to indicate intent
- remove redundant enum class start value
- replace C-style comments with C++ style
- make functions const
2015-03-03 17:42:07 +01:00
Dennis Luxen 133e382aae remove constexpr qualifier as numeric_limits is not yet constexpr on MSVC compiler 2015-03-03 14:43:38 +01:00
Dennis Luxen e02c721c2b further untangle model from functionality and put classes into seperate headers
- move get_network_distance() into routing base class
- don't reallocate queues every time but clear them. Should be cheaper
2015-03-03 14:22:52 +01:00
Dennis Luxen 5af0ceb2d2 use range based for loop 2015-03-03 14:22:27 +01:00
Dennis Luxen 6460fdc62b use std::size_t for timestamps to avoid implicit casts, use range-based for loops 2015-03-03 13:03:00 +01:00
Dennis Luxen 402ca780bf fix test expectation osrm-routed help output 2015-03-03 12:56:37 +01:00
Dennis Luxen 643ab92cd2 fix default value for max_locations_map_matching 2015-03-03 12:55:42 +01:00
Dennis Luxen a9c3b343fc separate model and computation in HMM matching 2015-03-03 12:48:33 +01:00
Dennis Luxen 592bebaf29 renamed: plugins/map_matching.hpp -> plugins/match.hpp to avoid confusion with routing_algorithms/map_matching.hpp 2015-03-03 12:01:40 +01:00
Dennis Luxen 4df215e674 replace -std::numeric_limits<T>::max() with ::lowest() 2015-03-03 11:53:31 +01:00
Dennis Luxen 91792f45ea fix compilation
- missing new 10th parameter to GenerateServerProgramOptions
2015-03-03 11:50:37 +01:00
Dennis Luxen 20091e94c8 fix compilation
- remove wrong comments
- fix include guard footer
- add curly braces
- add template specialization for std::vector<bool> in make_array
- reformat
2015-03-03 11:50:02 +01:00
Dennis Luxen 76aa494be4 fix compilation
- std::log and M_PI are not constexpr's by the standard. replace by a constant
- reformat
2015-03-03 11:48:15 +01:00
Dennis Luxen 6fb8fdc2bd fix compilation
- define max_number_of_candidates where its used
- add curly braces
- reformat
2015-03-03 11:46:24 +01:00
Patrick Niklaus 0d879ed290 Split trace if timestamp delta is over threshold
Even when matching is not broken we split the trace, if the
sampling frequency goes below 2 samples/minute.
2015-03-03 00:48:57 +01:00
Patrick Niklaus d8d46e0f3e Add routed parameter to limit matching size 2015-03-03 00:48:57 +01:00
Patrick Niklaus e5830b0116 Add parameters for map matching 2015-03-03 00:48:57 +01:00
Patrick Niklaus d89b171f49 Simplify json code in map matching plugin 2015-03-03 00:48:57 +01:00
Patrick Niklaus a760aec791 Add json logger to map_matching
This adds additional data to the json response, when OSRM is compiled
in debug mode.
2015-03-03 00:48:57 +01:00
Patrick Niklaus 34d5d353af Apply clang-format and split out json_util 2015-03-03 00:48:57 +01:00
Patrick Niklaus e8e637c4f2 Replace descriptor code with code that generates only geometry 2015-03-03 00:48:57 +01:00
Patrick Niklaus adbca39fef Fix include guard 2015-03-03 00:48:57 +01:00
Dennis Luxen a2c88b607f lint corrections
- fix license header
- let shared_ptr autodestruct as it's shared
- rename fences to resemble file names
- reorder includes into lexicographic order
2015-03-03 00:48:57 +01:00
Patrick Niklaus 2115a67d24 Link libOSRM with compute_angle 2015-03-03 00:48:57 +01:00
Patrick Niklaus dec73b02e9 Rename traces to matchings in response 2015-03-03 00:48:57 +01:00
Patrick Niklaus 0e6ed53cee Adapt to JSON container rename 2015-03-03 00:48:57 +01:00
Patrick Niklaus fd6c70afe1 Fix regression in sub-matching length check 2015-03-03 00:48:57 +01:00
Patrick Niklaus c4f193b13e Fix comment 2015-03-03 00:48:57 +01:00
Patrick Niklaus 70703c39f3 Add timestamp parameters and reset to beginning of breakage 2015-03-03 00:48:57 +01:00
Patrick Niklaus d429485f0c Fix stupid error in backtracking 2015-03-03 00:48:57 +01:00
Patrick Niklaus 89460dd39c Return indices instead of points 2015-03-03 00:48:57 +01:00
Patrick Niklaus f46b259384 Fix splitting traces 2015-03-03 00:48:56 +01:00
Patrick Niklaus fb0ce48f2f Simplify matching response 2015-03-03 00:48:56 +01:00
Patrick Niklaus cb4a81008c Split traces into subtraces 2015-03-03 00:48:56 +01:00
Patrick Niklaus d620da365e Implement more general pruning 2015-03-03 00:48:56 +01:00
Patrick Niklaus 0c3102721c Make number of candidates a parameter 2015-03-03 00:48:56 +01:00
Patrick Niklaus b3fa03043d Calculate the real route length for classification 2015-03-03 00:48:56 +01:00
Patrick Niklaus 38d7db49c8 Add state position to debug output 2015-03-03 00:48:56 +01:00
Patrick Niklaus 1a8c832039 Update format of debug json ouput 2015-03-03 00:48:56 +01:00
Patrick Niklaus 6e54f8cfa6 Tighter threshold on low probability transistions 2015-03-03 00:48:56 +01:00
Patrick Niklaus 4838ffb82d Fix nan values if matched to single point 2015-03-03 00:48:56 +01:00
Patrick Niklaus 1bcf41d382 Prune low probability transitions 2015-03-03 00:48:56 +01:00
Patrick Niklaus e381566494 Eliminate branch 2015-03-03 00:48:56 +01:00
Patrick Niklaus 66d7a073d3 Move splitting candidates to plugin 2015-03-03 00:48:56 +01:00
Patrick Niklaus 0637215b85 Skip computing viterbi if viterbi of previous state is lower than lower bound
This causes a speedup of 300%.
2015-03-03 00:48:56 +01:00
Patrick Niklaus dc1405ffa8 Fix typo in debugging code 2015-03-03 00:48:56 +01:00
Patrick Niklaus 0fce20c503 Directly compute log probabilities 2015-03-03 00:48:56 +01:00
Patrick Niklaus 1b16dd126b Actually compute and transmit confidence in the response 2015-03-03 00:48:56 +01:00
Patrick Niklaus fe07f9208c Add bayes classifier 2015-03-03 00:48:56 +01:00
Patrick Niklaus f092fc3fc6 Fix minimum number of candidates 2015-03-03 00:48:56 +01:00
Patrick Niklaus b5228dcda0 Detect possible uturns in the data.
To make them work, we have to disable PhantomNode splitting
for this coordinates.
2015-03-03 00:48:56 +01:00
Patrick Niklaus a5db3ea25b Print warning when more than 10 points are removed 2015-03-03 00:48:56 +01:00
Patrick Niklaus 173fad2362 Return error when less than 2 points left. 2015-03-03 00:48:55 +01:00
Patrick Niklaus 496338d84d Implemented pruning and breakage detection 2015-03-03 00:48:55 +01:00
Patrick Niklaus 59727a6967 Get all nodes in dense areas but make sure we don't underflow in sparse ones 2015-03-03 00:48:55 +01:00
Patrick Niklaus 3a5e41ed91 Implement missing matching pieces 2015-03-03 00:48:55 +01:00
Dennis Luxen 2259bce05f Add skeleton code for matching 2015-03-03 00:48:55 +01:00
Dennis Luxen 7e00a86bb4 implement ISO 8601 durations parsing, cf. #1399 2015-03-02 17:18:52 +01:00
Dennis Luxen 73a2a938b4 use CRTP instead of virtual functions in routing plugins 2015-03-02 11:55:55 +01:00
Dennis Luxen c2098938f5 add convenience variadic template function to append elements to a container 2015-02-27 13:52:58 +01:00
Dennis Luxen 773ff182ee fix license header 2015-02-26 18:54:13 +01:00
Dennis Luxen 878c49e4e1 fix incomplete implementation of movable bridges in bike profiles, plenty of regressions 2015-02-26 17:17:43 +01:00
Dennis Luxen 023dd3e880 fix regression in bike profile 2015-02-26 16:44:26 +01:00
Dennis Luxen 6b88856c16 add support for movable bridges in the biking profile, cf #1399 2015-02-26 16:28:04 +01:00
Dennis Luxen dd5f926077 respect capacity:car for movable bridges in car profile 2015-02-26 16:22:18 +01:00
Dennis Luxen 845020b0e2 remove debug output 2015-02-26 16:17:42 +01:00
Dennis Luxen 7cf363eb06 reorder includes, fixes style regression from commit fdf2e59. 2015-02-26 16:09:48 +01:00
Dennis Luxen f67e670621 Merge pull request #1400 from Project-OSRM/feature/bridge_movable
add movable bridge support to the car profile. Implements #1399
2015-02-26 15:58:30 +01:00
Dennis Luxen 645e3ccbb3 add movable bridge support to the car profile. Implements #1399 2015-02-26 14:56:01 +01:00
Dennis Luxen ab385f2bf5 Merge pull request #1396 from RockLobster/develop
Small change in order to be able to use OSRM as submodule in other projects
2015-02-26 11:07:24 +01:00
Dennis Luxen 5080b9a82b Merge pull request #1397 from Project-OSRM/escape-fix
JSON string escape fix
2015-02-26 11:05:59 +01:00
Dennis Luxen 51e42ded44 - output only get escaped when actually output. Better seperation of functionality
- refactor facade::GetEscapeName() into get_name_for_id() call that is implemented in subclasses
- remove dead code
- fix failing tests where names got double-escaped
- fixes https://github.com/Project-OSRM/node-osrm/issues/83
2015-02-26 10:11:33 +01:00
Dennis Luxen 37fb89c691 add size() call to integer range 2015-02-26 10:10:19 +01:00
Patrick Niklaus 440eda3807 Escape string in json renderer 2015-02-25 21:11:02 +01:00
RockLobster bad2576397 Replaced CMAKE_SOURCE_DIR in osrm root dir's cmake file with CMAKE_CURRENT_SOURCE_DIR
=> Allows osrm to be used as a subproject aswell
2015-02-25 18:25:03 +01:00
Patrick Niklaus fdf2e5934d Add algorithm include for any_of 2015-02-24 20:29:43 +01:00
Dennis Luxen 3da1e8598b fix copyright year 2015-02-24 14:36:38 +01:00
Dennis Luxen 0296c767bf fix code-format regression 2015-02-24 09:08:59 +01:00
Dennis Luxen c215c42289 Merge pull request #1390 from Project-OSRM/feature/width_penalty
implements a penalty for very narrow roads
2015-02-24 08:56:11 +01:00
Dennis Luxen 8adab95973 refactor iterator range utility class 2015-02-20 11:59:03 +01:00
Dennis Luxen b89c7580e6 implement scaling for narrow roads as an alternative expected speed and take the minimum. Follows @emiltin's idea. 2015-02-20 10:33:14 +01:00
Dennis Luxen a85fe2cb08 remove debug output, thx @emiltin 2015-02-20 10:33:14 +01:00
Dennis Luxen 4c4c126361 implements a penalty for very narrow road:
- implements discussion of #1388
- implements basic test cases
2015-02-20 10:33:14 +01:00
Patrick Niklaus e9e12b88f8 Add CORS Content-Type HTTP header flag
Firefox needs this for JSON.
2015-02-20 00:36:36 +01:00
Dennis Luxen dc08c516bf use std::tie() to simplify lexicographic comparisons 2015-02-19 19:15:16 +01:00
Patrick Niklaus 9b1f108051 Allow CORS requests in osrm-routed. 2015-02-19 10:42:45 +01:00
Dennis Luxen b0f9a0feb4 rename variable name to be a little more telling 2015-02-19 10:11:49 +01:00
Dennis Luxen 3bd27ae8c5 change copyright line from personal names to project 2015-02-19 09:19:51 +01:00
Dennis Luxen 79b9bdf7ce rename JSON namespace to osrm::json to avoid namespace clash with V8 2015-02-18 17:27:31 +01:00
Dennis Luxen 9e09168597 un-lint CMakeLists.txt 2015-02-16 14:18:04 +01:00
Dennis Luxen e5f12347bd simplify code by using new phantom node ctor 2015-02-13 14:26:19 +01:00
Dennis Luxen 86d3556c6d add ctor that converts from rtree segment to phantom node 2015-02-13 14:24:05 +01:00
Dennis Luxen 45838b33b7 avoid implicit conversion to int 2015-02-12 15:40:55 +01:00
Dennis Luxen a1d4798ded refactor AlternativePathRouting step to have the same interface semantics regardless of search direction 2015-02-12 15:03:53 +01:00
Dennis Luxen 25c52b7482 rewrite sort/unique function to be more generic 2015-02-12 15:02:16 +01:00
Dennis Luxen fcf9f266ad Merge pull request #1381 from neilbu/develop
Made the request parser a member of the Connection
2015-02-12 14:26:48 +01:00
Neil Buckman fa638ae3a0 Removed debug logging 2015-02-12 09:55:13 +00:00
Neil Buckman 6d9cd504a0 Made the request parser a member of the Connection
Previously, the request parser was created on demand...but this could
cause requests to be flagged as bad requests if the string length was
large enough to cause the string to be split up into chunks by boost's
read_some method.
2015-02-12 08:01:46 +00:00
Dennis Luxen f9e9bb8870 update slack channel 2015-02-11 13:22:18 +01:00
Dennis Luxen 85ab2425a8 move travis notifications to slack 2015-02-11 11:47:25 +01:00
Dennis Luxen 9931155c68 port make_unique from libcxx 2015-02-10 18:02:23 +01:00
Dennis Luxen 56b6d928b6 add include to be self-sufficient 2015-02-10 12:34:13 +01:00
Dennis Luxen b865bea482 fix floating point comparison, remove superflous inline keywords 2015-02-10 12:29:52 +01:00
Dennis Luxen b6314e0c73 remove unnecessary casts in debug build 2015-02-10 12:27:27 +01:00
Dennis Luxen 2c773750c7 fix const correctness 2015-02-10 12:26:57 +01:00
Dennis Luxen 539b9be1d3 fix warning: use of old-style cast 2015-02-10 12:12:05 +01:00
Dennis Luxen 00e8caa0e3 fix signed/unsigned comparisons and casts 2015-02-10 12:08:17 +01:00
Dennis Luxen 1ff8b62bf5 fix warning: extra ';' after member function definition 2015-02-10 12:03:23 +01:00
Dennis Luxen 25fb985af8 fix warning: use of old-style cast 2015-02-10 12:02:13 +01:00
Dennis Luxen 858245db7d fix warning: implicit signed/unsigned warning 2015-02-10 11:58:56 +01:00
Dennis Luxen 09bea2ad5b fix warning: implicit float/double cast 2015-02-10 11:32:39 +01:00
Dennis Luxen adb520ec2a fix old-style casts 2015-02-10 11:31:36 +01:00
Dennis Luxen 5a1ff4b50d fix warning: implicit conversion changes signedness: 'int' to 'unsigned int' 2015-02-10 11:09:51 +01:00
Dennis Luxen e0f8acf733 make constant a float to avoid implicit cast 2015-02-10 11:04:49 +01:00
Dennis Luxen a81542eeee add virtual keyword to functions with override final specifiers 2015-02-10 10:07:35 +01:00
Dennis Luxen f67eeb66aa untangle includes using iwyu 2015-02-09 17:38:40 +01:00
Dennis Luxen 884c998622 Squashed 'third_party/variant/' content from commit 24dcab2
git-subtree-dir: third_party/variant
git-subtree-split: 24dcab23c4f70e54838e4a32a228aba8045ae17b
2015-02-09 15:19:35 +01:00
Dennis Luxen 88c8d73a94 Merge commit '884c9986229d4228374959265905cfd7b7c90c08' as 'third_party/variant' 2015-02-09 15:19:35 +01:00
Dennis Luxen 86576768d1 remove manually add variant dir 2015-02-09 15:19:19 +01:00
Dennis Luxen 3327c32b20 remove useless parantheses 2015-02-09 14:09:09 +01:00
Dennis Luxen 97ed6a3a4e remove method stubs 2015-02-09 14:06:14 +01:00
Dennis Luxen 85d8e0ac2c minor reformat 2015-02-09 09:21:44 +01:00
Dennis Luxen 2a68f9f532 rename variable name 2015-02-06 11:58:41 +01:00
Dennis Luxen b55d35c7bb remove a number of useless parentheses 2015-02-06 09:54:34 +01:00
Dennis Luxen 98f85d7728 remove some lint in variable names 2015-02-05 18:33:21 +01:00
Dennis Luxen 328a7caf61 rename short variable names to be more telling 2015-02-05 17:54:32 +01:00
Dennis Luxen 275ea9b0bb mark GetTravelModeForEdgeID as override final 2015-02-05 15:20:15 +01:00
Dennis Luxen bb78bc8fe3 Squashed 'third_party/libosmium/' changes from 910f8f1..6522da5
6522da5 Merge pull request #79 from DennisOSRM/master
7c8d8dc add override keyword to close(), overridden function in include/osmium/io/detail/input_format.hpp
d24841e Changes copyright dates in all files to a consistent "2013-2015".
3adc7d7 Another try to make it compile on Windows.
20dad8e Use auto instead of hard-coded types, hopefully fixes Windows build.
b73ab3f Set build config in appveyor ctest call.
3e33857 Merge pull request #76 from BergWerkGIS/master
c78ca6e Merge remote-tracking branch 'upstream/master'
cf42013 enable test again
69e4a91 include compatibility.h
6f79b5c CMake: Remove Dart include, it seems to be superfluous.
4d40a18 Explicitly set copy constructors etc. for OutputIterator and test it.
69ee34c Run tests in build directory instead of source directory.
11c44c8 Fix typo.
675cc11 Fix formatting CMake config.
7aa3cb0 Add a benchmark counting amenity=post_box tags.
89fd942 Make it more evident that we handling constant tag lists.
c72bbdf Add count() and empty() functions to Filter class.
88b9543 Disable annoying warnings from YouCompleteMe.
6cec403 Benchmarks: Only find files, not directories etc. in data dir.
09c4630 Follow redirects in benchmark download script.
a8a552e Use Approx() function from Catch framework for floating point comparisons.
7db5086 Reorder data tests so fast tests run first.
24ce403 Fix #includes.
ad9515c Add some comments in different config files to explain what they are.
987aa9c Some README updates.
3c18de7 Add configuration for YouCompleteMe Vim plugin.
433148e Explicit comparison against 0 to avoid warning with MSVC.
e64a459 Small updates in benchmarks README.
e4aff7f Add benchmark to compare static vs. dynamic index maps.
f702634 Add missing include.
95a8c3b Merge branch 'master' of github.com:osmcode/libosmium
560a2ae Merge pull request #73 from osmcode/travis-fix
f41e4ca remove incorrect cd
f826107 Add some helper functions for working with entity_bits.
8fec1c1 Updated README: Lots of documentation is now on wiki.
6110cc8 Make cmake config work if no components are given.
8136557 Use 'Libosmium' instead of 'Osmium' as project name in doc.
10e631a Improved documenation: Dependencies to link with.
41d0ca4 Merge remote-tracking branch 'upstream/master'
6768026 SLN configuration is always 'Release'
5d985cf av: show env vars.
272ac88 don't use '%CONFIGURATION%' expands to e.g. 'Dev|x86'
59b15eb use cmake 3.1.0 again. old cmake on AppVeyor doesn't know yet about VS2014 SLN
0d0d71a try building with VS, Dev works only with VS at least locally
2fe6d02 name of geos.lib changed
fc4662e test latest binary package
d4a265f Add more labels to tests.
8722a3d Only check for valgrind if testing is enabled.
cf7dc56 README improvements.
13a426e Fix cpack configuration.
ae649c8 travis build: fix double install of make package
c102040 Move cmake config for documentation into doc directory.
6064d55 Also list advanced cmake variables in travis build.
c299bfa constexprt workaround for MSVC.
afcf7a1 Cleanup/formatting of cmake config.
a536720 Fix travis build by cloning osm-testdata in the right place.
2bdbf7f cmake: Don't clone osm-testdata repository any more.
5bdbb28 Rename test/osm-testdata to test/data-tests.
0ad0020 cmake: build data tests only by default on Dev builds
2cefa50 Add some benchmarks.
3fdb6e1 Remove outdated make_osmium_project.sh script.
aca58ac Fix cmake config: overwriting of variables.
152e318 Fix compilation of examples that need wingetopt on Windows.
ae17cd0 Remove superfluous warning on Windows for header test builds.
f88d4c2 Switch to /W3 on Windows.
8edeba5 Remove duplicate copy constructor.
cdb474e Cleanup examples cmake config
ca9045a Cmake cleanup.
501eb61 Update to new version of catch unit test framework.
0646d6c Parenthesize expression to make test clearer and avoid warnings.
dfdaeae Disable a warning that gdal throws on Windows.
eacfe4f Explicitly test int !=0 to convert to bool.
b3ba693 Cleanup of cmake config (mostly warning options Linux vs. Win)
3f5cb81 Appveyor: Also show advanced cmake variables.
b544bd9 Never return valid but empty buffer from Reader.read() call.
a34bb5d Declare var in a more local scope.
b83e5f1 Merge pull request #66 from BergWerkGIS/master
04ef1b2 Last try for today, should solve geos test failures
a749d6c hey AppVeyor: what's going on?
73131fb av: boost not found?? show directory tree
5e02886 av: should solve most "***Exception: Other" except for geos.dll related problem. should solve projection test fails.
a7ae560 FlexReader now takes location handler as parameter.
6f1bd8d Disable non-existing Debian build in Makefile.
3d75178 Change warning level on MSVC.
3f0abc0 Appveyor: List cached variables from cmake.
d1e1e9f Travis/Appveyor build in Dev and Release mode. Call ctest on Appveyor.
116bcc9 Fix default node location store.
dedfe0e Make classes we submit to queue properly copyable.
8a432c9 Try the same ugly hack on OPLOutputBlock.
9c5b314 Try a hack to see whether it works on MSVC.
9592132 Give XMLOutputBlock a copy constructor.
991f91a Disable warning C4715: "not all control paths return a value"
340a4d7 Fix copy constructor.
7ceae00 Give OPLOutputBlock a copy constructor which basically does a move.
e82951a Use rvalue as paremeter for queue submit function.
54a9cec Use explicit cast to double to silence warning.
7c5d04c Simplified use of ogr includes.
43fd388 Use appveyor supplied cmake.
ce4311e cmake cleanup.
1108517 Disable warnings from MSVC in OGR headers.
2fe820c Harmonize signature of virtual member function dump_as_list().
93c31b4 Parenthesize string in pragma message.
54ae1a0 Explicitly int to bool conversion to silence warning on MSVC.
4bde9b7 Formatting: Use spaces instead of tabs.
7224d84 cmake: Don't try to set C++ version with -std= with MSVC.
53fbcfd Remove trailing semikolon (which gcc doesn't like).
3b0c9ed Removed command that doesn't work on older cmakes.
de6cc78 Merge pull request #62 from BergWerkGIS/master
9126530 Use less warning options on Windows.
6ec79fb Silence unknown pragma warning on Windows.
b611589 Add static_cast to silence warning on windows.
18e54e9 remove call to build2.bat
b0d9d28 try again with -DCMAKE_BUILD_TYPE=Release
b495018 usage installed cmake, -DCMAKE_BUILD_TYPE=Dev
5bac95d Merge remote-tracking branch 'upstream/master'
d41ea31 cmake: Do not use -Werror when using MSVC compiler
04cfe00 Provide convenience include file to include all index maps.
72fbaa7 Rename multimap indexes according to new schema.
af49a27 Make registering index map types easier.
0a35701 av: remove debug echo calls
886c15f av: ditch -DCMAKE_BUILD_TYPE=Dev
ad0a629 The great renaming of map index classes.
97b4d34 av: try again
bf243b2 Move some hpp files into detail directory and fix include guards.
64e4841 av: try again calling cmake directly
1700789 Add way to dynamically choose node location index.
da49b7f av: try again with build2.bat
4bf55f5 is appveyor working again?
5e63433 delete ws_32.lib patch. generate makefile instead of VS
1054016 Merge remote-tracking branch 'upstream/master'
8c198fc av: try even newer cmake
7cccb06 av: maybe newer cmake helps
d04967a av: no existing env var was still there
80763c6 av: no build.bat, call cmake directly
3b58fc6 av: no cmds over spanning serveral lines?
33c09a0 CALL bat
34639c6 maybe double quotes?
72572de explicitly call VS2014 cmd prompt
6955e87 1st try on AppVeyor

git-subtree-dir: third_party/libosmium
git-subtree-split: 6522da53748e12379bbfaf70ad29ee7bd98ef02d
2015-02-05 15:13:48 +01:00
Dennis Luxen 10224a692b Merge commit 'bb78bc8fe305eef39ca0a5d5e9dedc466f803dfb' into develop 2015-02-05 15:13:48 +01:00
Dennis Luxen 3eb83d0737 add override final specifier to GetTravelMode function in facades 2015-02-05 14:58:07 +01:00
Dennis Luxen f35fa0049c reformat cherry-picked commit 2015-02-05 11:54:30 +01:00
Ben d77a88c21e added lua binding for osmium::Way::id()
Conflicts:
	extractor/scripting_environment.cpp
2015-02-05 11:54:07 +01:00
Dennis Luxen 3d55622237 search quietly for OpenMP 2015-02-05 11:37:55 +01:00
Dennis Luxen bf76465029 use C++11s std::hypot() instead of hand-rolled code 2015-02-05 11:22:46 +01:00
Ben 129a6ed99e added lua binding for osmium::Way::id() 2015-02-04 19:36:39 +00:00
Dennis Luxen 9f5fc4ab0c reorder includes 2015-01-31 21:17:16 +01:00
Dennis Luxen 97f6468663 yet another try to unhack libgomp linking: use OpenMP binding if and only if present 2015-01-29 17:29:03 +01:00
Dennis Luxen a883b73981 add explicit cmake checking step for libgomp 2015-01-29 17:01:08 +01:00
Dennis Luxen 36aadc21a7 fix names of fwd declarations 2015-01-29 16:48:59 +01:00
Dennis Luxen da469911d3 always link against libgomp 2015-01-29 16:23:04 +01:00
Dennis Luxen 4195b0d0e6 Merge pull request #1364 from Project-OSRM/feature/check_libgomp
check if stxxl compiles with or without libgomp, fixes #1361
2015-01-29 12:54:27 +01:00
Dennis Luxen d241aef502 fix checking for successful compilation of stxxl with OpenMP 2015-01-29 12:52:54 +01:00
Dennis Luxen 8b2ca6b13d check if stxxl compiles with or without libgomp, fixes #1361 2015-01-29 12:52:54 +01:00
Dennis Luxen ade94c87b5 remove constexpr keyword that MSVC2013CTP isnt able to handle 2015-01-29 12:50:06 +01:00
Dennis Luxen 46f3426c35 remove Http dir 2015-01-28 12:40:42 +01:00
Dennis Luxen 3503cd9b71 remove another windows directory from ignored files/dirs 2015-01-28 12:35:52 +01:00
Dennis Luxen 73cc040792 add new lower case files and directories to .gitignore 2015-01-28 12:32:09 +01:00
Dennis Luxen 6c6029618a remove left-over directories from the renaming spree 2015-01-28 12:30:14 +01:00
Dennis Luxen 2a8084b6c6 clean up derived classed and their functions to correctly use final keyword:
functions marked as final need to be marked virtual. use override specifier to do so
2015-01-28 12:03:21 +01:00
Dennis Luxen 86ca9bd0f9 mark simple logger write function as noexcept. 2015-01-28 10:09:46 +01:00
Dennis Luxen b192678abf add dummy case to switch statement. reflects all cases are covered and should shut up compiler warnings 2015-01-27 18:44:06 +01:00
Dennis Luxen 9a998d7b41 rename short variable name to be more telling 2015-01-27 18:40:01 +01:00
Dennis Luxen 64a6859753 reduce number of old-style casts 2015-01-27 18:37:52 +01:00
Dennis Luxen b20b7e65bf renamed: Util/* -> util/* 2015-01-27 17:47:23 +01:00
Dennis Luxen 203e3ef077 fix test after header file rename 2015-01-27 17:16:50 +01:00
Dennis Luxen 7be5502a12 renamed: Util/BoostFileSystemFix.h -> Util/boost_filesystem_2_fix.hpp
renamed:    Util/TrigonometryTables.h -> Util/trigonometry_table.hpp
2015-01-27 17:14:03 +01:00
Dennis Luxen 0de6e4ccbb renamed: Util/DataStoreOptions.h -> Util/datastore_options.hpp
renamed:    Util/ProgramOptions.h -> Util/routed_options.hpp
2015-01-27 17:06:10 +01:00
Dennis Luxen c8041bacd6 renamed: Util/IniFileUtil.h -> Util/ini_file.hpp 2015-01-27 16:57:50 +01:00
Dennis Luxen 1187f83ffd renamed: Library/*.h -> library/*.hpp 2015-01-27 16:35:19 +01:00
Dennis Luxen dd3b8469dd renamed: Include/* include/* 2015-01-27 13:17:18 +01:00
Dennis Luxen 34bbd7dcaa renaming yet another variable to fix gcc name lookup 2015-01-27 13:11:04 +01:00
Dennis Luxen 8318b3ba83 rename variable to be more telling that it's not a type but a variable 2015-01-27 13:01:33 +01:00
Dennis Luxen 6768ecc3fc rename variable to make name lookup not fail on gcc 2015-01-27 12:52:55 +01:00
Dennis Luxen 9672f00ec3 renamed: Server/*/*.h -> server/*/*.hpp 2015-01-27 12:35:29 +01:00
Dennis Luxen 0c1101739d renamed: Server/DataStructures/*.h -> Server/data_structures/*.hpp 2015-01-27 12:14:08 +01:00
Dennis Luxen 872cb2d9c8 rename string literal names to replace odd camel case 2015-01-27 11:52:56 +01:00
Dennis Luxen 3e47fe54fa refactor Server/Http to remove camel case 2015-01-27 11:45:33 +01:00
Dennis Luxen f0d3d23b5f make http header parsing case insensitive, and remove some dead code (reset function) 2015-01-27 09:58:26 +01:00
Dennis Luxen 69e59b0ced rename clear() function to reduce camel case noise 2015-01-27 09:57:14 +01:00
Dennis Luxen ad4fb5afe3 revert previous commit that replace boost::array by std::array. not compatible with clang-3.5/boost1.54 2015-01-26 17:37:37 +01:00
Dennis Luxen dd6dd63798 rename iterator variable to be more telling 2015-01-26 16:35:16 +01:00
Dennis Luxen 7a3748b8f6 remove redundant c'tor call 2015-01-26 16:34:05 +01:00
Dennis Luxen 06a08a874f fix performance regression in output generation, use copy elision and return result char array 2015-01-26 13:49:07 +01:00
Dennis Luxen 37a9813482 replace boost::array by std::array 2015-01-26 13:26:21 +01:00
Dennis Luxen fe7b436a8c refactor request parser to use C++11 idioms, plus a couple of consts 2015-01-26 13:20:22 +01:00
Dennis Luxen 601eff1af6 initialize compression type to be no compression 2015-01-26 11:25:10 +01:00
Dennis Luxen 29949eae1b remove unneeded include to boost/tribool 2015-01-23 18:55:58 +01:00
Dennis Luxen 9dfe6d1e85 use std::tuple to return multiple return values, hope for copy elision. Also, removes two cases of parameter reassignment 2015-01-23 18:53:37 +01:00
Dennis Luxen fb3bc22c64 replace boost::tribool with enum based implementation 2015-01-23 18:18:29 +01:00
Dennis Luxen b89304a24b add enum class based tribool implementation 2015-01-23 17:46:23 +01:00
Dennis Luxen 69b3457e83 replace boost::tuple by std::tuple 2015-01-23 17:14:12 +01:00
Dennis Luxen cf21074f10 use enum as return code instead of boolean logic in extractor 2015-01-23 16:59:13 +01:00
Dennis Luxen dc7f21513a move initialization of extractor config into main method and out out extraction logic 2015-01-23 16:30:14 +01:00
Dennis Luxen a15450af91 manually revert previous change as g++ doesnt convert bitfields properly 2015-01-23 14:24:02 +01:00
Dennis Luxen efbcce0ffe use bitfields to reduce struct size of segment information. size goes down from 28->24 bytes 2015-01-23 13:53:02 +01:00
Dennis Luxen 1c2c87e03d fix boundary edge case 2015-01-23 13:52:44 +01:00
Dennis Luxen 93b33c0518 fix cast to be explicit 2015-01-23 13:52:28 +01:00
Dennis Luxen 53e01952be replace for loops with counters by range-based for loops 2015-01-23 12:19:01 +01:00
Dennis Luxen 1c12b468a8 replace for loop with hand-rolled pair-wise traverse of container with call to for_each_pair; fix target type of cast 2015-01-23 12:11:51 +01:00
Dennis Luxen ccd803416e fix unintended float/epsilon<double> comparison 2015-01-23 11:49:02 +01:00
Dennis Luxen 62f2a42f28 reduce cyclomatic complexity in double->string bearing conversion 2015-01-23 11:44:35 +01:00
Dennis Luxen d6e76fd1c0 add whitespace 2015-01-23 11:38:47 +01:00
Dennis Luxen 9135c56ac6 fix implicit float/double conversion, use casts 2015-01-23 11:26:47 +01:00
Dennis Luxen 0e7eff3963 rename short variable names in mercator to be more telling 2015-01-23 11:14:29 +01:00
Dennis Luxen bd1928e445 rename short variable names to be more telling 2015-01-23 09:47:44 +01:00
Dennis Luxen 8e105af232 remove redundant code from switch statement in restriction parser 2015-01-23 09:25:05 +01:00
Dennis Luxen 796cbafde4 add missing include in release build 2015-01-22 17:57:38 +01:00
Dennis Luxen 29354a1586 fix bearing computation 2015-01-22 17:07:04 +01:00
Dennis Luxen bcd73e604c reformat coordinate and rtree test code 2015-01-22 17:00:48 +01:00
Dennis Luxen e80ca6553d use new coordinate interface in unit tests 2015-01-22 16:58:45 +01:00
Dennis Luxen 90f17c2140 remove is_set() and reset() functions from coordinate 2015-01-22 16:55:34 +01:00
Dennis Luxen 2e5cc1e6ae remove redundant code and streamline coordinate interface 2015-01-22 16:48:53 +01:00
Dennis Luxen 0ea7fd9c3d remove more dead/unused functions 2015-01-22 16:41:04 +01:00
Dennis Luxen 814d9aa01b reformat code source file 2015-01-22 16:33:27 +01:00
Dennis Luxen 3fa12445a5 rename coordinate calculation functions, remove code clutter 2015-01-22 16:28:40 +01:00
Dennis Luxen 547a2aec09 remove dead/redundant code 2015-01-22 15:50:04 +01:00
Dennis Luxen 9175fb7da8 remove unused debug code 2015-01-22 15:19:43 +01:00
Dennis Luxen 887032881a use std::any_of() algorithm instead of hand-rolled logic 2015-01-22 15:09:24 +01:00
Dennis Luxen e67f82283f replace temporary variable with short name by atomic<>.load call 2015-01-22 13:47:31 +01:00
Dennis Luxen cfa83658dc Use early exit/continue to simplify code and reduce indentation 2015-01-22 12:39:41 +01:00
Dennis Luxen c881aa7b32 Use early exit/continue to simplify code and reduce indentation, move increase/decrease query count into functions 2015-01-22 12:38:48 +01:00
Dennis Luxen a8db29399f remove unneeded else block in if statement 2015-01-22 12:28:00 +01:00
Dennis Luxen baacd0e50c reformat source files 2015-01-22 12:24:54 +01:00
Dennis Luxen 0f8c3b1960 fix copyright year 2015-01-22 12:18:48 +01:00
Dennis Luxen cd523cc934 conflate collapsable if statements 2015-01-22 12:14:14 +01:00
Dennis Luxen 044271a55c specialize insert function to pass by reference for non-fundamental types by using type traits 2015-01-22 11:02:49 +01:00
Dennis Luxen f662b9a081 install libgdal-dev on Travis 2015-01-20 18:45:49 +01:00
Dennis Luxen ba10f97420 add third_party directory node to the include dirs 2015-01-20 18:23:10 +01:00
Dennis Luxen 50c460ebd5 install mapbox/variant headers from third_party directory 2015-01-20 18:07:45 +01:00
Dennis Luxen 501863a0eb move external dependence mapbox/variant into third_party directory 2015-01-20 18:06:26 +01:00
Dennis Luxen ec9b2dbe42 remove debug info from binaries 2015-01-20 17:57:47 +01:00
Dennis Luxen db2ba22bd6 fix tests to run with new header coordinate_calculations 2015-01-20 17:56:50 +01:00
Dennis Luxen 087f08dad2 also build tests on travis CI 2015-01-20 17:56:30 +01:00
Dennis Luxen bf7b146dfc Merge pull request #1350 from Project-OSRM/feature/prune_incremental_search
speed up nearest neighbor query by pruning
2015-01-20 17:36:23 +01:00
Dennis Luxen 01f3237416 speed up nearest neighbor query by pruning, move coordinate calculations away from library interface 2015-01-20 16:24:49 +01:00
Dennis Luxen 8f813fbc67 clear result nodes/way in parser for each parsed element 2015-01-20 11:25:21 +01:00
Dennis Luxen f4ff695080 replace conditional operator by explicit serialization 2015-01-20 10:50:33 +01:00
Dennis Luxen 08cc2bbd70 move thread local variables out of parsing scope 2015-01-16 18:22:37 +01:00
Dennis Luxen 46a7e46068 serialize lvalues as MSVC barfs out on serializing the return value of the conditional operator 2015-01-16 18:12:21 +01:00
Dennis Luxen 472a567f42 add cmath include to fix call to std::abs() on clang compiler, reorder includes 2015-01-16 17:23:29 +01:00
Dennis Luxen f3bc1ed3a9 make floating point number literal a float 2015-01-16 17:21:02 +01:00
Dennis Luxen 7ba9b97afc reorder members of internal extractor edge. 56->40 bytes 2015-01-16 17:11:30 +01:00
Dennis Luxen 061d281d2a serialize bitfields thru local member mockups 2015-01-16 17:10:31 +01:00
Dennis Luxen 2835508292 fixes #1346:
- use const_iterator where it makes sense
- fix renumbering of turn restriction members
- remove redundant code
- fix counting of usable turn restrictions
2015-01-16 15:56:49 +01:00
Dennis Luxen 959d9a3ad9 explicitly implement check if is_only turn is restricted 2015-01-16 15:52:41 +01:00
Dennis Luxen 7cf34a6d6f make debug output more verbose during renumbering of turn restriction members 2015-01-16 15:47:01 +01:00
Dennis Luxen 8d6d7d1f20 remove superflous inline keywords 2015-01-16 11:27:46 +01:00
Dennis Luxen b115764d9c Merge pull request #1347 from Project-OSRM/perpendicular-fix
Fix ComputePerpendicularDistance convinience function
2015-01-16 09:53:49 +01:00
Patrick Niklaus 1b5d332e93 Add regression test for FixedpointCoordinate 2015-01-16 00:49:43 +01:00
Patrick Niklaus 356dfc806d Fix ComputePerpendicularDistance convinience function
This function is used by StaticRTree and returns wrong results.
The other variation is correct. To reduce code duplication
the correct version is used instead, as the implementation is nearly
identical.
2015-01-16 00:34:07 +01:00
Dennis Luxen f2b556adfd umbenannt: UnitTests/* -> unit_tests/* 2015-01-15 18:39:26 +01:00
Dennis Luxen 1bbfced61a reorder includes 2015-01-15 18:10:22 +01:00
Dennis Luxen 800cb8c6dd renamed: ../UnitTests/data_structures/BinaryHeapTest.cpp -> ../UnitTests/data_structures/binary_heap.cpp
renamed:    ../UnitTests/data_structures/RangeTableTest.cpp -> ../UnitTests/data_structures/range_table.cpp
renamed:    ../UnitTests/data_structures/StaticGraphTest.cpp -> ../UnitTests/data_structures/static_graph.cpp
renamed:    ../UnitTests/data_structures/StaticRTreeTest.cpp -> ../UnitTests/data_structures/static_rtree.cpp
2015-01-15 18:07:47 +01:00
Dennis Luxen 6b1d672dc1 fix signed/unsigned comparison 2015-01-15 13:11:25 +01:00
Dennis Luxen 6e138bbf54 fixes data structure tests:
- MapStorage: fix returned index in peek_index() on fail
- UnorderedMapStorage: fix returned index in peek_index() on fail
- BinaryHeap: auto-deduce Index type
- ArrayStorage: replace raw array with std::vector
2015-01-15 12:59:08 +01:00
Dennis Luxen 6dabf4507a implement peek_index() functions for all binary heap storage classes 2015-01-15 11:15:48 +01:00
Dennis Luxen 527e6cbc72 xor fast hash storage: reorder initialization of elements, delete default c'tor, resetting of table may be expensive as it is rare 2015-01-14 18:14:55 +01:00
Dennis Luxen 39edbcbabd after profiling with intel vtune, mitigate some performance hotspots. may give a 10-20% performance boost during preprocessing 2015-01-14 17:26:59 +01:00
Dennis Luxen 0077856d2f Merge commit 'b65f1d7df0b997eac085da7f5a3344a86b812916' as 'Include/variant' 2015-01-14 09:36:20 +01:00
Dennis Luxen b65f1d7df0 Squashed 'Include/variant/' content from commit 00ab881
git-subtree-dir: Include/variant
git-subtree-split: 00ab88117ed25f78cdca2faa00beea0061271e85
2015-01-14 09:36:20 +01:00
Dennis Luxen 201afbbeec rm hard copy of variant. 2015-01-14 09:32:43 +01:00
Dennis Luxen f5caf96d2e add new include dir of libosmium 2015-01-13 17:14:54 +01:00
Dennis Luxen 73efcc6b0c Squashed 'third_party/libosmium/' content from commit 910f8f1
git-subtree-dir: third_party/libosmium
git-subtree-split: 910f8f1e992402e0f1acd0132eaffa7539ca83d2
2015-01-13 16:54:25 +01:00
Dennis Luxen d69510f997 Merge commit '73efcc6b0ccedf8c1b6d95abdba8340cc9adf100' as 'third_party/libosmium' 2015-01-13 16:54:25 +01:00
Dennis Luxen d6946a8aae remove copy of libosmium, to be replaced by a subtree 2015-01-13 16:50:31 +01:00
Dennis Luxen ebbc168f3f fix implicit integer cast, reorder includes 2015-01-13 16:46:44 +01:00
Dennis Luxen 347cbd37ca fix include guard naming in plugin base 2015-01-13 16:15:51 +01:00
Dennis Luxen d190e0b771 Merge pull request #1343 from Project-OSRM/feature/static_graph_components
use static graph for component exploration, closes #1288
2015-01-13 16:06:48 +01:00
Dennis Luxen 5f28a7db0d add some whitespace 2015-01-13 15:52:24 +01:00
Dennis Luxen d0c99f1999 fix linking of benchmarks and tests 2015-01-13 15:45:27 +01:00
Dennis Luxen bf71781ee9 new file: Util/mercator.cpp
renamed:    Util/MercatorUtil.h -> Util/mercator.hpp
2015-01-13 14:57:23 +01:00
Dennis Luxen fbce104f3b use static graph for component exploration, closes #1288 2015-01-13 14:24:56 +01:00
Dennis Luxen ef9074f8e4 renamed: Util/finger_print.* -> Util/fingerprint.*
thx @emiltin
2015-01-13 11:16:13 +01:00
Dennis Luxen 67f3111cc0 renamed: Util/FingerPrint.h -> Util/finger_print.hpp 2015-01-13 11:05:22 +01:00
Dennis Luxen 56d2101b1a Merge pull request #1339 from Project-OSRM/test_appveyor_default_os
remove explicit appveyor os spec to get scheduled on hyper-v
2015-01-12 16:28:27 +01:00
Emil Tin a28395b116 remove accidentally added files 2015-01-12 13:58:32 +01:00
Emil Tin eebf3a54e2 cuke: abort if bins are missing, closes #1341 2015-01-12 13:56:43 +01:00
Dennis Luxen 7e70fa63d7 Merge pull request #1338 from frodrigo/develop
Black list access=psv for car profile
2015-01-09 23:39:49 +01:00
Dennis Luxen bea4b520c0 Revert "Revert "fix #1255 assume lift gates are passable""
This reverts commit cec3d1488a.

*sigh*
2015-01-09 19:15:00 +01:00
Dennis Luxen 64c17c4ecd remove explicit appveyor os spec to get scheduled on hyper-v 2015-01-09 18:53:15 +01:00
Frederic Rodrigo 26f7ac9ca1 Black list access=psv for car profile 2015-01-09 17:14:16 +00:00
Dennis Luxen b1a12768e1 fix parameter name for maximum number of location in distance table plugin 2015-01-08 17:41:19 +01:00
Dennis Luxen 0e5a448d04 Merge pull request #1335 from Project-OSRM/feature/frodrigo-max_locations_distance_table
Feature/frodrigo max locations distance table
2015-01-08 16:07:17 +01:00
Dennis Luxen 91a89399f8 fix copyright year 2015-01-08 15:07:01 +01:00
Dennis Luxen c6bb7c5993 renamed: Include/osrm/ServerConfig.h -> Include/osrm/libosrm_config.hpp
pass lib config object by reference
2015-01-08 15:05:54 +01:00
Dennis Luxen 48b131eb5c Merge branch 'max_locations_distance_table' of https://github.com/frodrigo/osrm-backend into frodrigo-max_locations_distance_table
Conflicts:
	Library/OSRM.h
	Library/OSRM_impl.cpp
	Library/OSRM_impl.h
2015-01-08 14:49:10 +01:00
Dennis Luxen 1328be2b61 move structs into anon namespace, move containers in function scope 2015-01-07 12:30:01 +01:00
Dennis Luxen 88c1e622dd fix copyright year 2015-01-07 12:29:13 +01:00
Dennis Luxen 10672786a1 fix copyright year and include guard 2015-01-07 12:28:26 +01:00
Dennis Luxen d896a9efec remove superflous inline keywords as this DeallocatingVector is header-defined, also remove ignored const keywords 2015-01-07 12:26:49 +01:00
Dennis Luxen 0ccdd4b6ad fix implicit conversion that _may_ lose integer precision 2015-01-07 12:26:09 +01:00
Dennis Luxen 66fc676858 remove unused parameter, move previously templated function into compile unit 2015-01-06 20:05:33 +01:00
Frederic Rodrigo 12f2acc9ff Order ServerPaths members by memory size, pass ServerPaths by ref 2015-01-06 15:33:57 +00:00
Dennis Luxen b53e8bf501 remove implicit conversion 2015-01-06 15:31:55 +01:00
Dennis Luxen e296264ea6 Merge pull request #1292 from Project-OSRM/feature/json_lib_interface
Feature/json lib interface
2015-01-06 15:27:40 +01:00
Frédéric Rodrigo 598f5519d1 Remove setters from structures server_config 2015-01-06 14:11:09 +00:00
Frédéric Rodrigo ced64d7a09 Move server configuration from method parameter to a struct 2015-01-06 14:11:09 +00:00
Frédéric Rodrigo 7075a8a8ef Fix tests for new option --max_locations_distance_table 2015-01-06 14:11:09 +00:00
Frédéric Rodrigo e2605c2838 Add a commande line option to osrm-routed for max locations supported in distance table query 2015-01-06 14:11:09 +00:00
Dennis Luxen be63939441 fix includes 2015-01-06 13:35:36 +01:00
Dennis Luxen dea9c37d99 fix bad request error message 2015-01-06 13:27:51 +01:00
Dennis Luxen 4d27366ead fix compilation of benchmark tests 2015-01-06 13:27:51 +01:00
Dennis Luxen a11a8429bb remove unneeded header file 2015-01-06 13:27:51 +01:00
Dennis Luxen 6da33cafe5 rebase branch onto latest develop, report changes. hurt a little 2015-01-06 13:27:50 +01:00
Dennis Luxen 06f82d5e8a install variant by default 2015-01-06 13:22:12 +01:00
Dennis Luxen 89dd0c4a40 install headers with .hpp suffix 2015-01-06 13:22:12 +01:00
Dennis Luxen 1b10f53eff DataStructures/RawRouteData.h -> DataStructures/internal_route_result.hpp, implements #1238 2015-01-06 13:22:12 +01:00
Dennis Luxen 8bd7d57dd8 fixed compilation of simple client
- adapted to new lib interface
- fixed return codes of command line parsing
- reformatted code
2015-01-06 13:20:56 +01:00
Dennis Luxen 4a6325696e change library interface to expose json container as structure to exchange data 2015-01-06 13:19:21 +01:00
Dennis Luxen b50a907ca3 fix changed include paths 2015-01-06 13:17:12 +01:00
Dennis Luxen 59e9a67abd rename and remove include header files for stabilized lib API 2015-01-06 13:09:44 +01:00
Liu Jiaming 1d2f06df6d Fix std::list splice usage error 2015-01-06 13:02:05 +01:00
Dennis Luxen 725b93a961 Merge branch 'develop' 2015-01-06 11:03:29 +01:00
Dennis Luxen a21e4c5a0b link library against exception lib 2015-01-06 11:00:44 +01:00
Dennis Luxen 433db17083 fix initialization of simple client 2015-01-05 18:14:49 +01:00
Dennis Luxen f8753fb9f1 fix overly long line 2015-01-05 16:32:11 +01:00
Dennis Luxen 25d5653f66 rename a number of overly long variable names 2015-01-05 16:29:33 +01:00
Dennis Luxen 703a88a639 remove empty d'tor from osrm::exception 2015-01-05 15:53:28 +01:00
Dennis Luxen 25326b571b renamed: Util/OSRMException.h -> Util/osrm_exception.hpp 2015-01-05 15:40:05 +01:00
Dennis Luxen 5e2f4c9d2d fix header include 2015-01-05 14:47:05 +01:00
Dennis Luxen f43d380fe2 remove unneeded method 2015-01-05 14:46:38 +01:00
Dennis Luxen 2240d3d0d1 add new header file 2015-01-05 14:39:17 +01:00
Dennis Luxen b6eea9a880 fix unintended implicit cast from unsigned to signed 2015-01-05 14:38:24 +01:00
Dennis Luxen 6bbd7c0c0b update ignore list in git 2015-01-05 14:37:35 +01:00
Dennis Luxen 2caeb4008c renamed: Util/GitDescription.cpp.in -> Util/git_sha.cpp.in
renamed:    Util/GitDescription.h -> Util/git_sha.h
2015-01-05 14:32:04 +01:00
Dennis Luxen a4919ffb45 re-enable hintin mechanism 2015-01-05 12:59:29 +01:00
Dennis Luxen b384340cbb Revert "remove remnants of hinting mechanism"
This reverts commit 7de428233e.
2015-01-05 12:57:34 +01:00
Dennis Luxen 061f46306f remove unneeded lvalue parameter 2015-01-05 12:00:11 +01:00
Dennis Luxen fe1f11b071 renamed: Util/StringUtil.h -> Util/string_util.hpp 2015-01-05 10:22:11 +01:00
Patrick Niklaus d3f5db576a Enable gcc color output when available 2015-01-04 23:13:15 +01:00
Emil Tin 0ca586e1c8 cuke: remove unneeded @x tag 2015-01-03 16:53:01 +01:00
Emil Tin a0b55f9df3 table tests: use empty string to mean no route 2015-01-03 11:12:47 +01:00
Dennis Luxen 24943ccee6 fix use of old-style cast 2015-01-02 17:43:46 +01:00
Dennis Luxen bcaaf34fa7 implicit conversion loses integer precision 2015-01-02 17:41:11 +01:00
Dennis Luxen ea17d1f6c7 dynamic exception specifications are deprecated, use 'noexcept' instead 2015-01-02 17:39:11 +01:00
Dennis Luxen 3be734010c fix warning: 'const' type qualifier on return type has no effect 2015-01-02 17:34:21 +01:00
Dennis Luxen e79787cc77 reorder members to avoid padding class 'SimpleLogger' with 4 bytes to align 'os' 2015-01-02 17:32:52 +01:00
Dennis Luxen 7de428233e remove remnants of hinting mechanism 2015-01-02 17:10:47 +01:00
Dennis Luxen 9722f56be8 remove more debug code 2015-01-02 16:41:36 +01:00
Dennis Luxen e766d206f1 remove debug code 2015-01-02 16:06:09 +01:00
Dennis Luxen 1fa9091239 retire json hinting mechanism 2015-01-02 15:46:43 +01:00
Dennis Luxen 04e1e5e3a2 reformat code 2015-01-02 15:17:15 +01:00
Dennis Luxen fa5c0560fa use tiny cc id if all phantoms have such an id, and if and only if all ids are equal 2015-01-02 09:36:27 +01:00
Dennis Luxen 55d47b3e31 reimplement incremental nearest neighbor query 2015-01-02 09:36:27 +01:00
Dennis Luxen 5bb96fd477 reformat code of phantom node c'tor for legibility 2015-01-02 09:36:27 +01:00
Dennis Luxen 22b404a1b4 add is_in_tiny_cc() util function 2015-01-02 09:36:27 +01:00
Dennis Luxen 03dcf82602 use first phantom node of second pair 2015-01-02 09:36:26 +01:00
Dennis Luxen 95d1e8a4f1 adapt viaroute plugin to query NN search for vector of phantom nodes 2015-01-02 09:36:26 +01:00
Emil Tin 67f68b47db add fuzzy match to table tests, add more tests 2015-01-01 20:19:41 +01:00
Emil Tin 593808f24d initial support for testing distance matrices 2015-01-01 15:12:45 +01:00
Dennis Luxen 0a884cc64a don't stop traversing at bollard node 2014-12-31 16:04:53 +01:00
Dennis Luxen a54d4b98b1 add const keyword in range based for loop 2014-12-31 16:04:53 +01:00
Patrick Niklaus 23132e5292 Use >= 0 to include routes where start/end is the same 2014-12-31 15:59:42 +01:00
Dennis Luxen d741b624be pass component class by ref (not value) in edge-based graph factory 2014-12-30 11:44:11 +01:00
Patrick Niklaus 00bc394bdb Fix off-by-one in distance table plugin.
Should fix #1320.
2014-12-28 17:45:55 +01:00
Dennis Luxen d7215ad185 fix tests, temporarily disable one test case 2014-12-24 13:03:05 +01:00
Dennis Luxen 2b63eb8243 remove zoom level from nearest neighbor calls 2014-12-24 10:40:03 +01:00
Dennis Luxen 1bb3da0332 expose component_id in phantom node 2014-12-24 10:25:27 +01:00
Dennis Luxen c7d3d635f6 fix test compile 2014-12-23 17:18:32 +01:00
Dennis Luxen f4c8db6105 - serialize component_id
- remove calls to deprecated NN function in facades
2014-12-23 16:14:28 +01:00
Dennis Luxen b2637b9a43 compute component id for each SCC 2014-12-23 15:26:06 +01:00
Dennis Luxen 09d0ac3838 add aux. function to get component id for a given node 2014-12-23 15:17:38 +01:00
Dennis Luxen f42cc848d5 - correct number of components in compressed graph by number of removed nodes
- replace integer for loops by integer range-based loop
2014-12-23 14:51:25 +01:00
Dennis Luxen 4b1224f874 fix copyright year 2014-12-23 14:38:04 +01:00
Dennis Luxen 10bb2cce8e count number of removed nodes as a private member variable in EdgeBasedGraphFactory 2014-12-23 14:37:01 +01:00
Dennis Luxen 8174b3b85a output total number of compoments and those of size one 2014-12-23 14:33:38 +01:00
Dennis Luxen 71e2f2ed61 move SCC stats output out of algo implementation 2014-12-23 14:31:55 +01:00
Dennis Luxen 8d8724b3e1 use SCC code for exploration of components 2014-12-23 12:27:04 +01:00
Dennis Luxen 47f65ccba6 use restriction map in tiny components 2014-12-23 11:47:19 +01:00
Dennis Luxen df0c1106ce compile and link restriction map object to components and routes 2014-12-23 11:46:25 +01:00
Dennis Luxen 47a2271e27 copy edits: 2014-12-23 11:30:45 +01:00
Dennis Luxen ea367a7f37 add better checks for forbidden routes 2014-12-22 18:12:47 +01:00
Dennis Luxen f4b192e33c simplify code 2014-12-22 18:12:18 +01:00
Dennis Luxen a5c824f694 adapt tiny_components.hpp to have the same interface as bfs_components.hpp 2014-12-22 16:43:57 +01:00
Dennis Luxen 75f9c08445 Merge pull request #1266 from Project-OSRM/revert-1256-patch-1
Revert "fix #1255 assume lift gates are passable"
2014-11-13 14:24:09 +01:00
Dennis Luxen cec3d1488a Revert "fix #1255 assume lift gates are passable" 2014-11-13 14:23:54 +01:00
Dennis Luxen ebec082da2 Merge pull request #1256 from AlanBell/patch-1
fix #1255 assume lift gates are passable
2014-11-13 14:23:42 +01:00
546 changed files with 55969 additions and 9492 deletions
+7 -20
View File
@@ -1,3 +1,7 @@
# pre compiled dependencies #
#############################
osrm-deps
# Compiled source #
###################
*.com
@@ -36,8 +40,8 @@ Thumbs.db
# build related files #
#######################
/build/
/Util/finger_print.cpp
/Util/GitDescription.cpp
/util/fingerprint_impl.hpp
/util/git_sha.cpp
/cmake/postinst
# Eclipse related files #
@@ -53,25 +57,8 @@ Thumbs.db
stxxl.log
stxxl.errlog
# compiled protobuffers #
#########################
/DataStructures/pbf-proto/*.pb.h
/DataStructures/pbf-proto/*.pb.cc
# External Libs #
#################
/lib/
/win/lib
# Visual Studio Temp + build Files #
# Compiled Binary Files #
####################################
/win/*.user
/win/*.ncb
/win/*.suo
/win/Debug/
/win/Release/
/win/bin/
/win/bin-debug/
/osrm-extract
/osrm-io-benchmark
/osrm-components
+9 -4
View File
@@ -10,6 +10,7 @@ install:
- sudo apt-get -q install protobuf-compiler libprotoc-dev libprotobuf7 libprotobuf-dev libbz2-dev libstxxl-dev libstxxl1 libxml2-dev libzip-dev lua5.1 liblua5.1-0-dev rubygems libtbb-dev
- sudo apt-get -q install g++-4.8
- sudo apt-get install libboost1.54-all-dev
- sudo apt-get install libgdal-dev
# luabind
- curl https://gist.githubusercontent.com/DennisOSRM/f2eb7b948e6fe1ae319e/raw/install-luabind.sh | sudo bash
# osmosis
@@ -24,10 +25,12 @@ before_script:
- bundle install
- mkdir build
- cd build
- cmake .. $CMAKEOPTIONS
- cmake .. $CMAKEOPTIONS -DBUILD_TOOLS=1
script:
- make -j 2
- make -j 2 tests
- make
- make tests
- make benchmarks
- ./algorithm-tests
- ./datastructure-tests
- cd ..
- cucumber -p verify
@@ -44,7 +47,9 @@ cache:
env:
- CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=g++-4.8" OSRM_PORT=5000 OSRM_TIMEOUT=60
- CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER=g++-4.8" OSRM_PORT=5010 OSRM_TIMEOUT=60
- CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DCMAKE_CXX_COMPILER=g++-4.8" OSRM_PORT=5020 OSRM_TIMEOUT=60
notifications:
slack: mapbox:4A6euphDwfxAQnhLurXbu6A1
irc:
channels:
- irc.oftc.net#osrm
@@ -54,7 +59,7 @@ notifications:
skip_join: false
recipients:
- dennis@mapbox.com
- patrick@mapbox.com
email:
on_success: change
on_failure: always
+102 -72
View File
@@ -1,17 +1,17 @@
cmake_minimum_required(VERSION 2.8.8)
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE)
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR AND NOT MSVC_IDE)
message(FATAL_ERROR "In-source builds are not allowed.
Please create a directory and run cmake from there, passing the path to this source directory as the last argument.
This process created the file `CMakeCache.txt' and the directory `CMakeFiles'. Please delete them.")
endif()
project(OSRM)
project(OSRM C CXX)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include(CheckCXXCompilerFlag)
include(FindPackageHandleStandardArgs)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(GetGitRevisionDescription)
git_describe(GIT_DESCRIPTION)
@@ -23,82 +23,89 @@ else()
message(WARNING "Building on a 32 bit system is unsupported")
endif()
if (WIN32 AND MSVC_VERSION LESS 1800)
if(WIN32 AND MSVC_VERSION LESS 1800)
message(FATAL_ERROR "Building with Microsoft compiler needs Visual Studio 2013 or later (Express version works too)")
endif()
OPTION(WITH_TOOLS "Build OSRM tools" OFF)
OPTION(BUILD_TOOLS "Build OSRM tools" OFF)
option(ENABLE_JSON_LOGGING "Adds additional JSON debug logging to the response" OFF)
option(WITH_TOOLS "Build OSRM tools" OFF)
option(BUILD_TOOLS "Build OSRM tools" OFF)
include_directories(${CMAKE_SOURCE_DIR}/Include/)
include_directories(${CMAKE_SOURCE_DIR}/third_party/)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/libosmium/include/)
add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/Util/finger_print.cpp finger_print.cpp.alwaysbuild
COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_SOURCE_DIR}
add_custom_target(FingerPrintConfigure ALL
${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_SOURCE_DIR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/FingerPrint-Config.cmake
DEPENDS
${CMAKE_SOURCE_DIR}/Util/finger_print.cpp.in
COMMENT "Configuring finger_print.cpp"
COMMENT "Configuring revision fingerprint"
VERBATIM)
add_custom_target(FingerPrintConfigure DEPENDS ${CMAKE_SOURCE_DIR}/Util/finger_print.cpp)
add_custom_target(tests DEPENDS datastructure-tests algorithm-tests)
add_custom_target(benchmarks DEPENDS rtree-bench)
set(BOOST_COMPONENTS date_time filesystem iostreams program_options regex system thread unit_test_framework)
configure_file(
${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp.in
${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp
${CMAKE_CURRENT_SOURCE_DIR}/util/git_sha.cpp.in
${CMAKE_CURRENT_SOURCE_DIR}/util/git_sha.cpp
)
file(GLOB ExtractorGlob extractor/*.cpp)
file(GLOB ImporterGlob data_structures/import_edge.cpp data_structures/external_memory_node.cpp)
add_library(IMPORT OBJECT ${ImporterGlob})
add_library(LOGGER OBJECT Util/simple_logger.cpp)
add_library(LOGGER OBJECT util/simple_logger.cpp)
add_library(PHANTOMNODE OBJECT data_structures/phantom_node.cpp)
add_library(EXCEPTION OBJECT util/osrm_exception.cpp)
add_library(MERCATOR OBJECT util/mercator.cpp)
add_library(ANGLE OBJECT util/compute_angle.cpp)
set(ExtractorSources extract.cpp ${ExtractorGlob})
add_executable(osrm-extract ${ExtractorSources} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:LOGGER>)
add_executable(osrm-extract ${ExtractorSources} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR>)
file(GLOB PrepareGlob contractor/*.cpp data_structures/hilbert_value.cpp data_structures/restriction_map.cpp Util/compute_angle.cpp)
add_library(RESTRICTION OBJECT data_structures/restriction_map.cpp)
file(GLOB PrepareGlob contractor/*.cpp data_structures/hilbert_value.cpp {RestrictionMapGlob})
set(PrepareSources prepare.cpp ${PrepareGlob})
add_executable(osrm-prepare ${PrepareSources} $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:LOGGER>)
add_executable(osrm-prepare ${PrepareSources} $<TARGET_OBJECTS:ANGLE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:RESTRICTION> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR>)
file(GLOB ServerGlob Server/*.cpp)
file(GLOB ServerGlob server/*.cpp)
file(GLOB DescriptorGlob descriptors/*.cpp)
file(GLOB DatastructureGlob data_structures/search_engine_data.cpp data_structures/route_parameters.cpp Util/bearing.cpp)
file(GLOB DatastructureGlob data_structures/search_engine_data.cpp data_structures/route_parameters.cpp util/bearing.cpp)
list(REMOVE_ITEM DatastructureGlob data_structures/Coordinate.cpp)
file(GLOB CoordinateGlob data_structures/Coordinate.cpp)
file(GLOB CoordinateGlob data_structures/coordinate*.cpp)
file(GLOB AlgorithmGlob algorithms/*.cpp)
file(GLOB HttpGlob Server/Http/*.cpp)
file(GLOB LibOSRMGlob Library/*.cpp)
file(GLOB DataStructureTestsGlob UnitTests/data_structures/*.cpp data_structures/hilbert_value.cpp)
file(GLOB AlgorithmTestsGlob UnitTests/Algorithms/*.cpp)
file(GLOB HttpGlob server/http/*.cpp)
file(GLOB LibOSRMGlob library/*.cpp)
file(GLOB DataStructureTestsGlob unit_tests/data_structures/*.cpp data_structures/hilbert_value.cpp)
file(GLOB AlgorithmTestsGlob unit_tests/algorithms/*.cpp)
set(
OSRMSources
${LibOSRMGlob}
${DescriptorGlob}
${DatastructureGlob}
${CoordinateGlob}
${AlgorithmGlob}
${HttpGlob}
)
add_library(COORDINATE OBJECT ${CoordinateGlob})
add_library(FINGERPRINT OBJECT Util/finger_print.cpp)
add_library(GITDESCRIPTION OBJECT Util/GitDescription.cpp)
add_library(OSRM ${OSRMSources} $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE>)
add_dependencies(FINGERPRINT FingerPrintConfigure)
add_executable(osrm-routed routed.cpp ${ServerGlob})
add_executable(osrm-datastore datastore.cpp $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:LOGGER>)
add_library(COORDINATE OBJECT ${CoordinateGlob})
add_library(GITDESCRIPTION OBJECT util/git_sha.cpp)
add_library(OSRM ${OSRMSources} $<TARGET_OBJECTS:ANGLE> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR> $<TARGET_OBJECTS:IMPORT>)
add_library(FINGERPRINT OBJECT util/fingerprint.cpp)
add_dependencies(FINGERPRINT FingerPrintConfigure)
add_dependencies(OSRM FingerPrintConfigure)
set_target_properties(FINGERPRINT PROPERTIES LINKER_LANGUAGE CXX)
add_executable(osrm-routed routed.cpp ${ServerGlob} $<TARGET_OBJECTS:EXCEPTION>)
add_executable(osrm-datastore datastore.cpp $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR>)
# Unit tests
add_executable(datastructure-tests EXCLUDE_FROM_ALL UnitTests/datastructure_tests.cpp ${DataStructureTestsGlob} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE>)
add_executable(algorithm-tests EXCLUDE_FROM_ALL UnitTests/algorithm_tests.cpp ${AlgorithmTestsGlob} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE>)
add_executable(datastructure-tests EXCLUDE_FROM_ALL unit_tests/datastructure_tests.cpp ${DataStructureTestsGlob} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR>)
add_executable(algorithm-tests EXCLUDE_FROM_ALL unit_tests/algorithm_tests.cpp ${AlgorithmTestsGlob} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE> $<TARGET_OBJECTS:EXCEPTION>)
# Benchmarks
add_executable(rtree-bench EXCLUDE_FROM_ALL benchmarks/static_rtree.cpp $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE>)
add_executable(rtree-bench EXCLUDE_FROM_ALL benchmarks/static_rtree.cpp $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR>)
# Check the release mode
if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
@@ -106,7 +113,7 @@ if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
endif()
if(CMAKE_BUILD_TYPE MATCHES Debug)
message(STATUS "Configuring OSRM in debug mode")
if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
if(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC")
message(STATUS "adding profiling flags")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage -fno-inline")
set(CMAKE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage -fno-inline")
@@ -116,40 +123,54 @@ if(CMAKE_BUILD_TYPE MATCHES Release)
message(STATUS "Configuring OSRM in release mode")
# Check if LTO is available
set(LTO_FLAGS "")
CHECK_CXX_COMPILER_FLAG("-flto" HAS_LTO_FLAG)
if (HAS_LTO_FLAG)
set(LTO_FLAGS "${LTO_FLAGS} -flto")
check_cxx_compiler_flag("-flto" LTO_AVAILABLE)
if(LTO_AVAILABLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
set(CHECK_LTO_SRC "int main(){return 0;}")
check_cxx_source_compiles("${CHECK_LTO_SRC}" LTO_WORKS)
if(LTO_WORKS)
message(STATUS "LTO working")
else()
message(STATUS "LTO broken")
set(CMAKE_CXX_FLAGS "${OLD_CXX_FLAGS}")
endif()
# Since gcc 4.9 the LTO format is non-standart ('slim'), so we need to use the build-in tools
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND
NOT "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "4.9.0" AND NOT MINGW)
message(STATUS "Using gcc specific binutils for LTO.")
set(CMAKE_AR "/usr/bin/gcc-ar")
set(CMAKE_RANLIB "/usr/bin/gcc-ranlib")
endif()
endif (HAS_LTO_FLAG)
endif()
endif()
if (NOT WIN32)
add_definitions(-DBOOST_TEST_DYN_LINK)
if(NOT WIN32)
add_definitions(-DBOOST_TEST_DYN_LINK)
endif()
# Configuring compilers
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
# using Clang
# -Weverything -Wno-c++98-compat -Wno-shadow -Wno-exit-time-destructors
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wunreachable-code -pedantic -fPIC")
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
set(COLOR_FLAG "-fdiagnostics-color=auto")
check_cxx_compiler_flag("-fdiagnostics-color=auto" HAS_COLOR_FLAG)
if(NOT HAS_COLOR_FLAG)
set(COLOR_FLAG "")
endif()
# using GCC
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -fPIC")
if (WIN32) # using mingw
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -fPIC ${COLOR_FLAG}")
if(WIN32) # using mingw
add_definitions(-D_USE_MATH_DEFINES) # define M_PI, M_1_PI etc.
add_definitions(-DWIN32)
SET(OPTIONAL_SOCKET_LIBS ws2_32 wsock32)
set(OPTIONAL_SOCKET_LIBS ws2_32 wsock32)
endif()
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")
# using Intel C++
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-intel -wd10237 -Wall -ipo -fPIC")
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC")
# using Visual Studio C++
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} date_time chrono zlib)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
@@ -162,8 +183,8 @@ elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
endif()
# Activate C++11
if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
ADD_DEFINITIONS(-std=c++11)
if(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ")
endif()
# Configuring other platform dependencies
@@ -233,7 +254,7 @@ include_directories(${LUABIND_INCLUDE_DIR})
target_link_libraries(osrm-extract ${LUABIND_LIBRARY})
target_link_libraries(osrm-prepare ${LUABIND_LIBRARY})
if( LUAJIT_FOUND )
if(LUAJIT_FOUND)
target_link_libraries(osrm-extract ${LUAJIT_LIBRARIES})
target_link_libraries(osrm-prepare ${LUAJIT_LIBRARIES})
else()
@@ -246,18 +267,20 @@ find_package(EXPAT REQUIRED)
include_directories(${EXPAT_INCLUDE_DIRS})
target_link_libraries(osrm-extract ${EXPAT_LIBRARIES})
find_package( STXXL REQUIRED )
find_package(STXXL REQUIRED)
include_directories(${STXXL_INCLUDE_DIR})
target_link_libraries(OSRM ${STXXL_LIBRARY})
target_link_libraries(osrm-extract ${STXXL_LIBRARY})
target_link_libraries(osrm-prepare ${STXXL_LIBRARY})
if(MINGW)
# STXXL needs OpenMP library
target_link_libraries(osrm-extract gomp)
set(OpenMP_FIND_QUIETLY ON)
find_package(OpenMP)
if(OPENMP_FOUND)
message(STATUS "OpenMP support found. Linking just in case for stxxl")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()
find_package( OSMPBF REQUIRED )
find_package(OSMPBF REQUIRED)
include_directories(${OSMPBF_INCLUDE_DIR})
target_link_libraries(osrm-extract ${OSMPBF_LIBRARY})
target_link_libraries(osrm-prepare ${OSMPBF_LIBRARY})
@@ -276,11 +299,16 @@ include_directories(${ZLIB_INCLUDE_DIRS})
target_link_libraries(osrm-extract ${ZLIB_LIBRARY})
target_link_libraries(osrm-routed ${ZLIB_LIBRARY})
if (ENABLE_JSON_LOGGING)
message(STATUS "Enabling json logging")
add_definitions(-DENABLE_JSON_LOGGING)
endif()
if(WITH_TOOLS OR BUILD_TOOLS)
message(STATUS "Activating OSRM internal tools")
find_package(GDAL)
if(GDAL_FOUND)
add_executable(osrm-components tools/components.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER>)
add_executable(osrm-components tools/components.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:RESTRICTION> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR>)
target_link_libraries(osrm-components ${TBB_LIBRARIES})
include_directories(${GDAL_INCLUDE_DIR})
target_link_libraries(
@@ -290,19 +318,19 @@ if(WITH_TOOLS OR BUILD_TOOLS)
else()
message(FATAL_ERROR "libgdal and/or development headers not found")
endif()
add_executable(osrm-cli tools/simpleclient.cpp $<TARGET_OBJECTS:LOGGER>)
add_executable(osrm-cli tools/simpleclient.cpp $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:COORDINATE>)
target_link_libraries(osrm-cli ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSRM)
target_link_libraries(osrm-cli ${TBB_LIBRARIES})
add_executable(osrm-io-benchmark tools/io-benchmark.cpp $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:LOGGER>)
add_executable(osrm-io-benchmark tools/io-benchmark.cpp $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:LOGGER>)
target_link_libraries(osrm-io-benchmark ${Boost_LIBRARIES})
add_executable(osrm-unlock-all tools/unlock_all_mutexes.cpp $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:LOGGER>)
add_executable(osrm-unlock-all tools/unlock_all_mutexes.cpp $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:EXCEPTION>)
target_link_libraries(osrm-unlock-all ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
if(UNIX AND NOT APPLE)
target_link_libraries(osrm-unlock-all rt)
endif()
add_executable(osrm-check-hsgr tools/check-hsgr.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:LOGGER>)
target_link_libraries(osrm-check-hsgr ${Boost_LIBRARIES})
add_executable(osrm-springclean tools/springclean.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:GITDESCRIPTION>)
add_executable(osrm-check-hsgr tools/check-hsgr.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:IMPORT>)
target_link_libraries(osrm-check-hsgr ${Boost_LIBRARIES} ${TBB_LIBRARIES})
add_executable(osrm-springclean tools/springclean.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:EXCEPTION>)
target_link_libraries(osrm-springclean ${Boost_LIBRARIES})
install(TARGETS osrm-cli DESTINATION bin)
@@ -312,7 +340,8 @@ if(WITH_TOOLS OR BUILD_TOOLS)
install(TARGETS osrm-springclean DESTINATION bin)
endif()
file(GLOB InstallGlob Include/osrm/*.h Library/OSRM.h)
file(GLOB InstallGlob include/osrm/*.hpp library/osrm.hpp)
file(GLOB VariantGlob third_party/variant/*.hpp)
# Add RPATH info to executables so that when they are run after being installed
# (i.e., from /usr/local/bin/) the linker can find library dependencies. For
@@ -323,6 +352,7 @@ set_property(TARGET osrm-datastore PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
set_property(TARGET osrm-routed PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
install(FILES ${InstallGlob} DESTINATION include/osrm)
install(FILES ${VariantGlob} DESTINATION include/variant)
install(TARGETS osrm-extract DESTINATION bin)
install(TARGETS osrm-prepare DESTINATION bin)
install(TARGETS osrm-datastore DESTINATION bin)
@@ -331,13 +361,13 @@ install(TARGETS OSRM DESTINATION lib)
list(GET Boost_LIBRARIES 1 BOOST_LIBRARY_FIRST)
get_filename_component(BOOST_LIBRARY_LISTING "${BOOST_LIBRARY_FIRST}" PATH)
set(BOOST_LIBRARY_LISTING "-L${BOOST_LIBRARY_LISTING}")
foreach (lib ${Boost_LIBRARIES})
foreach(lib ${Boost_LIBRARIES})
get_filename_component(BOOST_LIBRARY_NAME "${lib}" NAME_WE)
string(REPLACE "lib" "" BOOST_LIBRARY_NAME ${BOOST_LIBRARY_NAME})
set(BOOST_LIBRARY_LISTING "${BOOST_LIBRARY_LISTING} -l${BOOST_LIBRARY_NAME}")
endforeach ()
endforeach()
configure_file(${CMAKE_SOURCE_DIR}/cmake/pkgconfig.in libosrm.pc @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/pkgconfig.in libosrm.pc @ONLY)
install(FILES ${PROJECT_BINARY_DIR}/libosrm.pc DESTINATION lib/pkgconfig)
if(BUILD_DEBIAN_PACKAGE)
+1 -1
View File
@@ -4,4 +4,4 @@ gem "cucumber"
gem "rake"
gem "osmlib-base"
gem "sys-proctable"
gem "rspec-expectations"
gem "rspec-expectations"
+16 -11
View File
@@ -2,22 +2,27 @@ GEM
remote: http://rubygems.org/
specs:
builder (3.2.2)
cucumber (1.3.8)
cucumber (2.0.0)
builder (>= 2.1.2)
cucumber-core (~> 1.1.3)
diff-lcs (>= 1.1.3)
gherkin (~> 2.12.1)
gherkin (~> 2.12)
multi_json (>= 1.7.5, < 2.0)
multi_test (>= 0.0.2)
diff-lcs (1.2.4)
gherkin (2.12.1)
multi_test (>= 0.1.2)
cucumber-core (1.1.3)
gherkin (~> 2.12.0)
diff-lcs (1.2.5)
gherkin (2.12.2)
multi_json (~> 1.3)
multi_json (1.8.0)
multi_test (0.0.2)
multi_json (1.11.0)
multi_test (0.1.2)
osmlib-base (0.1.4)
rake (10.1.0)
rspec-expectations (2.14.3)
diff-lcs (>= 1.1.3, < 2.0)
sys-proctable (0.9.3)
rake (10.4.2)
rspec-expectations (3.2.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.2.0)
rspec-support (3.2.2)
sys-proctable (0.9.8)
PLATFORMS
ruby
-113
View File
@@ -1,113 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
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 FIXED_POINT_COORDINATE_H_
#define FIXED_POINT_COORDINATE_H_
#include <iosfwd> //for std::ostream
#include <string>
#include <type_traits>
namespace
{
constexpr float COORDINATE_PRECISION = 1000000.f;
}
struct FixedPointCoordinate
{
int lat;
int lon;
FixedPointCoordinate();
FixedPointCoordinate(int lat, int lon);
template<class T>
FixedPointCoordinate(const T &coordinate) : lat(coordinate.lat), lon(coordinate.lon)
{
static_assert(std::is_same<decltype(lat), decltype(coordinate.lat)>::value, "coordinate types incompatible");
static_assert(std::is_same<decltype(lon), decltype(coordinate.lon)>::value, "coordinate types incompatible");
}
void Reset();
bool isSet() const;
bool is_valid() const;
bool operator==(const FixedPointCoordinate &other) const;
static double
ApproximateDistance(const int lat1, const int lon1, const int lat2, const int lon2);
static double ApproximateDistance(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate);
static float ApproximateEuclideanDistance(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate);
static float
ApproximateEuclideanDistance(const int lat1, const int lon1, const int lat2, const int lon2);
static float ApproximateSquaredEuclideanDistance(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate);
static void convertInternalLatLonToString(const int value, std::string &output);
static void convertInternalCoordinateToString(const FixedPointCoordinate &coordinate,
std::string &output);
static void convertInternalReversedCoordinateToString(const FixedPointCoordinate &coordinate,
std::string &output);
static float ComputePerpendicularDistance(const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location);
static float ComputePerpendicularDistance(const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location,
FixedPointCoordinate &nearest_location,
float &ratio);
static int
OrderedPerpendicularDistanceApproximation(const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location);
static float GetBearing(const FixedPointCoordinate &A, const FixedPointCoordinate &B);
float GetBearing(const FixedPointCoordinate &other) const;
void Output(std::ostream &out) const;
static float DegreeToRadian(const float degree);
static float RadianToDegree(const float radian);
};
inline std::ostream &operator<<(std::ostream &out_stream, FixedPointCoordinate const &coordinate)
{
coordinate.Output(out_stream);
return out_stream;
}
#endif /* FIXED_POINT_COORDINATE_H_ */
-74
View File
@@ -1,74 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
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 REPLY_H
#define REPLY_H
#include "Header.h"
#include <boost/asio.hpp>
#include <vector>
namespace http
{
const char okHTML[] = "";
const char badRequestHTML[] = "{\"status\": 400,\"status_message\":\"Bad Request\"}";
const char internalServerErrorHTML[] =
"{\"status\": 500,\"status_message\":\"Internal Server Error\"}";
const char seperators[] = {':', ' '};
const char crlf[] = {'\r', '\n'};
const std::string okString = "HTTP/1.0 200 OK\r\n";
const std::string badRequestString = "HTTP/1.0 400 Bad Request\r\n";
const std::string internalServerErrorString = "HTTP/1.0 500 Internal Server Error\r\n";
class Reply
{
public:
enum status_type
{ ok = 200,
badRequest = 400,
internalServerError = 500 } status;
std::vector<Header> headers;
std::vector<boost::asio::const_buffer> ToBuffers();
std::vector<boost::asio::const_buffer> HeaderstoBuffers();
std::vector<char> content;
static Reply StockReply(status_type status);
void SetSize(const unsigned size);
void SetUncompressedSize();
Reply();
private:
std::string ToString(Reply::status_type status);
boost::asio::const_buffer ToBuffer(Reply::status_type status);
};
}
#endif // REPLY_H
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
+18 -13
View File
@@ -1,12 +1,25 @@
# Readme
## About
For instructions on how to compile and run OSRM, please consult the Wiki at
The Open Source Routing Machine is a high performance routing engine written in C++11 designed to run on OpenStreetMap data.
https://github.com/Project-OSRM/osrm-backend/wiki
## Current build status
or use our free and daily updated online service at
| build config | branch | status |
|:-------------|:--------|:------------|
| Linux | master | [![Build Status](https://travis-ci.org/Project-OSRM/osrm-backend.png?branch=master)](https://travis-ci.org/Project-OSRM/osrm-backend) |
| Linux | develop | [![Build Status](https://travis-ci.org/Project-OSRM/osrm-backend.png?branch=develop)](https://travis-ci.org/Project-OSRM/osrm-backend) |
| Windows | master/develop | [![Build status](https://ci.appveyor.com/api/projects/status/4iuo3s9gxprmcjjh)](https://ci.appveyor.com/project/DennisOSRM/osrm-backend) |
| LUAbind fork | master | [![Build Status](https://travis-ci.org/DennisOSRM/luabind.png?branch=master)](https://travis-ci.org/DennisOSRM/luabind) |
http://map.project-osrm.org
## Building
For instructions on how to [build](https://github.com/Project-OSRM/osrm-backend/wiki/Building-OSRM) and [run OSRM](https://github.com/Project-OSRM/osrm-backend/wiki/Running-OSRM), please consult [the Wiki](https://github.com/Project-OSRM/osrm-backend/wiki).
To quickly try OSRM use our [free and daily updated online service](http://map.project-osrm.org)
## Documentation
See the Wiki's [server API documentation](https://github.com/Project-OSRM/osrm-backend/wiki/Server-api) as well as the [library API documentation](https://github.com/Project-OSRM/osrm-backend/wiki/Library-api)
## References in publications
@@ -31,11 +44,3 @@ When using the code in a (scientific) publication, please cite
}
```
## Current build status
| build config | branch | status |
|:-------------|:--------|:------------|
| Linux | master | [![Build Status](https://travis-ci.org/Project-OSRM/osrm-backend.png?branch=master)](https://travis-ci.org/DennisOSRM/Project-OSRM) |
| Linux | develop | [![Build Status](https://travis-ci.org/Project-OSRM/osrm-backend.png?branch=develop)](https://travis-ci.org/DennisOSRM/Project-OSRM) |
| Windows | master/develop | [![Build status](https://ci.appveyor.com/api/projects/status/4iuo3s9gxprmcjjh)](https://ci.appveyor.com/project/DennisOSRM/osrm-backend) |
| LUAbind fork | master | [![Build Status](https://travis-ci.org/DennisOSRM/luabind.png?branch=master)](https://travis-ci.org/DennisOSRM/luabind) |
-74
View File
@@ -1,74 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
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 APIGRAMMAR_H_
#define APIGRAMMAR_H_
#include <boost/bind.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_action.hpp>
namespace qi = boost::spirit::qi;
template <typename Iterator, class HandlerT>
struct APIGrammar : qi::grammar<Iterator>
{
explicit APIGrammar(HandlerT * h) : APIGrammar::base_type(api_call), handler(h)
{
api_call = qi::lit('/') >> string[boost::bind(&HandlerT::setService, handler, ::_1)] >> *(query) >> -(uturns);
query = ('?') >> (+(zoom | output | jsonp | checksum | location | hint | u | cmp | language | instruction | geometry | alt_route | old_API | num_results) ) ;
zoom = (-qi::lit('&')) >> qi::lit('z') >> '=' >> qi::short_[boost::bind(&HandlerT::setZoomLevel, handler, ::_1)];
output = (-qi::lit('&')) >> qi::lit("output") >> '=' >> string[boost::bind(&HandlerT::setOutputFormat, handler, ::_1)];
jsonp = (-qi::lit('&')) >> qi::lit("jsonp") >> '=' >> stringwithPercent[boost::bind(&HandlerT::setJSONpParameter, handler, ::_1)];
checksum = (-qi::lit('&')) >> qi::lit("checksum") >> '=' >> qi::uint_[boost::bind(&HandlerT::setChecksum, handler, ::_1)];
instruction = (-qi::lit('&')) >> qi::lit("instructions") >> '=' >> qi::bool_[boost::bind(&HandlerT::setInstructionFlag, handler, ::_1)];
geometry = (-qi::lit('&')) >> qi::lit("geometry") >> '=' >> qi::bool_[boost::bind(&HandlerT::setGeometryFlag, handler, ::_1)];
cmp = (-qi::lit('&')) >> qi::lit("compression") >> '=' >> qi::bool_[boost::bind(&HandlerT::setCompressionFlag, handler, ::_1)];
location = (-qi::lit('&')) >> qi::lit("loc") >> '=' >> (qi::double_ >> qi::lit(',') >> qi::double_)[boost::bind(&HandlerT::addCoordinate, handler, ::_1)];
hint = (-qi::lit('&')) >> qi::lit("hint") >> '=' >> stringwithDot[boost::bind(&HandlerT::addHint, handler, ::_1)];
u = (-qi::lit('&')) >> qi::lit("u") >> '=' >> qi::bool_[boost::bind(&HandlerT::setUTurn, handler, ::_1)];
uturns = (-qi::lit('&')) >> qi::lit("uturns") >> '=' >> qi::bool_[boost::bind(&HandlerT::setAllUTurns, handler, ::_1)];
language = (-qi::lit('&')) >> qi::lit("hl") >> '=' >> string[boost::bind(&HandlerT::setLanguage, handler, ::_1)];
alt_route = (-qi::lit('&')) >> qi::lit("alt") >> '=' >> qi::bool_[boost::bind(&HandlerT::setAlternateRouteFlag, handler, ::_1)];
old_API = (-qi::lit('&')) >> qi::lit("geomformat") >> '=' >> string[boost::bind(&HandlerT::setDeprecatedAPIFlag, handler, ::_1)];
num_results = (-qi::lit('&')) >> qi::lit("num_results") >> '=' >> qi::short_[boost::bind(&HandlerT::setNumberOfResults, handler, ::_1)];
string = +(qi::char_("a-zA-Z"));
stringwithDot = +(qi::char_("a-zA-Z0-9_.-"));
stringwithPercent = +(qi::char_("a-zA-Z0-9_.-") | qi::char_('[') | qi::char_(']') | (qi::char_('%') >> qi::char_("0-9A-Z") >> qi::char_("0-9A-Z") ));
}
qi::rule<Iterator> api_call, query;
qi::rule<Iterator, std::string()> service, zoom, output, string, jsonp, checksum, location, hint,
stringwithDot, stringwithPercent, language, instruction, geometry,
cmp, alt_route, u, uturns, old_API, num_results;
HandlerT * handler;
};
#endif /* APIGRAMMAR_H_ */
-143
View File
@@ -1,143 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
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.
*/
#include "RequestHandler.h"
#include "APIGrammar.h"
#include "Http/Request.h"
#include "../data_structures/json_container.hpp"
#include "../Library/OSRM.h"
#include "../Util/json_renderer.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/StringUtil.h"
#include "../typedefs.h"
#include <osrm/Reply.h>
#include <osrm/RouteParameters.h>
#include <ctime>
#include <algorithm>
#include <iostream>
RequestHandler::RequestHandler() : routing_machine(nullptr) {}
void RequestHandler::handle_request(const http::Request &req, http::Reply &reply)
{
// parse command
try
{
std::string request;
URIDecode(req.uri, request);
// deactivated as GCC apparently does not implement that, not even in 4.9
// std::time_t t = std::time(nullptr);
// SimpleLogger().Write() << std::put_time(std::localtime(&t), "%m-%d-%Y %H:%M:%S") <<
// " " << req.endpoint.to_string() << " " <<
// req.referrer << ( 0 == req.referrer.length() ? "- " :" ") <<
// req.agent << ( 0 == req.agent.length() ? "- " :" ") << request;
time_t ltime;
struct tm *time_stamp;
ltime = time(nullptr);
time_stamp = localtime(&ltime);
// log timestamp
SimpleLogger().Write() << (time_stamp->tm_mday < 10 ? "0" : "") << time_stamp->tm_mday << "-"
<< (time_stamp->tm_mon + 1 < 10 ? "0" : "") << (time_stamp->tm_mon + 1) << "-"
<< 1900 + time_stamp->tm_year << " " << (time_stamp->tm_hour < 10 ? "0" : "")
<< time_stamp->tm_hour << ":" << (time_stamp->tm_min < 10 ? "0" : "") << time_stamp->tm_min
<< ":" << (time_stamp->tm_sec < 10 ? "0" : "") << time_stamp->tm_sec << " "
<< req.endpoint.to_string() << " " << req.referrer
<< (0 == req.referrer.length() ? "- " : " ") << req.agent
<< (0 == req.agent.length() ? "- " : " ") << request;
RouteParameters route_parameters;
APIGrammarParser api_parser(&route_parameters);
auto iter = request.begin();
const bool result = boost::spirit::qi::parse(iter, request.end(), api_parser);
// check if the was an error with the request
if (!result || (iter != request.end()))
{
reply = http::Reply::StockReply(http::Reply::badRequest);
reply.content.clear();
const auto position = std::distance(request.begin(), iter);
JSON::Object json_result;
json_result.values["status"] = 400;
std::string message = "Query string malformed close to position ";
message += cast::integral_to_string(position);
json_result.values["status_message"] = message;
JSON::render(reply.content, json_result);
return;
}
// parsing done, lets call the right plugin to handle the request
BOOST_ASSERT_MSG(routing_machine != nullptr, "pointer not init'ed");
if (!route_parameters.jsonp_parameter.empty())
{ // prepend response with jsonp parameter
const std::string json_p = (route_parameters.jsonp_parameter + "(");
reply.content.insert(reply.content.end(), json_p.begin(), json_p.end());
}
routing_machine->RunQuery(route_parameters, reply);
if (!route_parameters.jsonp_parameter.empty())
{ // append brace to jsonp response
reply.content.push_back(')');
}
// set headers
reply.headers.emplace_back("Content-Length", cast::integral_to_string(reply.content.size()));
if ("gpx" == route_parameters.output_format)
{ // gpx file
reply.headers.emplace_back("Content-Type", "application/gpx+xml; charset=UTF-8");
reply.headers.emplace_back("Content-Disposition", "attachment; filename=\"route.gpx\"");
}
else if (route_parameters.jsonp_parameter.empty())
{ // json file
reply.headers.emplace_back("Content-Type", "application/json; charset=UTF-8");
reply.headers.emplace_back("Content-Disposition", "inline; filename=\"response.json\"");
}
else
{ // jsonp
reply.headers.emplace_back("Content-Type", "text/javascript; charset=UTF-8");
reply.headers.emplace_back("Content-Disposition", "inline; filename=\"response.js\"");
}
}
catch (const std::exception &e)
{
reply = http::Reply::StockReply(http::Reply::internalServerError);
SimpleLogger().Write(logWARNING) << "[server error] code: " << e.what()
<< ", uri: " << req.uri;
return;
}
}
void RequestHandler::RegisterRoutingMachine(OSRM *osrm) { routing_machine = osrm; }
-310
View File
@@ -1,310 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
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.
*/
#include "RequestParser.h"
#include "Http/Request.h"
namespace http
{
RequestParser::RequestParser() : state_(method_start), header({"", ""}) {}
void RequestParser::Reset() { state_ = method_start; }
boost::tuple<boost::tribool, char *>
RequestParser::Parse(Request &req, char *begin, char *end, http::CompressionType &compression_type)
{
while (begin != end)
{
boost::tribool result = consume(req, *begin++, compression_type);
if (result || !result)
{
return boost::make_tuple(result, begin);
}
}
boost::tribool result = boost::indeterminate;
return boost::make_tuple(result, begin);
}
boost::tribool
RequestParser::consume(Request &req, char input, http::CompressionType &compression_type)
{
switch (state_)
{
case method_start:
if (!isChar(input) || isCTL(input) || isTSpecial(input))
{
return false;
}
state_ = method;
return boost::indeterminate;
case method:
if (input == ' ')
{
state_ = uri;
return boost::indeterminate;
}
if (!isChar(input) || isCTL(input) || isTSpecial(input))
{
return false;
}
return boost::indeterminate;
case uri_start:
if (isCTL(input))
{
return false;
}
state_ = uri;
req.uri.push_back(input);
return boost::indeterminate;
case uri:
if (input == ' ')
{
state_ = http_version_h;
return boost::indeterminate;
}
if (isCTL(input))
{
return false;
}
req.uri.push_back(input);
return boost::indeterminate;
case http_version_h:
if (input == 'H')
{
state_ = http_version_t_1;
return boost::indeterminate;
}
return false;
case http_version_t_1:
if (input == 'T')
{
state_ = http_version_t_2;
return boost::indeterminate;
}
return false;
case http_version_t_2:
if (input == 'T')
{
state_ = http_version_p;
return boost::indeterminate;
}
return false;
case http_version_p:
if (input == 'P')
{
state_ = http_version_slash;
return boost::indeterminate;
}
return false;
case http_version_slash:
if (input == '/')
{
state_ = http_version_major_start;
return boost::indeterminate;
}
return false;
case http_version_major_start:
if (isDigit(input))
{
state_ = http_version_major;
return boost::indeterminate;
}
return false;
case http_version_major:
if (input == '.')
{
state_ = http_version_minor_start;
return boost::indeterminate;
}
if (isDigit(input))
{
return boost::indeterminate;
}
return false;
case http_version_minor_start:
if (isDigit(input))
{
state_ = http_version_minor;
return boost::indeterminate;
}
return false;
case http_version_minor:
if (input == '\r')
{
state_ = expecting_newline_1;
return boost::indeterminate;
}
if (isDigit(input))
{
return boost::indeterminate;
}
return false;
case expecting_newline_1:
if (input == '\n')
{
state_ = header_line_start;
return boost::indeterminate;
}
return false;
case header_line_start:
if (header.name == "Accept-Encoding")
{
/* giving gzip precedence over deflate */
if (header.value.find("deflate") != std::string::npos)
{
compression_type = deflateRFC1951;
}
if (header.value.find("gzip") != std::string::npos)
{
compression_type = gzipRFC1952;
}
}
if ("Referer" == header.name)
{
req.referrer = header.value;
}
if ("User-Agent" == header.name)
{
req.agent = header.value;
}
if (input == '\r')
{
state_ = expecting_newline_3;
return boost::indeterminate;
}
if (!isChar(input) || isCTL(input) || isTSpecial(input))
{
return false;
}
state_ = header_name;
header.Clear();
header.name.push_back(input);
return boost::indeterminate;
case header_lws:
if (input == '\r')
{
state_ = expecting_newline_2;
return boost::indeterminate;
}
if (input == ' ' || input == '\t')
{
return boost::indeterminate;
}
if (isCTL(input))
{
return false;
}
state_ = header_value;
return boost::indeterminate;
case header_name:
if (input == ':')
{
state_ = space_before_header_value;
return boost::indeterminate;
}
if (!isChar(input) || isCTL(input) || isTSpecial(input))
{
return false;
}
header.name.push_back(input);
return boost::indeterminate;
case space_before_header_value:
if (input == ' ')
{
state_ = header_value;
return boost::indeterminate;
}
return false;
case header_value:
if (input == '\r')
{
state_ = expecting_newline_2;
return boost::indeterminate;
}
if (isCTL(input))
{
return false;
}
header.value.push_back(input);
return boost::indeterminate;
case expecting_newline_2:
if (input == '\n')
{
state_ = header_line_start;
return boost::indeterminate;
}
return false;
default: // expecting_newline_3:
return (input == '\n');
// default:
// return false;
}
}
inline bool RequestParser::isChar(int character) { return character >= 0 && character <= 127; }
inline bool RequestParser::isCTL(int character)
{
return (character >= 0 && character <= 31) || (character == 127);
}
inline bool RequestParser::isTSpecial(int character)
{
switch (character)
{
case '(':
case ')':
case '<':
case '>':
case '@':
case ',':
case ';':
case ':':
case '\\':
case '"':
case '/':
case '[':
case ']':
case '?':
case '=':
case '{':
case '}':
case ' ':
case '\t':
return true;
default:
return false;
}
}
inline bool RequestParser::isDigit(int character) { return character >= '0' && character <= '9'; }
}
-90
View File
@@ -1,90 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
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 REQUEST_PARSER_H
#define REQUEST_PARSER_H
#include "Http/CompressionType.h"
#include <osrm/Header.h>
#include <boost/logic/tribool.hpp>
#include <boost/tuple/tuple.hpp>
namespace http
{
struct Request;
class RequestParser
{
public:
RequestParser();
void Reset();
boost::tuple<boost::tribool, char *>
Parse(Request &req, char *begin, char *end, CompressionType &compression_type);
private:
boost::tribool consume(Request &req, char input, CompressionType &compression_type);
inline bool isChar(int c);
inline bool isCTL(int c);
inline bool isTSpecial(int c);
inline bool isDigit(int c);
enum state
{ method_start,
method,
uri_start,
uri,
http_version_h,
http_version_t_1,
http_version_t_2,
http_version_p,
http_version_slash,
http_version_major_start,
http_version_major,
http_version_minor_start,
http_version_minor,
expecting_newline_1,
header_line_start,
header_lws,
header_name,
space_before_header_value,
header_value,
expecting_newline_2,
expecting_newline_3 } state_;
Header header;
};
} // namespace http
#endif // REQUEST_PARSER_H
-790
View File
@@ -1,790 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
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 TRIGONOMETRY_TABLES_H
#define TRIGONOMETRY_TABLES_H
#include "../typedefs.h"
#include <cmath>
#include <limits>
constexpr unsigned short atan_table[4096] = {
0x0000, 0x0014, 0x0028, 0x003d, 0x0051, 0x0065,
0x007a, 0x008e, 0x00a3, 0x00b7, 0x00cb, 0x00e0,
0x00f4, 0x0108, 0x011d, 0x0131, 0x0146, 0x015a,
0x016e, 0x0183, 0x0197, 0x01ab, 0x01c0, 0x01d4,
0x01e9, 0x01fd, 0x0211, 0x0226, 0x023a, 0x024e,
0x0263, 0x0277, 0x028c, 0x02a0, 0x02b4, 0x02c9,
0x02dd, 0x02f1, 0x0306, 0x031a, 0x032f, 0x0343,
0x0357, 0x036c, 0x0380, 0x0394, 0x03a9, 0x03bd,
0x03d2, 0x03e6, 0x03fa, 0x040f, 0x0423, 0x0437,
0x044c, 0x0460, 0x0475, 0x0489, 0x049d, 0x04b2,
0x04c6, 0x04da, 0x04ef, 0x0503, 0x0517, 0x052c,
0x0540, 0x0555, 0x0569, 0x057d, 0x0592, 0x05a6,
0x05ba, 0x05cf, 0x05e3, 0x05f8, 0x060c, 0x0620,
0x0635, 0x0649, 0x065d, 0x0672, 0x0686, 0x069b,
0x06af, 0x06c3, 0x06d8, 0x06ec, 0x0700, 0x0715,
0x0729, 0x073d, 0x0752, 0x0766, 0x077b, 0x078f,
0x07a3, 0x07b8, 0x07cc, 0x07e0, 0x07f5, 0x0809,
0x081d, 0x0832, 0x0846, 0x085b, 0x086f, 0x0883,
0x0898, 0x08ac, 0x08c0, 0x08d5, 0x08e9, 0x08fd,
0x0912, 0x0926, 0x093b, 0x094f, 0x0963, 0x0978,
0x098c, 0x09a0, 0x09b5, 0x09c9, 0x09dd, 0x09f2,
0x0a06, 0x0a1a, 0x0a2f, 0x0a43, 0x0a58, 0x0a6c,
0x0a80, 0x0a95, 0x0aa9, 0x0abd, 0x0ad2, 0x0ae6,
0x0afa, 0x0b0f, 0x0b23, 0x0b37, 0x0b4c, 0x0b60,
0x0b75, 0x0b89, 0x0b9d, 0x0bb2, 0x0bc6, 0x0bda,
0x0bef, 0x0c03, 0x0c17, 0x0c2c, 0x0c40, 0x0c54,
0x0c69, 0x0c7d, 0x0c91, 0x0ca6, 0x0cba, 0x0cce,
0x0ce3, 0x0cf7, 0x0d0b, 0x0d20, 0x0d34, 0x0d48,
0x0d5d, 0x0d71, 0x0d86, 0x0d9a, 0x0dae, 0x0dc3,
0x0dd7, 0x0deb, 0x0e00, 0x0e14, 0x0e28, 0x0e3d,
0x0e51, 0x0e65, 0x0e7a, 0x0e8e, 0x0ea2, 0x0eb7,
0x0ecb, 0x0edf, 0x0ef4, 0x0f08, 0x0f1c, 0x0f31,
0x0f45, 0x0f59, 0x0f6e, 0x0f82, 0x0f96, 0x0fab,
0x0fbf, 0x0fd3, 0x0fe8, 0x0ffc, 0x1010, 0x1025,
0x1039, 0x104d, 0x1062, 0x1076, 0x108a, 0x109e,
0x10b3, 0x10c7, 0x10db, 0x10f0, 0x1104, 0x1118,
0x112d, 0x1141, 0x1155, 0x116a, 0x117e, 0x1192,
0x11a7, 0x11bb, 0x11cf, 0x11e4, 0x11f8, 0x120c,
0x1221, 0x1235, 0x1249, 0x125d, 0x1272, 0x1286,
0x129a, 0x12af, 0x12c3, 0x12d7, 0x12ec, 0x1300,
0x1314, 0x1329, 0x133d, 0x1351, 0x1365, 0x137a,
0x138e, 0x13a2, 0x13b7, 0x13cb, 0x13df, 0x13f4,
0x1408, 0x141c, 0x1431, 0x1445, 0x1459, 0x146d,
0x1482, 0x1496, 0x14aa, 0x14bf, 0x14d3, 0x14e7,
0x14fb, 0x1510, 0x1524, 0x1538, 0x154d, 0x1561,
0x1575, 0x1589, 0x159e, 0x15b2, 0x15c6, 0x15db,
0x15ef, 0x1603, 0x1617, 0x162c, 0x1640, 0x1654,
0x1669, 0x167d, 0x1691, 0x16a5, 0x16ba, 0x16ce,
0x16e2, 0x16f7, 0x170b, 0x171f, 0x1733, 0x1748,
0x175c, 0x1770, 0x1784, 0x1799, 0x17ad, 0x17c1,
0x17d6, 0x17ea, 0x17fe, 0x1812, 0x1827, 0x183b,
0x184f, 0x1863, 0x1878, 0x188c, 0x18a0, 0x18b4,
0x18c9, 0x18dd, 0x18f1, 0x1905, 0x191a, 0x192e,
0x1942, 0x1957, 0x196b, 0x197f, 0x1993, 0x19a8,
0x19bc, 0x19d0, 0x19e4, 0x19f9, 0x1a0d, 0x1a21,
0x1a35, 0x1a49, 0x1a5e, 0x1a72, 0x1a86, 0x1a9a,
0x1aaf, 0x1ac3, 0x1ad7, 0x1aeb, 0x1b00, 0x1b14,
0x1b28, 0x1b3c, 0x1b51, 0x1b65, 0x1b79, 0x1b8d,
0x1ba2, 0x1bb6, 0x1bca, 0x1bde, 0x1bf2, 0x1c07,
0x1c1b, 0x1c2f, 0x1c43, 0x1c58, 0x1c6c, 0x1c80,
0x1c94, 0x1ca8, 0x1cbd, 0x1cd1, 0x1ce5, 0x1cf9,
0x1d0e, 0x1d22, 0x1d36, 0x1d4a, 0x1d5e, 0x1d73,
0x1d87, 0x1d9b, 0x1daf, 0x1dc3, 0x1dd8, 0x1dec,
0x1e00, 0x1e14, 0x1e28, 0x1e3d, 0x1e51, 0x1e65,
0x1e79, 0x1e8d, 0x1ea2, 0x1eb6, 0x1eca, 0x1ede,
0x1ef2, 0x1f07, 0x1f1b, 0x1f2f, 0x1f43, 0x1f57,
0x1f6c, 0x1f80, 0x1f94, 0x1fa8, 0x1fbc, 0x1fd1,
0x1fe5, 0x1ff9, 0x200d, 0x2021, 0x2035, 0x204a,
0x205e, 0x2072, 0x2086, 0x209a, 0x20ae, 0x20c3,
0x20d7, 0x20eb, 0x20ff, 0x2113, 0x2127, 0x213c,
0x2150, 0x2164, 0x2178, 0x218c, 0x21a0, 0x21b5,
0x21c9, 0x21dd, 0x21f1, 0x2205, 0x2219, 0x222e,
0x2242, 0x2256, 0x226a, 0x227e, 0x2292, 0x22a6,
0x22bb, 0x22cf, 0x22e3, 0x22f7, 0x230b, 0x231f,
0x2333, 0x2348, 0x235c, 0x2370, 0x2384, 0x2398,
0x23ac, 0x23c0, 0x23d5, 0x23e9, 0x23fd, 0x2411,
0x2425, 0x2439, 0x244d, 0x2461, 0x2476, 0x248a,
0x249e, 0x24b2, 0x24c6, 0x24da, 0x24ee, 0x2502,
0x2517, 0x252b, 0x253f, 0x2553, 0x2567, 0x257b,
0x258f, 0x25a3, 0x25b7, 0x25cb, 0x25e0, 0x25f4,
0x2608, 0x261c, 0x2630, 0x2644, 0x2658, 0x266c,
0x2680, 0x2694, 0x26a9, 0x26bd, 0x26d1, 0x26e5,
0x26f9, 0x270d, 0x2721, 0x2735, 0x2749, 0x275d,
0x2771, 0x2785, 0x279a, 0x27ae, 0x27c2, 0x27d6,
0x27ea, 0x27fe, 0x2812, 0x2826, 0x283a, 0x284e,
0x2862, 0x2876, 0x288a, 0x289e, 0x28b3, 0x28c7,
0x28db, 0x28ef, 0x2903, 0x2917, 0x292b, 0x293f,
0x2953, 0x2967, 0x297b, 0x298f, 0x29a3, 0x29b7,
0x29cb, 0x29df, 0x29f3, 0x2a07, 0x2a1b, 0x2a2f,
0x2a43, 0x2a58, 0x2a6c, 0x2a80, 0x2a94, 0x2aa8,
0x2abc, 0x2ad0, 0x2ae4, 0x2af8, 0x2b0c, 0x2b20,
0x2b34, 0x2b48, 0x2b5c, 0x2b70, 0x2b84, 0x2b98,
0x2bac, 0x2bc0, 0x2bd4, 0x2be8, 0x2bfc, 0x2c10,
0x2c24, 0x2c38, 0x2c4c, 0x2c60, 0x2c74, 0x2c88,
0x2c9c, 0x2cb0, 0x2cc4, 0x2cd8, 0x2cec, 0x2d00,
0x2d14, 0x2d28, 0x2d3c, 0x2d50, 0x2d64, 0x2d78,
0x2d8c, 0x2da0, 0x2db4, 0x2dc8, 0x2ddc, 0x2df0,
0x2e04, 0x2e18, 0x2e2c, 0x2e40, 0x2e54, 0x2e68,
0x2e7c, 0x2e90, 0x2ea3, 0x2eb7, 0x2ecb, 0x2edf,
0x2ef3, 0x2f07, 0x2f1b, 0x2f2f, 0x2f43, 0x2f57,
0x2f6b, 0x2f7f, 0x2f93, 0x2fa7, 0x2fbb, 0x2fcf,
0x2fe3, 0x2ff7, 0x300b, 0x301e, 0x3032, 0x3046,
0x305a, 0x306e, 0x3082, 0x3096, 0x30aa, 0x30be,
0x30d2, 0x30e6, 0x30fa, 0x310e, 0x3122, 0x3135,
0x3149, 0x315d, 0x3171, 0x3185, 0x3199, 0x31ad,
0x31c1, 0x31d5, 0x31e9, 0x31fd, 0x3210, 0x3224,
0x3238, 0x324c, 0x3260, 0x3274, 0x3288, 0x329c,
0x32b0, 0x32c3, 0x32d7, 0x32eb, 0x32ff, 0x3313,
0x3327, 0x333b, 0x334f, 0x3363, 0x3376, 0x338a,
0x339e, 0x33b2, 0x33c6, 0x33da, 0x33ee, 0x3401,
0x3415, 0x3429, 0x343d, 0x3451, 0x3465, 0x3479,
0x348c, 0x34a0, 0x34b4, 0x34c8, 0x34dc, 0x34f0,
0x3504, 0x3517, 0x352b, 0x353f, 0x3553, 0x3567,
0x357b, 0x358e, 0x35a2, 0x35b6, 0x35ca, 0x35de,
0x35f2, 0x3605, 0x3619, 0x362d, 0x3641, 0x3655,
0x3668, 0x367c, 0x3690, 0x36a4, 0x36b8, 0x36cb,
0x36df, 0x36f3, 0x3707, 0x371b, 0x372f, 0x3742,
0x3756, 0x376a, 0x377e, 0x3791, 0x37a5, 0x37b9,
0x37cd, 0x37e1, 0x37f4, 0x3808, 0x381c, 0x3830,
0x3844, 0x3857, 0x386b, 0x387f, 0x3893, 0x38a6,
0x38ba, 0x38ce, 0x38e2, 0x38f5, 0x3909, 0x391d,
0x3931, 0x3944, 0x3958, 0x396c, 0x3980, 0x3993,
0x39a7, 0x39bb, 0x39cf, 0x39e2, 0x39f6, 0x3a0a,
0x3a1e, 0x3a31, 0x3a45, 0x3a59, 0x3a6d, 0x3a80,
0x3a94, 0x3aa8, 0x3abb, 0x3acf, 0x3ae3, 0x3af7,
0x3b0a, 0x3b1e, 0x3b32, 0x3b45, 0x3b59, 0x3b6d,
0x3b81, 0x3b94, 0x3ba8, 0x3bbc, 0x3bcf, 0x3be3,
0x3bf7, 0x3c0b, 0x3c1e, 0x3c32, 0x3c46, 0x3c59,
0x3c6d, 0x3c81, 0x3c94, 0x3ca8, 0x3cbc, 0x3ccf,
0x3ce3, 0x3cf7, 0x3d0a, 0x3d1e, 0x3d32, 0x3d45,
0x3d59, 0x3d6d, 0x3d80, 0x3d94, 0x3da8, 0x3dbb,
0x3dcf, 0x3de3, 0x3df6, 0x3e0a, 0x3e1e, 0x3e31,
0x3e45, 0x3e59, 0x3e6c, 0x3e80, 0x3e93, 0x3ea7,
0x3ebb, 0x3ece, 0x3ee2, 0x3ef6, 0x3f09, 0x3f1d,
0x3f30, 0x3f44, 0x3f58, 0x3f6b, 0x3f7f, 0x3f93,
0x3fa6, 0x3fba, 0x3fcd, 0x3fe1, 0x3ff5, 0x4008,
0x401c, 0x402f, 0x4043, 0x4057, 0x406a, 0x407e,
0x4091, 0x40a5, 0x40b8, 0x40cc, 0x40e0, 0x40f3,
0x4107, 0x411a, 0x412e, 0x4142, 0x4155, 0x4169,
0x417c, 0x4190, 0x41a3, 0x41b7, 0x41ca, 0x41de,
0x41f2, 0x4205, 0x4219, 0x422c, 0x4240, 0x4253,
0x4267, 0x427a, 0x428e, 0x42a1, 0x42b5, 0x42c9,
0x42dc, 0x42f0, 0x4303, 0x4317, 0x432a, 0x433e,
0x4351, 0x4365, 0x4378, 0x438c, 0x439f, 0x43b3,
0x43c6, 0x43da, 0x43ed, 0x4401, 0x4414, 0x4428,
0x443b, 0x444f, 0x4462, 0x4476, 0x4489, 0x449d,
0x44b0, 0x44c4, 0x44d7, 0x44eb, 0x44fe, 0x4512,
0x4525, 0x4539, 0x454c, 0x4560, 0x4573, 0x4586,
0x459a, 0x45ad, 0x45c1, 0x45d4, 0x45e8, 0x45fb,
0x460f, 0x4622, 0x4636, 0x4649, 0x465c, 0x4670,
0x4683, 0x4697, 0x46aa, 0x46be, 0x46d1, 0x46e5,
0x46f8, 0x470b, 0x471f, 0x4732, 0x4746, 0x4759,
0x476c, 0x4780, 0x4793, 0x47a7, 0x47ba, 0x47cd,
0x47e1, 0x47f4, 0x4808, 0x481b, 0x482e, 0x4842,
0x4855, 0x4869, 0x487c, 0x488f, 0x48a3, 0x48b6,
0x48ca, 0x48dd, 0x48f0, 0x4904, 0x4917, 0x492a,
0x493e, 0x4951, 0x4965, 0x4978, 0x498b, 0x499f,
0x49b2, 0x49c5, 0x49d9, 0x49ec, 0x49ff, 0x4a13,
0x4a26, 0x4a39, 0x4a4d, 0x4a60, 0x4a73, 0x4a87,
0x4a9a, 0x4aad, 0x4ac1, 0x4ad4, 0x4ae7, 0x4afb,
0x4b0e, 0x4b21, 0x4b35, 0x4b48, 0x4b5b, 0x4b6f,
0x4b82, 0x4b95, 0x4ba8, 0x4bbc, 0x4bcf, 0x4be2,
0x4bf6, 0x4c09, 0x4c1c, 0x4c2f, 0x4c43, 0x4c56,
0x4c69, 0x4c7d, 0x4c90, 0x4ca3, 0x4cb6, 0x4cca,
0x4cdd, 0x4cf0, 0x4d03, 0x4d17, 0x4d2a, 0x4d3d,
0x4d50, 0x4d64, 0x4d77, 0x4d8a, 0x4d9d, 0x4db1,
0x4dc4, 0x4dd7, 0x4dea, 0x4dfe, 0x4e11, 0x4e24,
0x4e37, 0x4e4b, 0x4e5e, 0x4e71, 0x4e84, 0x4e97,
0x4eab, 0x4ebe, 0x4ed1, 0x4ee4, 0x4ef7, 0x4f0b,
0x4f1e, 0x4f31, 0x4f44, 0x4f57, 0x4f6b, 0x4f7e,
0x4f91, 0x4fa4, 0x4fb7, 0x4fcb, 0x4fde, 0x4ff1,
0x5004, 0x5017, 0x502a, 0x503e, 0x5051, 0x5064,
0x5077, 0x508a, 0x509d, 0x50b1, 0x50c4, 0x50d7,
0x50ea, 0x50fd, 0x5110, 0x5123, 0x5137, 0x514a,
0x515d, 0x5170, 0x5183, 0x5196, 0x51a9, 0x51bc,
0x51d0, 0x51e3, 0x51f6, 0x5209, 0x521c, 0x522f,
0x5242, 0x5255, 0x5268, 0x527c, 0x528f, 0x52a2,
0x52b5, 0x52c8, 0x52db, 0x52ee, 0x5301, 0x5314,
0x5327, 0x533a, 0x534e, 0x5361, 0x5374, 0x5387,
0x539a, 0x53ad, 0x53c0, 0x53d3, 0x53e6, 0x53f9,
0x540c, 0x541f, 0x5432, 0x5445, 0x5458, 0x546b,
0x547e, 0x5491, 0x54a5, 0x54b8, 0x54cb, 0x54de,
0x54f1, 0x5504, 0x5517, 0x552a, 0x553d, 0x5550,
0x5563, 0x5576, 0x5589, 0x559c, 0x55af, 0x55c2,
0x55d5, 0x55e8, 0x55fb, 0x560e, 0x5621, 0x5634,
0x5647, 0x565a, 0x566d, 0x5680, 0x5693, 0x56a6,
0x56b9, 0x56cb, 0x56de, 0x56f1, 0x5704, 0x5717,
0x572a, 0x573d, 0x5750, 0x5763, 0x5776, 0x5789,
0x579c, 0x57af, 0x57c2, 0x57d5, 0x57e8, 0x57fb,
0x580e, 0x5820, 0x5833, 0x5846, 0x5859, 0x586c,
0x587f, 0x5892, 0x58a5, 0x58b8, 0x58cb, 0x58de,
0x58f0, 0x5903, 0x5916, 0x5929, 0x593c, 0x594f,
0x5962, 0x5975, 0x5988, 0x599a, 0x59ad, 0x59c0,
0x59d3, 0x59e6, 0x59f9, 0x5a0c, 0x5a1f, 0x5a31,
0x5a44, 0x5a57, 0x5a6a, 0x5a7d, 0x5a90, 0x5aa2,
0x5ab5, 0x5ac8, 0x5adb, 0x5aee, 0x5b01, 0x5b13,
0x5b26, 0x5b39, 0x5b4c, 0x5b5f, 0x5b72, 0x5b84,
0x5b97, 0x5baa, 0x5bbd, 0x5bd0, 0x5be2, 0x5bf5,
0x5c08, 0x5c1b, 0x5c2e, 0x5c40, 0x5c53, 0x5c66,
0x5c79, 0x5c8c, 0x5c9e, 0x5cb1, 0x5cc4, 0x5cd7,
0x5ce9, 0x5cfc, 0x5d0f, 0x5d22, 0x5d34, 0x5d47,
0x5d5a, 0x5d6d, 0x5d7f, 0x5d92, 0x5da5, 0x5db8,
0x5dca, 0x5ddd, 0x5df0, 0x5e03, 0x5e15, 0x5e28,
0x5e3b, 0x5e4d, 0x5e60, 0x5e73, 0x5e86, 0x5e98,
0x5eab, 0x5ebe, 0x5ed0, 0x5ee3, 0x5ef6, 0x5f09,
0x5f1b, 0x5f2e, 0x5f41, 0x5f53, 0x5f66, 0x5f79,
0x5f8b, 0x5f9e, 0x5fb1, 0x5fc3, 0x5fd6, 0x5fe9,
0x5ffb, 0x600e, 0x6021, 0x6033, 0x6046, 0x6059,
0x606b, 0x607e, 0x6091, 0x60a3, 0x60b6, 0x60c8,
0x60db, 0x60ee, 0x6100, 0x6113, 0x6126, 0x6138,
0x614b, 0x615d, 0x6170, 0x6183, 0x6195, 0x61a8,
0x61ba, 0x61cd, 0x61e0, 0x61f2, 0x6205, 0x6217,
0x622a, 0x623d, 0x624f, 0x6262, 0x6274, 0x6287,
0x6299, 0x62ac, 0x62bf, 0x62d1, 0x62e4, 0x62f6,
0x6309, 0x631b, 0x632e, 0x6340, 0x6353, 0x6366,
0x6378, 0x638b, 0x639d, 0x63b0, 0x63c2, 0x63d5,
0x63e7, 0x63fa, 0x640c, 0x641f, 0x6431, 0x6444,
0x6456, 0x6469, 0x647b, 0x648e, 0x64a0, 0x64b3,
0x64c5, 0x64d8, 0x64ea, 0x64fd, 0x650f, 0x6522,
0x6534, 0x6547, 0x6559, 0x656c, 0x657e, 0x6591,
0x65a3, 0x65b5, 0x65c8, 0x65da, 0x65ed, 0x65ff,
0x6612, 0x6624, 0x6637, 0x6649, 0x665b, 0x666e,
0x6680, 0x6693, 0x66a5, 0x66b8, 0x66ca, 0x66dc,
0x66ef, 0x6701, 0x6714, 0x6726, 0x6738, 0x674b,
0x675d, 0x6770, 0x6782, 0x6794, 0x67a7, 0x67b9,
0x67cc, 0x67de, 0x67f0, 0x6803, 0x6815, 0x6827,
0x683a, 0x684c, 0x685e, 0x6871, 0x6883, 0x6896,
0x68a8, 0x68ba, 0x68cd, 0x68df, 0x68f1, 0x6904,
0x6916, 0x6928, 0x693b, 0x694d, 0x695f, 0x6972,
0x6984, 0x6996, 0x69a8, 0x69bb, 0x69cd, 0x69df,
0x69f2, 0x6a04, 0x6a16, 0x6a29, 0x6a3b, 0x6a4d,
0x6a5f, 0x6a72, 0x6a84, 0x6a96, 0x6aa9, 0x6abb,
0x6acd, 0x6adf, 0x6af2, 0x6b04, 0x6b16, 0x6b28,
0x6b3b, 0x6b4d, 0x6b5f, 0x6b71, 0x6b84, 0x6b96,
0x6ba8, 0x6bba, 0x6bcd, 0x6bdf, 0x6bf1, 0x6c03,
0x6c15, 0x6c28, 0x6c3a, 0x6c4c, 0x6c5e, 0x6c70,
0x6c83, 0x6c95, 0x6ca7, 0x6cb9, 0x6ccb, 0x6cde,
0x6cf0, 0x6d02, 0x6d14, 0x6d26, 0x6d39, 0x6d4b,
0x6d5d, 0x6d6f, 0x6d81, 0x6d93, 0x6da6, 0x6db8,
0x6dca, 0x6ddc, 0x6dee, 0x6e00, 0x6e12, 0x6e25,
0x6e37, 0x6e49, 0x6e5b, 0x6e6d, 0x6e7f, 0x6e91,
0x6ea3, 0x6eb6, 0x6ec8, 0x6eda, 0x6eec, 0x6efe,
0x6f10, 0x6f22, 0x6f34, 0x6f46, 0x6f58, 0x6f6b,
0x6f7d, 0x6f8f, 0x6fa1, 0x6fb3, 0x6fc5, 0x6fd7,
0x6fe9, 0x6ffb, 0x700d, 0x701f, 0x7031, 0x7043,
0x7055, 0x7068, 0x707a, 0x708c, 0x709e, 0x70b0,
0x70c2, 0x70d4, 0x70e6, 0x70f8, 0x710a, 0x711c,
0x712e, 0x7140, 0x7152, 0x7164, 0x7176, 0x7188,
0x719a, 0x71ac, 0x71be, 0x71d0, 0x71e2, 0x71f4,
0x7206, 0x7218, 0x722a, 0x723c, 0x724e, 0x7260,
0x7272, 0x7284, 0x7296, 0x72a8, 0x72ba, 0x72cc,
0x72dd, 0x72ef, 0x7301, 0x7313, 0x7325, 0x7337,
0x7349, 0x735b, 0x736d, 0x737f, 0x7391, 0x73a3,
0x73b5, 0x73c7, 0x73d8, 0x73ea, 0x73fc, 0x740e,
0x7420, 0x7432, 0x7444, 0x7456, 0x7468, 0x747a,
0x748b, 0x749d, 0x74af, 0x74c1, 0x74d3, 0x74e5,
0x74f7, 0x7509, 0x751a, 0x752c, 0x753e, 0x7550,
0x7562, 0x7574, 0x7585, 0x7597, 0x75a9, 0x75bb,
0x75cd, 0x75df, 0x75f0, 0x7602, 0x7614, 0x7626,
0x7638, 0x764a, 0x765b, 0x766d, 0x767f, 0x7691,
0x76a3, 0x76b4, 0x76c6, 0x76d8, 0x76ea, 0x76fb,
0x770d, 0x771f, 0x7731, 0x7743, 0x7754, 0x7766,
0x7778, 0x778a, 0x779b, 0x77ad, 0x77bf, 0x77d1,
0x77e2, 0x77f4, 0x7806, 0x7818, 0x7829, 0x783b,
0x784d, 0x785e, 0x7870, 0x7882, 0x7894, 0x78a5,
0x78b7, 0x78c9, 0x78da, 0x78ec, 0x78fe, 0x7910,
0x7921, 0x7933, 0x7945, 0x7956, 0x7968, 0x797a,
0x798b, 0x799d, 0x79af, 0x79c0, 0x79d2, 0x79e4,
0x79f5, 0x7a07, 0x7a19, 0x7a2a, 0x7a3c, 0x7a4e,
0x7a5f, 0x7a71, 0x7a82, 0x7a94, 0x7aa6, 0x7ab7,
0x7ac9, 0x7adb, 0x7aec, 0x7afe, 0x7b0f, 0x7b21,
0x7b33, 0x7b44, 0x7b56, 0x7b67, 0x7b79, 0x7b8b,
0x7b9c, 0x7bae, 0x7bbf, 0x7bd1, 0x7be2, 0x7bf4,
0x7c06, 0x7c17, 0x7c29, 0x7c3a, 0x7c4c, 0x7c5d,
0x7c6f, 0x7c81, 0x7c92, 0x7ca4, 0x7cb5, 0x7cc7,
0x7cd8, 0x7cea, 0x7cfb, 0x7d0d, 0x7d1e, 0x7d30,
0x7d41, 0x7d53, 0x7d64, 0x7d76, 0x7d87, 0x7d99,
0x7daa, 0x7dbc, 0x7dcd, 0x7ddf, 0x7df0, 0x7e02,
0x7e13, 0x7e25, 0x7e36, 0x7e48, 0x7e59, 0x7e6b,
0x7e7c, 0x7e8e, 0x7e9f, 0x7eb0, 0x7ec2, 0x7ed3,
0x7ee5, 0x7ef6, 0x7f08, 0x7f19, 0x7f2b, 0x7f3c,
0x7f4d, 0x7f5f, 0x7f70, 0x7f82, 0x7f93, 0x7fa4,
0x7fb6, 0x7fc7, 0x7fd9, 0x7fea, 0x7ffb, 0x800d,
0x801e, 0x8030, 0x8041, 0x8052, 0x8064, 0x8075,
0x8086, 0x8098, 0x80a9, 0x80bb, 0x80cc, 0x80dd,
0x80ef, 0x8100, 0x8111, 0x8123, 0x8134, 0x8145,
0x8157, 0x8168, 0x8179, 0x818b, 0x819c, 0x81ad,
0x81bf, 0x81d0, 0x81e1, 0x81f3, 0x8204, 0x8215,
0x8226, 0x8238, 0x8249, 0x825a, 0x826c, 0x827d,
0x828e, 0x829f, 0x82b1, 0x82c2, 0x82d3, 0x82e5,
0x82f6, 0x8307, 0x8318, 0x832a, 0x833b, 0x834c,
0x835d, 0x836f, 0x8380, 0x8391, 0x83a2, 0x83b3,
0x83c5, 0x83d6, 0x83e7, 0x83f8, 0x840a, 0x841b,
0x842c, 0x843d, 0x844e, 0x8460, 0x8471, 0x8482,
0x8493, 0x84a4, 0x84b6, 0x84c7, 0x84d8, 0x84e9,
0x84fa, 0x850b, 0x851d, 0x852e, 0x853f, 0x8550,
0x8561, 0x8572, 0x8584, 0x8595, 0x85a6, 0x85b7,
0x85c8, 0x85d9, 0x85ea, 0x85fb, 0x860d, 0x861e,
0x862f, 0x8640, 0x8651, 0x8662, 0x8673, 0x8684,
0x8695, 0x86a7, 0x86b8, 0x86c9, 0x86da, 0x86eb,
0x86fc, 0x870d, 0x871e, 0x872f, 0x8740, 0x8751,
0x8762, 0x8773, 0x8784, 0x8796, 0x87a7, 0x87b8,
0x87c9, 0x87da, 0x87eb, 0x87fc, 0x880d, 0x881e,
0x882f, 0x8840, 0x8851, 0x8862, 0x8873, 0x8884,
0x8895, 0x88a6, 0x88b7, 0x88c8, 0x88d9, 0x88ea,
0x88fb, 0x890c, 0x891d, 0x892e, 0x893f, 0x8950,
0x8961, 0x8972, 0x8983, 0x8994, 0x89a5, 0x89b6,
0x89c6, 0x89d7, 0x89e8, 0x89f9, 0x8a0a, 0x8a1b,
0x8a2c, 0x8a3d, 0x8a4e, 0x8a5f, 0x8a70, 0x8a81,
0x8a92, 0x8aa3, 0x8ab3, 0x8ac4, 0x8ad5, 0x8ae6,
0x8af7, 0x8b08, 0x8b19, 0x8b2a, 0x8b3b, 0x8b4b,
0x8b5c, 0x8b6d, 0x8b7e, 0x8b8f, 0x8ba0, 0x8bb1,
0x8bc1, 0x8bd2, 0x8be3, 0x8bf4, 0x8c05, 0x8c16,
0x8c27, 0x8c37, 0x8c48, 0x8c59, 0x8c6a, 0x8c7b,
0x8c8c, 0x8c9c, 0x8cad, 0x8cbe, 0x8ccf, 0x8ce0,
0x8cf0, 0x8d01, 0x8d12, 0x8d23, 0x8d34, 0x8d44,
0x8d55, 0x8d66, 0x8d77, 0x8d87, 0x8d98, 0x8da9,
0x8dba, 0x8dca, 0x8ddb, 0x8dec, 0x8dfd, 0x8e0d,
0x8e1e, 0x8e2f, 0x8e40, 0x8e50, 0x8e61, 0x8e72,
0x8e83, 0x8e93, 0x8ea4, 0x8eb5, 0x8ec5, 0x8ed6,
0x8ee7, 0x8ef8, 0x8f08, 0x8f19, 0x8f2a, 0x8f3a,
0x8f4b, 0x8f5c, 0x8f6c, 0x8f7d, 0x8f8e, 0x8f9e,
0x8faf, 0x8fc0, 0x8fd0, 0x8fe1, 0x8ff2, 0x9002,
0x9013, 0x9024, 0x9034, 0x9045, 0x9056, 0x9066,
0x9077, 0x9088, 0x9098, 0x90a9, 0x90b9, 0x90ca,
0x90db, 0x90eb, 0x90fc, 0x910c, 0x911d, 0x912e,
0x913e, 0x914f, 0x915f, 0x9170, 0x9181, 0x9191,
0x91a2, 0x91b2, 0x91c3, 0x91d3, 0x91e4, 0x91f5,
0x9205, 0x9216, 0x9226, 0x9237, 0x9247, 0x9258,
0x9268, 0x9279, 0x9289, 0x929a, 0x92aa, 0x92bb,
0x92cc, 0x92dc, 0x92ed, 0x92fd, 0x930e, 0x931e,
0x932f, 0x933f, 0x9350, 0x9360, 0x9370, 0x9381,
0x9391, 0x93a2, 0x93b2, 0x93c3, 0x93d3, 0x93e4,
0x93f4, 0x9405, 0x9415, 0x9426, 0x9436, 0x9447,
0x9457, 0x9467, 0x9478, 0x9488, 0x9499, 0x94a9,
0x94ba, 0x94ca, 0x94da, 0x94eb, 0x94fb, 0x950c,
0x951c, 0x952c, 0x953d, 0x954d, 0x955e, 0x956e,
0x957e, 0x958f, 0x959f, 0x95af, 0x95c0, 0x95d0,
0x95e1, 0x95f1, 0x9601, 0x9612, 0x9622, 0x9632,
0x9643, 0x9653, 0x9663, 0x9674, 0x9684, 0x9694,
0x96a5, 0x96b5, 0x96c5, 0x96d6, 0x96e6, 0x96f6,
0x9707, 0x9717, 0x9727, 0x9738, 0x9748, 0x9758,
0x9768, 0x9779, 0x9789, 0x9799, 0x97aa, 0x97ba,
0x97ca, 0x97da, 0x97eb, 0x97fb, 0x980b, 0x981b,
0x982c, 0x983c, 0x984c, 0x985c, 0x986d, 0x987d,
0x988d, 0x989d, 0x98ad, 0x98be, 0x98ce, 0x98de,
0x98ee, 0x98ff, 0x990f, 0x991f, 0x992f, 0x993f,
0x9950, 0x9960, 0x9970, 0x9980, 0x9990, 0x99a0,
0x99b1, 0x99c1, 0x99d1, 0x99e1, 0x99f1, 0x9a01,
0x9a12, 0x9a22, 0x9a32, 0x9a42, 0x9a52, 0x9a62,
0x9a72, 0x9a83, 0x9a93, 0x9aa3, 0x9ab3, 0x9ac3,
0x9ad3, 0x9ae3, 0x9af3, 0x9b04, 0x9b14, 0x9b24,
0x9b34, 0x9b44, 0x9b54, 0x9b64, 0x9b74, 0x9b84,
0x9b94, 0x9ba4, 0x9bb5, 0x9bc5, 0x9bd5, 0x9be5,
0x9bf5, 0x9c05, 0x9c15, 0x9c25, 0x9c35, 0x9c45,
0x9c55, 0x9c65, 0x9c75, 0x9c85, 0x9c95, 0x9ca5,
0x9cb5, 0x9cc5, 0x9cd5, 0x9ce5, 0x9cf5, 0x9d05,
0x9d15, 0x9d25, 0x9d35, 0x9d45, 0x9d55, 0x9d65,
0x9d75, 0x9d85, 0x9d95, 0x9da5, 0x9db5, 0x9dc5,
0x9dd5, 0x9de5, 0x9df5, 0x9e05, 0x9e15, 0x9e25,
0x9e35, 0x9e45, 0x9e55, 0x9e65, 0x9e74, 0x9e84,
0x9e94, 0x9ea4, 0x9eb4, 0x9ec4, 0x9ed4, 0x9ee4,
0x9ef4, 0x9f04, 0x9f14, 0x9f23, 0x9f33, 0x9f43,
0x9f53, 0x9f63, 0x9f73, 0x9f83, 0x9f93, 0x9fa3,
0x9fb2, 0x9fc2, 0x9fd2, 0x9fe2, 0x9ff2, 0xa002,
0xa012, 0xa021, 0xa031, 0xa041, 0xa051, 0xa061,
0xa071, 0xa080, 0xa090, 0xa0a0, 0xa0b0, 0xa0c0,
0xa0cf, 0xa0df, 0xa0ef, 0xa0ff, 0xa10f, 0xa11e,
0xa12e, 0xa13e, 0xa14e, 0xa15e, 0xa16d, 0xa17d,
0xa18d, 0xa19d, 0xa1ac, 0xa1bc, 0xa1cc, 0xa1dc,
0xa1eb, 0xa1fb, 0xa20b, 0xa21b, 0xa22a, 0xa23a,
0xa24a, 0xa25a, 0xa269, 0xa279, 0xa289, 0xa298,
0xa2a8, 0xa2b8, 0xa2c8, 0xa2d7, 0xa2e7, 0xa2f7,
0xa306, 0xa316, 0xa326, 0xa335, 0xa345, 0xa355,
0xa364, 0xa374, 0xa384, 0xa393, 0xa3a3, 0xa3b3,
0xa3c2, 0xa3d2, 0xa3e2, 0xa3f1, 0xa401, 0xa411,
0xa420, 0xa430, 0xa440, 0xa44f, 0xa45f, 0xa46e,
0xa47e, 0xa48e, 0xa49d, 0xa4ad, 0xa4bc, 0xa4cc,
0xa4dc, 0xa4eb, 0xa4fb, 0xa50a, 0xa51a, 0xa52a,
0xa539, 0xa549, 0xa558, 0xa568, 0xa577, 0xa587,
0xa597, 0xa5a6, 0xa5b6, 0xa5c5, 0xa5d5, 0xa5e4,
0xa5f4, 0xa603, 0xa613, 0xa622, 0xa632, 0xa641,
0xa651, 0xa660, 0xa670, 0xa67f, 0xa68f, 0xa69e,
0xa6ae, 0xa6bd, 0xa6cd, 0xa6dc, 0xa6ec, 0xa6fb,
0xa70b, 0xa71a, 0xa72a, 0xa739, 0xa749, 0xa758,
0xa768, 0xa777, 0xa787, 0xa796, 0xa7a5, 0xa7b5,
0xa7c4, 0xa7d4, 0xa7e3, 0xa7f3, 0xa802, 0xa812,
0xa821, 0xa830, 0xa840, 0xa84f, 0xa85f, 0xa86e,
0xa87d, 0xa88d, 0xa89c, 0xa8ac, 0xa8bb, 0xa8ca,
0xa8da, 0xa8e9, 0xa8f8, 0xa908, 0xa917, 0xa927,
0xa936, 0xa945, 0xa955, 0xa964, 0xa973, 0xa983,
0xa992, 0xa9a1, 0xa9b1, 0xa9c0, 0xa9cf, 0xa9df,
0xa9ee, 0xa9fd, 0xaa0d, 0xaa1c, 0xaa2b, 0xaa3b,
0xaa4a, 0xaa59, 0xaa69, 0xaa78, 0xaa87, 0xaa96,
0xaaa6, 0xaab5, 0xaac4, 0xaad4, 0xaae3, 0xaaf2,
0xab01, 0xab11, 0xab20, 0xab2f, 0xab3e, 0xab4e,
0xab5d, 0xab6c, 0xab7b, 0xab8b, 0xab9a, 0xaba9,
0xabb8, 0xabc7, 0xabd7, 0xabe6, 0xabf5, 0xac04,
0xac14, 0xac23, 0xac32, 0xac41, 0xac50, 0xac60,
0xac6f, 0xac7e, 0xac8d, 0xac9c, 0xacab, 0xacbb,
0xacca, 0xacd9, 0xace8, 0xacf7, 0xad06, 0xad16,
0xad25, 0xad34, 0xad43, 0xad52, 0xad61, 0xad70,
0xad80, 0xad8f, 0xad9e, 0xadad, 0xadbc, 0xadcb,
0xadda, 0xade9, 0xadf8, 0xae08, 0xae17, 0xae26,
0xae35, 0xae44, 0xae53, 0xae62, 0xae71, 0xae80,
0xae8f, 0xae9e, 0xaead, 0xaebd, 0xaecc, 0xaedb,
0xaeea, 0xaef9, 0xaf08, 0xaf17, 0xaf26, 0xaf35,
0xaf44, 0xaf53, 0xaf62, 0xaf71, 0xaf80, 0xaf8f,
0xaf9e, 0xafad, 0xafbc, 0xafcb, 0xafda, 0xafe9,
0xaff8, 0xb007, 0xb016, 0xb025, 0xb034, 0xb043,
0xb052, 0xb061, 0xb070, 0xb07f, 0xb08e, 0xb09d,
0xb0ac, 0xb0bb, 0xb0ca, 0xb0d9, 0xb0e8, 0xb0f6,
0xb105, 0xb114, 0xb123, 0xb132, 0xb141, 0xb150,
0xb15f, 0xb16e, 0xb17d, 0xb18c, 0xb19b, 0xb1aa,
0xb1b8, 0xb1c7, 0xb1d6, 0xb1e5, 0xb1f4, 0xb203,
0xb212, 0xb221, 0xb22f, 0xb23e, 0xb24d, 0xb25c,
0xb26b, 0xb27a, 0xb289, 0xb297, 0xb2a6, 0xb2b5,
0xb2c4, 0xb2d3, 0xb2e2, 0xb2f1, 0xb2ff, 0xb30e,
0xb31d, 0xb32c, 0xb33b, 0xb349, 0xb358, 0xb367,
0xb376, 0xb385, 0xb393, 0xb3a2, 0xb3b1, 0xb3c0,
0xb3cf, 0xb3dd, 0xb3ec, 0xb3fb, 0xb40a, 0xb418,
0xb427, 0xb436, 0xb445, 0xb453, 0xb462, 0xb471,
0xb480, 0xb48e, 0xb49d, 0xb4ac, 0xb4bb, 0xb4c9,
0xb4d8, 0xb4e7, 0xb4f6, 0xb504, 0xb513, 0xb522,
0xb530, 0xb53f, 0xb54e, 0xb55c, 0xb56b, 0xb57a,
0xb588, 0xb597, 0xb5a6, 0xb5b5, 0xb5c3, 0xb5d2,
0xb5e1, 0xb5ef, 0xb5fe, 0xb60d, 0xb61b, 0xb62a,
0xb638, 0xb647, 0xb656, 0xb664, 0xb673, 0xb682,
0xb690, 0xb69f, 0xb6ae, 0xb6bc, 0xb6cb, 0xb6d9,
0xb6e8, 0xb6f7, 0xb705, 0xb714, 0xb722, 0xb731,
0xb740, 0xb74e, 0xb75d, 0xb76b, 0xb77a, 0xb788,
0xb797, 0xb7a6, 0xb7b4, 0xb7c3, 0xb7d1, 0xb7e0,
0xb7ee, 0xb7fd, 0xb80b, 0xb81a, 0xb829, 0xb837,
0xb846, 0xb854, 0xb863, 0xb871, 0xb880, 0xb88e,
0xb89d, 0xb8ab, 0xb8ba, 0xb8c8, 0xb8d7, 0xb8e5,
0xb8f4, 0xb902, 0xb911, 0xb91f, 0xb92e, 0xb93c,
0xb94b, 0xb959, 0xb968, 0xb976, 0xb984, 0xb993,
0xb9a1, 0xb9b0, 0xb9be, 0xb9cd, 0xb9db, 0xb9ea,
0xb9f8, 0xba06, 0xba15, 0xba23, 0xba32, 0xba40,
0xba4f, 0xba5d, 0xba6b, 0xba7a, 0xba88, 0xba97,
0xbaa5, 0xbab3, 0xbac2, 0xbad0, 0xbade, 0xbaed,
0xbafb, 0xbb0a, 0xbb18, 0xbb26, 0xbb35, 0xbb43,
0xbb51, 0xbb60, 0xbb6e, 0xbb7c, 0xbb8b, 0xbb99,
0xbba8, 0xbbb6, 0xbbc4, 0xbbd3, 0xbbe1, 0xbbef,
0xbbfd, 0xbc0c, 0xbc1a, 0xbc28, 0xbc37, 0xbc45,
0xbc53, 0xbc62, 0xbc70, 0xbc7e, 0xbc8c, 0xbc9b,
0xbca9, 0xbcb7, 0xbcc6, 0xbcd4, 0xbce2, 0xbcf0,
0xbcff, 0xbd0d, 0xbd1b, 0xbd29, 0xbd38, 0xbd46,
0xbd54, 0xbd62, 0xbd71, 0xbd7f, 0xbd8d, 0xbd9b,
0xbdaa, 0xbdb8, 0xbdc6, 0xbdd4, 0xbde2, 0xbdf1,
0xbdff, 0xbe0d, 0xbe1b, 0xbe29, 0xbe38, 0xbe46,
0xbe54, 0xbe62, 0xbe70, 0xbe7f, 0xbe8d, 0xbe9b,
0xbea9, 0xbeb7, 0xbec5, 0xbed4, 0xbee2, 0xbef0,
0xbefe, 0xbf0c, 0xbf1a, 0xbf28, 0xbf37, 0xbf45,
0xbf53, 0xbf61, 0xbf6f, 0xbf7d, 0xbf8b, 0xbf99,
0xbfa7, 0xbfb6, 0xbfc4, 0xbfd2, 0xbfe0, 0xbfee,
0xbffc, 0xc00a, 0xc018, 0xc026, 0xc034, 0xc042,
0xc051, 0xc05f, 0xc06d, 0xc07b, 0xc089, 0xc097,
0xc0a5, 0xc0b3, 0xc0c1, 0xc0cf, 0xc0dd, 0xc0eb,
0xc0f9, 0xc107, 0xc115, 0xc123, 0xc131, 0xc13f,
0xc14d, 0xc15b, 0xc169, 0xc177, 0xc185, 0xc193,
0xc1a1, 0xc1af, 0xc1bd, 0xc1cb, 0xc1d9, 0xc1e7,
0xc1f5, 0xc203, 0xc211, 0xc21f, 0xc22d, 0xc23b,
0xc249, 0xc257, 0xc265, 0xc273, 0xc281, 0xc28f,
0xc29d, 0xc2ab, 0xc2b8, 0xc2c6, 0xc2d4, 0xc2e2,
0xc2f0, 0xc2fe, 0xc30c, 0xc31a, 0xc328, 0xc336,
0xc344, 0xc352, 0xc35f, 0xc36d, 0xc37b, 0xc389,
0xc397, 0xc3a5, 0xc3b3, 0xc3c1, 0xc3ce, 0xc3dc,
0xc3ea, 0xc3f8, 0xc406, 0xc414, 0xc422, 0xc42f,
0xc43d, 0xc44b, 0xc459, 0xc467, 0xc475, 0xc482,
0xc490, 0xc49e, 0xc4ac, 0xc4ba, 0xc4c7, 0xc4d5,
0xc4e3, 0xc4f1, 0xc4ff, 0xc50d, 0xc51a, 0xc528,
0xc536, 0xc544, 0xc551, 0xc55f, 0xc56d, 0xc57b,
0xc589, 0xc596, 0xc5a4, 0xc5b2, 0xc5c0, 0xc5cd,
0xc5db, 0xc5e9, 0xc5f7, 0xc604, 0xc612, 0xc620,
0xc62d, 0xc63b, 0xc649, 0xc657, 0xc664, 0xc672,
0xc680, 0xc68d, 0xc69b, 0xc6a9, 0xc6b7, 0xc6c4,
0xc6d2, 0xc6e0, 0xc6ed, 0xc6fb, 0xc709, 0xc716,
0xc724, 0xc732, 0xc73f, 0xc74d, 0xc75b, 0xc768,
0xc776, 0xc784, 0xc791, 0xc79f, 0xc7ad, 0xc7ba,
0xc7c8, 0xc7d6, 0xc7e3, 0xc7f1, 0xc7fe, 0xc80c,
0xc81a, 0xc827, 0xc835, 0xc842, 0xc850, 0xc85e,
0xc86b, 0xc879, 0xc886, 0xc894, 0xc8a2, 0xc8af,
0xc8bd, 0xc8ca, 0xc8d8, 0xc8e5, 0xc8f3, 0xc901,
0xc90e, 0xc91c, 0xc929, 0xc937, 0xc944, 0xc952,
0xc95f, 0xc96d, 0xc97b, 0xc988, 0xc996, 0xc9a3,
0xc9b1, 0xc9be, 0xc9cc, 0xc9d9, 0xc9e7, 0xc9f4,
0xca02, 0xca0f, 0xca1d, 0xca2a, 0xca38, 0xca45,
0xca53, 0xca60, 0xca6e, 0xca7b, 0xca89, 0xca96,
0xcaa4, 0xcab1, 0xcabe, 0xcacc, 0xcad9, 0xcae7,
0xcaf4, 0xcb02, 0xcb0f, 0xcb1d, 0xcb2a, 0xcb37,
0xcb45, 0xcb52, 0xcb60, 0xcb6d, 0xcb7b, 0xcb88,
0xcb95, 0xcba3, 0xcbb0, 0xcbbe, 0xcbcb, 0xcbd8,
0xcbe6, 0xcbf3, 0xcc01, 0xcc0e, 0xcc1b, 0xcc29,
0xcc36, 0xcc43, 0xcc51, 0xcc5e, 0xcc6c, 0xcc79,
0xcc86, 0xcc94, 0xcca1, 0xccae, 0xccbc, 0xccc9,
0xccd6, 0xcce4, 0xccf1, 0xccfe, 0xcd0c, 0xcd19,
0xcd26, 0xcd34, 0xcd41, 0xcd4e, 0xcd5b, 0xcd69,
0xcd76, 0xcd83, 0xcd91, 0xcd9e, 0xcdab, 0xcdb9,
0xcdc6, 0xcdd3, 0xcde0, 0xcdee, 0xcdfb, 0xce08,
0xce15, 0xce23, 0xce30, 0xce3d, 0xce4a, 0xce58,
0xce65, 0xce72, 0xce7f, 0xce8d, 0xce9a, 0xcea7,
0xceb4, 0xcec2, 0xcecf, 0xcedc, 0xcee9, 0xcef6,
0xcf04, 0xcf11, 0xcf1e, 0xcf2b, 0xcf38, 0xcf46,
0xcf53, 0xcf60, 0xcf6d, 0xcf7a, 0xcf87, 0xcf95,
0xcfa2, 0xcfaf, 0xcfbc, 0xcfc9, 0xcfd6, 0xcfe4,
0xcff1, 0xcffe, 0xd00b, 0xd018, 0xd025, 0xd032,
0xd040, 0xd04d, 0xd05a, 0xd067, 0xd074, 0xd081,
0xd08e, 0xd09b, 0xd0a9, 0xd0b6, 0xd0c3, 0xd0d0,
0xd0dd, 0xd0ea, 0xd0f7, 0xd104, 0xd111, 0xd11e,
0xd12b, 0xd139, 0xd146, 0xd153, 0xd160, 0xd16d,
0xd17a, 0xd187, 0xd194, 0xd1a1, 0xd1ae, 0xd1bb,
0xd1c8, 0xd1d5, 0xd1e2, 0xd1ef, 0xd1fc, 0xd209,
0xd216, 0xd223, 0xd230, 0xd23d, 0xd24a, 0xd257,
0xd264, 0xd271, 0xd27e, 0xd28b, 0xd298, 0xd2a5,
0xd2b2, 0xd2bf, 0xd2cc, 0xd2d9, 0xd2e6, 0xd2f3,
0xd300, 0xd30d, 0xd31a, 0xd327, 0xd334, 0xd341,
0xd34e, 0xd35b, 0xd368, 0xd375, 0xd382, 0xd38f,
0xd39c, 0xd3a8, 0xd3b5, 0xd3c2, 0xd3cf, 0xd3dc,
0xd3e9, 0xd3f6, 0xd403, 0xd410, 0xd41d, 0xd42a,
0xd436, 0xd443, 0xd450, 0xd45d, 0xd46a, 0xd477,
0xd484, 0xd491, 0xd49e, 0xd4aa, 0xd4b7, 0xd4c4,
0xd4d1, 0xd4de, 0xd4eb, 0xd4f8, 0xd504, 0xd511,
0xd51e, 0xd52b, 0xd538, 0xd545, 0xd551, 0xd55e,
0xd56b, 0xd578, 0xd585, 0xd591, 0xd59e, 0xd5ab,
0xd5b8, 0xd5c5, 0xd5d1, 0xd5de, 0xd5eb, 0xd5f8,
0xd605, 0xd611, 0xd61e, 0xd62b, 0xd638, 0xd645,
0xd651, 0xd65e, 0xd66b, 0xd678, 0xd684, 0xd691,
0xd69e, 0xd6ab, 0xd6b7, 0xd6c4, 0xd6d1, 0xd6de,
0xd6ea, 0xd6f7, 0xd704, 0xd710, 0xd71d, 0xd72a,
0xd737, 0xd743, 0xd750, 0xd75d, 0xd769, 0xd776,
0xd783, 0xd78f, 0xd79c, 0xd7a9, 0xd7b6, 0xd7c2,
0xd7cf, 0xd7dc, 0xd7e8, 0xd7f5, 0xd802, 0xd80e,
0xd81b, 0xd828, 0xd834, 0xd841, 0xd84e, 0xd85a,
0xd867, 0xd873, 0xd880, 0xd88d, 0xd899, 0xd8a6,
0xd8b3, 0xd8bf, 0xd8cc, 0xd8d8, 0xd8e5, 0xd8f2,
0xd8fe, 0xd90b, 0xd917, 0xd924, 0xd931, 0xd93d,
0xd94a, 0xd956, 0xd963, 0xd970, 0xd97c, 0xd989,
0xd995, 0xd9a2, 0xd9ae, 0xd9bb, 0xd9c8, 0xd9d4,
0xd9e1, 0xd9ed, 0xd9fa, 0xda06, 0xda13, 0xda1f,
0xda2c, 0xda38, 0xda45, 0xda51, 0xda5e, 0xda6a,
0xda77, 0xda84, 0xda90, 0xda9d, 0xdaa9, 0xdab6,
0xdac2, 0xdacf, 0xdadb, 0xdae7, 0xdaf4, 0xdb00,
0xdb0d, 0xdb19, 0xdb26, 0xdb32, 0xdb3f, 0xdb4b,
0xdb58, 0xdb64, 0xdb71, 0xdb7d, 0xdb8a, 0xdb96,
0xdba2, 0xdbaf, 0xdbbb, 0xdbc8, 0xdbd4, 0xdbe1,
0xdbed, 0xdbf9, 0xdc06, 0xdc12, 0xdc1f, 0xdc2b,
0xdc38, 0xdc44, 0xdc50, 0xdc5d, 0xdc69, 0xdc76,
0xdc82, 0xdc8e, 0xdc9b, 0xdca7, 0xdcb3, 0xdcc0,
0xdccc, 0xdcd9, 0xdce5, 0xdcf1, 0xdcfe, 0xdd0a,
0xdd16, 0xdd23, 0xdd2f, 0xdd3b, 0xdd48, 0xdd54,
0xdd60, 0xdd6d, 0xdd79, 0xdd85, 0xdd92, 0xdd9e,
0xddaa, 0xddb7, 0xddc3, 0xddcf, 0xdddc, 0xdde8,
0xddf4, 0xde01, 0xde0d, 0xde19, 0xde25, 0xde32,
0xde3e, 0xde4a, 0xde57, 0xde63, 0xde6f, 0xde7b,
0xde88, 0xde94, 0xdea0, 0xdeac, 0xdeb9, 0xdec5,
0xded1, 0xdedd, 0xdeea, 0xdef6, 0xdf02, 0xdf0e,
0xdf1b, 0xdf27, 0xdf33, 0xdf3f, 0xdf4c, 0xdf58,
0xdf64, 0xdf70, 0xdf7c, 0xdf89, 0xdf95, 0xdfa1,
0xdfad, 0xdfb9, 0xdfc6, 0xdfd2, 0xdfde, 0xdfea,
0xdff6, 0xe003, 0xe00f, 0xe01b, 0xe027, 0xe033,
0xe03f, 0xe04c, 0xe058, 0xe064, 0xe070, 0xe07c,
0xe088, 0xe094, 0xe0a1, 0xe0ad, 0xe0b9, 0xe0c5,
0xe0d1, 0xe0dd, 0xe0e9, 0xe0f5, 0xe102, 0xe10e,
0xe11a, 0xe126, 0xe132, 0xe13e, 0xe14a, 0xe156,
0xe162, 0xe16e, 0xe17b, 0xe187, 0xe193, 0xe19f,
0xe1ab, 0xe1b7, 0xe1c3, 0xe1cf, 0xe1db, 0xe1e7,
0xe1f3, 0xe1ff, 0xe20b, 0xe217, 0xe223, 0xe22f,
0xe23c, 0xe248, 0xe254, 0xe260, 0xe26c, 0xe278,
0xe284, 0xe290, 0xe29c, 0xe2a8, 0xe2b4, 0xe2c0,
0xe2cc, 0xe2d8, 0xe2e4, 0xe2f0, 0xe2fc, 0xe308,
0xe314, 0xe320, 0xe32c, 0xe338, 0xe344, 0xe350,
0xe35c, 0xe368, 0xe374, 0xe380, 0xe38b, 0xe397,
0xe3a3, 0xe3af, 0xe3bb, 0xe3c7, 0xe3d3, 0xe3df,
0xe3eb, 0xe3f7, 0xe403, 0xe40f, 0xe41b, 0xe427,
0xe433, 0xe43f, 0xe44a, 0xe456, 0xe462, 0xe46e,
0xe47a, 0xe486, 0xe492, 0xe49e, 0xe4aa, 0xe4b6,
0xe4c1, 0xe4cd, 0xe4d9, 0xe4e5, 0xe4f1, 0xe4fd,
0xe509, 0xe515, 0xe520, 0xe52c, 0xe538, 0xe544,
0xe550, 0xe55c, 0xe567, 0xe573, 0xe57f, 0xe58b,
0xe597, 0xe5a3, 0xe5af, 0xe5ba, 0xe5c6, 0xe5d2,
0xe5de, 0xe5ea, 0xe5f5, 0xe601, 0xe60d, 0xe619,
0xe625, 0xe630, 0xe63c, 0xe648, 0xe654, 0xe660,
0xe66b, 0xe677, 0xe683, 0xe68f, 0xe69a, 0xe6a6,
0xe6b2, 0xe6be, 0xe6ca, 0xe6d5, 0xe6e1, 0xe6ed,
0xe6f9, 0xe704, 0xe710, 0xe71c, 0xe727, 0xe733,
0xe73f, 0xe74b, 0xe756, 0xe762, 0xe76e, 0xe77a,
0xe785, 0xe791, 0xe79d, 0xe7a8, 0xe7b4, 0xe7c0,
0xe7cb, 0xe7d7, 0xe7e3, 0xe7ef, 0xe7fa, 0xe806,
0xe812, 0xe81d, 0xe829, 0xe835, 0xe840, 0xe84c,
0xe858, 0xe863, 0xe86f, 0xe87b, 0xe886, 0xe892,
0xe89e, 0xe8a9, 0xe8b5, 0xe8c0, 0xe8cc, 0xe8d8,
0xe8e3, 0xe8ef, 0xe8fb, 0xe906, 0xe912, 0xe91d,
0xe929, 0xe935, 0xe940, 0xe94c, 0xe958, 0xe963,
0xe96f, 0xe97a, 0xe986, 0xe991, 0xe99d, 0xe9a9,
0xe9b4, 0xe9c0, 0xe9cb, 0xe9d7, 0xe9e3, 0xe9ee,
0xe9fa, 0xea05, 0xea11, 0xea1c, 0xea28, 0xea33,
0xea3f, 0xea4a, 0xea56, 0xea62, 0xea6d, 0xea79,
0xea84, 0xea90, 0xea9b, 0xeaa7, 0xeab2, 0xeabe,
0xeac9, 0xead5, 0xeae0, 0xeaec, 0xeaf7, 0xeb03,
0xeb0e, 0xeb1a, 0xeb25, 0xeb31, 0xeb3c, 0xeb48,
0xeb53, 0xeb5f, 0xeb6a, 0xeb76, 0xeb81, 0xeb8d,
0xeb98, 0xeba3, 0xebaf, 0xebba, 0xebc6, 0xebd1,
0xebdd, 0xebe8, 0xebf4, 0xebff, 0xec0a, 0xec16,
0xec21, 0xec2d, 0xec38, 0xec44, 0xec4f, 0xec5a,
0xec66, 0xec71, 0xec7d, 0xec88, 0xec93, 0xec9f,
0xecaa, 0xecb6, 0xecc1, 0xeccc, 0xecd8, 0xece3,
0xecef, 0xecfa, 0xed05, 0xed11, 0xed1c, 0xed27,
0xed33, 0xed3e, 0xed4a, 0xed55, 0xed60, 0xed6c,
0xed77, 0xed82, 0xed8e, 0xed99, 0xeda4, 0xedb0,
0xedbb, 0xedc6, 0xedd2, 0xeddd, 0xede8, 0xedf4,
0xedff, 0xee0a, 0xee15, 0xee21, 0xee2c, 0xee37,
0xee43, 0xee4e, 0xee59, 0xee65, 0xee70, 0xee7b,
0xee86, 0xee92, 0xee9d, 0xeea8, 0xeeb3, 0xeebf,
0xeeca, 0xeed5, 0xeee1, 0xeeec, 0xeef7, 0xef02,
0xef0e, 0xef19, 0xef24, 0xef2f, 0xef3a, 0xef46,
0xef51, 0xef5c, 0xef67, 0xef73, 0xef7e, 0xef89,
0xef94, 0xef9f, 0xefab, 0xefb6, 0xefc1, 0xefcc,
0xefd7, 0xefe3, 0xefee, 0xeff9, 0xf004, 0xf00f,
0xf01b, 0xf026, 0xf031, 0xf03c, 0xf047, 0xf052,
0xf05e, 0xf069, 0xf074, 0xf07f, 0xf08a, 0xf095,
0xf0a1, 0xf0ac, 0xf0b7, 0xf0c2, 0xf0cd, 0xf0d8,
0xf0e3, 0xf0ef, 0xf0fa, 0xf105, 0xf110, 0xf11b,
0xf126, 0xf131, 0xf13c, 0xf147, 0xf153, 0xf15e,
0xf169, 0xf174, 0xf17f, 0xf18a, 0xf195, 0xf1a0,
0xf1ab, 0xf1b6, 0xf1c2, 0xf1cd, 0xf1d8, 0xf1e3,
0xf1ee, 0xf1f9, 0xf204, 0xf20f, 0xf21a, 0xf225,
0xf230, 0xf23b, 0xf246, 0xf251, 0xf25c, 0xf267,
0xf272, 0xf27d, 0xf288, 0xf293, 0xf29f, 0xf2aa,
0xf2b5, 0xf2c0, 0xf2cb, 0xf2d6, 0xf2e1, 0xf2ec,
0xf2f7, 0xf302, 0xf30d, 0xf318, 0xf323, 0xf32e,
0xf339, 0xf344, 0xf34f, 0xf35a, 0xf364, 0xf36f,
0xf37a, 0xf385, 0xf390, 0xf39b, 0xf3a6, 0xf3b1,
0xf3bc, 0xf3c7, 0xf3d2, 0xf3dd, 0xf3e8, 0xf3f3,
0xf3fe, 0xf409, 0xf414, 0xf41f, 0xf42a, 0xf435,
0xf43f, 0xf44a, 0xf455, 0xf460, 0xf46b, 0xf476,
0xf481, 0xf48c, 0xf497, 0xf4a2, 0xf4ad, 0xf4b7,
0xf4c2, 0xf4cd, 0xf4d8, 0xf4e3, 0xf4ee, 0xf4f9,
0xf504, 0xf50f, 0xf519, 0xf524, 0xf52f, 0xf53a,
0xf545, 0xf550, 0xf55b, 0xf565, 0xf570, 0xf57b,
0xf586, 0xf591, 0xf59c, 0xf5a6, 0xf5b1, 0xf5bc,
0xf5c7, 0xf5d2, 0xf5dd, 0xf5e7, 0xf5f2, 0xf5fd,
0xf608, 0xf613, 0xf61d, 0xf628, 0xf633, 0xf63e,
0xf649, 0xf653, 0xf65e, 0xf669, 0xf674, 0xf67f,
0xf689, 0xf694, 0xf69f, 0xf6aa, 0xf6b4, 0xf6bf,
0xf6ca, 0xf6d5, 0xf6e0, 0xf6ea, 0xf6f5, 0xf700,
0xf70b, 0xf715, 0xf720, 0xf72b, 0xf736, 0xf740,
0xf74b, 0xf756, 0xf760, 0xf76b, 0xf776, 0xf781,
0xf78b, 0xf796, 0xf7a1, 0xf7ab, 0xf7b6, 0xf7c1,
0xf7cc, 0xf7d6, 0xf7e1, 0xf7ec, 0xf7f6, 0xf801,
0xf80c, 0xf816, 0xf821, 0xf82c, 0xf836, 0xf841,
0xf84c, 0xf856, 0xf861, 0xf86c, 0xf876, 0xf881,
0xf88c, 0xf896, 0xf8a1, 0xf8ac, 0xf8b6, 0xf8c1,
0xf8cc, 0xf8d6, 0xf8e1, 0xf8ec, 0xf8f6, 0xf901,
0xf90b, 0xf916, 0xf921, 0xf92b, 0xf936, 0xf941,
0xf94b, 0xf956, 0xf960, 0xf96b, 0xf976, 0xf980,
0xf98b, 0xf995, 0xf9a0, 0xf9aa, 0xf9b5, 0xf9c0,
0xf9ca, 0xf9d5, 0xf9df, 0xf9ea, 0xf9f4, 0xf9ff,
0xfa0a, 0xfa14, 0xfa1f, 0xfa29, 0xfa34, 0xfa3e,
0xfa49, 0xfa53, 0xfa5e, 0xfa69, 0xfa73, 0xfa7e,
0xfa88, 0xfa93, 0xfa9d, 0xfaa8, 0xfab2, 0xfabd,
0xfac7, 0xfad2, 0xfadc, 0xfae7, 0xfaf1, 0xfafc,
0xfb06, 0xfb11, 0xfb1b, 0xfb26, 0xfb30, 0xfb3b,
0xfb45, 0xfb50, 0xfb5a, 0xfb65, 0xfb6f, 0xfb7a,
0xfb84, 0xfb8f, 0xfb99, 0xfba4, 0xfbae, 0xfbb8,
0xfbc3, 0xfbcd, 0xfbd8, 0xfbe2, 0xfbed, 0xfbf7,
0xfc02, 0xfc0c, 0xfc16, 0xfc21, 0xfc2b, 0xfc36,
0xfc40, 0xfc4b, 0xfc55, 0xfc5f, 0xfc6a, 0xfc74,
0xfc7f, 0xfc89, 0xfc93, 0xfc9e, 0xfca8, 0xfcb3,
0xfcbd, 0xfcc7, 0xfcd2, 0xfcdc, 0xfce7, 0xfcf1,
0xfcfb, 0xfd06, 0xfd10, 0xfd1a, 0xfd25, 0xfd2f,
0xfd3a, 0xfd44, 0xfd4e, 0xfd59, 0xfd63, 0xfd6d,
0xfd78, 0xfd82, 0xfd8c, 0xfd97, 0xfda1, 0xfdab,
0xfdb6, 0xfdc0, 0xfdca, 0xfdd5, 0xfddf, 0xfde9,
0xfdf4, 0xfdfe, 0xfe08, 0xfe13, 0xfe1d, 0xfe27,
0xfe32, 0xfe3c, 0xfe46, 0xfe50, 0xfe5b, 0xfe65,
0xfe6f, 0xfe7a, 0xfe84, 0xfe8e, 0xfe98, 0xfea3,
0xfead, 0xfeb7, 0xfec1, 0xfecc, 0xfed6, 0xfee0,
0xfeeb, 0xfef5, 0xfeff, 0xff09, 0xff14, 0xff1e,
0xff28, 0xff32, 0xff3c, 0xff47, 0xff51, 0xff5b,
0xff65, 0xff70, 0xff7a, 0xff84, 0xff8e, 0xff98,
0xffa3, 0xffad, 0xffb7, 0xffc1, 0xffcc, 0xffd6,
0xffe0, 0xffea, 0xfff4, 0xffff
};
// max value is pi/4
constexpr double SCALING_FACTOR = 4. / M_PI * 0xFFFF;
inline double atan2_lookup(double y, double x)
{
if (std::abs(x) < std::numeric_limits<double>::epsilon())
{
if (y >= 0.)
{
return M_PI / 2.;
}
else
{
return -M_PI / 2.;
}
}
unsigned octant = 0;
if (x < 0.)
{
octant = 1;
x = -x;
}
if (y < 0.)
{
octant |= 2;
y = -y;
}
double t = y / x;
if (t > 1.0)
{
octant |= 4;
t = 1.0 / t;
}
double angle = atan_table[(unsigned)(t * 4095)] / SCALING_FACTOR;
switch (octant)
{
case 0:
break;
case 1:
angle = M_PI - angle;
break;
case 2:
angle = -angle;
break;
case 3:
angle = -M_PI + angle;
break;
case 4:
angle = M_PI / 2.0 - angle;
break;
case 5:
angle = M_PI / 2.0 + angle;
break;
case 6:
angle = -M_PI / 2.0 + angle;
break;
case 7:
angle = -M_PI / 2.0 - angle;
break;
}
return angle;
}
#endif // TRIGONOMETRY_TABLES_H
-325
View File
@@ -1,325 +0,0 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
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 GRAPHLOADER_H
#define GRAPHLOADER_H
#include "OSRMException.h"
#include "../data_structures/external_memory_node.hpp"
#include "../data_structures/import_edge.hpp"
#include "../data_structures/query_node.hpp"
#include "../data_structures/restriction.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/FingerPrint.h"
#include "../typedefs.h"
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <tbb/parallel_sort.h>
#include <cmath>
#include <algorithm>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <unordered_map>
#include <vector>
template <typename EdgeT>
NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
std::vector<EdgeT> &edge_list,
std::vector<NodeID> &barrier_node_list,
std::vector<NodeID> &traffic_light_node_list,
std::vector<QueryNode> *int_to_ext_node_id_map,
std::vector<TurnRestriction> &restriction_list)
{
const FingerPrint fingerprint_orig;
FingerPrint fingerprint_loaded;
input_stream.read((char *)&fingerprint_loaded, sizeof(FingerPrint));
if (!fingerprint_loaded.TestGraphUtil(fingerprint_orig))
{
SimpleLogger().Write(logWARNING) << ".osrm was prepared with different build.\n"
"Reprocess to get rid of this warning.";
}
std::unordered_map<NodeID, NodeID> ext_to_int_id_map;
NodeID n;
input_stream.read((char *)&n, sizeof(NodeID));
SimpleLogger().Write() << "Importing n = " << n << " nodes ";
ExternalMemoryNode current_node;
for (NodeID i = 0; i < n; ++i)
{
input_stream.read((char *)&current_node, sizeof(ExternalMemoryNode));
int_to_ext_node_id_map->emplace_back(current_node.lat, current_node.lon, current_node.node_id);
ext_to_int_id_map.emplace(current_node.node_id, i);
if (current_node.barrier)
{
barrier_node_list.emplace_back(i);
}
if (current_node.traffic_lights)
{
traffic_light_node_list.emplace_back(i);
}
}
// tighten vector sizes
barrier_node_list.shrink_to_fit();
traffic_light_node_list.shrink_to_fit();
// renumber nodes in turn restrictions
for (TurnRestriction &current_restriction : restriction_list)
{
auto internal_id_iter = ext_to_int_id_map.find(current_restriction.from.node);
if (internal_id_iter == ext_to_int_id_map.end())
{
SimpleLogger().Write(logDEBUG) << "Unmapped from Node of restriction";
continue;
}
current_restriction.from.node = internal_id_iter->second;
internal_id_iter = ext_to_int_id_map.find(current_restriction.via.node);
if (internal_id_iter == ext_to_int_id_map.end())
{
SimpleLogger().Write(logDEBUG) << "Unmapped via node of restriction";
continue;
}
current_restriction.via.node = internal_id_iter->second;
internal_id_iter = ext_to_int_id_map.find(current_restriction.to.node);
if (internal_id_iter == ext_to_int_id_map.end())
{
SimpleLogger().Write(logDEBUG) << "Unmapped to node of restriction";
continue;
}
current_restriction.to.node = internal_id_iter->second;
}
EdgeWeight weight;
NodeID source, target;
unsigned nameID;
int length;
short dir; // direction (0 = open, 1 = forward, 2+ = open)
bool is_roundabout, ignore_in_grid, is_access_restricted, is_split;
TravelMode travel_mode;
EdgeID m;
input_stream.read((char *)&m, sizeof(unsigned));
edge_list.reserve(m);
SimpleLogger().Write() << " and " << m << " edges ";
for (EdgeID i = 0; i < m; ++i)
{
input_stream.read((char *)&source, sizeof(unsigned));
input_stream.read((char *)&target, sizeof(unsigned));
input_stream.read((char *)&length, sizeof(int));
input_stream.read((char *)&dir, sizeof(short));
input_stream.read((char *)&weight, sizeof(int));
input_stream.read((char *)&nameID, sizeof(unsigned));
input_stream.read((char *)&is_roundabout, sizeof(bool));
input_stream.read((char *)&ignore_in_grid, sizeof(bool));
input_stream.read((char *)&is_access_restricted, sizeof(bool));
input_stream.read((char *)&travel_mode, sizeof(TravelMode));
input_stream.read((char *)&is_split, sizeof(bool));
BOOST_ASSERT_MSG(length > 0, "loaded null length edge");
BOOST_ASSERT_MSG(weight > 0, "loaded null weight");
BOOST_ASSERT_MSG(0 <= dir && dir <= 2, "loaded bogus direction");
bool forward = true;
bool backward = true;
if (1 == dir)
{
backward = false;
}
if (2 == dir)
{
forward = false;
}
// translate the external NodeIDs to internal IDs
auto internal_id_iter = ext_to_int_id_map.find(source);
if (ext_to_int_id_map.find(source) == ext_to_int_id_map.end())
{
#ifndef NDEBUG
SimpleLogger().Write(logWARNING) << " unresolved source NodeID: " << source;
#endif
continue;
}
source = internal_id_iter->second;
internal_id_iter = ext_to_int_id_map.find(target);
if (ext_to_int_id_map.find(target) == ext_to_int_id_map.end())
{
#ifndef NDEBUG
SimpleLogger().Write(logWARNING) << "unresolved target NodeID : " << target;
#endif
continue;
}
target = internal_id_iter->second;
BOOST_ASSERT_MSG(source != SPECIAL_NODEID && target != SPECIAL_NODEID,
"nonexisting source or target");
if (source > target)
{
std::swap(source, target);
std::swap(forward, backward);
}
edge_list.emplace_back(source,
target,
nameID,
weight,
forward,
backward,
is_roundabout,
ignore_in_grid,
is_access_restricted,
travel_mode,
is_split);
}
ext_to_int_id_map.clear();
tbb::parallel_sort(edge_list.begin(), edge_list.end());
for (unsigned i = 1; i < edge_list.size(); ++i)
{
if ((edge_list[i - 1].target == edge_list[i].target) &&
(edge_list[i - 1].source == edge_list[i].source))
{
const bool edge_flags_equivalent =
(edge_list[i - 1].forward == edge_list[i].forward) &&
(edge_list[i - 1].backward == edge_list[i].backward);
const bool edge_flags_are_superset1 =
(edge_list[i - 1].forward && edge_list[i - 1].backward) &&
(edge_list[i].forward != edge_list[i].backward);
const bool edge_flags_are_superset_2 =
(edge_list[i].forward && edge_list[i].backward) &&
(edge_list[i - 1].forward != edge_list[i - 1].backward);
if (edge_flags_equivalent)
{
edge_list[i].weight = std::min(edge_list[i - 1].weight, edge_list[i].weight);
edge_list[i - 1].source = SPECIAL_NODEID;
}
else if (edge_flags_are_superset1)
{
if (edge_list[i - 1].weight <= edge_list[i].weight)
{
// edge i-1 is smaller and goes in both directions. Throw away the other edge
edge_list[i].source = SPECIAL_NODEID;
}
else
{
// edge i-1 is open in both directions, but edge i is smaller in one direction.
// Close edge i-1 in this direction
edge_list[i - 1].forward = !edge_list[i].forward;
edge_list[i - 1].backward = !edge_list[i].backward;
}
}
else if (edge_flags_are_superset_2)
{
if (edge_list[i - 1].weight <= edge_list[i].weight)
{
// edge i-1 is smaller for one direction. edge i is open in both. close edge i
// in the other direction
edge_list[i].forward = !edge_list[i - 1].forward;
edge_list[i].backward = !edge_list[i - 1].backward;
}
else
{
// edge i is smaller and goes in both direction. Throw away edge i-1
edge_list[i - 1].source = SPECIAL_NODEID;
}
}
}
}
const auto new_end_iter = std::remove_if(edge_list.begin(), edge_list.end(), [] (const EdgeT &edge)
{
return edge.source == SPECIAL_NODEID ||
edge.target == SPECIAL_NODEID;
});
edge_list.erase(new_end_iter, edge_list.end()); // remove excess candidates.
edge_list.shrink_to_fit();
SimpleLogger().Write() << "Graph loaded ok and has " << edge_list.size() << " edges";
return n;
}
template <typename NodeT, typename EdgeT>
unsigned readHSGRFromStream(const boost::filesystem::path &hsgr_file,
std::vector<NodeT> &node_list,
std::vector<EdgeT> &edge_list,
unsigned *check_sum)
{
if (!boost::filesystem::exists(hsgr_file))
{
throw OSRMException("hsgr file does not exist");
}
if (0 == boost::filesystem::file_size(hsgr_file))
{
throw OSRMException("hsgr file is empty");
}
boost::filesystem::ifstream hsgr_input_stream(hsgr_file, std::ios::binary);
FingerPrint fingerprint_loaded, fingerprint_orig;
hsgr_input_stream.read((char *)&fingerprint_loaded, sizeof(FingerPrint));
if (!fingerprint_loaded.TestGraphUtil(fingerprint_orig))
{
SimpleLogger().Write(logWARNING) << ".hsgr was prepared with different build.\n"
"Reprocess to get rid of this warning.";
}
unsigned number_of_nodes = 0;
unsigned number_of_edges = 0;
hsgr_input_stream.read((char *)check_sum, sizeof(unsigned));
hsgr_input_stream.read((char *)&number_of_nodes, sizeof(unsigned));
BOOST_ASSERT_MSG(0 != number_of_nodes, "number of nodes is zero");
hsgr_input_stream.read((char *)&number_of_edges, sizeof(unsigned));
SimpleLogger().Write() << "number_of_nodes: " << number_of_nodes
<< ", number_of_edges: " << number_of_edges;
// BOOST_ASSERT_MSG( 0 != number_of_edges, "number of edges is zero");
node_list.resize(number_of_nodes);
hsgr_input_stream.read((char *)&(node_list[0]), number_of_nodes * sizeof(NodeT));
edge_list.resize(number_of_edges);
if (number_of_edges > 0)
{
hsgr_input_stream.read((char *)&(edge_list[0]), number_of_edges * sizeof(EdgeT));
}
hsgr_input_stream.close();
return number_of_nodes;
}
#endif // GRAPHLOADER_H
-42
View File
@@ -1,42 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef RANGE_ALGORITHMS_HPP
#define RANGE_ALGORITHMS_HPP
#include <algorithm>
namespace osrm {
template<class Container>
auto max_element(const Container & c) -> decltype(std::max_element(c.begin(), c.end()))
{
return std::max_element(c.begin(), c.end());
}
template<class Container>
auto max_element(const Container & c) -> decltype(std::max_element(c.cbegin(), c.cend()))
{
return std::max_element(c.cbegin(), c.cend());
}
}
#endif // RANGE_ALGORITHMS_HPP
+117
View File
@@ -0,0 +1,117 @@
/*
Copyright (c) 2015, 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 BAYES_CLASSIFIER_HPP
#define BAYES_CLASSIFIER_HPP
#include <cmath>
#include <vector>
struct NormalDistribution
{
NormalDistribution(const double mean, const double standard_deviation)
: mean(mean), standard_deviation(standard_deviation)
{
}
// FIXME implement log-probability version since its faster
double density_function(const double val) const
{
const double x = val - mean;
return 1.0 / (std::sqrt(2. * M_PI) * standard_deviation) *
std::exp(-x * x / (standard_deviation * standard_deviation));
}
double mean;
double standard_deviation;
};
struct LaplaceDistribution
{
LaplaceDistribution(const double location, const double scale)
: location(location), scale(scale)
{
}
// FIXME implement log-probability version since its faster
double density_function(const double val) const
{
const double x = std::abs(val - location);
return 1.0 / (2. * scale) * std::exp(-x / scale);
}
double location;
double scale;
};
template <typename PositiveDistributionT, typename NegativeDistributionT, typename ValueT>
class BayesClassifier
{
public:
enum class ClassLabel : unsigned
{
NEGATIVE,
POSITIVE
};
using ClassificationT = std::pair<ClassLabel, double>;
BayesClassifier(const PositiveDistributionT &positive_distribution,
const NegativeDistributionT &negative_distribution,
const double positive_apriori_probability)
: positive_distribution(positive_distribution),
negative_distribution(negative_distribution),
positive_apriori_probability(positive_apriori_probability),
negative_apriori_probability(1. - positive_apriori_probability)
{
}
// Returns label and the probability of the label.
ClassificationT classify(const ValueT &v) const
{
const double positive_postpriori =
positive_apriori_probability * positive_distribution.density_function(v);
const double negative_postpriori =
negative_apriori_probability * negative_distribution.density_function(v);
const double norm = positive_postpriori + negative_postpriori;
if (positive_postpriori > negative_postpriori)
{
return std::make_pair(ClassLabel::POSITIVE, positive_postpriori / norm);
}
return std::make_pair(ClassLabel::NEGATIVE, negative_postpriori / norm);
}
private:
PositiveDistributionT positive_distribution;
NegativeDistributionT negative_distribution;
double positive_apriori_probability;
double negative_apriori_probability;
};
#endif // BAYES_CLASSIFIER_HPP
+30 -30
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -95,8 +95,8 @@ template <typename GraphT> class BFSComponentExplorer
* Explores the current component that starts at node using BFS.
*/
unsigned ExploreComponent(std::queue<std::pair<NodeID, NodeID>> &bfs_queue,
NodeID node,
unsigned current_component)
NodeID node,
unsigned current_component)
{
/*
Graphical representation of variables:
@@ -118,42 +118,42 @@ template <typename GraphT> class BFSComponentExplorer
std::pair<NodeID, NodeID> current_queue_item = bfs_queue.front();
bfs_queue.pop();
const NodeID v = current_queue_item.first; // current node
const NodeID v = current_queue_item.first; // current node
const NodeID u = current_queue_item.second; // parent
// increment size counter of current component
++current_component_size;
const bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end());
if (!is_barrier_node)
if (m_barrier_nodes.find(v) != m_barrier_nodes.end())
{
const NodeID to_node_of_only_restriction =
m_restriction_map.CheckForEmanatingIsOnlyTurn(u, v);
continue;
}
const NodeID to_node_of_only_restriction =
m_restriction_map.CheckForEmanatingIsOnlyTurn(u, v);
for (auto e2 : m_graph.GetAdjacentEdgeRange(v))
for (auto e2 : m_graph.GetAdjacentEdgeRange(v))
{
const NodeID w = m_graph.GetTarget(e2);
if (to_node_of_only_restriction != std::numeric_limits<unsigned>::max() &&
w != to_node_of_only_restriction)
{
const NodeID w = m_graph.GetTarget(e2);
// At an only_-restriction but not at the right turn
continue;
}
if (to_node_of_only_restriction != std::numeric_limits<unsigned>::max() &&
w != to_node_of_only_restriction)
if (u != w)
{
// only add an edge if turn is not a U-turn except
// when it is at the end of a dead-end street.
if (!m_restriction_map.CheckIfTurnIsRestricted(u, v, w))
{
// At an only_-restriction but not at the right turn
continue;
}
if (u != w)
{
// only add an edge if turn is not a U-turn except
// when it is at the end of a dead-end street.
if (!m_restriction_map.CheckIfTurnIsRestricted(u, v, w))
// only add an edge if turn is not prohibited
if (std::numeric_limits<unsigned>::max() == m_component_index_list[w])
{
// only add an edge if turn is not prohibited
if (std::numeric_limits<unsigned>::max() == m_component_index_list[w])
{
// insert next (node, parent) only if w has
// not yet been explored
// mark node as read
m_component_index_list[w] = current_component;
bfs_queue.emplace(w, v);
}
// insert next (node, parent) only if w has
// not yet been explored
// mark node as read
m_component_index_list[w] = current_component;
bfs_queue.emplace(w, v);
}
}
}
+7 -8
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -49,7 +49,7 @@ class IteratorbasedCRC32
while (iter != end)
{
using value_type = typename std::iterator_traits<Iterator>::value_type;
char *data = (char *)(&(*iter));
const char *data = reinterpret_cast<const char *>(&(*iter));
if (use_hardware_implementation)
{
@@ -73,14 +73,14 @@ class IteratorbasedCRC32
return sse42_found;
}
unsigned compute_in_software(char *str, unsigned len)
unsigned compute_in_software(const char *str, unsigned len)
{
crc_processor.process_bytes(str, len);
return crc_processor.checksum();
}
// adapted from http://byteworm.com/2010/10/13/crc32/
unsigned compute_in_hardware(char *str, unsigned len)
unsigned compute_in_hardware(const char *str, unsigned len)
{
#if defined(__x86_64__)
unsigned q = len / sizeof(unsigned);
@@ -96,7 +96,7 @@ class IteratorbasedCRC32
++p;
}
str = (char *)p;
str = reinterpret_cast<char *>(p);
while (r--)
{
__asm__ __volatile__(".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;"
@@ -116,7 +116,7 @@ class IteratorbasedCRC32
return ecx;
}
#if defined(__MINGW64__) || defined(_MSC_VER)
#if defined(__MINGW64__) || defined(_MSC_VER) || !defined(__x86_64__)
inline void
__get_cpuid(int param, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) const
{
@@ -131,8 +131,7 @@ class IteratorbasedCRC32
struct RangebasedCRC32
{
template<typename Iteratable>
unsigned operator()(const Iteratable &iterable)
template <typename Iteratable> unsigned operator()(const Iteratable &iterable)
{
return crc32(std::begin(iterable), std::end(iterable));
}
+6 -8
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -28,15 +28,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "douglas_peucker.hpp"
#include "../data_structures/segment_information.hpp"
#include "../Util/integer_range.hpp"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
#include <osrm/coordinate.hpp>
#include <cmath>
#include <algorithm>
#include <iterator>
namespace
{
@@ -65,12 +63,12 @@ struct CoordinatePairCalculator
// compute distance (a,c)
const float x_value_1 = (first_lon - float_lon1) * cos((float_lat1 + first_lat) / 2.f);
const float y_value_1 = first_lat - float_lat1;
const float dist1 = sqrt(std::pow(x_value_1, 2) + std::pow(y_value_1, 2)) * earth_radius;
const float dist1 = std::hypot(x_value_1, y_value_1) * earth_radius;
// compute distance (b,c)
const float x_value_2 = (second_lon - float_lon1) * cos((float_lat1 + second_lat) / 2.f);
const float y_value_2 = second_lat - float_lat1;
const float dist2 = sqrt(std::pow(x_value_2, 2) + std::pow(y_value_2, 2)) * earth_radius;
const float dist2 = std::hypot(x_value_2, y_value_2) * earth_radius;
// return the minimum
return static_cast<int>(std::min(dist1, dist2));
@@ -90,7 +88,7 @@ void DouglasPeucker::Run(std::vector<SegmentInformation> &input_geometry, const
void DouglasPeucker::Run(RandomAccessIt begin, RandomAccessIt end, const unsigned zoom_level)
{
unsigned size = std::distance(begin, end);
const auto size = std::distance(begin, end);
if (size < 2)
{
return;
+7 -6
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2013, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -28,9 +28,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef DOUGLAS_PEUCKER_HPP_
#define DOUGLAS_PEUCKER_HPP_
#include <stack>
#include <vector>
#include "../data_structures/segment_information.hpp"
#include <array>
#include <stack>
#include <utility>
#include <vector>
/* This class object computes the bitvector of indicating generalized input
* points according to the (Ramer-)Douglas-Peucker algorithm.
@@ -39,9 +42,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* bit indicating if the points is present in the generalization.
* Note: points may also be pre-selected*/
struct SegmentInformation;
static const std::array<int, 19> DOUGLAS_PEUCKER_THRESHOLDS {{
static const std::array<int, 19> DOUGLAS_PEUCKER_THRESHOLDS{{
512440, // z0
256720, // z1
122560, // z2
+7 -10
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -28,7 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef OBJECT_ENCODER_HPP
#define OBJECT_ENCODER_HPP
#include "../Util/StringUtil.h"
#include "../util/string_util.hpp"
#include <boost/assert.hpp>
#include <boost/archive/iterators/base64_from_binary.hpp>
@@ -49,10 +49,9 @@ struct ObjectEncoder
8,
6>;
template <class ObjectT>
static void EncodeToBase64(const ObjectT &object, std::string &encoded)
template <class ObjectT> static void EncodeToBase64(const ObjectT &object, std::string &encoded)
{
const char *char_ptr_to_object = (const char *)&object;
const char *char_ptr_to_object = reinterpret_cast<const char *>(&object);
std::vector<unsigned char> data(sizeof(object));
std::copy(char_ptr_to_object, char_ptr_to_object + sizeof(ObjectT), data.begin());
@@ -71,8 +70,7 @@ struct ObjectEncoder
replaceAll(encoded, "/", "_");
}
template <class ObjectT>
static void DecodeFromBase64(const std::string &input, ObjectT &object)
template <class ObjectT> static void DecodeFromBase64(const std::string &input, ObjectT &object)
{
try
{
@@ -81,9 +79,8 @@ struct ObjectEncoder
replaceAll(encoded, "-", "+");
replaceAll(encoded, "_", "/");
std::copy(binary_t(encoded.begin()),
binary_t(encoded.begin() + encoded.length() - 1),
(char *)&object);
std::copy(binary_t(encoded.begin()), binary_t(encoded.begin() + encoded.length() - 1),
reinterpret_cast<char *>(&object));
}
catch (...)
{
+40 -10
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -28,7 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "polyline_compressor.hpp"
#include "../data_structures/segment_information.hpp"
#include <osrm/Coordinate.h>
#include <osrm/coordinate.hpp>
std::string PolylineCompressor::encode_vector(std::vector<int> &numbers) const
{
@@ -56,19 +56,11 @@ std::string PolylineCompressor::encode_number(int number_to_encode) const
{
const int next_value = (0x20 | (number_to_encode & 0x1f)) + 63;
output += static_cast<char>(next_value);
if (92 == next_value)
{
output += static_cast<char>(next_value);
}
number_to_encode >>= 5;
}
number_to_encode += 63;
output += static_cast<char>(number_to_encode);
if (92 == number_to_encode)
{
output += static_cast<char>(number_to_encode);
}
return output;
}
@@ -96,3 +88,41 @@ PolylineCompressor::get_encoded_string(const std::vector<SegmentInformation> &po
}
return encode_vector(delta_numbers);
}
std::vector<FixedPointCoordinate> PolylineCompressor::decode_string(const std::string &geometry_string) const
{
std::vector<FixedPointCoordinate> new_coordinates;
int index = 0, len = geometry_string.size();
int lat = 0, lng = 0;
while (index < len)
{
int b, shift = 0, result = 0;
do
{
b = geometry_string.at(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do
{
b = geometry_string.at(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;
FixedPointCoordinate p;
p.lat = COORDINATE_PRECISION * (((double) lat / 1E6));
p.lon = COORDINATE_PRECISION * (((double) lng / 1E6));
new_coordinates.push_back(p);
}
return new_coordinates;
}
+5 -1
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2013, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -30,6 +30,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct SegmentInformation;
#include <osrm/coordinate.hpp>
#include <string>
#include <vector>
@@ -42,6 +44,8 @@ class PolylineCompressor
public:
std::string get_encoded_string(const std::vector<SegmentInformation> &polyline) const;
std::vector<FixedPointCoordinate> decode_string(const std::string &geometry_string) const;
};
#endif /* POLYLINECOMPRESSOR_H_ */
+7 -7
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -30,23 +30,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "polyline_compressor.hpp"
#include "../data_structures/segment_information.hpp"
#include <osrm/Coordinate.h>
#include <osrm/coordinate.hpp>
JSON::String
osrm::json::String
PolylineFormatter::printEncodedString(const std::vector<SegmentInformation> &polyline) const
{
return JSON::String(PolylineCompressor().get_encoded_string(polyline));
return osrm::json::String(PolylineCompressor().get_encoded_string(polyline));
}
JSON::Array
osrm::json::Array
PolylineFormatter::printUnencodedString(const std::vector<SegmentInformation> &polyline) const
{
JSON::Array json_geometry_array;
osrm::json::Array json_geometry_array;
for (const auto &segment : polyline)
{
if (segment.necessary)
{
JSON::Array json_coordinate;
osrm::json::Array json_coordinate;
json_coordinate.values.push_back(segment.location.lat / COORDINATE_PRECISION);
json_coordinate.values.push_back(segment.location.lon / COORDINATE_PRECISION);
json_geometry_array.values.push_back(json_coordinate);
+4 -4
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -30,16 +30,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct SegmentInformation;
#include "../data_structures/json_container.hpp"
#include <osrm/json_container.hpp>
#include <string>
#include <vector>
struct PolylineFormatter
{
JSON::String printEncodedString(const std::vector<SegmentInformation> &polyline) const;
osrm::json::String printEncodedString(const std::vector<SegmentInformation> &polyline) const;
JSON::Array printUnencodedString(const std::vector<SegmentInformation> &polyline) const;
osrm::json::Array printUnencodedString(const std::vector<SegmentInformation> &polyline) const;
};
#endif /* POLYLINE_FORMATTER_HPP */
+27 -34
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -54,7 +54,8 @@ template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
for (const SegmentT &segment : segment_list)
{
if (segment.name_id != blocked_name_id && segment.length > result_segment.length && segment.name_id != 0)
if (segment.name_id != blocked_name_id && segment.length > result_segment.length &&
segment.name_id != 0)
{
result_segment = segment;
}
@@ -73,9 +74,13 @@ template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
SegmentT alternative_segment_1, alternative_segment_2;
auto length_comperator = [](const SegmentT &a, const SegmentT &b)
{ return a.length > b.length; };
{
return a.length > b.length;
};
auto name_id_comperator = [](const SegmentT &a, const SegmentT &b)
{ return a.name_id < b.name_id; };
{
return a.name_id < b.name_id;
};
if (shortest_path_segments.empty())
{
@@ -87,8 +92,7 @@ template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
shortest_segment_1 = shortest_path_segments[0];
if (!alternative_path_segments.empty())
{
std::sort(alternative_path_segments.begin(),
alternative_path_segments.end(),
std::sort(alternative_path_segments.begin(), alternative_path_segments.end(),
length_comperator);
// also pick the longest segment for the alternative path
@@ -99,16 +103,13 @@ template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
// alternative
std::vector<SegmentT> shortest_path_set_difference(shortest_path_segments.size());
std::sort(shortest_path_segments.begin(), shortest_path_segments.end(), name_id_comperator);
std::sort(alternative_path_segments.begin(), alternative_path_segments.end(), name_id_comperator);
std::set_difference(shortest_path_segments.begin(),
shortest_path_segments.end(),
alternative_path_segments.begin(),
alternative_path_segments.end(),
shortest_path_set_difference.begin(),
name_id_comperator);
std::sort(alternative_path_segments.begin(), alternative_path_segments.end(),
name_id_comperator);
std::set_difference(shortest_path_segments.begin(), shortest_path_segments.end(),
alternative_path_segments.begin(), alternative_path_segments.end(),
shortest_path_set_difference.begin(), name_id_comperator);
std::sort(shortest_path_set_difference.begin(),
shortest_path_set_difference.end(),
std::sort(shortest_path_set_difference.begin(), shortest_path_set_difference.end(),
length_comperator);
shortest_segment_2 =
PickNextLongestSegment(shortest_path_set_difference, shortest_segment_1.name_id);
@@ -116,29 +117,23 @@ template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
// compute the set difference (for alternative path) depending on names between shortest and
// alternative
// vectors are still sorted, no need to do again
BOOST_ASSERT(std::is_sorted(shortest_path_segments.begin(),
shortest_path_segments.end(),
BOOST_ASSERT(std::is_sorted(shortest_path_segments.begin(), shortest_path_segments.end(),
name_id_comperator));
BOOST_ASSERT(std::is_sorted(alternative_path_segments.begin(),
alternative_path_segments.end(),
name_id_comperator));
alternative_path_segments.end(), name_id_comperator));
std::vector<SegmentT> alternative_path_set_difference(alternative_path_segments.size());
std::set_difference(alternative_path_segments.begin(),
alternative_path_segments.end(),
shortest_path_segments.begin(),
shortest_path_segments.end(),
alternative_path_set_difference.begin(),
name_id_comperator);
std::set_difference(alternative_path_segments.begin(), alternative_path_segments.end(),
shortest_path_segments.begin(), shortest_path_segments.end(),
alternative_path_set_difference.begin(), name_id_comperator);
std::sort(alternative_path_set_difference.begin(),
alternative_path_set_difference.end(),
std::sort(alternative_path_set_difference.begin(), alternative_path_set_difference.end(),
length_comperator);
if (!alternative_path_segments.empty())
{
alternative_segment_2 = PickNextLongestSegment(alternative_path_set_difference,
alternative_segment_1.name_id);
alternative_segment_1.name_id);
}
// move the segments into the order in which they occur.
@@ -152,15 +147,13 @@ template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
}
// fetching names for the selected segments
route_names.shortest_path_name_1 =
facade->GetEscapedNameForNameID(shortest_segment_1.name_id);
route_names.shortest_path_name_2 =
facade->GetEscapedNameForNameID(shortest_segment_2.name_id);
route_names.shortest_path_name_1 = facade->get_name_for_id(shortest_segment_1.name_id);
route_names.shortest_path_name_2 = facade->get_name_for_id(shortest_segment_2.name_id);
route_names.alternative_path_name_1 =
facade->GetEscapedNameForNameID(alternative_segment_1.name_id);
facade->get_name_for_id(alternative_segment_1.name_id);
route_names.alternative_path_name_2 =
facade->GetEscapedNameForNameID(alternative_segment_2.name_id);
facade->get_name_for_id(alternative_segment_2.name_id);
return route_names;
}
+58 -115
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -34,21 +34,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../data_structures/query_node.hpp"
#include "../data_structures/percent.hpp"
#include "../data_structures/restriction.hpp"
#include "../data_structures/restriction_map.hpp"
#include "../data_structures/turn_instructions.hpp"
#include "../Util/integer_range.hpp"
#include "../Util/OSRMException.h"
#include "../Util/simple_logger.hpp"
#include "../Util/std_hash.hpp"
#include "../Util/timing_util.hpp"
#include "../util/integer_range.hpp"
#include "../util/simple_logger.hpp"
#include "../util/std_hash.hpp"
#include "../util/timing_util.hpp"
#include <osrm/Coordinate.h>
#include <osrm/coordinate.hpp>
#include <boost/assert.hpp>
#include <tbb/parallel_sort.h>
#include <cstdint>
#include <memory>
@@ -57,8 +56,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <unordered_set>
#include <vector>
template <typename GraphT>
class TarjanSCC
template <typename GraphT> class TarjanSCC
{
struct TarjanStackFrame
{
@@ -75,80 +73,40 @@ class TarjanSCC
bool on_stack;
};
using RestrictionSource = std::pair<NodeID, NodeID>;
using RestrictionTarget = std::pair<NodeID, bool>;
using EmanatingRestrictionsVector = std::vector<RestrictionTarget>;
using RestrictionMap = std::unordered_map<RestrictionSource, unsigned>;
std::vector<EmanatingRestrictionsVector> m_restriction_bucket_list;
std::vector<unsigned> components_index;
std::vector<unsigned> components_index;
std::vector<NodeID> component_size_vector;
std::shared_ptr<GraphT> m_node_based_graph;
std::unordered_set<NodeID> barrier_node_list;
unsigned size_one_counter;
std::unordered_set<NodeID> barrier_node_set;
RestrictionMap m_restriction_map;
std::size_t size_one_counter;
public:
template <class ContainerT>
TarjanSCC(std::shared_ptr<GraphT> graph,
std::vector<NodeID> &bn,
std::vector<TurnRestriction> &irs)
: components_index(graph->GetNumberOfNodes(), SPECIAL_NODEID),
m_node_based_graph(graph),
size_one_counter(0)
const RestrictionMap &restrictions,
const ContainerT &barrier_node_list)
: components_index(graph->GetNumberOfNodes(), SPECIAL_NODEID), m_node_based_graph(graph),
m_restriction_map(restrictions), size_one_counter(0)
{
TIMER_START(SCC_LOAD);
for (const TurnRestriction &restriction : irs)
{
std::pair<NodeID, NodeID> restriction_source = {restriction.from.node,
restriction.via.node};
unsigned index = 0;
const auto restriction_iterator = m_restriction_map.find(restriction_source);
if (restriction_iterator == m_restriction_map.end())
{
index = m_restriction_bucket_list.size();
m_restriction_bucket_list.resize(index + 1);
m_restriction_map.emplace(restriction_source, index);
}
else
{
index = restriction_iterator->second;
// Map already contains an is_only_*-restriction
if (m_restriction_bucket_list.at(index).begin()->second)
{
continue;
}
else if (restriction.flags.is_only)
{
// We are going to insert an is_only_*-restriction. There can be only one.
m_restriction_bucket_list.at(index).clear();
}
}
m_restriction_bucket_list.at(index)
.emplace_back(restriction.to.node, restriction.flags.is_only);
}
barrier_node_list.insert(bn.begin(), bn.end());
TIMER_STOP(SCC_LOAD);
SimpleLogger().Write() << "Loading data into SCC took " << TIMER_MSEC(SCC_LOAD)/1000. << "s";
barrier_node_set.insert(std::begin(barrier_node_list), std::end(barrier_node_list));
BOOST_ASSERT(m_node_based_graph->GetNumberOfNodes() > 0);
}
void Run()
void run()
{
TIMER_START(SCC_RUN);
const NodeID max_node_id = m_node_based_graph->GetNumberOfNodes();
// The following is a hack to distinguish between stuff that happens
// before the recursive call and stuff that happens after
std::stack<TarjanStackFrame> recursion_stack;
// true = stuff before, false = stuff after call
std::stack<NodeID> tarjan_stack;
std::vector<TarjanNode> tarjan_node_list(m_node_based_graph->GetNumberOfNodes());
std::vector<TarjanNode> tarjan_node_list(max_node_id);
unsigned component_index = 0, size_of_current_component = 0;
int index = 0;
const NodeID last_node = m_node_based_graph->GetNumberOfNodes();
std::vector<bool> processing_node_before_recursion(m_node_based_graph->GetNumberOfNodes(), true);
for(const NodeID node : osrm::irange(0u, last_node))
unsigned index = 0;
std::vector<bool> processing_node_before_recursion(max_node_id, true);
for (const NodeID node : osrm::irange(0u, max_node_id))
{
if (SPECIAL_NODEID == components_index[node])
{
@@ -158,8 +116,10 @@ class TarjanSCC
while (!recursion_stack.empty())
{
TarjanStackFrame currentFrame = recursion_stack.top();
const NodeID u = currentFrame.parent;
const NodeID v = currentFrame.v;
recursion_stack.pop();
const bool before_recursion = processing_node_before_recursion[v];
if (before_recursion && tarjan_node_list[v].index != UINT_MAX)
@@ -180,10 +140,31 @@ class TarjanSCC
tarjan_node_list[v].on_stack = true;
++index;
// Traverse outgoing edges
const NodeID to_node_of_only_restriction =
m_restriction_map.CheckForEmanatingIsOnlyTurn(u, v);
for (const auto current_edge : m_node_based_graph->GetAdjacentEdgeRange(v))
{
const auto vprime = m_node_based_graph->GetTarget(current_edge);
// Traverse outgoing edges
if (barrier_node_set.find(v) != barrier_node_set.end() && u != vprime)
{
continue;
}
if (to_node_of_only_restriction != std::numeric_limits<unsigned>::max() &&
vprime == to_node_of_only_restriction)
{
// At an only_-restriction but not at the right turn
// continue;
}
if (m_restriction_map.CheckIfTurnIsRestricted(u, v, vprime))
{
// continue;
}
if (SPECIAL_NODEID == tarjan_node_list[vprime].index)
{
recursion_stack.emplace(TarjanStackFrame(vprime, v));
@@ -234,63 +215,25 @@ class TarjanSCC
}
TIMER_STOP(SCC_RUN);
SimpleLogger().Write() << "SCC run took: " << TIMER_MSEC(SCC_RUN)/1000. << "s";
SimpleLogger().Write() << "identified: " << component_size_vector.size() << " many components";
SimpleLogger().Write() << "SCC run took: " << TIMER_MSEC(SCC_RUN) / 1000. << "s";
size_one_counter = std::count_if(component_size_vector.begin(),
component_size_vector.end(),
size_one_counter = std::count_if(component_size_vector.begin(), component_size_vector.end(),
[](unsigned value)
{
return 1 == value;
});
SimpleLogger().Write() << "identified " << size_one_counter << " SCCs of size 1";
return 1 == value;
});
}
std::size_t get_number_of_components() const { return component_size_vector.size(); }
std::size_t get_size_one_count() const { return size_one_counter; }
unsigned get_component_size(const NodeID node) const
{
return component_size_vector[components_index[node]];
}
private:
unsigned CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const
{
std::pair<NodeID, NodeID> restriction_source = {u, v};
const auto restriction_iterator = m_restriction_map.find(restriction_source);
if (restriction_iterator != m_restriction_map.end())
{
const unsigned index = restriction_iterator->second;
for (const RestrictionSource &restriction_target : m_restriction_bucket_list.at(index))
{
if (restriction_target.second)
{
return restriction_target.first;
}
}
}
return SPECIAL_NODEID;
}
bool CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const
{
// only add an edge if turn is not a U-turn except it is the end of dead-end street.
std::pair<NodeID, NodeID> restriction_source = {u, v};
const auto restriction_iterator = m_restriction_map.find(restriction_source);
if (restriction_iterator != m_restriction_map.end())
{
const unsigned index = restriction_iterator->second;
for (const RestrictionTarget &restriction_target : m_restriction_bucket_list.at(index))
{
if (w == restriction_target.first)
{
return true;
}
}
}
return false;
}
unsigned get_component_id(const NodeID node) const { return components_index[node]; }
};
#endif /* TINY_COMPONENTS_HPP */
+113
View File
@@ -0,0 +1,113 @@
@ECHO OFF
SETLOCAL
SET EL=0
ECHO platform^: %platform%
:: HARDCODE "x64" as it is uppercase on AppVeyor and download from S3 is case sensitive
SET DEPSPKG=osrm-deps-win-x64-14.0.7z
:: local development
IF "%computername%"=="MB" GOTO SKIPDL
IF EXIST %DEPSPKG% DEL %DEPSPKG%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO downloading %DEPSPKG%
powershell Invoke-WebRequest https://mapbox.s3.amazonaws.com/windows-builds/windows-deps/$env:DEPSPKG -OutFile C:\projects\osrm\$env:DEPSPKG
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
7z -y x %DEPSPKG% | %windir%\system32\FIND "ing archive"
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
:SKIPDL
IF EXIST build rd /s /q build
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
mkdir build
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
cd build
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
SET OSRMDEPSDIR=c:\projects\osrm\osrm-deps
set PREFIX=%OSRMDEPSDIR%/libs
set BOOST_ROOT=%OSRMDEPSDIR%/boost
set TBB_INSTALL_DIR=%OSRMDEPSDIR%/tbb
set TBB_ARCH_PLATFORM=intel64/vc14
ECHO calling cmake ....
cmake .. ^
-G "Visual Studio 14 Win64" ^
-DBOOST_ROOT=%BOOST_ROOT% ^
-DBoost_ADDITIONAL_VERSIONS=1.57 ^
-DBoost_USE_MULTITHREADED=ON ^
-DBoost_USE_STATIC_LIBS=ON ^
-DCMAKE_BUILD_TYPE=%CONFIGURATION% ^
-DCMAKE_INSTALL_PREFIX=%PREFIX%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO building ...
msbuild OSRM.sln ^
/p:Configuration=%Configuration% ^
/p:Platform=x64 ^
/t:rebuild ^
/p:BuildInParallel=true ^
/m:%NUMBER_OF_PROCESSORS% ^
/toolsversion:14.0 ^
/p:PlatformToolset=v140 ^
/clp:Verbosity=normal ^
/nologo ^
/flp1:logfile=build_errors.txt;errorsonly ^
/flp2:logfile=build_warnings.txt;warningsonly
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO ========= TODO^: CREATE PACKAGES ==========
CD c:\projects\osrm\build\%Configuration%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
SET PATH=c:\projects\osrm\osrm-deps\libs\bin;%PATH%
ECHO running datastructure-tests.exe ...
datastructure-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO running algorithm-tests.exe ...
algorithm-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
GOTO DONE
:ERROR
SET EL=%ERRORLEVEL%
ECHO ============== ERROR ===============
:DONE
ECHO ============= DONE ===============
CD C:\projects\osrm
EXIT /b %EL%
- cd c:/projects/osrm
- mkdir build
- cd build
- echo Running cmake...
- call "%VS120COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64
- SET PATH=C:\Program Files (x86)\MSBuild\12.0\bin\;%PATH%
- SET P=c:/projects/osrm
- set TBB_INSTALL_DIR=%P%/tbb
- set TBB_ARCH_PLATFORM=intel64/vc12
- cmake .. -G "Visual Studio 14 Win64" -DCMAKE_BUILD_TYPE=%Configuration% -DCMAKE_INSTALL_PREFIX=%P%/libs -DBOOST_ROOT=%P%/boost_min -DBoost_ADDITIONAL_VERSIONS=1.57 -DBoost_USE_STATIC_LIBS=ON
- SET PLATFORM_TOOLSET=v140
- SET TOOLS_VERSION=14.0
- msbuild /p:Platform=x64 /clp:Verbosity=minimal /toolsversion:%TOOLS_VERSION% /p:PlatformToolset=%PLATFORM_TOOLSET% /nologo OSRM.sln
- msbuild /p:Platform=x64 /clp:Verbosity=minimal /toolsversion:%TOOLS_VERSION% /p:PlatformToolset=%PLATFORM_TOOLSET% /nologo tests.vcxproj
- cd %Configuration%
- if "%APPVEYOR_REPO_BRANCH%"=="develop" (7z a %P%/osrm_%Configuration%.zip *.exe *.pdb %P%/libs/bin/*.dll -tzip)
- cd ..\..\profiles
- echo disk=c:\temp\stxxl,10000,wincall > .stxxl.txt
- if "%APPVEYOR_REPO_BRANCH%"=="develop" (7z a %P%/osrm_%Configuration%.zip * -tzip)
- set PATH=%PATH%;c:/projects/osrm/libs/bin
- cd c:/projects/osrm/build/%Configuration%
- datastructure-tests.exe
- algorithm-tests.exe
+8 -38
View File
@@ -1,63 +1,33 @@
environment:
matrix:
- configuration: Debug
- configuration: Release
# branches to build
branches:
# whitelist
only:
- develop
# Operating system (build VM template)
os: Windows Server 2012 R2
# - configuration: Debug
# scripts that are called at very beginning, before repo cloning
init:
- git config --global core.autocrlf input
os: Visual Studio 2015 RC
# clone directory
clone_folder: c:\projects\osrm
platform: x64
install:
# by default, all script lines are interpreted as batch
- nuget install protobuf
- cd c:\projects\osrm
- curl -O http://build.project-osrm.org/libs_osrm_%Configuration%.7z
- 7z x libs_osrm_%Configuration%.7z | find ":"
- set PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%PATH%
- CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64
build_script:
- cd c:/projects/osrm
- mkdir build
- cd build
- echo Running cmake...
- call "%VS120COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64
- SET PATH=C:\Program Files (x86)\MSBuild\12.0\bin\;%PATH%
- SET P=c:/projects/osrm
- set TBB_INSTALL_DIR=%P%/tbb
- set TBB_ARCH_PLATFORM=intel64/vc12
- cmake .. -G "Visual Studio 12 Win64" -DCMAKE_BUILD_TYPE=%Configuration% -DCMAKE_INSTALL_PREFIX=%P%/libs -DBOOST_ROOT=%P%/boost_min -DBoost_ADDITIONAL_VERSIONS=1.57 -DBoost_USE_STATIC_LIBS=ON -T CTP_Nov2013
- msbuild /clp:Verbosity=minimal /nologo OSRM.sln
- msbuild /clp:Verbosity=minimal /nologo tests.vcxproj
- cd %Configuration%
- if "%APPVEYOR_REPO_BRANCH%"=="develop" (7z a %P%/osrm_%Configuration%.zip *.exe *.pdb %P%/libs/bin/*.dll -tzip)
- cd ..\..\profiles
- echo disk=c:\temp\stxxl,10000,wincall > .stxxl.txt
- if "%APPVEYOR_REPO_BRANCH%"=="develop" (7z a %P%/osrm_%Configuration%.zip * -tzip)
- set PATH=%PATH%;c:/projects/osrm/libs/bin
- cd c:/projects/osrm/build/%Configuration%
- datastructure-tests.exe
- algorithm-tests.exe
- CALL appveyor-build.bat
test: off
artifacts:
- path: osrm_Debug.zip
name: osrm_Debug.zip
- path: osrm_Release.zip
name: osrm_Release.zip
# - path: osrm_Debug.zip
# name: osrm_Debug.zip
deploy:
provider: FTP
+21 -26
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -29,10 +29,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../data_structures/query_node.hpp"
#include "../data_structures/shared_memory_vector_wrapper.hpp"
#include "../data_structures/static_rtree.hpp"
#include "../util/boost_filesystem_2_fix.hpp"
#include "../data_structures/edge_based_node.hpp"
#include "../Util/BoostFileSystemFix.h"
#include <osrm/Coordinate.h>
#include <osrm/coordinate.hpp>
#include <random>
@@ -52,10 +52,10 @@ FixedPointCoordinateListPtr LoadCoordinates(const boost::filesystem::path &nodes
boost::filesystem::ifstream nodes_input_stream(nodes_file, std::ios::binary);
QueryNode current_node;
unsigned number_of_coordinates = 0;
nodes_input_stream.read((char *)&number_of_coordinates, sizeof(unsigned));
auto coords = std::make_shared<std::vector<FixedPointCoordinate>>(number_of_coordinates);
for (unsigned i = 0; i < number_of_coordinates; ++i)
unsigned coordinate_count = 0;
nodes_input_stream.read((char *)&coordinate_count, sizeof(unsigned));
auto coords = std::make_shared<std::vector<FixedPointCoordinate>>(coordinate_count);
for (unsigned i = 0; i < coordinate_count; ++i)
{
nodes_input_stream.read((char *)&current_node, sizeof(QueryNode));
coords->at(i) = FixedPointCoordinate(current_node.lat, current_node.lon);
@@ -84,15 +84,13 @@ void Benchmark(BenchStaticRTree &rtree, unsigned num_queries)
<< "\n";
TIMER_START(query_phantom);
std::vector<PhantomNode> resulting_phantom_node_vector;
std::vector<PhantomNode> phantom_node_vector;
for (const auto &q : queries)
{
resulting_phantom_node_vector.clear();
rtree.IncrementalFindPhantomNodeForCoordinate(
q, resulting_phantom_node_vector, 3, num_results);
resulting_phantom_node_vector.clear();
rtree.IncrementalFindPhantomNodeForCoordinate(
q, resulting_phantom_node_vector, 17, num_results);
phantom_node_vector.clear();
rtree.IncrementalFindPhantomNodeForCoordinate(q, phantom_node_vector, 3, num_results);
phantom_node_vector.clear();
rtree.IncrementalFindPhantomNodeForCoordinate(q, phantom_node_vector, 17, num_results);
}
TIMER_STOP(query_phantom);
@@ -122,18 +120,17 @@ void Benchmark(BenchStaticRTree &rtree, unsigned num_queries)
std::cout << "#### FindPhantomNodeForCoordinate"
<< "\n";
TIMER_START(query_phantomnode);
TIMER_START(query_node);
for (const auto &q : queries)
{
PhantomNode phantom;
rtree.FindPhantomNodeForCoordinate(q, phantom, 3);
}
TIMER_STOP(query_phantomnode);
TIMER_STOP(query_node);
std::cout << "Took " << TIMER_MSEC(query_phantomnode) << " msec for " << num_queries
<< " queries."
std::cout << "Took " << TIMER_MSEC(query_node) << " msec for " << num_queries << " queries."
<< "\n";
std::cout << TIMER_MSEC(query_phantomnode) / ((double)num_queries) << " msec/query."
std::cout << TIMER_MSEC(query_node) / ((double)num_queries) << " msec/query."
<< "\n";
{
@@ -143,15 +140,13 @@ void Benchmark(BenchStaticRTree &rtree, unsigned num_queries)
<< "\n";
TIMER_START(query_phantom);
std::vector<PhantomNode> resulting_phantom_node_vector;
std::vector<PhantomNode> phantom_node_vector;
for (const auto &q : queries)
{
resulting_phantom_node_vector.clear();
rtree.IncrementalFindPhantomNodeForCoordinate(
q, resulting_phantom_node_vector, 3, num_results);
resulting_phantom_node_vector.clear();
rtree.IncrementalFindPhantomNodeForCoordinate(
q, resulting_phantom_node_vector, 17, num_results);
phantom_node_vector.clear();
rtree.IncrementalFindPhantomNodeForCoordinate(q, phantom_node_vector, 3, num_results);
phantom_node_vector.clear();
rtree.IncrementalFindPhantomNodeForCoordinate(q, phantom_node_vector, 17, num_results);
}
TIMER_STOP(query_phantom);
+19
View File
@@ -0,0 +1,19 @@
@ECHO OFF
SET PLATFORM=x64
SET CONFIGURATION=Release
WHERE msbuild
IF %ERRORLEVEL% EQU 0 GOTO RUNBUILD
SET PATH=C:\mb\windows-builds-64\tmp-bin\cmake-3.1.0-win32-x86\bin;%PATH%
SET PATH=C:\Program Files\7-Zip;%PATH%
ECHO activating VS command prompt ...
SET PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%PATH%
CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64
:RUNBUILD
powershell Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted -Force
CALL appveyor-build.bat
EXIT /b %ERRORLEVEL%
+4 -4
View File
@@ -1,10 +1,10 @@
set(OLDFILE ${SOURCE_DIR}/Util/FingerPrint.cpp)
set(OLDFILE ${SOURCE_DIR}/util/fingerprint_impl.hpp)
if (EXISTS ${OLDFILE})
file(REMOVE_RECURSE ${OLDFILE})
endif()
file(MD5 ${SOURCE_DIR}/prepare.cpp MD5PREPARE)
file(MD5 ${SOURCE_DIR}/data_structures/static_rtree.hpp MD5RTREE)
file(MD5 ${SOURCE_DIR}/Util/graph_loader.hpp MD5GRAPH)
file(MD5 ${SOURCE_DIR}/Server/DataStructures/InternalDataFacade.h MD5OBJECTS)
file(MD5 ${SOURCE_DIR}/util/graph_loader.hpp MD5GRAPH)
file(MD5 ${SOURCE_DIR}/server/data_structures/internal_datafacade.hpp MD5OBJECTS)
CONFIGURE_FILE( ${SOURCE_DIR}/Util/finger_print.cpp.in ${SOURCE_DIR}/Util/finger_print.cpp )
CONFIGURE_FILE(${SOURCE_DIR}/util/fingerprint_impl.hpp.in ${SOURCE_DIR}/util/fingerprint_impl.hpp)
+97 -107
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -35,10 +35,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../data_structures/query_edge.hpp"
#include "../data_structures/xor_fast_hash.hpp"
#include "../data_structures/xor_fast_hash_storage.hpp"
#include "../Util/integer_range.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/StringUtil.h"
#include "../Util/timing_util.hpp"
#include "../util/integer_range.hpp"
#include "../util/simple_logger.hpp"
#include "../util/timing_util.hpp"
#include "../typedefs.h"
#include <boost/assert.hpp>
@@ -93,9 +92,11 @@ class Contractor
};
using ContractorGraph = DynamicGraph<ContractorEdgeData>;
// using ContractorHeap = BinaryHeap<NodeID, NodeID, int, ContractorHeapData, ArrayStorage<NodeID, NodeID>
// using ContractorHeap = BinaryHeap<NodeID, NodeID, int, ContractorHeapData,
// ArrayStorage<NodeID, NodeID>
// >;
using ContractorHeap = BinaryHeap<NodeID, NodeID, int, ContractorHeapData, XORFastHashStorage<NodeID, NodeID>>;
using ContractorHeap =
BinaryHeap<NodeID, NodeID, int, ContractorHeapData, XORFastHashStorage<NodeID, NodeID>>;
using ContractorEdge = ContractorGraph::InputEdge;
struct ContractorThreadData
@@ -132,15 +133,14 @@ class Contractor
bool is_independent : 1;
};
struct ThreadDataContainer
{
explicit ThreadDataContainer(int number_of_nodes) : number_of_nodes(number_of_nodes) {}
explicit ThreadDataContainer(int number_of_nodes) : number_of_nodes(number_of_nodes) {}
inline ContractorThreadData* getThreadData()
inline ContractorThreadData *getThreadData()
{
bool exists = false;
auto& ref = data.local(exists);
auto &ref = data.local(exists);
if (!exists)
{
ref = std::make_shared<ContractorThreadData>(number_of_nodes);
@@ -150,7 +150,8 @@ class Contractor
}
int number_of_nodes;
using EnumerableThreadData = tbb::enumerable_thread_specific<std::shared_ptr<ContractorThreadData>>;
using EnumerableThreadData =
tbb::enumerable_thread_specific<std::shared_ptr<ContractorThreadData>>;
EnumerableThreadData data;
};
@@ -163,32 +164,30 @@ class Contractor
const auto dend = input_edge_list.dend();
for (auto diter = input_edge_list.dbegin(); diter != dend; ++diter)
{
BOOST_ASSERT_MSG(static_cast<unsigned int>(std::max(diter->weight, 1)) > 0, "edge distance < 1");
BOOST_ASSERT_MSG(static_cast<unsigned int>(std::max(diter->weight, 1)) > 0,
"edge distance < 1");
#ifndef NDEBUG
if (static_cast<unsigned int>(std::max(diter->weight, 1)) > 24 * 60 * 60 * 10)
{
SimpleLogger().Write(logWARNING) << "Edge weight large -> "
<< static_cast<unsigned int>(std::max(diter->weight, 1));
SimpleLogger().Write(logWARNING)
<< "Edge weight large -> "
<< static_cast<unsigned int>(std::max(diter->weight, 1)) << " : "
<< static_cast<unsigned int>(diter->source) << " -> " << static_cast<unsigned int>(diter->target);
}
#endif
edges.emplace_back(diter->source, diter->target,
static_cast<unsigned int>(std::max(diter->weight, 1)),
1,
diter->edge_id,
false,
diter->forward ? true : false,
diter->backward ? true : false);
static_cast<unsigned int>(std::max(diter->weight, 1)), 1,
diter->edge_id, false, diter->forward ? true : false,
diter->backward ? true : false);
edges.emplace_back(diter->target, diter->source,
static_cast<unsigned int>(std::max(diter->weight, 1)),
1,
diter->edge_id,
false,
diter->backward ? true : false,
diter->forward ? true : false);
static_cast<unsigned int>(std::max(diter->weight, 1)), 1,
diter->edge_id, false, diter->backward ? true : false,
diter->forward ? true : false);
}
// clear input vector
input_edge_list.clear();
// FIXME not sure if we need this
edges.shrink_to_fit();
tbb::parallel_sort(edges.begin(), edges.end());
@@ -283,20 +282,20 @@ class Contractor
std::cout << "contractor finished initalization" << std::endl;
}
~Contractor() { }
~Contractor() {}
void Run()
{
// for the preperation we can use a big grain size, which is much faster (probably cache)
constexpr size_t InitGrainSize = 100000;
constexpr size_t PQGrainSize = 100000;
constexpr size_t InitGrainSize = 100000;
constexpr size_t PQGrainSize = 100000;
// auto_partitioner will automatically increase the blocksize if we have
// a lot of data. It is *important* for the last loop iterations
// (which have a very small dataset) that it is devisible.
constexpr size_t IndependentGrainSize = 1;
constexpr size_t ContractGrainSize = 1;
constexpr size_t NeighboursGrainSize = 1;
constexpr size_t DeleteGrainSize = 1;
constexpr size_t ContractGrainSize = 1;
constexpr size_t NeighboursGrainSize = 1;
constexpr size_t DeleteGrainSize = 1;
const NodeID number_of_nodes = contractor_graph->GetNumberOfNodes();
Percent p(number_of_nodes);
@@ -308,30 +307,28 @@ class Contractor
std::vector<float> node_priorities(number_of_nodes);
std::vector<NodePriorityData> node_data(number_of_nodes);
// initialize priorities in parallel
tbb::parallel_for(tbb::blocked_range<int>(0, number_of_nodes, InitGrainSize),
[&remaining_nodes](const tbb::blocked_range<int>& range)
{
for (int x = range.begin(); x != range.end(); ++x)
{
remaining_nodes[x].id = x;
}
}
);
[&remaining_nodes](const tbb::blocked_range<int> &range)
{
for (int x = range.begin(); x != range.end(); ++x)
{
remaining_nodes[x].id = x;
}
});
std::cout << "initializing elimination PQ ..." << std::flush;
tbb::parallel_for(tbb::blocked_range<int>(0, number_of_nodes, PQGrainSize),
[this, &node_priorities, &node_data, &thread_data_list](const tbb::blocked_range<int>& range)
{
ContractorThreadData *data = thread_data_list.getThreadData();
for (int x = range.begin(); x != range.end(); ++x)
{
node_priorities[x] = this->EvaluateNodePriority(data, &node_data[x], x);
}
}
);
[this, &node_priorities, &node_data, &thread_data_list](
const tbb::blocked_range<int> &range)
{
ContractorThreadData *data = thread_data_list.getThreadData();
for (int x = range.begin(); x != range.end(); ++x)
{
node_priorities[x] =
this->EvaluateNodePriority(data, &node_data[x], x);
}
});
std::cout << "ok" << std::endl << "preprocessing " << number_of_nodes << " nodes ..."
<< std::flush;
@@ -369,7 +366,8 @@ class Contractor
remaining_nodes[new_node_id].id = new_node_id;
}
// walk over all nodes
for (const auto i : osrm::irange<std::size_t>(0, contractor_graph->GetNumberOfNodes()))
for (const auto i :
osrm::irange<std::size_t>(0, contractor_graph->GetNumberOfNodes()))
{
const NodeID source = i;
for (auto current_edge : contractor_graph->GetAdjacentEdgeRange(source))
@@ -385,11 +383,9 @@ class Contractor
{
// node is not yet contracted.
// add (renumbered) outgoing edges to new DynamicGraph.
ContractorEdge new_edge = {
new_node_id_from_orig_id_map[source],
new_node_id_from_orig_id_map[target],
data
};
ContractorEdge new_edge = {new_node_id_from_orig_id_map[source],
new_node_id_from_orig_id_map[target],
data};
new_edge.data.is_original_via_node_ID = true;
BOOST_ASSERT_MSG(UINT_MAX != new_node_id_from_orig_id_map[source],
@@ -428,28 +424,30 @@ class Contractor
const int last = (int)remaining_nodes.size();
tbb::parallel_for(tbb::blocked_range<int>(0, last, IndependentGrainSize),
[this, &node_priorities, &remaining_nodes, &thread_data_list](const tbb::blocked_range<int>& range)
{
ContractorThreadData *data = thread_data_list.getThreadData();
// determine independent node set
for (int i = range.begin(); i != range.end(); ++i)
{
const NodeID node = remaining_nodes[i].id;
remaining_nodes[i].is_independent =
this->IsNodeIndependent(node_priorities, data, node);
}
}
);
[this, &node_priorities, &remaining_nodes, &thread_data_list](
const tbb::blocked_range<int> &range)
{
ContractorThreadData *data = thread_data_list.getThreadData();
// determine independent node set
for (int i = range.begin(); i != range.end(); ++i)
{
const NodeID node = remaining_nodes[i].id;
remaining_nodes[i].is_independent =
this->IsNodeIndependent(node_priorities, data, node);
}
});
const auto first = stable_partition(remaining_nodes.begin(),
remaining_nodes.end(),
const auto first = stable_partition(remaining_nodes.begin(), remaining_nodes.end(),
[](RemainingNodeData node_data)
{ return !node_data.is_independent; });
{
return !node_data.is_independent;
});
const int first_independent_node = static_cast<int>(first - remaining_nodes.begin());
// contract independent nodes
tbb::parallel_for(tbb::blocked_range<int>(first_independent_node, last, ContractGrainSize),
[this, &remaining_nodes, &thread_data_list](const tbb::blocked_range<int>& range)
tbb::parallel_for(
tbb::blocked_range<int>(first_independent_node, last, ContractGrainSize),
[this, &remaining_nodes, &thread_data_list](const tbb::blocked_range<int> &range)
{
ContractorThreadData *data = thread_data_list.getThreadData();
for (int position = range.begin(); position != range.end(); ++position)
@@ -457,19 +455,18 @@ class Contractor
const NodeID x = remaining_nodes[position].id;
this->ContractNode<false>(data, x);
}
}
);
});
// make sure we really sort each block
tbb::parallel_for(thread_data_list.data.range(),
[&](const ThreadDataContainer::EnumerableThreadData::range_type& range)
tbb::parallel_for(
thread_data_list.data.range(),
[&](const ThreadDataContainer::EnumerableThreadData::range_type &range)
{
for (auto& data : range)
std::sort(data->inserted_edges.begin(),
data->inserted_edges.end());
}
);
tbb::parallel_for(tbb::blocked_range<int>(first_independent_node, last, DeleteGrainSize),
[this, &remaining_nodes, &thread_data_list](const tbb::blocked_range<int>& range)
for (auto &data : range)
std::sort(data->inserted_edges.begin(), data->inserted_edges.end());
});
tbb::parallel_for(
tbb::blocked_range<int>(first_independent_node, last, DeleteGrainSize),
[this, &remaining_nodes, &thread_data_list](const tbb::blocked_range<int> &range)
{
ContractorThreadData *data = thread_data_list.getThreadData();
for (int position = range.begin(); position != range.end(); ++position)
@@ -477,15 +474,15 @@ class Contractor
const NodeID x = remaining_nodes[position].id;
this->DeleteIncomingEdges(data, x);
}
}
);
});
// insert new edges
for (auto& data : thread_data_list.data)
for (auto &data : thread_data_list.data)
{
for (const ContractorEdge &edge : data->inserted_edges)
{
const EdgeID current_edge_ID = contractor_graph->FindEdge(edge.source, edge.target);
const EdgeID current_edge_ID =
contractor_graph->FindEdge(edge.source, edge.target);
if (current_edge_ID < contractor_graph->EndEdges(edge.source))
{
ContractorGraph::EdgeData &current_data =
@@ -504,8 +501,10 @@ class Contractor
data->inserted_edges.clear();
}
tbb::parallel_for(tbb::blocked_range<int>(first_independent_node, last, NeighboursGrainSize),
[this, &remaining_nodes, &node_priorities, &node_data, &thread_data_list](const tbb::blocked_range<int>& range)
tbb::parallel_for(
tbb::blocked_range<int>(first_independent_node, last, NeighboursGrainSize),
[this, &remaining_nodes, &node_priorities, &node_data, &thread_data_list](
const tbb::blocked_range<int> &range)
{
ContractorThreadData *data = thread_data_list.getThreadData();
for (int position = range.begin(); position != range.end(); ++position)
@@ -513,8 +512,7 @@ class Contractor
NodeID x = remaining_nodes[position].id;
this->UpdateNodeNeighbours(node_priorities, node_data, data, x);
}
}
);
});
// remove contracted nodes from the pool
number_of_contracted_nodes += last - first_independent_node;
@@ -775,17 +773,11 @@ class Contractor
{
inserted_edges.emplace_back(source, target, path_distance,
out_data.originalEdges + in_data.originalEdges,
node,
true,
true,
false);
node, true, true, false);
inserted_edges.emplace_back(target, source, path_distance,
out_data.originalEdges + in_data.originalEdges,
node,
true,
false,
true);
node, true, false, true);
}
}
}
@@ -884,10 +876,9 @@ class Contractor
return true;
}
inline bool IsNodeIndependent(
const std::vector<float> &priorities,
ContractorThreadData *const data,
NodeID node) const
inline bool IsNodeIndependent(const std::vector<float> &priorities,
ContractorThreadData *const data,
NodeID node) const
{
const float priority = priorities[node];
@@ -964,7 +955,6 @@ class Contractor
}
std::shared_ptr<ContractorGraph> contractor_graph;
std::vector<ContractorGraph::InputEdge> contracted_edge_list;
stxxl::vector<QueryEdge> external_edge_list;
std::vector<NodeID> orig_node_id_to_new_id_map;
XORFastHash fast_hash;
+135
View File
@@ -0,0 +1,135 @@
/*
Copyright (c) 2015, 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.
*/
#include "contractor_options.hpp"
#include "../util/git_sha.hpp"
#include "../util/simple_logger.hpp"
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <tbb/task_scheduler_init.h>
return_code
ContractorOptions::ParseArguments(int argc, char *argv[], ContractorConfig &contractor_config)
{
// declare a group of options that will be allowed only on command line
boost::program_options::options_description generic_options("Options");
generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")(
"config,c", boost::program_options::value<boost::filesystem::path>(&contractor_config.config_file_path)
->default_value("contractor.ini"),
"Path to a configuration file.");
// declare a group of options that will be allowed both on command line and in config file
boost::program_options::options_description config_options("Configuration");
config_options.add_options()(
"restrictions,r",
boost::program_options::value<boost::filesystem::path>(&contractor_config.restrictions_path),
"Restrictions file in .osrm.restrictions format")(
"profile,p", boost::program_options::value<boost::filesystem::path>(&contractor_config.profile_path)
->default_value("profile.lua"),
"Path to LUA routing profile")(
"threads,t", boost::program_options::value<unsigned int>(&contractor_config.requested_num_threads)
->default_value(tbb::task_scheduler_init::default_num_threads()),
"Number of threads to use");
// hidden options, will be allowed both on command line and in config file, but will not be
// shown to the user
boost::program_options::options_description hidden_options("Hidden options");
hidden_options.add_options()(
"input,i", boost::program_options::value<boost::filesystem::path>(&contractor_config.osrm_input_path),
"Input file in .osm, .osm.bz2 or .osm.pbf format");
// positional option
boost::program_options::positional_options_description positional_options;
positional_options.add("input", 1);
// combine above options for parsing
boost::program_options::options_description cmdline_options;
cmdline_options.add(generic_options).add(config_options).add(hidden_options);
boost::program_options::options_description config_file_options;
config_file_options.add(config_options).add(hidden_options);
boost::program_options::options_description visible_options(
"Usage: " + boost::filesystem::basename(argv[0]) + " <input.osrm> [options]");
visible_options.add(generic_options).add(config_options);
// parse command line options
boost::program_options::variables_map option_variables;
boost::program_options::store(boost::program_options::command_line_parser(argc, argv)
.options(cmdline_options)
.positional(positional_options)
.run(),
option_variables);
const auto &temp_config_path = option_variables["config"].as<boost::filesystem::path>();
if (boost::filesystem::is_regular_file(temp_config_path))
{
boost::program_options::store(boost::program_options::parse_config_file<char>(
temp_config_path.string().c_str(), cmdline_options, true),
option_variables);
}
if (option_variables.count("version"))
{
SimpleLogger().Write() << g_GIT_DESCRIPTION;
return return_code::exit;
}
if (option_variables.count("help"))
{
SimpleLogger().Write() << "\n" << visible_options;
return return_code::exit;
}
boost::program_options::notify(option_variables);
if (!option_variables.count("restrictions"))
{
contractor_config.restrictions_path = contractor_config.osrm_input_path.string() + ".restrictions";
}
if (!option_variables.count("input"))
{
SimpleLogger().Write() << "\n" << visible_options;
return return_code::fail;
}
return return_code::ok;
}
void ContractorOptions::GenerateOutputFilesNames(ContractorConfig &contractor_config)
{
contractor_config.node_output_path = contractor_config.osrm_input_path.string() + ".nodes";
contractor_config.edge_output_path = contractor_config.osrm_input_path.string() + ".edges";
contractor_config.geometry_output_path = contractor_config.osrm_input_path.string() + ".geometry";
contractor_config.graph_output_path = contractor_config.osrm_input_path.string() + ".hsgr";
contractor_config.rtree_nodes_output_path = contractor_config.osrm_input_path.string() + ".ramIndex";
contractor_config.rtree_leafs_output_path = contractor_config.osrm_input_path.string() + ".fileIndex";
}
+68
View File
@@ -0,0 +1,68 @@
/*
Copyright (c) 2015, 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 CONTRACTOR_OPTIONS_HPP
#define CONTRACTOR_OPTIONS_HPP
#include <boost/filesystem/path.hpp>
#include <string>
enum class return_code : unsigned
{
ok,
fail,
exit
};
struct ContractorConfig
{
ContractorConfig() noexcept : requested_num_threads(0) {}
boost::filesystem::path config_file_path;
boost::filesystem::path osrm_input_path;
boost::filesystem::path restrictions_path;
boost::filesystem::path profile_path;
std::string node_output_path;
std::string edge_output_path;
std::string geometry_output_path;
std::string graph_output_path;
std::string rtree_nodes_output_path;
std::string rtree_leafs_output_path;
unsigned requested_num_threads;
};
struct ContractorOptions
{
static return_code ParseArguments(int argc, char *argv[], ContractorConfig &extractor_config);
static void GenerateOutputFilesNames(ContractorConfig &extractor_config);
};
#endif // EXTRACTOR_OPTIONS_HPP
+191 -177
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -26,13 +26,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "edge_based_graph_factory.hpp"
#include "../algorithms/bfs_components.hpp"
#include "../algorithms/tiny_components.hpp"
#include "../data_structures/percent.hpp"
#include "../Util/compute_angle.hpp"
#include "../Util/integer_range.hpp"
#include "../Util/lua_util.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/timing_util.hpp"
#include "../util/compute_angle.hpp"
#include "../util/integer_range.hpp"
#include "../util/lua_util.hpp"
#include "../util/simple_logger.hpp"
#include "../util/timing_util.hpp"
#include <boost/assert.hpp>
@@ -40,22 +40,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <iomanip>
#include <limits>
EdgeBasedGraphFactory::EdgeBasedGraphFactory(
const std::shared_ptr<NodeBasedDynamicGraph> &node_based_graph,
std::unique_ptr<RestrictionMap> restriction_map,
std::vector<NodeID> &barrier_node_list,
std::vector<NodeID> &traffic_light_node_list,
std::vector<QueryNode> &node_info_list,
SpeedProfileProperties &speed_profile)
EdgeBasedGraphFactory::EdgeBasedGraphFactory(std::shared_ptr<NodeBasedDynamicGraph> node_based_graph,
std::shared_ptr<RestrictionMap> restriction_map,
std::unique_ptr<std::vector<NodeID>> barrier_node_list,
std::unique_ptr<std::vector<NodeID>> traffic_light_node_list,
const std::vector<QueryNode> &node_info_list,
const SpeedProfileProperties &speed_profile)
: speed_profile(speed_profile),
m_number_of_edge_based_nodes(std::numeric_limits<unsigned>::max()),
m_node_info_list(node_info_list), m_node_based_graph(node_based_graph),
m_restriction_map(std::move(restriction_map)), max_id(0)
m_node_info_list(node_info_list),
m_node_based_graph(std::move(node_based_graph)),
m_restriction_map(std::move(restriction_map)), max_id(0), removed_node_count(0)
{
// insert into unordered sets for fast lookup
m_barrier_nodes.insert(barrier_node_list.begin(), barrier_node_list.end());
m_traffic_lights.insert(traffic_light_node_list.begin(), traffic_light_node_list.end());
m_barrier_nodes.insert(barrier_node_list->begin(), barrier_node_list->end());
m_traffic_lights.insert(traffic_light_node_list->begin(), traffic_light_node_list->end());
}
void EdgeBasedGraphFactory::GetEdgeBasedEdges(DeallocatingVector<EdgeBasedEdge> &output_edge_list)
@@ -78,31 +77,25 @@ void EdgeBasedGraphFactory::GetEdgeBasedNodes(std::vector<EdgeBasedNode> &nodes)
nodes.swap(m_edge_based_node_list);
}
void
EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeID node_v, const bool belongs_to_tiny_cc)
void EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u,
const NodeID node_v,
const unsigned component_id)
{
// merge edges together into one EdgeBasedNode
BOOST_ASSERT(node_u != SPECIAL_NODEID);
BOOST_ASSERT(node_v != SPECIAL_NODEID);
// find forward edge id and
const EdgeID e1 = m_node_based_graph->FindEdge(node_u, node_v);
BOOST_ASSERT(e1 != SPECIAL_EDGEID);
const EdgeID edge_id_1 = m_node_based_graph->FindEdge(node_u, node_v);
BOOST_ASSERT(edge_id_1 != SPECIAL_EDGEID);
const EdgeData &forward_data = m_node_based_graph->GetEdgeData(e1);
const EdgeData &forward_data = m_node_based_graph->GetEdgeData(edge_id_1);
// find reverse edge id and
const EdgeID e2 = m_node_based_graph->FindEdge(node_v, node_u);
const EdgeID edge_id_2 = m_node_based_graph->FindEdge(node_v, node_u);
BOOST_ASSERT(edge_id_2 != SPECIAL_EDGEID);
#ifndef NDEBUG
if (e2 == m_node_based_graph->EndEdges(node_v))
{
SimpleLogger().Write(logWARNING) << "Did not find edge (" << node_v << "," << node_u << ")";
}
#endif
BOOST_ASSERT(e2 != SPECIAL_EDGEID);
BOOST_ASSERT(e2 < m_node_based_graph->EndEdges(node_v));
const EdgeData &reverse_data = m_node_based_graph->GetEdgeData(e2);
const EdgeData &reverse_data = m_node_based_graph->GetEdgeData(edge_id_2);
if (forward_data.edgeBasedNodeID == SPECIAL_NODEID &&
reverse_data.edgeBasedNodeID == SPECIAL_NODEID)
@@ -110,17 +103,17 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeID nod
return;
}
BOOST_ASSERT(m_geometry_compressor.HasEntryForID(e1) ==
m_geometry_compressor.HasEntryForID(e2));
if (m_geometry_compressor.HasEntryForID(e1))
BOOST_ASSERT(m_geometry_compressor.HasEntryForID(edge_id_1) ==
m_geometry_compressor.HasEntryForID(edge_id_2));
if (m_geometry_compressor.HasEntryForID(edge_id_1))
{
BOOST_ASSERT(m_geometry_compressor.HasEntryForID(e2));
BOOST_ASSERT(m_geometry_compressor.HasEntryForID(edge_id_2));
// reconstruct geometry and put in each individual edge with its offset
const std::vector<GeometryCompressor::CompressedNode> &forward_geometry =
m_geometry_compressor.GetBucketReference(e1);
m_geometry_compressor.GetBucketReference(edge_id_1);
const std::vector<GeometryCompressor::CompressedNode> &reverse_geometry =
m_geometry_compressor.GetBucketReference(e2);
m_geometry_compressor.GetBucketReference(edge_id_2);
BOOST_ASSERT(forward_geometry.size() == reverse_geometry.size());
BOOST_ASSERT(0 != forward_geometry.size());
const unsigned geometry_size = static_cast<unsigned>(forward_geometry.size());
@@ -171,20 +164,13 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeID nod
BOOST_ASSERT(current_edge_target_coordinate_id != current_edge_source_coordinate_id);
// build edges
m_edge_based_node_list.emplace_back(forward_data.edgeBasedNodeID,
reverse_data.edgeBasedNodeID,
current_edge_source_coordinate_id,
current_edge_target_coordinate_id,
forward_data.nameID,
forward_geometry[i].second,
reverse_geometry[geometry_size - 1 - i].second,
forward_dist_prefix_sum[i],
reverse_dist_prefix_sum[i],
m_geometry_compressor.GetPositionForID(e1),
i,
belongs_to_tiny_cc,
forward_data.travel_mode,
reverse_data.travel_mode);
m_edge_based_node_list.emplace_back(
forward_data.edgeBasedNodeID, reverse_data.edgeBasedNodeID,
current_edge_source_coordinate_id, current_edge_target_coordinate_id,
forward_data.nameID, forward_geometry[i].second,
reverse_geometry[geometry_size - 1 - i].second, forward_dist_prefix_sum[i],
reverse_dist_prefix_sum[i], m_geometry_compressor.GetPositionForID(edge_id_1),
component_id, i, forward_data.travel_mode, reverse_data.travel_mode);
current_edge_source_coordinate_id = current_edge_target_coordinate_id;
BOOST_ASSERT(m_edge_based_node_list.back().IsCompressed());
@@ -201,21 +187,22 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeID nod
}
else
{
BOOST_ASSERT(!m_geometry_compressor.HasEntryForID(e2));
BOOST_ASSERT(!m_geometry_compressor.HasEntryForID(edge_id_2));
if (forward_data.edgeBasedNodeID != SPECIAL_NODEID)
{
BOOST_ASSERT(forward_data.forward);
}
else
{
BOOST_ASSERT(!forward_data.forward);
}
if (reverse_data.edgeBasedNodeID != SPECIAL_NODEID)
{
BOOST_ASSERT(reverse_data.forward);
}
if (forward_data.edgeBasedNodeID == SPECIAL_NODEID)
{
BOOST_ASSERT(!forward_data.forward);
}
if (reverse_data.edgeBasedNodeID == SPECIAL_NODEID)
else
{
BOOST_ASSERT(!reverse_data.forward);
}
@@ -223,20 +210,10 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeID nod
BOOST_ASSERT(forward_data.edgeBasedNodeID != SPECIAL_NODEID ||
reverse_data.edgeBasedNodeID != SPECIAL_NODEID);
m_edge_based_node_list.emplace_back(forward_data.edgeBasedNodeID,
reverse_data.edgeBasedNodeID,
node_u,
node_v,
forward_data.nameID,
forward_data.distance,
reverse_data.distance,
0,
0,
SPECIAL_EDGEID,
0,
belongs_to_tiny_cc,
forward_data.travel_mode,
reverse_data.travel_mode);
m_edge_based_node_list.emplace_back(
forward_data.edgeBasedNodeID, reverse_data.edgeBasedNodeID, node_u, node_v,
forward_data.nameID, forward_data.distance, reverse_data.distance, 0, 0, SPECIAL_EDGEID,
component_id, 0, forward_data.travel_mode, reverse_data.travel_mode);
BOOST_ASSERT(!m_edge_based_node_list.back().IsCompressed());
}
}
@@ -244,7 +221,8 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeID nod
void EdgeBasedGraphFactory::FlushVectorToStream(
std::ofstream &edge_data_file, std::vector<OriginalEdgeData> &original_edge_data_vector) const
{
if (original_edge_data_vector.empty()) {
if (original_edge_data_vector.empty())
{
return;
}
edge_data_file.write((char *)&(original_edge_data_vector[0]),
@@ -256,7 +234,6 @@ void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename,
const std::string &geometry_filename,
lua_State *lua_state)
{
TIMER_START(geometry);
CompressGeometry();
TIMER_STOP(geometry);
@@ -290,7 +267,6 @@ void EdgeBasedGraphFactory::CompressGeometry()
const unsigned original_number_of_edges = m_node_based_graph->GetNumberOfEdges();
Percent progress(original_number_of_nodes);
unsigned removed_node_count = 0;
for (const NodeID node_v : osrm::irange(0u, original_number_of_nodes))
{
@@ -314,12 +290,33 @@ void EdgeBasedGraphFactory::CompressGeometry()
continue;
}
/*
* reverse_e2 forward_e2
* u <---------- v -----------> w
* ----------> <-----------
* forward_e1 reverse_e1
*
* Will be compressed to:
*
* reverse_e1
* u <---------- w
* ---------->
* forward_e1
*
* If the edges are compatible.
*
*/
const bool reverse_edge_order =
!(m_node_based_graph->GetEdgeData(m_node_based_graph->BeginEdges(node_v)).forward);
const EdgeID forward_e2 = m_node_based_graph->BeginEdges(node_v) + reverse_edge_order;
BOOST_ASSERT(SPECIAL_EDGEID != forward_e2);
BOOST_ASSERT(forward_e2 >= m_node_based_graph->BeginEdges(node_v) &&
forward_e2 < m_node_based_graph->EndEdges(node_v));
const EdgeID reverse_e2 = m_node_based_graph->BeginEdges(node_v) + 1 - reverse_edge_order;
BOOST_ASSERT(SPECIAL_EDGEID != reverse_e2);
BOOST_ASSERT(reverse_e2 >= m_node_based_graph->BeginEdges(node_v) &&
reverse_e2 < m_node_based_graph->EndEdges(node_v));
const EdgeData &fwd_edge_data2 = m_node_based_graph->GetEdgeData(forward_e2);
const EdgeData &rev_edge_data2 = m_node_based_graph->GetEdgeData(reverse_e2);
@@ -332,7 +329,6 @@ void EdgeBasedGraphFactory::CompressGeometry()
BOOST_ASSERT(node_u != node_v);
const EdgeID forward_e1 = m_node_based_graph->FindEdge(node_u, node_v);
BOOST_ASSERT(m_node_based_graph->EndEdges(node_u) != forward_e1);
BOOST_ASSERT(SPECIAL_EDGEID != forward_e1);
BOOST_ASSERT(node_v == m_node_based_graph->GetTarget(forward_e1));
const EdgeID reverse_e1 = m_node_based_graph->FindEdge(node_w, node_v);
@@ -342,16 +338,25 @@ void EdgeBasedGraphFactory::CompressGeometry()
const EdgeData &fwd_edge_data1 = m_node_based_graph->GetEdgeData(forward_e1);
const EdgeData &rev_edge_data1 = m_node_based_graph->GetEdgeData(reverse_e1);
if ((m_node_based_graph->FindEdge(node_u, node_w) != m_node_based_graph->EndEdges(node_u)) ||
(m_node_based_graph->FindEdge(node_w, node_u) != m_node_based_graph->EndEdges(node_w)))
if (m_node_based_graph->FindEdgeInEitherDirection(node_u, node_w) != SPECIAL_EDGEID)
{
continue;
}
if ( // TODO: rename to IsCompatibleTo
fwd_edge_data1.IsEqualTo(fwd_edge_data2) &&
rev_edge_data1.IsEqualTo(rev_edge_data2))
// this case can happen if two ways with different names overlap
if (fwd_edge_data1.nameID != rev_edge_data1.nameID ||
fwd_edge_data2.nameID != rev_edge_data2.nameID)
{
continue;
}
if (fwd_edge_data1.IsCompatibleTo(fwd_edge_data2) && rev_edge_data1.IsCompatibleTo(rev_edge_data2))
{
BOOST_ASSERT(m_node_based_graph->GetEdgeData(forward_e1).nameID ==
m_node_based_graph->GetEdgeData(reverse_e1).nameID);
BOOST_ASSERT(m_node_based_graph->GetEdgeData(forward_e2).nameID ==
m_node_based_graph->GetEdgeData(reverse_e2).nameID);
// Get distances before graph is modified
const int forward_weight1 = m_node_based_graph->GetEdgeData(forward_e1).distance;
const int forward_weight2 = m_node_based_graph->GetEdgeData(forward_e2).distance;
@@ -363,15 +368,14 @@ void EdgeBasedGraphFactory::CompressGeometry()
const int reverse_weight2 = m_node_based_graph->GetEdgeData(reverse_e2).distance;
BOOST_ASSERT(0 != reverse_weight1);
BOOST_ASSERT(0 != forward_weight2);
BOOST_ASSERT(0 != reverse_weight2);
const bool add_traffic_signal_penalty =
(m_traffic_lights.find(node_v) != m_traffic_lights.end());
const bool has_node_penalty = m_traffic_lights.find(node_v) != m_traffic_lights.end();
// add weight of e2's to e1
m_node_based_graph->GetEdgeData(forward_e1).distance += fwd_edge_data2.distance;
m_node_based_graph->GetEdgeData(reverse_e1).distance += rev_edge_data2.distance;
if (add_traffic_signal_penalty)
if (has_node_penalty)
{
m_node_based_graph->GetEdgeData(forward_e1).distance +=
speed_profile.traffic_signal_penalty;
@@ -389,32 +393,24 @@ void EdgeBasedGraphFactory::CompressGeometry()
// update any involved turn restrictions
m_restriction_map->FixupStartingTurnRestriction(node_u, node_v, node_w);
m_restriction_map->FixupArrivingTurnRestriction(node_u, node_v, node_w, m_node_based_graph);
m_restriction_map->FixupArrivingTurnRestriction(node_u, node_v, node_w,
*m_node_based_graph);
m_restriction_map->FixupStartingTurnRestriction(node_w, node_v, node_u);
m_restriction_map->FixupArrivingTurnRestriction(node_w, node_v, node_u, m_node_based_graph);
m_restriction_map->FixupArrivingTurnRestriction(node_w, node_v, node_u,
*m_node_based_graph);
// store compressed geometry in container
m_geometry_compressor.CompressEdge(
forward_e1,
forward_e2,
node_v,
node_w,
forward_weight1 +
(add_traffic_signal_penalty ? speed_profile.traffic_signal_penalty : 0),
forward_e1, forward_e2, node_v, node_w,
forward_weight1 + (has_node_penalty ? speed_profile.traffic_signal_penalty : 0),
forward_weight2);
m_geometry_compressor.CompressEdge(
reverse_e1,
reverse_e2,
node_v,
node_u,
reverse_weight1,
reverse_weight2 +
(add_traffic_signal_penalty ? speed_profile.traffic_signal_penalty : 0));
reverse_e1, reverse_e2, node_v, node_u, reverse_weight1,
reverse_weight2 + (has_node_penalty ? speed_profile.traffic_signal_penalty : 0));
++removed_node_count;
BOOST_ASSERT(m_node_based_graph->GetEdgeData(forward_e1).nameID ==
m_node_based_graph->GetEdgeData(reverse_e1).nameID);
}
}
SimpleLogger().Write() << "removed " << removed_node_count << " nodes";
@@ -423,7 +419,7 @@ void EdgeBasedGraphFactory::CompressGeometry()
unsigned new_node_count = 0;
unsigned new_edge_count = 0;
for(const auto i : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes()))
for (const auto i : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes()))
{
if (m_node_based_graph->GetOutDegree(i) > 0)
{
@@ -432,25 +428,25 @@ void EdgeBasedGraphFactory::CompressGeometry()
}
}
SimpleLogger().Write() << "new nodes: " << new_node_count << ", edges " << new_edge_count;
SimpleLogger().Write() << "Node compression ratio: " << new_node_count /
(double)original_number_of_nodes;
SimpleLogger().Write() << "Edge compression ratio: " << new_edge_count /
(double)original_number_of_edges;
SimpleLogger().Write() << "Node compression ratio: "
<< new_node_count / (double)original_number_of_nodes;
SimpleLogger().Write() << "Edge compression ratio: "
<< new_edge_count / (double)original_number_of_edges;
}
/**
* Writes the id of the edge in the edge expanded graph (into the edge in the node based graph)
*/
/// Renumbers all _forward_ edges and sets the edgeBasedNodeID.
/// A specific numbering is not important. Any unique ID will do.
void EdgeBasedGraphFactory::RenumberEdges()
{
// renumber edge based node IDs
// renumber edge based node of outgoing edges
unsigned numbered_edges_count = 0;
for (NodeID current_node = 0; current_node < m_node_based_graph->GetNumberOfNodes();
++current_node)
for (const auto current_node : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes()))
{
for (EdgeID current_edge : m_node_based_graph->GetAdjacentEdgeRange(current_node))
for (const auto current_edge : m_node_based_graph->GetAdjacentEdgeRange(current_node))
{
EdgeData &edge_data = m_node_based_graph->GetEdgeData(current_edge);
// this edge is an incoming edge
if (!edge_data.forward)
{
continue;
@@ -471,54 +467,74 @@ void EdgeBasedGraphFactory::RenumberEdges()
*/
void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
{
SimpleLogger().Write() << "Identifying components of the road network";
SimpleLogger().Write() << "Identifying components of the (compressed) road network";
// Run a BFS on the undirected graph and identify small components
BFSComponentExplorer<NodeBasedDynamicGraph> component_explorer(
*m_node_based_graph, *m_restriction_map, m_barrier_nodes);
TarjanSCC<NodeBasedDynamicGraph> component_explorer(m_node_based_graph, *m_restriction_map,
m_barrier_nodes);
component_explorer.run();
SimpleLogger().Write() << "identified: " << component_explorer.GetNumberOfComponents()
<< " many components";
SimpleLogger().Write() << "identified: "
<< component_explorer.get_number_of_components() - removed_node_count
<< " (compressed) components";
SimpleLogger().Write() << "identified "
<< component_explorer.get_size_one_count() - removed_node_count
<< " (compressed) SCCs of size 1";
SimpleLogger().Write() << "generating edge-expanded nodes";
Percent progress(m_node_based_graph->GetNumberOfNodes());
// loop over all edges and generate new set of nodes
for (NodeID u = 0, end = m_node_based_graph->GetNumberOfNodes(); u < end; ++u)
for (const auto node_u : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes()))
{
BOOST_ASSERT(u != SPECIAL_NODEID);
BOOST_ASSERT(u < m_node_based_graph->GetNumberOfNodes());
progress.printStatus(u);
for (EdgeID e1 : m_node_based_graph->GetAdjacentEdgeRange(u))
BOOST_ASSERT(node_u != SPECIAL_NODEID);
BOOST_ASSERT(node_u < m_node_based_graph->GetNumberOfNodes());
progress.printStatus(node_u);
for (EdgeID e1 : m_node_based_graph->GetAdjacentEdgeRange(node_u))
{
const EdgeData &edge_data = m_node_based_graph->GetEdgeData(e1);
BOOST_ASSERT(e1 != SPECIAL_EDGEID);
const NodeID v = m_node_based_graph->GetTarget(e1);
const NodeID node_v = m_node_based_graph->GetTarget(e1);
BOOST_ASSERT(SPECIAL_NODEID != v);
// pick only every other edge
if (u > v)
BOOST_ASSERT(SPECIAL_NODEID != node_v);
// pick only every other edge, since we have every edge as an outgoing
// and incoming egde
if (node_u > node_v)
{
continue;
}
BOOST_ASSERT(u < v);
BOOST_ASSERT(node_u < node_v);
// Note: edges that end on barrier nodes or on a turn restriction
// may actually be in two distinct components. We choose the smallest
const unsigned size_of_component = std::min(component_explorer.GetComponentSize(u),
component_explorer.GetComponentSize(v));
const unsigned size_of_component =
std::min(component_explorer.get_component_size(node_u),
component_explorer.get_component_size(node_v));
const bool component_is_tiny = (size_of_component < 1000);
const unsigned id_of_smaller_component = [node_u, node_v, &component_explorer]
{
if (component_explorer.get_component_size(node_u) <
component_explorer.get_component_size(node_v))
{
return component_explorer.get_component_id(node_u);
}
return component_explorer.get_component_id(node_v);
}();
const bool component_is_tiny = size_of_component < 1000;
// we only set edgeBasedNodeID for forward edges
if (edge_data.edgeBasedNodeID == SPECIAL_NODEID)
{
InsertEdgeBasedNode(v, u, component_is_tiny);
InsertEdgeBasedNode(node_v, node_u,
(component_is_tiny ? id_of_smaller_component + 1 : 0));
}
else
{
InsertEdgeBasedNode(u, v, component_is_tiny);
InsertEdgeBasedNode(node_u, node_v,
(component_is_tiny ? id_of_smaller_component + 1 : 0));
}
}
}
@@ -530,9 +546,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
/**
* Actually it also generates OriginalEdgeData and serializes them...
*/
void
EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename,
lua_State *lua_state)
void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
const std::string &original_edge_data_filename, lua_State *lua_state)
{
SimpleLogger().Write() << "generating edge-expanded edges";
@@ -557,10 +572,10 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg
Percent progress(m_node_based_graph->GetNumberOfNodes());
for (NodeID u = 0, end = m_node_based_graph->GetNumberOfNodes(); u < end; ++u)
for (const auto node_u : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes()))
{
progress.printStatus(u);
for (const EdgeID e1 : m_node_based_graph->GetAdjacentEdgeRange(u))
progress.printStatus(node_u);
for (const EdgeID e1 : m_node_based_graph->GetAdjacentEdgeRange(node_u))
{
if (!m_node_based_graph->GetEdgeData(e1).forward)
{
@@ -568,21 +583,21 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg
}
++node_based_edge_counter;
const NodeID v = m_node_based_graph->GetTarget(e1);
const NodeID to_node_of_only_restriction =
m_restriction_map->CheckForEmanatingIsOnlyTurn(u, v);
const bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end());
const NodeID node_v = m_node_based_graph->GetTarget(e1);
const NodeID only_restriction_to_node =
m_restriction_map->CheckForEmanatingIsOnlyTurn(node_u, node_v);
const bool is_barrier_node = m_barrier_nodes.find(node_v) != m_barrier_nodes.end();
for (EdgeID e2 : m_node_based_graph->GetAdjacentEdgeRange(v))
for (const EdgeID e2 : m_node_based_graph->GetAdjacentEdgeRange(node_v))
{
if (!m_node_based_graph->GetEdgeData(e2).forward)
{
continue;
}
const NodeID w = m_node_based_graph->GetTarget(e2);
const NodeID node_w = m_node_based_graph->GetTarget(e2);
if ((to_node_of_only_restriction != SPECIAL_NODEID) &&
(w != to_node_of_only_restriction))
if ((only_restriction_to_node != SPECIAL_NODEID) &&
(node_w != only_restriction_to_node))
{
// We are at an only_-restriction but not at the right turn.
++restricted_turns_counter;
@@ -591,7 +606,7 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg
if (is_barrier_node)
{
if (u != w)
if (node_u != node_w)
{
++skipped_barrier_turns_counter;
continue;
@@ -599,7 +614,7 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg
}
else
{
if ((u == w) && (m_node_based_graph->GetOutDegree(v) > 1))
if ((node_u == node_w) && (m_node_based_graph->GetOutDegree(node_v) > 1))
{
++skipped_uturns_counter;
continue;
@@ -608,9 +623,9 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg
// only add an edge if turn is not a U-turn except when it is
// at the end of a dead-end street
if (m_restriction_map->CheckIfTurnIsRestricted(u, v, w) &&
(to_node_of_only_restriction == SPECIAL_NODEID) &&
(w != to_node_of_only_restriction))
if (m_restriction_map->CheckIfTurnIsRestricted(node_u, node_v, node_w) &&
(only_restriction_to_node == SPECIAL_NODEID) &&
(node_w != only_restriction_to_node))
{
// We are at an only_-restriction but not at the right turn.
++restricted_turns_counter;
@@ -627,26 +642,28 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg
// the following is the core of the loop.
unsigned distance = edge_data1.distance;
if (m_traffic_lights.find(v) != m_traffic_lights.end())
if (m_traffic_lights.find(node_v) != m_traffic_lights.end())
{
distance += speed_profile.traffic_signal_penalty;
}
// unpack last node of first segment if packed
const auto first_coordinate = m_node_info_list[(m_geometry_compressor.HasEntryForID(e1) ?
m_geometry_compressor.GetLastNodeIDOfBucket(e1) :
u)];
const auto first_coordinate =
m_node_info_list[(m_geometry_compressor.HasEntryForID(e1)
? m_geometry_compressor.GetLastNodeIDOfBucket(e1)
: node_u)];
// unpack first node of second segment if packed
const auto third_coordinate = m_node_info_list[(m_geometry_compressor.HasEntryForID(e2) ?
m_geometry_compressor.GetFirstNodeIDOfBucket(e2) :
w)];
const auto third_coordinate =
m_node_info_list[(m_geometry_compressor.HasEntryForID(e2)
? m_geometry_compressor.GetFirstNodeIDOfBucket(e2)
: node_w)];
const double turn_angle = ComputeAngle::OfThreeFixedPointCoordinates(
first_coordinate, m_node_info_list[v], third_coordinate);
first_coordinate, m_node_info_list[node_v], third_coordinate);
const int turn_penalty = GetTurnPenalty(turn_angle, lua_state);
TurnInstruction turn_instruction = AnalyzeTurn(u, v, w, turn_angle);
TurnInstruction turn_instruction = AnalyzeTurn(node_u, node_v, node_w, turn_angle);
if (turn_instruction == TurnInstruction::UTurn)
{
distance += speed_profile.u_turn_penalty;
@@ -661,10 +678,8 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg
}
original_edge_data_vector.emplace_back(
(edge_is_compressed ? m_geometry_compressor.GetPositionForID(e1) : v),
edge_data1.nameID,
turn_instruction,
edge_is_compressed,
(edge_is_compressed ? m_geometry_compressor.GetPositionForID(e1) : node_v),
edge_data1.nameID, turn_instruction, edge_is_compressed,
edge_data2.travel_mode);
++original_edges_counter;
@@ -677,12 +692,9 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg
BOOST_ASSERT(SPECIAL_NODEID != edge_data1.edgeBasedNodeID);
BOOST_ASSERT(SPECIAL_NODEID != edge_data2.edgeBasedNodeID);
m_edge_based_edge_list.emplace_back(EdgeBasedEdge(edge_data1.edgeBasedNodeID,
edge_data2.edgeBasedNodeID,
m_edge_based_edge_list.size(),
distance,
true,
false));
m_edge_based_edge_list.emplace_back(
EdgeBasedEdge(edge_data1.edgeBasedNodeID, edge_data2.edgeBasedNodeID,
m_edge_based_edge_list.size(), distance, true, false));
}
}
}
@@ -713,7 +725,10 @@ int EdgeBasedGraphFactory::GetTurnPenalty(double angle, lua_State *lua_state) co
// call lua profile to compute turn penalty
return luabind::call_function<int>(lua_state, "turn_function", 180. - angle);
}
catch (const luabind::error &er) { SimpleLogger().Write(logWARNING) << er.what(); }
catch (const luabind::error &er)
{
SimpleLogger().Write(logWARNING) << er.what();
}
}
return 0;
}
@@ -721,8 +736,7 @@ int EdgeBasedGraphFactory::GetTurnPenalty(double angle, lua_State *lua_state) co
TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID node_u,
const NodeID node_v,
const NodeID node_w,
const double angle)
const
const double angle) const
{
if (node_u == node_w)
{
+12 -9
View File
@@ -59,12 +59,12 @@ class EdgeBasedGraphFactory
struct SpeedProfileProperties;
explicit EdgeBasedGraphFactory(const std::shared_ptr<NodeBasedDynamicGraph> &node_based_graph,
std::unique_ptr<RestrictionMap> restricion_map,
std::vector<NodeID> &barrier_node_list,
std::vector<NodeID> &traffic_light_node_list,
std::vector<QueryNode> &node_info_list,
SpeedProfileProperties &speed_profile);
explicit EdgeBasedGraphFactory(std::shared_ptr<NodeBasedDynamicGraph> node_based_graph,
std::shared_ptr<RestrictionMap> restricion_map,
std::unique_ptr<std::vector<NodeID>> barrier_node_list,
std::unique_ptr<std::vector<NodeID>> traffic_light_node_list,
const std::vector<QueryNode> &node_info_list,
const SpeedProfileProperties &speed_profile);
void Run(const std::string &original_edge_data_filename,
const std::string &geometry_filename,
@@ -97,15 +97,16 @@ class EdgeBasedGraphFactory
unsigned m_number_of_edge_based_nodes;
std::vector<QueryNode> m_node_info_list;
std::vector<EdgeBasedNode> m_edge_based_node_list;
DeallocatingVector<EdgeBasedEdge> m_edge_based_edge_list;
const std::vector<QueryNode>& m_node_info_list;
std::shared_ptr<NodeBasedDynamicGraph> m_node_based_graph;
std::shared_ptr<RestrictionMap> m_restriction_map;
std::unordered_set<NodeID> m_barrier_nodes;
std::unordered_set<NodeID> m_traffic_lights;
std::unique_ptr<RestrictionMap> m_restriction_map;
GeometryCompressor m_geometry_compressor;
@@ -115,12 +116,14 @@ class EdgeBasedGraphFactory
void GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename,
lua_State *lua_state);
void InsertEdgeBasedNode(const NodeID u, const NodeID v, const bool belongsToTinyComponent);
void InsertEdgeBasedNode(const NodeID u, const NodeID v, const unsigned component_id);
void FlushVectorToStream(std::ofstream &edge_data_file,
std::vector<OriginalEdgeData> &original_edge_data_vector) const;
NodeID max_id;
std::size_t removed_node_count;
};
#endif /* EDGE_BASED_GRAPH_FACTORY_HPP_ */
+18 -23
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -26,7 +26,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "geometry_compressor.hpp"
#include "../Util/simple_logger.hpp"
#include "../util/simple_logger.hpp"
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
@@ -35,9 +35,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <limits>
#include <string>
int free_list_maximum = 0;
int UniqueNumber() { return ++free_list_maximum; }
GeometryCompressor::GeometryCompressor()
{
m_free_list.reserve(100);
@@ -174,8 +171,8 @@ void GeometryCompressor::CompressEdge(const EdgeID edge_id_1,
m_compressed_geometries[list_to_remove_index];
// found an existing list, append it to the list of edge_id_1
edge_bucket_list1.insert(
edge_bucket_list1.end(), edge_bucket_list2.begin(), edge_bucket_list2.end());
edge_bucket_list1.insert(edge_bucket_list1.end(), edge_bucket_list2.begin(),
edge_bucket_list2.end());
// remove the list of edge_id_2
m_edge_id_to_list_index_map.erase(edge_id_2);
@@ -211,9 +208,8 @@ void GeometryCompressor::PrintStatistics() const
"\n compressed edges: " << compressed_edges
<< "\n compressed geometries: " << compressed_geometries
<< "\n longest chain length: " << longest_chain_length
<< "\n cmpr ratio: "
<< ((float)compressed_edges /
std::max(compressed_geometries, (uint64_t)1))
<< "\n cmpr ratio: " << ((float)compressed_edges /
std::max(compressed_geometries, (uint64_t)1))
<< "\n avg chain length: "
<< (float)compressed_geometries /
std::max((uint64_t)1, compressed_edges);
@@ -226,16 +222,15 @@ GeometryCompressor::GetBucketReference(const EdgeID edge_id) const
return m_compressed_geometries.at(index);
}
NodeID GeometryCompressor::GetFirstNodeIDOfBucket(const EdgeID edge_id) const
{
const auto &bucket = GetBucketReference(edge_id);
BOOST_ASSERT(bucket.size() >= 2);
return bucket[1].first;
}
NodeID GeometryCompressor::GetLastNodeIDOfBucket(const EdgeID edge_id) const
{
const auto &bucket = GetBucketReference(edge_id);
BOOST_ASSERT(bucket.size() >= 2);
return bucket[bucket.size()-2].first;
}
NodeID GeometryCompressor::GetFirstNodeIDOfBucket(const EdgeID edge_id) const
{
const auto &bucket = GetBucketReference(edge_id);
BOOST_ASSERT(bucket.size() >= 2);
return bucket[1].first;
}
NodeID GeometryCompressor::GetLastNodeIDOfBucket(const EdgeID edge_id) const
{
const auto &bucket = GetBucketReference(edge_id);
BOOST_ASSERT(bucket.size() >= 2);
return bucket[bucket.size() - 2].first;
}
+2
View File
@@ -58,6 +58,8 @@ class GeometryCompressor
NodeID GetLastNodeIDOfBucket(const EdgeID edge_id) const;
private:
int free_list_maximum = 0;
void IncreaseFreeList();
std::vector<std::vector<CompressedNode>> m_compressed_geometries;
std::vector<unsigned> m_free_list;
+197 -348
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -34,21 +34,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../data_structures/static_rtree.hpp"
#include "../data_structures/restriction_map.hpp"
#include "../Util/GitDescription.h"
#include "../Util/graph_loader.hpp"
#include "../Util/integer_range.hpp"
#include "../Util/lua_util.hpp"
#include "../Util/make_unique.hpp"
#include "../Util/OSRMException.h"
#include "../Util/simple_logger.hpp"
#include "../Util/StringUtil.h"
#include "../Util/timing_util.hpp"
#include "../util/git_sha.hpp"
#include "../util/graph_loader.hpp"
#include "../util/integer_range.hpp"
#include "../util/lua_util.hpp"
#include "../util/make_unique.hpp"
#include "../util/osrm_exception.hpp"
#include "../util/simple_logger.hpp"
#include "../util/string_util.hpp"
#include "../util/timing_util.hpp"
#include "../typedefs.h"
#include <boost/filesystem/fstream.hpp>
#include <boost/program_options.hpp>
#include <tbb/task_scheduler_init.h>
#include <tbb/parallel_sort.h>
#include <chrono>
@@ -57,172 +56,98 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <thread>
#include <vector>
Prepare::Prepare() : requested_num_threads(1) {}
Prepare::~Prepare() {}
int Prepare::Process(int argc, char *argv[])
int Prepare::Run()
{
LogPolicy::GetInstance().Unmute();
TIMER_START(preparing);
TIMER_START(expansion);
if (!ParseArguments(argc, argv))
{
return 0;
}
if (!boost::filesystem::is_regular_file(input_path))
{
SimpleLogger().Write(logWARNING) << "Input file " << input_path.string() << " not found!";
return 1;
}
if (!boost::filesystem::is_regular_file(profile_path))
{
SimpleLogger().Write(logWARNING) << "Profile " << profile_path.string() << " not found!";
return 1;
}
if (1 > requested_num_threads)
{
SimpleLogger().Write(logWARNING) << "Number of threads must be 1 or larger";
return 1;
}
const unsigned recommended_num_threads = tbb::task_scheduler_init::default_num_threads();
SimpleLogger().Write() << "Input file: " << input_path.filename().string();
SimpleLogger().Write() << "Restrictions file: " << restrictions_path.filename().string();
SimpleLogger().Write() << "Profile: " << profile_path.filename().string();
SimpleLogger().Write() << "Threads: " << requested_num_threads;
if (recommended_num_threads != requested_num_threads)
{
SimpleLogger().Write(logWARNING) << "The recommended number of threads is "
<< recommended_num_threads
<< "! This setting may have performance side-effects.";
}
tbb::task_scheduler_init init(requested_num_threads);
LogPolicy::GetInstance().Unmute();
FingerPrint fingerprint_orig;
CheckRestrictionsFile(fingerprint_orig);
boost::filesystem::ifstream input_stream(input_path, std::ios::in | std::ios::binary);
node_filename = input_path.string() + ".nodes";
edge_out = input_path.string() + ".edges";
geometry_filename = input_path.string() + ".geometry";
graph_out = input_path.string() + ".hsgr";
rtree_nodes_path = input_path.string() + ".ramIndex";
rtree_leafs_path = input_path.string() + ".fileIndex";
/*** Setup Scripting Environment ***/
// Create a new lua state
lua_State *lua_state = luaL_newstate();
// Connect LuaBind to this lua state
luabind::open(lua_state);
EdgeBasedGraphFactory::SpeedProfileProperties speed_profile;
if (!SetupScriptingEnvironment(lua_state, speed_profile))
{
return 1;
}
#ifdef WIN32
#pragma message("Memory consumption on Windows can be higher due to different bit packing")
#else
static_assert(sizeof(ImportEdge) == 20,
"changing ImportEdge type has influence on memory consumption!");
static_assert(sizeof(NodeBasedEdge) == 20,
"changing NodeBasedEdge type has influence on memory consumption!");
static_assert(sizeof(EdgeBasedEdge) == 16,
"changing EdgeBasedEdge type has influence on memory consumption!");
#endif
NodeID number_of_node_based_nodes =
readBinaryOSRMGraphFromStream(input_stream,
edge_list,
barrier_node_list,
traffic_light_list,
&internal_to_external_node_map,
restriction_list);
input_stream.close();
if (edge_list.empty())
{
SimpleLogger().Write(logWARNING) << "The input data is empty, exiting.";
return 1;
}
TIMER_START(preparing);
SimpleLogger().Write() << restriction_list.size() << " restrictions, "
<< barrier_node_list.size() << " bollard nodes, "
<< traffic_light_list.size() << " traffic lights";
// Create a new lua state
std::vector<EdgeBasedNode> node_based_edge_list;
unsigned number_of_edge_based_nodes = 0;
SimpleLogger().Write() << "Generating edge-expanded graph representation";
TIMER_START(expansion);
auto node_based_edge_list = osrm::make_unique<std::vector<EdgeBasedNode>>();;
DeallocatingVector<EdgeBasedEdge> edge_based_edge_list;
auto internal_to_external_node_map = osrm::make_unique<std::vector<QueryNode>>();
auto graph_size =
BuildEdgeExpandedGraph(*internal_to_external_node_map,
*node_based_edge_list, edge_based_edge_list);
// init node_based_edge_list, edge_based_edge_list by edgeList
number_of_edge_based_nodes = BuildEdgeExpandedGraph(lua_state,
number_of_node_based_nodes,
node_based_edge_list,
edge_based_edge_list,
speed_profile);
lua_close(lua_state);
auto number_of_node_based_nodes = graph_size.first;
auto number_of_edge_based_nodes = graph_size.second;
TIMER_STOP(expansion);
BuildRTree(node_based_edge_list);
SimpleLogger().Write() << "building r-tree ...";
TIMER_START(rtree);
RangebasedCRC32 crc32;
if (crc32.using_hardware())
{
SimpleLogger().Write() << "using hardware based CRC32 computation";
}
else
{
SimpleLogger().Write() << "using software based CRC32 computation";
}
BuildRTree(*node_based_edge_list, *internal_to_external_node_map);
const unsigned crc32_value = crc32(node_based_edge_list);
node_based_edge_list.clear();
node_based_edge_list.shrink_to_fit();
SimpleLogger().Write() << "CRC32: " << crc32_value;
TIMER_STOP(rtree);
WriteNodeMapping();
SimpleLogger().Write() << "writing node map ...";
WriteNodeMapping(std::move(internal_to_external_node_map));
/***
* Contracting the edge-expanded graph
*/
SimpleLogger().Write() << "initializing contractor";
auto contractor =
osrm::make_unique<Contractor>(number_of_edge_based_nodes, edge_based_edge_list);
// Contracting the edge-expanded graph
TIMER_START(contraction);
contractor->Run();
auto contracted_edge_list = osrm::make_unique<DeallocatingVector<QueryEdge>>();
ContractGraph(number_of_edge_based_nodes, edge_based_edge_list, *contracted_edge_list);
TIMER_STOP(contraction);
SimpleLogger().Write() << "Contraction took " << TIMER_SEC(contraction) << " sec";
DeallocatingVector<QueryEdge> contracted_edge_list;
contractor->GetEdges(contracted_edge_list);
contractor.reset();
std::size_t number_of_used_edges = WriteContractedGraph(number_of_edge_based_nodes,
std::move(node_based_edge_list),
std::move(contracted_edge_list));
/***
* Sorting contracted edges in a way that the static query graph can read some in in-place.
*/
TIMER_STOP(preparing);
tbb::parallel_sort(contracted_edge_list.begin(), contracted_edge_list.end());
const unsigned contracted_edge_count = contracted_edge_list.size();
SimpleLogger().Write() << "Preprocessing : " << TIMER_SEC(preparing) << " seconds";
SimpleLogger().Write() << "Expansion : " << (number_of_node_based_nodes / TIMER_SEC(expansion))
<< " nodes/sec and "
<< (number_of_edge_based_nodes / TIMER_SEC(expansion)) << " edges/sec";
SimpleLogger().Write() << "Contraction: "
<< (number_of_edge_based_nodes / TIMER_SEC(contraction))
<< " nodes/sec and " << number_of_used_edges / TIMER_SEC(contraction)
<< " edges/sec";
SimpleLogger().Write() << "finished preprocessing";
return 0;
}
std::size_t Prepare::WriteContractedGraph(unsigned number_of_edge_based_nodes,
std::unique_ptr<std::vector<EdgeBasedNode>> node_based_edge_list,
std::unique_ptr<DeallocatingVector<QueryEdge>> contracted_edge_list)
{
const unsigned crc32_value = CalculateEdgeChecksum(std::move(node_based_edge_list));
// Sorting contracted edges in a way that the static query graph can read some in in-place.
tbb::parallel_sort(contracted_edge_list->begin(), contracted_edge_list->end());
const unsigned contracted_edge_count = contracted_edge_list->size();
SimpleLogger().Write() << "Serializing compacted graph of " << contracted_edge_count
<< " edges";
boost::filesystem::ofstream hsgr_output_stream(graph_out, std::ios::binary);
hsgr_output_stream.write((char *)&fingerprint_orig, sizeof(FingerPrint));
const FingerPrint fingerprint = FingerPrint::GetValid();
boost::filesystem::ofstream hsgr_output_stream(config.graph_output_path, std::ios::binary);
hsgr_output_stream.write((char *)&fingerprint, sizeof(FingerPrint));
const unsigned max_used_node_id = 1 + [&contracted_edge_list]
{
unsigned tmp_max = 0;
for (const QueryEdge &edge : contracted_edge_list)
for (const QueryEdge &edge : *contracted_edge_list)
{
BOOST_ASSERT(SPECIAL_NODEID != edge.source);
BOOST_ASSERT(SPECIAL_NODEID != edge.target);
@@ -247,7 +172,7 @@ int Prepare::Process(int argc, char *argv[])
for (const auto node : osrm::irange(0u, max_used_node_id))
{
last_edge = edge;
while ((edge < contracted_edge_count) && (contracted_edge_list[edge].source == node))
while ((edge < contracted_edge_count) && ((*contracted_edge_list)[edge].source == node))
{
++edge;
}
@@ -276,19 +201,19 @@ int Prepare::Process(int argc, char *argv[])
hsgr_output_stream.write((char *)&node_array[0],
sizeof(StaticGraph<EdgeData>::NodeArrayEntry) * node_array_size);
}
// serialize all edges
// serialize all edges
SimpleLogger().Write() << "Building edge array";
edge = 0;
int number_of_used_edges = 0;
StaticGraph<EdgeData>::EdgeArrayEntry current_edge;
for (const auto edge : osrm::irange<std::size_t>(0, contracted_edge_list.size()))
for (const auto edge : osrm::irange<std::size_t>(0, contracted_edge_list->size()))
{
// no eigen loops
BOOST_ASSERT(contracted_edge_list[edge].source != contracted_edge_list[edge].target);
current_edge.target = contracted_edge_list[edge].target;
current_edge.data = contracted_edge_list[edge].data;
BOOST_ASSERT((*contracted_edge_list)[edge].source != (*contracted_edge_list)[edge].target);
current_edge.target = (*contracted_edge_list)[edge].target;
current_edge.data = (*contracted_edge_list)[edge].data;
// every target needs to be valid
BOOST_ASSERT(current_edge.target < max_used_node_id);
@@ -296,12 +221,12 @@ int Prepare::Process(int argc, char *argv[])
if (current_edge.data.distance <= 0)
{
SimpleLogger().Write(logWARNING) << "Edge: " << edge
<< ",source: " << contracted_edge_list[edge].source
<< ", target: " << contracted_edge_list[edge].target
<< ",source: " << (*contracted_edge_list)[edge].source
<< ", target: " << (*contracted_edge_list)[edge].target
<< ", dist: " << current_edge.data.distance;
SimpleLogger().Write(logWARNING) << "Failed at adjacency list of node "
<< contracted_edge_list[edge].source << "/"
<< (*contracted_edge_list)[edge].source << "/"
<< node_array.size() - 1;
return 1;
}
@@ -311,174 +236,54 @@ int Prepare::Process(int argc, char *argv[])
++number_of_used_edges;
}
hsgr_output_stream.close();
TIMER_STOP(preparing);
SimpleLogger().Write() << "Preprocessing : " << TIMER_SEC(preparing) << " seconds";
SimpleLogger().Write() << "Expansion : " << (number_of_node_based_nodes / TIMER_SEC(expansion))
<< " nodes/sec and "
<< (number_of_edge_based_nodes / TIMER_SEC(expansion)) << " edges/sec";
SimpleLogger().Write() << "Contraction: "
<< (number_of_edge_based_nodes / TIMER_SEC(contraction))
<< " nodes/sec and " << number_of_used_edges / TIMER_SEC(contraction)
<< " edges/sec";
node_array.clear();
SimpleLogger().Write() << "finished preprocessing";
return 0;
return number_of_used_edges;
}
/**
\brief Parses command line arguments
\param argc count of arguments
\param argv array of arguments
\param result [out] value for exit return value
\return true if everything is ok, false if need to terminate execution
*/
bool Prepare::ParseArguments(int argc, char *argv[])
unsigned Prepare::CalculateEdgeChecksum(std::unique_ptr<std::vector<EdgeBasedNode>> node_based_edge_list)
{
// declare a group of options that will be allowed only on command line
boost::program_options::options_description generic_options("Options");
generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")(
"config,c",
boost::program_options::value<boost::filesystem::path>(&config_file_path)
->default_value("contractor.ini"),
"Path to a configuration file.");
// declare a group of options that will be allowed both on command line and in config file
boost::program_options::options_description config_options("Configuration");
config_options.add_options()(
"restrictions,r",
boost::program_options::value<boost::filesystem::path>(&restrictions_path),
"Restrictions file in .osrm.restrictions format")(
"profile,p",
boost::program_options::value<boost::filesystem::path>(&profile_path)
->default_value("profile.lua"),
"Path to LUA routing profile")(
"threads,t",
boost::program_options::value<unsigned int>(&requested_num_threads)
->default_value(tbb::task_scheduler_init::default_num_threads()),
"Number of threads to use");
// hidden options, will be allowed both on command line and in config file, but will not be
// shown to the user
boost::program_options::options_description hidden_options("Hidden options");
hidden_options.add_options()(
"input,i",
boost::program_options::value<boost::filesystem::path>(&input_path),
"Input file in .osm, .osm.bz2 or .osm.pbf format");
// positional option
boost::program_options::positional_options_description positional_options;
positional_options.add("input", 1);
// combine above options for parsing
boost::program_options::options_description cmdline_options;
cmdline_options.add(generic_options).add(config_options).add(hidden_options);
boost::program_options::options_description config_file_options;
config_file_options.add(config_options).add(hidden_options);
boost::program_options::options_description visible_options(
"Usage: " + boost::filesystem::basename(argv[0]) + " <input.osrm> [options]");
visible_options.add(generic_options).add(config_options);
// parse command line options
boost::program_options::variables_map option_variables;
boost::program_options::store(boost::program_options::command_line_parser(argc, argv)
.options(cmdline_options)
.positional(positional_options)
.run(),
option_variables);
const auto& temp_config_path = option_variables["config"].as<boost::filesystem::path>();
if (boost::filesystem::is_regular_file(temp_config_path))
RangebasedCRC32 crc32;
if (crc32.using_hardware())
{
boost::program_options::store(boost::program_options::parse_config_file<char>(temp_config_path.string().c_str(), cmdline_options, true),
option_variables);
SimpleLogger().Write() << "using hardware based CRC32 computation";
}
else
{
SimpleLogger().Write() << "using software based CRC32 computation";
}
if (option_variables.count("version"))
{
SimpleLogger().Write() << g_GIT_DESCRIPTION;
return false;
}
const unsigned crc32_value = crc32(*node_based_edge_list);
SimpleLogger().Write() << "CRC32: " << crc32_value;
if (option_variables.count("help"))
{
SimpleLogger().Write() << "\n" << visible_options;
return false;
}
boost::program_options::notify(option_variables);
if (!option_variables.count("restrictions"))
{
restrictions_path = std::string(input_path.string() + ".restrictions");
}
if (!option_variables.count("input"))
{
SimpleLogger().Write() << "\n" << visible_options;
return false;
}
return true;
}
/**
\brief Loads and checks file UUIDs
*/
void Prepare::CheckRestrictionsFile(FingerPrint &fingerprint_orig)
{
boost::filesystem::ifstream restriction_stream(restrictions_path, std::ios::binary);
FingerPrint fingerprint_loaded;
unsigned number_of_usable_restrictions = 0;
restriction_stream.read((char *)&fingerprint_loaded, sizeof(FingerPrint));
if (!fingerprint_loaded.TestPrepare(fingerprint_orig))
{
SimpleLogger().Write(logWARNING) << ".restrictions was prepared with different build.\n"
"Reprocess to get rid of this warning.";
}
restriction_stream.read((char *)&number_of_usable_restrictions, sizeof(unsigned));
restriction_list.resize(number_of_usable_restrictions);
if (number_of_usable_restrictions > 0)
{
restriction_stream.read((char *)&(restriction_list[0]),
number_of_usable_restrictions * sizeof(TurnRestriction));
}
restriction_stream.close();
return crc32_value;
}
/**
\brief Setups scripting environment (lua-scripting)
Also initializes speed profile.
*/
bool
Prepare::SetupScriptingEnvironment(lua_State *lua_state,
EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile)
void Prepare::SetupScriptingEnvironment(
lua_State *lua_state, EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile)
{
// open utility libraries string library;
luaL_openlibs(lua_state);
// adjust lua load path
luaAddScriptFolderToLoadPath(lua_state, profile_path.string().c_str());
luaAddScriptFolderToLoadPath(lua_state, config.profile_path.string().c_str());
// Now call our function in a lua script
if (0 != luaL_dofile(lua_state, profile_path.string().c_str()))
if (0 != luaL_dofile(lua_state, config.profile_path.string().c_str()))
{
std::cerr << lua_tostring(lua_state, -1) << " occured in scripting block" << std::endl;
return false;
std::stringstream msg;
msg << lua_tostring(lua_state, -1) << " occured in scripting block";
throw osrm::exception(msg.str());
}
if (0 != luaL_dostring(lua_state, "return traffic_signal_penalty\n"))
{
std::cerr << lua_tostring(lua_state, -1) << " occured in scripting block" << std::endl;
return false;
std::stringstream msg;
msg << lua_tostring(lua_state, -1) << " occured in scripting block";
throw osrm::exception(msg.str());
}
speed_profile.traffic_signal_penalty = 10 * lua_tointeger(lua_state, -1);
SimpleLogger().Write(logDEBUG)
@@ -486,96 +291,140 @@ Prepare::SetupScriptingEnvironment(lua_State *lua_state,
if (0 != luaL_dostring(lua_state, "return u_turn_penalty\n"))
{
std::cerr << lua_tostring(lua_state, -1) << " occured in scripting block" << std::endl;
return false;
std::stringstream msg;
msg << lua_tostring(lua_state, -1) << " occured in scripting block";
throw osrm::exception(msg.str());
}
speed_profile.u_turn_penalty = 10 * lua_tointeger(lua_state, -1);
speed_profile.has_turn_penalty_function = lua_function_exists(lua_state, "turn_function");
return true;
}
/**
\brief Build load restrictions from .restriction file
*/
std::shared_ptr<RestrictionMap> Prepare::LoadRestrictionMap()
{
boost::filesystem::ifstream input_stream(config.restrictions_path, std::ios::in | std::ios::binary);
std::vector<TurnRestriction> restriction_list;
loadRestrictionsFromFile(input_stream, restriction_list);
SimpleLogger().Write() << " - " << restriction_list.size() << " restrictions.";
return std::make_shared<RestrictionMap>(restriction_list);
}
/**
\brief Load node based graph from .osrm file
*/
std::shared_ptr<NodeBasedDynamicGraph>
Prepare::LoadNodeBasedGraph(std::vector<NodeID> &barrier_node_list,
std::vector<NodeID> &traffic_light_list,
std::vector<QueryNode>& internal_to_external_node_map)
{
std::vector<NodeBasedEdge> edge_list;
boost::filesystem::ifstream input_stream(config.osrm_input_path, std::ios::in | std::ios::binary);
NodeID number_of_node_based_nodes = loadNodesFromFile(input_stream,
barrier_node_list, traffic_light_list,
internal_to_external_node_map);
SimpleLogger().Write() << " - " << barrier_node_list.size() << " bollard nodes, "
<< traffic_light_list.size() << " traffic lights";
loadEdgesFromFile(input_stream, edge_list);
if (edge_list.empty())
{
SimpleLogger().Write(logWARNING) << "The input data is empty, exiting.";
return std::shared_ptr<NodeBasedDynamicGraph>();
}
return NodeBasedDynamicGraphFromImportEdges(number_of_node_based_nodes, edge_list);
}
/**
\brief Building an edge-expanded graph from node-based input and turn restrictions
*/
std::size_t
Prepare::BuildEdgeExpandedGraph(lua_State *lua_state,
NodeID number_of_node_based_nodes,
std::pair<std::size_t, std::size_t>
Prepare::BuildEdgeExpandedGraph(std::vector<QueryNode> &internal_to_external_node_map,
std::vector<EdgeBasedNode> &node_based_edge_list,
DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile)
DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list)
{
SimpleLogger().Write() << "Generating edge-expanded graph representation";
std::shared_ptr<NodeBasedDynamicGraph> node_based_graph =
NodeBasedDynamicGraphFromImportEdges(number_of_node_based_nodes, edge_list);
std::unique_ptr<RestrictionMap> restriction_map = osrm::make_unique<RestrictionMap>(restriction_list);
std::shared_ptr<EdgeBasedGraphFactory> edge_based_graph_factory =
std::make_shared<EdgeBasedGraphFactory>(node_based_graph,
std::move(restriction_map),
barrier_node_list,
traffic_light_list,
internal_to_external_node_map,
speed_profile);
edge_list.clear();
edge_list.shrink_to_fit();
lua_State *lua_state = luaL_newstate();
luabind::open(lua_state);
edge_based_graph_factory->Run(edge_out, geometry_filename, lua_state);
EdgeBasedGraphFactory::SpeedProfileProperties speed_profile;
restriction_list.clear();
restriction_list.shrink_to_fit();
barrier_node_list.clear();
barrier_node_list.shrink_to_fit();
traffic_light_list.clear();
traffic_light_list.shrink_to_fit();
SetupScriptingEnvironment(lua_state, speed_profile);
auto barrier_node_list = osrm::make_unique<std::vector<NodeID>>();
auto traffic_light_list = osrm::make_unique<std::vector<NodeID>>();
auto restriction_map = LoadRestrictionMap();
auto node_based_graph = LoadNodeBasedGraph(*barrier_node_list, *traffic_light_list, internal_to_external_node_map);
const std::size_t number_of_node_based_nodes = node_based_graph->GetNumberOfNodes();
EdgeBasedGraphFactory edge_based_graph_factory(node_based_graph,
restriction_map,
std::move(barrier_node_list),
std::move(traffic_light_list),
internal_to_external_node_map,
speed_profile);
edge_based_graph_factory.Run(config.edge_output_path, config.geometry_output_path, lua_state);
lua_close(lua_state);
const std::size_t number_of_edge_based_nodes =
edge_based_graph_factory->GetNumberOfEdgeBasedNodes();
edge_based_graph_factory.GetNumberOfEdgeBasedNodes();
BOOST_ASSERT(number_of_edge_based_nodes != std::numeric_limits<unsigned>::max());
#ifndef WIN32
static_assert(sizeof(EdgeBasedEdge) == 16,
"changing ImportEdge type has influence on memory consumption!");
#endif
edge_based_graph_factory->GetEdgeBasedEdges(edge_based_edge_list);
edge_based_graph_factory->GetEdgeBasedNodes(node_based_edge_list);
edge_based_graph_factory.GetEdgeBasedEdges(edge_based_edge_list);
edge_based_graph_factory.GetEdgeBasedNodes(node_based_edge_list);
edge_based_graph_factory.reset();
node_based_graph.reset();
return std::make_pair(number_of_node_based_nodes, number_of_edge_based_nodes);
}
return number_of_edge_based_nodes;
/**
\brief Build contracted graph.
*/
void Prepare::ContractGraph(const std::size_t number_of_edge_based_nodes,
DeallocatingVector<EdgeBasedEdge>& edge_based_edge_list,
DeallocatingVector<QueryEdge>& contracted_edge_list)
{
Contractor contractor(number_of_edge_based_nodes, edge_based_edge_list);
contractor.Run();
contractor.GetEdges(contracted_edge_list);
}
/**
\brief Writing info on original (node-based) nodes
*/
void Prepare::WriteNodeMapping()
void Prepare::WriteNodeMapping(std::unique_ptr<std::vector<QueryNode>> internal_to_external_node_map)
{
SimpleLogger().Write() << "writing node map ...";
boost::filesystem::ofstream node_stream(node_filename, std::ios::binary);
const unsigned size_of_mapping = internal_to_external_node_map.size();
boost::filesystem::ofstream node_stream(config.node_output_path, std::ios::binary);
const unsigned size_of_mapping = internal_to_external_node_map->size();
node_stream.write((char *)&size_of_mapping, sizeof(unsigned));
if (size_of_mapping > 0)
{
node_stream.write((char *)&(internal_to_external_node_map[0]),
node_stream.write((char *) internal_to_external_node_map->data(),
size_of_mapping * sizeof(QueryNode));
}
node_stream.close();
internal_to_external_node_map.clear();
internal_to_external_node_map.shrink_to_fit();
}
/**
\brief Building rtree-based nearest-neighbor data structure
Saves info to files: '.ramIndex' and '.fileIndex'.
Saves tree into '.ramIndex' and leaves into '.fileIndex'.
*/
void Prepare::BuildRTree(std::vector<EdgeBasedNode> &node_based_edge_list)
void Prepare::BuildRTree(const std::vector<EdgeBasedNode> &node_based_edge_list, const std::vector<QueryNode>& internal_to_external_node_map)
{
SimpleLogger().Write() << "building r-tree ...";
StaticRTree<EdgeBasedNode>(node_based_edge_list,
rtree_nodes_path.c_str(),
rtree_leafs_path.c_str(),
internal_to_external_node_map);
StaticRTree<EdgeBasedNode>(node_based_edge_list, config.rtree_nodes_output_path.c_str(),
config.rtree_leafs_output_path.c_str(), internal_to_external_node_map);
}
+24 -34
View File
@@ -28,11 +28,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef PROCESSING_CHAIN_HPP
#define PROCESSING_CHAIN_HPP
#include "contractor_options.hpp"
#include "edge_based_graph_factory.hpp"
#include "../data_structures/query_edge.hpp"
#include "../data_structures/static_graph.hpp"
class FingerPrint;
struct EdgeBasedNode;
struct lua_State;
@@ -50,46 +50,36 @@ class Prepare
using InputEdge = DynamicGraph<EdgeData>::InputEdge;
using StaticEdge = StaticGraph<EdgeData>::InputEdge;
explicit Prepare();
explicit Prepare(const ContractorConfig& contractor_config)
: config(contractor_config) {}
Prepare(const Prepare &) = delete;
~Prepare();
int Process(int argc, char *argv[]);
int Run();
protected:
bool ParseArguments(int argc, char *argv[]);
void CheckRestrictionsFile(FingerPrint &fingerprint_orig);
bool SetupScriptingEnvironment(lua_State *myLuaState,
void SetupScriptingEnvironment(lua_State *myLuaState,
EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile);
std::size_t BuildEdgeExpandedGraph(lua_State *myLuaState,
NodeID nodeBasedNodeNumber,
std::vector<EdgeBasedNode> &nodeBasedEdgeList,
DeallocatingVector<EdgeBasedEdge> &edgeBasedEdgeList,
EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile);
void WriteNodeMapping();
void BuildRTree(std::vector<EdgeBasedNode> &node_based_edge_list);
std::shared_ptr<RestrictionMap> LoadRestrictionMap();
unsigned CalculateEdgeChecksum(std::unique_ptr<std::vector<EdgeBasedNode>> node_based_edge_list);
void ContractGraph(const std::size_t number_of_edge_based_nodes,
DeallocatingVector<EdgeBasedEdge>& edge_based_edge_list,
DeallocatingVector<QueryEdge>& contracted_edge_list);
std::size_t WriteContractedGraph(unsigned number_of_edge_based_nodes,
std::unique_ptr<std::vector<EdgeBasedNode>> node_based_edge_list,
std::unique_ptr<DeallocatingVector<QueryEdge>> contracted_edge_list);
std::shared_ptr<NodeBasedDynamicGraph> LoadNodeBasedGraph(std::vector<NodeID> &barrier_node_list,
std::vector<NodeID> &traffic_light_list,
std::vector<QueryNode>& internal_to_external_node_map);
std::pair<std::size_t, std::size_t>
BuildEdgeExpandedGraph(std::vector<QueryNode> &internal_to_external_node_map,
std::vector<EdgeBasedNode> &node_based_edge_list,
DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list);
void WriteNodeMapping(std::unique_ptr<std::vector<QueryNode>> internal_to_external_node_map);
void BuildRTree(const std::vector<EdgeBasedNode> &node_based_edge_list,
const std::vector<QueryNode> &internal_to_external_node_map);
private:
std::vector<QueryNode> internal_to_external_node_map;
std::vector<TurnRestriction> restriction_list;
std::vector<NodeID> barrier_node_list;
std::vector<NodeID> traffic_light_list;
std::vector<ImportEdge> edge_list;
unsigned requested_num_threads;
boost::filesystem::path config_file_path;
boost::filesystem::path input_path;
boost::filesystem::path restrictions_path;
boost::filesystem::path preinfo_path;
boost::filesystem::path profile_path;
std::string node_filename;
std::string edge_out;
std::string info_out;
std::string geometry_filename;
std::string graph_out;
std::string rtree_nodes_path;
std::string rtree_leafs_path;
ContractorConfig config;
};
#endif // PROCESSING_CHAIN_HPP
-483
View File
@@ -1,483 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
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.
*/
#include <osrm/Coordinate.h>
#include "../Util/MercatorUtil.h"
#ifndef NDEBUG
#include "../Util/simple_logger.hpp"
#endif
#include "../Util/StringUtil.h"
#include <boost/assert.hpp>
#ifndef NDEBUG
#include <bitset>
#endif
#include <iostream>
#include <limits>
FixedPointCoordinate::FixedPointCoordinate()
: lat(std::numeric_limits<int>::min()), lon(std::numeric_limits<int>::min())
{
}
FixedPointCoordinate::FixedPointCoordinate(int lat, int lon) : lat(lat), lon(lon)
{
#ifndef NDEBUG
if (0 != (std::abs(lat) >> 30))
{
std::bitset<32> y_coordinate_vector(lat);
SimpleLogger().Write(logDEBUG) << "broken lat: " << lat
<< ", bits: " << y_coordinate_vector;
}
if (0 != (std::abs(lon) >> 30))
{
std::bitset<32> x_coordinate_vector(lon);
SimpleLogger().Write(logDEBUG) << "broken lon: " << lon
<< ", bits: " << x_coordinate_vector;
}
#endif
}
void FixedPointCoordinate::Reset()
{
lat = std::numeric_limits<int>::min();
lon = std::numeric_limits<int>::min();
}
bool FixedPointCoordinate::isSet() const
{
return (std::numeric_limits<int>::min() != lat) && (std::numeric_limits<int>::min() != lon);
}
bool FixedPointCoordinate::is_valid() const
{
if (lat > 90 * COORDINATE_PRECISION || lat < -90 * COORDINATE_PRECISION ||
lon > 180 * COORDINATE_PRECISION || lon < -180 * COORDINATE_PRECISION)
{
return false;
}
return true;
}
bool FixedPointCoordinate::operator==(const FixedPointCoordinate &other) const
{
return lat == other.lat && lon == other.lon;
}
double FixedPointCoordinate::ApproximateDistance(const int lat1,
const int lon1,
const int lat2,
const int lon2)
{
BOOST_ASSERT(lat1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lat2 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon2 != std::numeric_limits<int>::min());
double RAD = 0.017453292519943295769236907684886;
double lt1 = lat1 / COORDINATE_PRECISION;
double ln1 = lon1 / COORDINATE_PRECISION;
double lt2 = lat2 / COORDINATE_PRECISION;
double ln2 = lon2 / COORDINATE_PRECISION;
double dlat1 = lt1 * (RAD);
double dlong1 = ln1 * (RAD);
double dlat2 = lt2 * (RAD);
double dlong2 = ln2 * (RAD);
double dLong = dlong1 - dlong2;
double dLat = dlat1 - dlat2;
double aHarv = pow(sin(dLat / 2.0), 2.0) + cos(dlat1) * cos(dlat2) * pow(sin(dLong / 2.), 2);
double cHarv = 2. * atan2(sqrt(aHarv), sqrt(1.0 - aHarv));
// earth radius varies between 6,356.750-6,378.135 km (3,949.901-3,963.189mi)
// The IUGG value for the equatorial radius is 6378.137 km (3963.19 miles)
const double earth = 6372797.560856;
return earth * cHarv;
}
double FixedPointCoordinate::ApproximateDistance(const FixedPointCoordinate &coordinate_1,
const FixedPointCoordinate &coordinate_2)
{
return ApproximateDistance(
coordinate_1.lat, coordinate_1.lon, coordinate_2.lat, coordinate_2.lon);
}
float FixedPointCoordinate::ApproximateEuclideanDistance(const FixedPointCoordinate &coordinate_1,
const FixedPointCoordinate &coordinate_2)
{
return ApproximateEuclideanDistance(
coordinate_1.lat, coordinate_1.lon, coordinate_2.lat, coordinate_2.lon);
}
float FixedPointCoordinate::ApproximateEuclideanDistance(const int lat1,
const int lon1,
const int lat2,
const int lon2)
{
BOOST_ASSERT(lat1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lat2 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon2 != std::numeric_limits<int>::min());
const float RAD = 0.017453292519943295769236907684886f;
const float float_lat1 = (lat1 / COORDINATE_PRECISION) * RAD;
const float float_lon1 = (lon1 / COORDINATE_PRECISION) * RAD;
const float float_lat2 = (lat2 / COORDINATE_PRECISION) * RAD;
const float float_lon2 = (lon2 / COORDINATE_PRECISION) * RAD;
const float x_value = (float_lon2 - float_lon1) * cos((float_lat1 + float_lat2) / 2.f);
const float y_value = float_lat2 - float_lat1;
const float earth_radius = 6372797.560856f;
return sqrt(x_value * x_value + y_value * y_value) * earth_radius;
}
float
FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &source_coordinate,
const FixedPointCoordinate &target_coordinate,
const FixedPointCoordinate &point)
{
// initialize values
const float x_value = static_cast<float>(lat2y(point.lat / COORDINATE_PRECISION));
const float y_value = point.lon / COORDINATE_PRECISION;
float a = static_cast<float>(lat2y(source_coordinate.lat / COORDINATE_PRECISION));
float b = source_coordinate.lon / COORDINATE_PRECISION;
float c = static_cast<float>(lat2y(target_coordinate.lat / COORDINATE_PRECISION));
float d = target_coordinate.lon / COORDINATE_PRECISION;
float p, q;
if (std::abs(a - c) > std::numeric_limits<float>::epsilon())
{
const float slope = (d - b) / (c - a); // slope
// Projection of (x,y) on line joining (a,b) and (c,d)
p = ((x_value + (slope * y_value)) + (slope * slope * a - slope * b)) /
(1.f + slope * slope);
q = b + slope * (p - a);
}
else
{
p = c;
q = y_value;
}
float ratio;
bool inverse_ratio = false;
// straight line segment on equator
if (std::abs(c) < std::numeric_limits<float>::epsilon() &&
std::abs(a) < std::numeric_limits<float>::epsilon())
{
ratio = (q - b) / (d - b);
}
else
{
if (std::abs(c) < std::numeric_limits<float>::epsilon())
{
// swap start/end
std::swap(a, c);
std::swap(b, d);
inverse_ratio = true;
}
float nY = (d * p - c * q) / (a * d - b * c);
// discretize the result to coordinate precision. it's a hack!
if (std::abs(nY) < (1.f / COORDINATE_PRECISION))
{
nY = 0.f;
}
// compute ratio
ratio = (p - nY * a) / c;
}
if (std::isnan(ratio))
{
ratio = (target_coordinate == point ? 1.f : 0.f);
}
else if (std::abs(ratio) <= std::numeric_limits<float>::epsilon())
{
ratio = 0.f;
}
else if (std::abs(ratio - 1.f) <= std::numeric_limits<float>::epsilon())
{
ratio = 1.f;
}
// we need to do this, if we switched start/end coordinates
if (inverse_ratio)
{
ratio = 1.0f - ratio;
}
// compute the nearest location
FixedPointCoordinate nearest_location;
BOOST_ASSERT(!std::isnan(ratio));
if (ratio <= 0.f)
{ // point is "left" of edge
nearest_location = source_coordinate;
}
else if (ratio >= 1.f)
{ // point is "right" of edge
nearest_location = target_coordinate;
}
else
{ // point lies in between
nearest_location.lat = static_cast<int>(y2lat(p) * COORDINATE_PRECISION);
nearest_location.lon = static_cast<int>(q * COORDINATE_PRECISION);
}
BOOST_ASSERT(nearest_location.is_valid());
return FixedPointCoordinate::ApproximateEuclideanDistance(point, nearest_location);
}
float FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location,
FixedPointCoordinate &nearest_location,
float &ratio)
{
BOOST_ASSERT(query_location.is_valid());
// initialize values
const double x = lat2y(query_location.lat / COORDINATE_PRECISION);
const double y = query_location.lon / COORDINATE_PRECISION;
const double a = lat2y(segment_source.lat / COORDINATE_PRECISION);
const double b = segment_source.lon / COORDINATE_PRECISION;
const double c = lat2y(segment_target.lat / COORDINATE_PRECISION);
const double d = segment_target.lon / COORDINATE_PRECISION;
double p, q /*,mX*/, nY;
if (std::abs(a - c) > std::numeric_limits<double>::epsilon())
{
const double m = (d - b) / (c - a); // slope
// Projection of (x,y) on line joining (a,b) and (c,d)
p = ((x + (m * y)) + (m * m * a - m * b)) / (1.f + m * m);
q = b + m * (p - a);
}
else
{
p = c;
q = y;
}
nY = (d * p - c * q) / (a * d - b * c);
// discretize the result to coordinate precision. it's a hack!
if (std::abs(nY) < (1.f / COORDINATE_PRECISION))
{
nY = 0.f;
}
// compute ratio
ratio = (p - nY * a) / c; // These values are actually n/m+n and m/m+n , we need
// not calculate the explicit values of m an n as we
// are just interested in the ratio
if (std::isnan(ratio))
{
ratio = (segment_target == query_location ? 1.f : 0.f);
}
else if (std::abs(ratio) <= std::numeric_limits<double>::epsilon())
{
ratio = 0.f;
}
else if (std::abs(ratio - 1.f) <= std::numeric_limits<double>::epsilon())
{
ratio = 1.f;
}
// compute nearest location
BOOST_ASSERT(!std::isnan(ratio));
if (ratio <= 0.f)
{
nearest_location = segment_source;
}
else if (ratio >= 1.f)
{
nearest_location = segment_target;
}
else
{
// point lies in between
nearest_location.lat = static_cast<int>(y2lat(p) * COORDINATE_PRECISION);
nearest_location.lon = static_cast<int>(q * COORDINATE_PRECISION);
}
BOOST_ASSERT(nearest_location.is_valid());
const float approximate_distance =
FixedPointCoordinate::ApproximateEuclideanDistance(query_location, nearest_location);
BOOST_ASSERT(0. <= approximate_distance);
return approximate_distance;
}
void FixedPointCoordinate::convertInternalLatLonToString(const int value, std::string &output)
{
char buffer[12];
buffer[11] = 0; // zero termination
output = printInt<11, 6>(buffer, value);
}
void FixedPointCoordinate::convertInternalCoordinateToString(const FixedPointCoordinate &coord,
std::string &output)
{
std::string tmp;
tmp.reserve(23);
convertInternalLatLonToString(coord.lon, tmp);
output = tmp;
output += ",";
convertInternalLatLonToString(coord.lat, tmp);
output += tmp;
}
void
FixedPointCoordinate::convertInternalReversedCoordinateToString(const FixedPointCoordinate &coord,
std::string &output)
{
std::string tmp;
tmp.reserve(23);
convertInternalLatLonToString(coord.lat, tmp);
output = tmp;
output += ",";
convertInternalLatLonToString(coord.lon, tmp);
output += tmp;
}
void FixedPointCoordinate::Output(std::ostream &out) const
{
out << "(" << lat / COORDINATE_PRECISION << "," << lon / COORDINATE_PRECISION << ")";
}
float FixedPointCoordinate::GetBearing(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate)
{
const float lon_diff =
second_coordinate.lon / COORDINATE_PRECISION - first_coordinate.lon / COORDINATE_PRECISION;
const float lon_delta = DegreeToRadian(lon_diff);
const float lat1 = DegreeToRadian(first_coordinate.lat / COORDINATE_PRECISION);
const float lat2 = DegreeToRadian(second_coordinate.lat / COORDINATE_PRECISION);
const float y = sin(lon_delta) * cos(lat2);
const float x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lon_delta);
float result = RadianToDegree(std::atan2(y, x));
while (result < 0.f)
{
result += 360.f;
}
while (result >= 360.f)
{
result -= 360.f;
}
return result;
}
float FixedPointCoordinate::GetBearing(const FixedPointCoordinate &other) const
{
const float lon_delta =
DegreeToRadian(lon / COORDINATE_PRECISION - other.lon / COORDINATE_PRECISION);
const float lat1 = DegreeToRadian(other.lat / COORDINATE_PRECISION);
const float lat2 = DegreeToRadian(lat / COORDINATE_PRECISION);
const float y_value = std::sin(lon_delta) * std::cos(lat2);
const float x_value =
std::cos(lat1) * std::sin(lat2) - std::sin(lat1) * std::cos(lat2) * std::cos(lon_delta);
float result = RadianToDegree(std::atan2(y_value, x_value));
while (result < 0.f)
{
result += 360.f;
}
while (result >= 360.f)
{
result -= 360.f;
}
return result;
}
float FixedPointCoordinate::DegreeToRadian(const float degree)
{
return degree * (static_cast<float>(M_PI) / 180.f);
}
float FixedPointCoordinate::RadianToDegree(const float radian)
{
return radian * (180.f * static_cast<float>(M_1_PI));
}
// This distance computation does integer arithmetic only and is a lot faster than
// the other distance function which are numerically correct('ish).
// It preserves some order among the elements that make it useful for certain purposes
int FixedPointCoordinate::OrderedPerpendicularDistanceApproximation(
const FixedPointCoordinate &input_point,
const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target)
{
// initialize values
const float x = static_cast<float>(lat2y(input_point.lat / COORDINATE_PRECISION));
const float y = input_point.lon / COORDINATE_PRECISION;
const float a = static_cast<float>(lat2y(segment_source.lat / COORDINATE_PRECISION));
const float b = segment_source.lon / COORDINATE_PRECISION;
const float c = static_cast<float>(lat2y(segment_target.lat / COORDINATE_PRECISION));
const float d = segment_target.lon / COORDINATE_PRECISION;
float p, q;
if (a == c)
{
p = c;
q = y;
}
else
{
const float m = (d - b) / (c - a); // slope
// Projection of (x,y) on line joining (a,b) and (c,d)
p = ((x + (m * y)) + (m * m * a - m * b)) / (1.f + m * m);
q = b + m * (p - a);
}
const float nY = (d * p - c * q) / (a * d - b * c);
float ratio = (p - nY * a) / c; // These values are actually n/m+n and m/m+n , we need
// not calculate the explicit values of m an n as we
// are just interested in the ratio
if (std::isnan(ratio))
{
ratio = (segment_target == input_point) ? 1.f : 0.f;
}
// compute target quasi-location
int dx, dy;
if (ratio < 0.f)
{
dx = input_point.lon - segment_source.lon;
dy = input_point.lat - segment_source.lat;
}
else if (ratio > 1.f)
{
dx = input_point.lon - segment_target.lon;
dy = input_point.lat - segment_target.lat;
}
else
{
// point lies in between
dx = input_point.lon - static_cast<int>(q * COORDINATE_PRECISION);
dy = input_point.lat - static_cast<int>(y2lat(p) * COORDINATE_PRECISION);
}
// return an approximation in the plane
return static_cast<int>(sqrt(dx * dx + dy * dy));
}
-123
View File
@@ -1,123 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
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 INPUT_READER_FACTORY_H
#define INPUT_READER_FACTORY_H
#include <boost/assert.hpp>
#include <bzlib.h>
#include <libxml/xmlreader.h>
struct BZ2Context
{
FILE *file;
BZFILE *bz2;
int error;
int nUnused;
char unused[BZ_MAX_UNUSED];
};
int readFromBz2Stream(void *pointer, char *buffer, int len)
{
void *unusedTmpVoid = nullptr;
char *unusedTmp = nullptr;
BZ2Context *context = (BZ2Context *)pointer;
int read = 0;
while (0 == read &&
!(BZ_STREAM_END == context->error && 0 == context->nUnused && feof(context->file)))
{
read = BZ2_bzRead(&context->error, context->bz2, buffer, len);
if (BZ_OK == context->error)
{
return read;
}
else if (BZ_STREAM_END == context->error)
{
BZ2_bzReadGetUnused(&context->error, context->bz2, &unusedTmpVoid, &context->nUnused);
BOOST_ASSERT_MSG(BZ_OK == context->error, "Could not BZ2_bzReadGetUnused");
unusedTmp = (char *)unusedTmpVoid;
for (int i = 0; i < context->nUnused; i++)
{
context->unused[i] = unusedTmp[i];
}
BZ2_bzReadClose(&context->error, context->bz2);
BOOST_ASSERT_MSG(BZ_OK == context->error, "Could not BZ2_bzReadClose");
context->error = BZ_STREAM_END; // set to the stream end for next call to this function
if (0 == context->nUnused && feof(context->file))
{
return read;
}
else
{
context->bz2 = BZ2_bzReadOpen(
&context->error, context->file, 0, 0, context->unused, context->nUnused);
BOOST_ASSERT_MSG(nullptr != context->bz2, "Could not open file");
}
}
else
{
BOOST_ASSERT_MSG(false, "Could not read bz2 file");
}
}
return read;
}
int closeBz2Stream(void *pointer)
{
BZ2Context *context = (BZ2Context *)pointer;
fclose(context->file);
delete context;
return 0;
}
xmlTextReaderPtr inputReaderFactory(const char *name)
{
std::string inputName(name);
if (inputName.find(".osm.bz2") != std::string::npos)
{
BZ2Context *context = new BZ2Context();
context->error = false;
context->file = fopen(name, "r");
int error;
context->bz2 =
BZ2_bzReadOpen(&error, context->file, 0, 0, context->unused, context->nUnused);
if (context->bz2 == nullptr || context->file == nullptr)
{
delete context;
return nullptr;
}
return xmlReaderForIO(readFromBz2Stream, closeBz2Stream, (void *)context, nullptr, nullptr, 0);
}
else
{
return xmlNewTextReaderFilename(name);
}
}
#endif // INPUT_READER_FACTORY_H
+38 -20
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -36,24 +36,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <type_traits>
#include <unordered_map>
#include <vector>
#include <cstring>
template <typename NodeID, typename Key> class ArrayStorage
{
public:
explicit ArrayStorage(size_t size) : positions(new Key[size])
{
memset(positions, 0, size * sizeof(Key));
}
explicit ArrayStorage(size_t size) : positions(size, 0) {}
~ArrayStorage() { delete[] positions; }
~ArrayStorage() {}
Key &operator[](NodeID node) { return positions[node]; }
Key peek_index(const NodeID node) const { return positions[node]; }
void Clear() {}
private:
Key *positions;
std::vector<Key> positions;
};
template <typename NodeID, typename Key> class MapStorage
@@ -65,6 +63,16 @@ template <typename NodeID, typename Key> class MapStorage
void Clear() { nodes.clear(); }
Key peek_index(const NodeID node) const
{
const auto iter = nodes.find(node);
if (nodes.end() != iter)
{
return iter->second;
}
return std::numeric_limits<Key>::max();
}
private:
std::map<NodeID, Key> nodes;
};
@@ -76,6 +84,16 @@ template <typename NodeID, typename Key> class UnorderedMapStorage
Key &operator[](const NodeID node) { return nodes[node]; }
Key peek_index(const NodeID node) const
{
const auto iter = nodes.find(node);
if (std::end(nodes) != iter)
{
return iter->second;
}
return std::numeric_limits<Key>::max();
}
Key const &operator[](const NodeID node) const
{
auto iter = nodes.find(node);
@@ -132,13 +150,13 @@ class BinaryHeap
Data &GetData(NodeID node)
{
const Key index = node_index[node];
const Key index = node_index.peek_index(node);
return inserted_nodes[index].data;
}
Data const &GetData(NodeID node) const
{
const Key index = node_index[node];
const Key index = node_index.peek_index(node);
return inserted_nodes[index].data;
}
@@ -148,17 +166,17 @@ class BinaryHeap
return inserted_nodes[index].weight;
}
bool WasRemoved(const NodeID node)
bool WasRemoved(const NodeID node) const
{
BOOST_ASSERT(WasInserted(node));
const Key index = node_index[node];
const Key index = node_index.peek_index(node);
return inserted_nodes[index].key == 0;
}
bool WasInserted(const NodeID node)
bool WasInserted(const NodeID node) const
{
const Key index = node_index[node];
if (index >= static_cast<Key>(inserted_nodes.size()))
const auto index = node_index.peek_index(node);
if (index >= static_cast<decltype(index)>(inserted_nodes.size()))
{
return false;
}
@@ -200,7 +218,7 @@ class BinaryHeap
void DecreaseKey(NodeID node, Weight weight)
{
BOOST_ASSERT(std::numeric_limits<NodeID>::max() != node);
const Key &index = node_index[node];
const Key &index = node_index.peek_index(node);
Key &key = inserted_nodes[index].key;
BOOST_ASSERT(key >= 0);
@@ -235,12 +253,12 @@ class BinaryHeap
{
const Key droppingIndex = heap[key].index;
const Weight weight = heap[key].weight;
const Key heap_size = static_cast<Key>(heap.size());
Key nextKey = key << 1;
while (nextKey < static_cast<Key>(heap.size()))
while (nextKey < heap_size)
{
const Key nextKeyOther = nextKey + 1;
if ((nextKeyOther < static_cast<Key>(heap.size())) &&
(heap[nextKey].weight > heap[nextKeyOther].weight))
if ((nextKeyOther < heap_size) && (heap[nextKey].weight > heap[nextKeyOther].weight))
{
nextKey = nextKeyOther;
}
@@ -279,7 +297,7 @@ class BinaryHeap
void CheckHeap()
{
#ifndef NDEBUG
for (Key i = 2; i < (Key)heap.size(); ++i)
for (std::size_t i = 2; i < heap.size(); ++i)
{
BOOST_ASSERT(heap[i].weight >= heap[i >> 1].weight);
}
+9 -7
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -40,9 +40,10 @@ template <typename Data> class ConcurrentQueue
inline void push(const Data &data)
{
std::unique_lock<std::mutex> lock(m_mutex);
m_not_full.wait(lock,
[this]
{ return m_internal_queue.size() < m_internal_queue.capacity(); });
m_not_full.wait(lock, [this]
{
return m_internal_queue.size() < m_internal_queue.capacity();
});
m_internal_queue.push_back(data);
m_not_empty.notify_one();
}
@@ -52,9 +53,10 @@ template <typename Data> class ConcurrentQueue
inline void wait_and_pop(Data &popped_value)
{
std::unique_lock<std::mutex> lock(m_mutex);
m_not_empty.wait(lock,
[this]
{ return !m_internal_queue.empty(); });
m_not_empty.wait(lock, [this]
{
return !m_internal_queue.empty();
});
popped_value = m_internal_queue.front();
m_internal_queue.pop_front();
m_not_full.notify_one();
+87
View File
@@ -0,0 +1,87 @@
/*
Copyright (c) 2015, 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.
*/
#include "coordinate_calculation.hpp"
#ifndef NDEBUG
#include "../util/simple_logger.hpp"
#endif
#include <osrm/coordinate.hpp>
#ifndef NDEBUG
#include <bitset>
#endif
#include <iostream>
#include <limits>
FixedPointCoordinate::FixedPointCoordinate()
: lat(std::numeric_limits<int>::min()), lon(std::numeric_limits<int>::min())
{
}
FixedPointCoordinate::FixedPointCoordinate(int lat, int lon) : lat(lat), lon(lon)
{
#ifndef NDEBUG
if (0 != (std::abs(lat) >> 30))
{
std::bitset<32> y_coordinate_vector(lat);
SimpleLogger().Write(logDEBUG) << "broken lat: " << lat
<< ", bits: " << y_coordinate_vector;
}
if (0 != (std::abs(lon) >> 30))
{
std::bitset<32> x_coordinate_vector(lon);
SimpleLogger().Write(logDEBUG) << "broken lon: " << lon
<< ", bits: " << x_coordinate_vector;
}
#endif
}
bool FixedPointCoordinate::is_valid() const
{
if (lat > 90 * COORDINATE_PRECISION || lat < -90 * COORDINATE_PRECISION ||
lon > 180 * COORDINATE_PRECISION || lon < -180 * COORDINATE_PRECISION)
{
return false;
}
return true;
}
bool FixedPointCoordinate::operator==(const FixedPointCoordinate &other) const
{
return lat == other.lat && lon == other.lon;
}
void FixedPointCoordinate::output(std::ostream &out) const
{
out << "(" << lat / COORDINATE_PRECISION << "," << lon / COORDINATE_PRECISION << ")";
}
float FixedPointCoordinate::bearing(const FixedPointCoordinate &other) const
{
return coordinate_calculation::bearing(other, *this);
}
+268
View File
@@ -0,0 +1,268 @@
/*
Copyright (c) 2015, 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.
*/
#include "coordinate_calculation.hpp"
#include "../util/mercator.hpp"
#include "../util/string_util.hpp"
#include <boost/assert.hpp>
#include <osrm/coordinate.hpp>
#include <cmath>
#include <limits>
namespace
{
constexpr static const float RAD = 0.017453292519943295769236907684886f;
// earth radius varies between 6,356.750-6,378.135 km (3,949.901-3,963.189mi)
// The IUGG value for the equatorial radius is 6378.137 km (3963.19 miles)
constexpr static const float earth_radius = 6372797.560856f;
}
double coordinate_calculation::great_circle_distance(const int lat1,
const int lon1,
const int lat2,
const int lon2)
{
BOOST_ASSERT(lat1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lat2 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon2 != std::numeric_limits<int>::min());
const double lt1 = lat1 / COORDINATE_PRECISION;
const double ln1 = lon1 / COORDINATE_PRECISION;
const double lt2 = lat2 / COORDINATE_PRECISION;
const double ln2 = lon2 / COORDINATE_PRECISION;
const double dlat1 = lt1 * (RAD);
const double dlong1 = ln1 * (RAD);
const double dlat2 = lt2 * (RAD);
const double dlong2 = ln2 * (RAD);
const double dLong = dlong1 - dlong2;
const double dLat = dlat1 - dlat2;
const double aHarv = std::pow(std::sin(dLat / 2.0), 2.0) +
std::cos(dlat1) * std::cos(dlat2) * std::pow(std::sin(dLong / 2.), 2);
const double cHarv = 2. * std::atan2(std::sqrt(aHarv), std::sqrt(1.0 - aHarv));
return earth_radius * cHarv;
}
double coordinate_calculation::great_circle_distance(const FixedPointCoordinate &coordinate_1,
const FixedPointCoordinate &coordinate_2)
{
return great_circle_distance(coordinate_1.lat, coordinate_1.lon, coordinate_2.lat,
coordinate_2.lon);
}
float coordinate_calculation::euclidean_distance(const FixedPointCoordinate &coordinate_1,
const FixedPointCoordinate &coordinate_2)
{
return euclidean_distance(coordinate_1.lat, coordinate_1.lon, coordinate_2.lat,
coordinate_2.lon);
}
float coordinate_calculation::euclidean_distance(const int lat1,
const int lon1,
const int lat2,
const int lon2)
{
BOOST_ASSERT(lat1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lat2 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon2 != std::numeric_limits<int>::min());
const float float_lat1 = (lat1 / COORDINATE_PRECISION) * RAD;
const float float_lon1 = (lon1 / COORDINATE_PRECISION) * RAD;
const float float_lat2 = (lat2 / COORDINATE_PRECISION) * RAD;
const float float_lon2 = (lon2 / COORDINATE_PRECISION) * RAD;
const float x_value = (float_lon2 - float_lon1) * std::cos((float_lat1 + float_lat2) / 2.f);
const float y_value = float_lat2 - float_lat1;
return std::hypot(x_value, y_value) * earth_radius;
}
float coordinate_calculation::perpendicular_distance(const FixedPointCoordinate &source_coordinate,
const FixedPointCoordinate &target_coordinate,
const FixedPointCoordinate &query_location)
{
float ratio;
FixedPointCoordinate nearest_location;
return perpendicular_distance(source_coordinate, target_coordinate, query_location,
nearest_location, ratio);
}
float coordinate_calculation::perpendicular_distance(const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location,
FixedPointCoordinate &nearest_location,
float &ratio)
{
return perpendicular_distance_from_projected_coordinate(
segment_source, segment_target, query_location,
{mercator::lat2y(query_location.lat / COORDINATE_PRECISION),
query_location.lon / COORDINATE_PRECISION},
nearest_location, ratio);
}
float coordinate_calculation::perpendicular_distance_from_projected_coordinate(
const FixedPointCoordinate &source_coordinate,
const FixedPointCoordinate &target_coordinate,
const FixedPointCoordinate &query_location,
const std::pair<double, double> &projected_coordinate)
{
float ratio;
FixedPointCoordinate nearest_location;
return perpendicular_distance_from_projected_coordinate(source_coordinate, target_coordinate,
query_location, projected_coordinate,
nearest_location, ratio);
}
float coordinate_calculation::perpendicular_distance_from_projected_coordinate(
const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location,
const std::pair<double, double> &projected_coordinate,
FixedPointCoordinate &nearest_location,
float &ratio)
{
BOOST_ASSERT(query_location.is_valid());
// initialize values
const double x = projected_coordinate.first;
const double y = projected_coordinate.second;
const double a = mercator::lat2y(segment_source.lat / COORDINATE_PRECISION);
const double b = segment_source.lon / COORDINATE_PRECISION;
const double c = mercator::lat2y(segment_target.lat / COORDINATE_PRECISION);
const double d = segment_target.lon / COORDINATE_PRECISION;
double p, q /*,mX*/, nY;
if (std::abs(a - c) > std::numeric_limits<double>::epsilon())
{
const double m = (d - b) / (c - a); // slope
// Projection of (x,y) on line joining (a,b) and (c,d)
p = ((x + (m * y)) + (m * m * a - m * b)) / (1.f + m * m);
q = b + m * (p - a);
}
else
{
p = c;
q = y;
}
nY = (d * p - c * q) / (a * d - b * c);
// discretize the result to coordinate precision. it's a hack!
if (std::abs(nY) < (1.f / COORDINATE_PRECISION))
{
nY = 0.f;
}
// compute ratio
ratio =
static_cast<float>((p - nY * a) / c); // These values are actually n/m+n and m/m+n , we need
// not calculate the explicit values of m an n as we
// are just interested in the ratio
if (std::isnan(ratio))
{
ratio = (segment_target == query_location ? 1.f : 0.f);
}
else if (std::abs(ratio) <= std::numeric_limits<float>::epsilon())
{
ratio = 0.f;
}
else if (std::abs(ratio - 1.f) <= std::numeric_limits<float>::epsilon())
{
ratio = 1.f;
}
// compute nearest location
BOOST_ASSERT(!std::isnan(ratio));
if (ratio <= 0.f)
{
nearest_location = segment_source;
}
else if (ratio >= 1.f)
{
nearest_location = segment_target;
}
else
{
// point lies in between
nearest_location.lat = static_cast<int>(mercator::y2lat(p) * COORDINATE_PRECISION);
nearest_location.lon = static_cast<int>(q * COORDINATE_PRECISION);
}
BOOST_ASSERT(nearest_location.is_valid());
const float approximate_distance =
coordinate_calculation::euclidean_distance(query_location, nearest_location);
BOOST_ASSERT(0.f <= approximate_distance);
return approximate_distance;
}
void coordinate_calculation::lat_or_lon_to_string(const int value, std::string &output)
{
char buffer[12];
buffer[11] = 0; // zero termination
output = printInt<11, 6>(buffer, value);
}
float coordinate_calculation::deg_to_rad(const float degree)
{
return degree * (static_cast<float>(M_PI) / 180.f);
}
float coordinate_calculation::rad_to_deg(const float radian)
{
return radian * (180.f * static_cast<float>(M_1_PI));
}
float coordinate_calculation::bearing(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate)
{
const float lon_diff =
second_coordinate.lon / COORDINATE_PRECISION - first_coordinate.lon / COORDINATE_PRECISION;
const float lon_delta = deg_to_rad(lon_diff);
const float lat1 = deg_to_rad(first_coordinate.lat / COORDINATE_PRECISION);
const float lat2 = deg_to_rad(second_coordinate.lat / COORDINATE_PRECISION);
const float y = std::sin(lon_delta) * std::cos(lat2);
const float x =
std::cos(lat1) * std::sin(lat2) - std::sin(lat1) * std::cos(lat2) * std::cos(lon_delta);
float result = rad_to_deg(std::atan2(y, x));
while (result < 0.f)
{
result += 360.f;
}
while (result >= 360.f)
{
result -= 360.f;
}
return result;
}
@@ -0,0 +1,82 @@
/*
Copyright (c) 2015, 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 COORDINATE_CALCULATION
#define COORDINATE_CALCULATION
struct FixedPointCoordinate;
#include <string>
#include <utility>
struct coordinate_calculation
{
static double
great_circle_distance(const int lat1, const int lon1, const int lat2, const int lon2);
static double great_circle_distance(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate);
static float euclidean_distance(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate);
static float euclidean_distance(const int lat1, const int lon1, const int lat2, const int lon2);
static void lat_or_lon_to_string(const int value, std::string &output);
static float perpendicular_distance(const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location);
static float perpendicular_distance(const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location,
FixedPointCoordinate &nearest_location,
float &ratio);
static float perpendicular_distance_from_projected_coordinate(
const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location,
const std::pair<double, double> &projected_coordinate);
static float perpendicular_distance_from_projected_coordinate(
const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location,
const std::pair<double, double> &projected_coordinate,
FixedPointCoordinate &nearest_location,
float &ratio);
static float deg_to_rad(const float degree);
static float rad_to_deg(const float radian);
static float bearing(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate);
};
#endif // COORDINATE_CALCULATION
+38 -37
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -25,19 +25,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef DEALLOCATINGVECTOR_H_
#define DEALLOCATINGVECTOR_H_
#ifndef DEALLOCATING_VECTOR_HPP
#define DEALLOCATING_VECTOR_HPP
#include "../Util/integer_range.hpp"
#include "../util/integer_range.hpp"
#include <boost/iterator/iterator_facade.hpp>
#include <limits>
#include <utility>
#include <vector>
template <typename ElementT> struct DeallocatingVectorIteratorState
{
DeallocatingVectorIteratorState() : index(-1), bucket_list(nullptr) {}
DeallocatingVectorIteratorState()
: index(std::numeric_limits<std::size_t>::max()), bucket_list(nullptr)
{
}
explicit DeallocatingVectorIteratorState(const DeallocatingVectorIteratorState &r)
: index(r.index), bucket_list(r.bucket_list)
{
@@ -50,7 +54,7 @@ template <typename ElementT> struct DeallocatingVectorIteratorState
std::size_t index;
std::vector<ElementT *> *bucket_list;
inline DeallocatingVectorIteratorState &operator=(const DeallocatingVectorIteratorState &other)
DeallocatingVectorIteratorState &operator=(const DeallocatingVectorIteratorState &other)
{
index = other.index;
bucket_list = other.bucket_list;
@@ -171,17 +175,20 @@ class DeallocatingVector
// this forward-only iterator deallocates all buckets that have been visited
using deallocation_iterator = DeallocatingVectorRemoveIterator<ElementT, ELEMENTS_PER_BLOCK>;
DeallocatingVector() : current_size(0) { bucket_list.emplace_back(new ElementT[ELEMENTS_PER_BLOCK]); }
DeallocatingVector() : current_size(0)
{
bucket_list.emplace_back(new ElementT[ELEMENTS_PER_BLOCK]);
}
~DeallocatingVector() { clear(); }
inline void swap(DeallocatingVector<ElementT, ELEMENTS_PER_BLOCK> &other)
void swap(DeallocatingVector<ElementT, ELEMENTS_PER_BLOCK> &other)
{
std::swap(current_size, other.current_size);
bucket_list.swap(other.bucket_list);
}
inline void clear()
void clear()
{
// Delete[]'ing ptr's to all Buckets
for (auto bucket : bucket_list)
@@ -192,11 +199,12 @@ class DeallocatingVector
bucket = nullptr;
}
}
bucket_list.clear(); bucket_list.shrink_to_fit();
bucket_list.clear();
bucket_list.shrink_to_fit();
current_size = 0;
}
inline void push_back(const ElementT &element)
void push_back(const ElementT &element)
{
const std::size_t current_capacity = capacity();
if (current_size == current_capacity)
@@ -209,7 +217,7 @@ class DeallocatingVector
++current_size;
}
template <typename... Ts> inline void emplace_back(Ts &&... element)
template <typename... Ts> void emplace_back(Ts &&... element)
{
const std::size_t current_capacity = capacity();
if (current_size == current_capacity)
@@ -222,9 +230,9 @@ class DeallocatingVector
++current_size;
}
inline void reserve(const std::size_t) const { /* don't do anything */ }
void reserve(const std::size_t) const { /* don't do anything */}
inline void resize(const std::size_t new_size)
void resize(const std::size_t new_size)
{
if (new_size >= current_size)
{
@@ -234,9 +242,10 @@ class DeallocatingVector
}
}
else
{ // down-size
{ // down-size
const std::size_t number_of_necessary_buckets = 1 + (new_size / ELEMENTS_PER_BLOCK);
for (const auto bucket_index : osrm::irange(number_of_necessary_buckets, bucket_list.size()))
for (const auto bucket_index :
osrm::irange(number_of_necessary_buckets, bucket_list.size()))
{
if (nullptr != bucket_list[bucket_index])
{
@@ -248,58 +257,50 @@ class DeallocatingVector
current_size = new_size;
}
inline std::size_t size() const { return current_size; }
std::size_t size() const { return current_size; }
inline std::size_t capacity() const { return bucket_list.size() * ELEMENTS_PER_BLOCK; }
std::size_t capacity() const { return bucket_list.size() * ELEMENTS_PER_BLOCK; }
inline iterator begin() { return iterator(static_cast<std::size_t>(0), &bucket_list); }
iterator begin() { return iterator(static_cast<std::size_t>(0), &bucket_list); }
inline iterator end() { return iterator(size(), &bucket_list); }
iterator end() { return iterator(size(), &bucket_list); }
inline deallocation_iterator dbegin()
deallocation_iterator dbegin()
{
return deallocation_iterator(static_cast<std::size_t>(0), &bucket_list);
}
inline deallocation_iterator dend() { return deallocation_iterator(size(), &bucket_list); }
deallocation_iterator dend() { return deallocation_iterator(size(), &bucket_list); }
inline const_iterator begin() const
const_iterator begin() const
{
return const_iterator(static_cast<std::size_t>(0), &bucket_list);
}
inline const_iterator end() const { return const_iterator(size(), &bucket_list); }
const_iterator end() const { return const_iterator(size(), &bucket_list); }
inline ElementT &operator[](const std::size_t index)
ElementT &operator[](const std::size_t index)
{
const std::size_t _bucket = index / ELEMENTS_PER_BLOCK;
const std::size_t _index = index % ELEMENTS_PER_BLOCK;
return (bucket_list[_bucket][_index]);
}
const inline ElementT &operator[](const std::size_t index) const
ElementT &operator[](const std::size_t index) const
{
const std::size_t _bucket = index / ELEMENTS_PER_BLOCK;
const std::size_t _index = index % ELEMENTS_PER_BLOCK;
return (bucket_list[_bucket][_index]);
}
inline ElementT &back()
ElementT &back() const
{
const std::size_t _bucket = current_size / ELEMENTS_PER_BLOCK;
const std::size_t _index = current_size % ELEMENTS_PER_BLOCK;
return (bucket_list[_bucket][_index]);
}
const inline ElementT &back() const
{
const std::size_t _bucket = current_size / ELEMENTS_PER_BLOCK;
const std::size_t _index = current_size % ELEMENTS_PER_BLOCK;
return (bucket_list[_bucket][_index]);
}
template<class InputIterator>
const inline void append(InputIterator first, const InputIterator last)
template <class InputIterator> void append(InputIterator first, const InputIterator last)
{
InputIterator position = first;
while (position != last)
@@ -310,4 +311,4 @@ class DeallocatingVector
}
};
#endif /* DEALLOCATINGVECTOR_H_ */
#endif /* DEALLOCATING_VECTOR_HPP */
+94 -47
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -29,16 +29,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define DYNAMICGRAPH_HPP
#include "deallocating_vector.hpp"
#include "../Util/integer_range.hpp"
#include "../util/integer_range.hpp"
#include "../typedefs.h"
#include <boost/assert.hpp>
#include <cstdint>
#include <algorithm>
#include <limits>
#include <vector>
#include <atomic>
#include <limits>
#include <tuple>
#include <vector>
template <typename EdgeDataT> class DynamicGraph
{
@@ -55,58 +57,64 @@ template <typename EdgeDataT> class DynamicGraph
NodeIterator target;
EdgeDataT data;
InputEdge() : source(std::numeric_limits<NodeIterator>::max()), target(std::numeric_limits<NodeIterator>::max()) { }
template<typename... Ts>
InputEdge(NodeIterator source, NodeIterator target, Ts &&...data) : source(source), target(target), data(std::forward<Ts>(data)...) { }
bool operator<(const InputEdge &right) const
InputEdge()
: source(std::numeric_limits<NodeIterator>::max()),
target(std::numeric_limits<NodeIterator>::max())
{
if (source != right.source)
{
return source < right.source;
}
return target < right.target;
}
template <typename... Ts>
InputEdge(NodeIterator source, NodeIterator target, Ts &&... data)
: source(source), target(target), data(std::forward<Ts>(data)...)
{
}
bool operator<(const InputEdge &rhs) const
{
return std::tie(source, target) < std::tie(rhs.source, rhs.target);
}
};
// Constructs an empty graph with a given number of nodes.
explicit DynamicGraph(NodeIterator nodes) : number_of_nodes(nodes), number_of_edges(0)
{
node_list.reserve(number_of_nodes);
node_list.resize(number_of_nodes);
node_array.reserve(number_of_nodes);
node_array.resize(number_of_nodes);
edge_list.reserve(number_of_nodes * 1.1);
edge_list.resize(number_of_nodes);
}
/**
* Constructs a DynamicGraph from a list of edges sorted by source node id.
*/
template <class ContainerT> DynamicGraph(const NodeIterator nodes, const ContainerT &graph)
{
number_of_nodes = nodes;
number_of_edges = (EdgeIterator)graph.size();
node_list.reserve(number_of_nodes + 1);
node_list.resize(number_of_nodes + 1);
number_of_edges = static_cast<EdgeIterator>(graph.size());
// node_array.reserve(number_of_nodes + 1);
node_array.resize(number_of_nodes + 1);
EdgeIterator edge = 0;
EdgeIterator position = 0;
for (const auto node : osrm::irange(0u, number_of_nodes))
{
EdgeIterator lastEdge = edge;
EdgeIterator last_edge = edge;
while (edge < number_of_edges && graph[edge].source == node)
{
++edge;
}
node_list[node].firstEdge = position;
node_list[node].edges = edge - lastEdge;
position += node_list[node].edges;
node_array[node].first_edge = position;
node_array[node].edges = edge - last_edge;
position += node_array[node].edges;
}
node_list.back().firstEdge = position;
node_array.back().first_edge = position;
edge_list.reserve(static_cast<std::size_t>(edge_list.size() * 1.1));
edge_list.resize(position);
edge = 0;
for (const auto node : osrm::irange(0u, number_of_nodes))
{
for (const auto i : osrm::irange(node_list[node].firstEdge,
node_list[node].firstEdge + node_list[node].edges))
for (const auto i : osrm::irange(node_array[node].first_edge,
node_array[node].first_edge + node_array[node].edges))
{
edge_list[i].target = graph[edge].target;
edge_list[i].data = graph[edge].data;
@@ -121,7 +129,7 @@ template <typename EdgeDataT> class DynamicGraph
unsigned GetNumberOfEdges() const { return number_of_edges; }
unsigned GetOutDegree(const NodeIterator n) const { return node_list[n].edges; }
unsigned GetOutDegree(const NodeIterator n) const { return node_array[n].edges; }
unsigned GetDirectedOutDegree(const NodeIterator n) const
{
@@ -146,12 +154,12 @@ template <typename EdgeDataT> class DynamicGraph
EdgeIterator BeginEdges(const NodeIterator n) const
{
return EdgeIterator(node_list[n].firstEdge);
return EdgeIterator(node_array[n].first_edge);
}
EdgeIterator EndEdges(const NodeIterator n) const
{
return EdgeIterator(node_list[n].firstEdge + node_list[n].edges);
return EdgeIterator(node_array[n].first_edge + node_array[n].edges);
}
EdgeRange GetAdjacentEdgeRange(const NodeIterator node) const
@@ -161,7 +169,7 @@ template <typename EdgeDataT> class DynamicGraph
NodeIterator InsertNode()
{
node_list.emplace_back(node_list.back());
node_array.emplace_back(node_array.back());
number_of_nodes += 1;
return number_of_nodes;
@@ -170,14 +178,14 @@ template <typename EdgeDataT> class DynamicGraph
// adds an edge. Invalidates edge iterators for the source node
EdgeIterator InsertEdge(const NodeIterator from, const NodeIterator to, const EdgeDataT &data)
{
Node &node = node_list[from];
EdgeIterator newFirstEdge = node.edges + node.firstEdge;
Node &node = node_array[from];
EdgeIterator newFirstEdge = node.edges + node.first_edge;
if (newFirstEdge >= edge_list.size() || !isDummy(newFirstEdge))
{
if (node.firstEdge != 0 && isDummy(node.firstEdge - 1))
if (node.first_edge != 0 && isDummy(node.first_edge - 1))
{
node.firstEdge--;
edge_list[node.firstEdge] = edge_list[node.firstEdge + node.edges];
node.first_edge--;
edge_list[node.first_edge] = edge_list[node.first_edge + node.edges];
}
else
{
@@ -192,32 +200,32 @@ template <typename EdgeDataT> class DynamicGraph
edge_list.resize(edge_list.size() + newSize);
for (const auto i : osrm::irange(0u, node.edges))
{
edge_list[newFirstEdge + i] = edge_list[node.firstEdge + i];
makeDummy(node.firstEdge + i);
edge_list[newFirstEdge + i] = edge_list[node.first_edge + i];
makeDummy(node.first_edge + i);
}
for (const auto i : osrm::irange(node.edges + 1, newSize))
{
makeDummy(newFirstEdge + i);
}
node.firstEdge = newFirstEdge;
node.first_edge = newFirstEdge;
}
}
Edge &edge = edge_list[node.firstEdge + node.edges];
Edge &edge = edge_list[node.first_edge + node.edges];
edge.target = to;
edge.data = data;
++number_of_edges;
++node.edges;
return EdgeIterator(node.firstEdge + node.edges);
return EdgeIterator(node.first_edge + node.edges);
}
// removes an edge. Invalidates edge iterators for the source node
void DeleteEdge(const NodeIterator source, const EdgeIterator e)
{
Node &node = node_list[source];
Node &node = node_array[source];
--number_of_edges;
--node.edges;
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != node.edges);
const unsigned last = node.firstEdge + node.edges;
const unsigned last = node.first_edge + node.edges;
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != last);
// swap with last edge
edge_list[e] = edge_list[last];
@@ -242,7 +250,7 @@ template <typename EdgeDataT> class DynamicGraph
}
number_of_edges -= deleted;
node_list[source].edges -= deleted;
node_array[source].edges -= deleted;
return deleted;
}
@@ -257,7 +265,46 @@ template <typename EdgeDataT> class DynamicGraph
return i;
}
}
return EndEdges(from);
return SPECIAL_EDGEID;
}
// searches for a specific edge
EdgeIterator FindSmallestEdge(const NodeIterator from, const NodeIterator to) const
{
EdgeIterator smallest_edge = SPECIAL_EDGEID;
EdgeWeight smallest_weight = INVALID_EDGE_WEIGHT;
for (auto edge : GetAdjacentEdgeRange(from))
{
const NodeID target = GetTarget(edge);
const EdgeWeight weight = GetEdgeData(edge).distance;
if (target == to && weight < smallest_weight)
{
smallest_edge = edge;
smallest_weight = weight;
}
}
return smallest_edge;
}
EdgeIterator FindEdgeInEitherDirection(const NodeIterator from, const NodeIterator to) const
{
EdgeIterator tmp = FindEdge(from, to);
return (SPECIAL_NODEID != tmp ? tmp : FindEdge(to, from));
}
EdgeIterator
FindEdgeIndicateIfReverse(const NodeIterator from, const NodeIterator to, bool &result) const
{
EdgeIterator current_iterator = FindEdge(from, to);
if (SPECIAL_NODEID == current_iterator)
{
current_iterator = FindEdge(to, from);
if (SPECIAL_NODEID != current_iterator)
{
result = true;
}
}
return current_iterator;
}
protected:
@@ -274,7 +321,7 @@ template <typename EdgeDataT> class DynamicGraph
struct Node
{
// index of the first edge
EdgeIterator firstEdge;
EdgeIterator first_edge;
// amount of edges
unsigned edges;
};
@@ -288,7 +335,7 @@ template <typename EdgeDataT> class DynamicGraph
NodeIterator number_of_nodes;
std::atomic_uint number_of_edges;
std::vector<Node> node_list;
std::vector<Node> node_array;
DeallocatingVector<Edge> edge_list;
};
+51 -67
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -31,95 +31,79 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../data_structures/travel_mode.hpp"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
#include <osrm/coordinate.hpp>
#include <limits>
struct EdgeBasedNode
{
EdgeBasedNode()
: forward_edge_based_node_id(SPECIAL_NODEID), reverse_edge_based_node_id(SPECIAL_NODEID),
u(SPECIAL_NODEID), v(SPECIAL_NODEID), name_id(0),
forward_weight(INVALID_EDGE_WEIGHT >> 1), reverse_weight(INVALID_EDGE_WEIGHT >> 1),
forward_offset(0), reverse_offset(0), packed_geometry_id(SPECIAL_EDGEID),
component_id(-1), fwd_segment_position(std::numeric_limits<unsigned short>::max()),
forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
{
}
EdgeBasedNode() :
forward_edge_based_node_id(SPECIAL_NODEID),
reverse_edge_based_node_id(SPECIAL_NODEID),
u(SPECIAL_NODEID),
v(SPECIAL_NODEID),
name_id(0),
forward_weight(INVALID_EDGE_WEIGHT >> 1),
reverse_weight(INVALID_EDGE_WEIGHT >> 1),
forward_offset(0),
reverse_offset(0),
packed_geometry_id(SPECIAL_EDGEID),
fwd_segment_position( std::numeric_limits<unsigned short>::max() ),
is_in_tiny_cc(false),
forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
{ }
explicit EdgeBasedNode(
NodeID forward_edge_based_node_id,
NodeID reverse_edge_based_node_id,
NodeID u,
NodeID v,
unsigned name_id,
int forward_weight,
int reverse_weight,
int forward_offset,
int reverse_offset,
unsigned packed_geometry_id,
unsigned short fwd_segment_position,
bool belongs_to_tiny_component,
TravelMode forward_travel_mode,
TravelMode backward_travel_mode
) :
forward_edge_based_node_id(forward_edge_based_node_id),
reverse_edge_based_node_id(reverse_edge_based_node_id),
u(u),
v(v),
name_id(name_id),
forward_weight(forward_weight),
reverse_weight(reverse_weight),
forward_offset(forward_offset),
reverse_offset(reverse_offset),
packed_geometry_id(packed_geometry_id),
fwd_segment_position(fwd_segment_position),
is_in_tiny_cc(belongs_to_tiny_component),
forward_travel_mode(forward_travel_mode),
backward_travel_mode(backward_travel_mode)
explicit EdgeBasedNode(NodeID forward_edge_based_node_id,
NodeID reverse_edge_based_node_id,
NodeID u,
NodeID v,
unsigned name_id,
int forward_weight,
int reverse_weight,
int forward_offset,
int reverse_offset,
unsigned packed_geometry_id,
unsigned component_id,
unsigned short fwd_segment_position,
TravelMode forward_travel_mode,
TravelMode backward_travel_mode)
: forward_edge_based_node_id(forward_edge_based_node_id),
reverse_edge_based_node_id(reverse_edge_based_node_id), u(u), v(v), name_id(name_id),
forward_weight(forward_weight), reverse_weight(reverse_weight),
forward_offset(forward_offset), reverse_offset(reverse_offset),
packed_geometry_id(packed_geometry_id), component_id(component_id),
fwd_segment_position(fwd_segment_position), forward_travel_mode(forward_travel_mode),
backward_travel_mode(backward_travel_mode)
{
BOOST_ASSERT((forward_edge_based_node_id != SPECIAL_NODEID) ||
(reverse_edge_based_node_id != SPECIAL_NODEID));
}
static inline FixedPointCoordinate Centroid(const FixedPointCoordinate & a, const FixedPointCoordinate & b)
static inline FixedPointCoordinate Centroid(const FixedPointCoordinate &a,
const FixedPointCoordinate &b)
{
FixedPointCoordinate centroid;
//The coordinates of the midpoint are given by:
centroid.lat = (a.lat + b.lat)/2;
centroid.lon = (a.lon + b.lon)/2;
// The coordinates of the midpoint are given by:
centroid.lat = (a.lat + b.lat) / 2;
centroid.lon = (a.lon + b.lon) / 2;
return centroid;
}
bool IsCompressed() const
{
return packed_geometry_id != SPECIAL_EDGEID;
}
bool IsCompressed() const { return packed_geometry_id != SPECIAL_EDGEID; }
bool is_in_tiny_cc() const { return 0 != component_id; }
NodeID forward_edge_based_node_id; // needed for edge-expanded graph
NodeID reverse_edge_based_node_id; // needed for edge-expanded graph
NodeID u; // indices into the coordinates array
NodeID v; // indices into the coordinates array
unsigned name_id; // id of the edge name
int forward_weight; // weight of the edge
int reverse_weight; // weight in the other direction (may be different)
int forward_offset; // prefix sum of the weight up the edge TODO: short must suffice
int reverse_offset; // prefix sum of the weight from the edge TODO: short must suffice
NodeID u; // indices into the coordinates array
NodeID v; // indices into the coordinates array
unsigned name_id; // id of the edge name
int forward_weight; // weight of the edge
int reverse_weight; // weight in the other direction (may be different)
int forward_offset; // prefix sum of the weight up the edge TODO: short must suffice
int reverse_offset; // prefix sum of the weight from the edge TODO: short must suffice
unsigned packed_geometry_id; // if set, then the edge represents a packed geometry
unsigned component_id;
unsigned short fwd_segment_position; // segment id in a compressed geometry
bool is_in_tiny_cc;
TravelMode forward_travel_mode : 4;
TravelMode backward_travel_mode : 4;
};
#endif //EDGE_BASED_NODE_HPP
#endif // EDGE_BASED_NODE_HPP
+4 -6
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -26,6 +26,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "external_memory_node.hpp"
#include "query_node.hpp"
#include <limits>
@@ -44,11 +45,8 @@ ExternalMemoryNode ExternalMemoryNode::min_value()
ExternalMemoryNode ExternalMemoryNode::max_value()
{
return ExternalMemoryNode(std::numeric_limits<int>::max(),
std::numeric_limits<int>::max(),
std::numeric_limits<unsigned>::max(),
false,
false);
return ExternalMemoryNode(std::numeric_limits<int>::max(), std::numeric_limits<int>::max(),
std::numeric_limits<unsigned>::max(), false, false);
}
bool ExternalMemoryNodeSTXXLCompare::operator()(const ExternalMemoryNode &left,
+2 -2
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -30,7 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "query_node.hpp"
#include <string>
#include "../typedefs.h"
struct ExternalMemoryNode : QueryNode
{
+1 -1
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
+158
View File
@@ -0,0 +1,158 @@
/*
Copyright (c) 2015, 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 HIDDEN_MARKOV_MODEL
#define HIDDEN_MARKOV_MODEL
#include "../util/integer_range.hpp"
#include <boost/assert.hpp>
#include <cmath>
#include <limits>
#include <vector>
namespace osrm
{
namespace matching
{
static const double log_2_pi = std::log(2. * M_PI);
static const double IMPOSSIBLE_LOG_PROB = -std::numeric_limits<double>::infinity();
static const double MINIMAL_LOG_PROB = std::numeric_limits<double>::lowest();
static const std::size_t INVALID_STATE = std::numeric_limits<std::size_t>::max();
} // namespace matching
} // namespace osrm
// closures to precompute log -> only simple floating point operations
struct EmissionLogProbability
{
double sigma_z;
double log_sigma_z;
EmissionLogProbability(const double sigma_z) : sigma_z(sigma_z), log_sigma_z(std::log(sigma_z))
{
}
double operator()(const double distance) const
{
return -0.5 * (osrm::matching::log_2_pi + (distance / sigma_z) * (distance / sigma_z)) -
log_sigma_z;
}
};
struct TransitionLogProbability
{
double beta;
double log_beta;
TransitionLogProbability(const double beta) : beta(beta), log_beta(std::log(beta)) {}
double operator()(const double d_t) const { return -log_beta - d_t / beta; }
};
template <class CandidateLists> struct HiddenMarkovModel
{
std::vector<std::vector<double>> viterbi;
std::vector<std::vector<std::pair<unsigned, unsigned>>> parents;
std::vector<std::vector<float>> path_lengths;
std::vector<std::vector<bool>> pruned;
std::vector<std::vector<bool>> suspicious;
std::vector<bool> breakage;
const CandidateLists &candidates_list;
const EmissionLogProbability &emission_log_probability;
HiddenMarkovModel(const CandidateLists &candidates_list,
const EmissionLogProbability &emission_log_probability)
: breakage(candidates_list.size()), candidates_list(candidates_list),
emission_log_probability(emission_log_probability)
{
for (const auto &l : candidates_list)
{
viterbi.emplace_back(l.size());
parents.emplace_back(l.size());
path_lengths.emplace_back(l.size());
suspicious.emplace_back(l.size());
pruned.emplace_back(l.size());
}
clear(0);
}
void clear(std::size_t initial_timestamp)
{
BOOST_ASSERT(viterbi.size() == parents.size() && parents.size() == path_lengths.size() &&
path_lengths.size() == pruned.size() && pruned.size() == breakage.size());
for (const auto t : osrm::irange(initial_timestamp, viterbi.size()))
{
std::fill(viterbi[t].begin(), viterbi[t].end(), osrm::matching::IMPOSSIBLE_LOG_PROB);
std::fill(parents[t].begin(), parents[t].end(), std::make_pair(0u, 0u));
std::fill(path_lengths[t].begin(), path_lengths[t].end(), 0);
std::fill(suspicious[t].begin(), suspicious[t].end(), true);
std::fill(pruned[t].begin(), pruned[t].end(), true);
}
std::fill(breakage.begin() + initial_timestamp, breakage.end(), true);
}
std::size_t initialize(std::size_t initial_timestamp)
{
BOOST_ASSERT(initial_timestamp < candidates_list.size());
do
{
for (const auto s : osrm::irange<std::size_t>(0u, viterbi[initial_timestamp].size()))
{
viterbi[initial_timestamp][s] =
emission_log_probability(candidates_list[initial_timestamp][s].second);
parents[initial_timestamp][s] = std::make_pair(initial_timestamp, s);
pruned[initial_timestamp][s] =
viterbi[initial_timestamp][s] < osrm::matching::MINIMAL_LOG_PROB;
suspicious[initial_timestamp][s] = false;
breakage[initial_timestamp] =
breakage[initial_timestamp] && pruned[initial_timestamp][s];
}
++initial_timestamp;
} while (breakage[initial_timestamp - 1]);
if (initial_timestamp >= viterbi.size())
{
return osrm::matching::INVALID_STATE;
}
BOOST_ASSERT(initial_timestamp > 0);
--initial_timestamp;
BOOST_ASSERT(breakage[initial_timestamp] == false);
return initial_timestamp;
}
};
#endif // HIDDEN_MARKOV_MODEL
+2 -2
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -27,7 +27,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "hilbert_value.hpp"
#include <osrm/Coordinate.h>
#include <osrm/coordinate.hpp>
uint64_t HilbertCode::operator()(const FixedPointCoordinate &current_coordinate) const
{
+1 -1
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
+12 -4
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -27,7 +27,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "import_edge.hpp"
#include <boost/assert.hpp>
#include "travel_mode.hpp"
#include "../typedefs.h"
bool NodeBasedEdge::operator<(const NodeBasedEdge &other) const
{
@@ -46,6 +47,13 @@ bool NodeBasedEdge::operator<(const NodeBasedEdge &other) const
return source < other.source;
}
NodeBasedEdge::NodeBasedEdge()
: source(SPECIAL_NODEID), target(SPECIAL_NODEID), name_id(0), weight(0), forward(false),
backward(false), roundabout(false), in_tiny_cc(false),
access_restricted(false), is_split(false), travel_mode(false)
{
}
NodeBasedEdge::NodeBasedEdge(NodeID source,
NodeID target,
NodeID name_id,
@@ -57,8 +65,8 @@ NodeBasedEdge::NodeBasedEdge(NodeID source,
bool access_restricted,
TravelMode travel_mode,
bool is_split)
: source(source), target(target), name_id(name_id), weight(weight),
forward(forward), backward(backward), roundabout(roundabout), in_tiny_cc(in_tiny_cc),
: source(source), target(target), name_id(name_id), weight(weight), forward(forward),
backward(backward), roundabout(roundabout), in_tiny_cc(in_tiny_cc),
access_restricted(access_restricted), is_split(is_split), travel_mode(travel_mode)
{
}
+2 -5
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2013, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -35,6 +35,7 @@ struct NodeBasedEdge
{
bool operator<(const NodeBasedEdge &e) const;
NodeBasedEdge();
explicit NodeBasedEdge(NodeID source,
NodeID target,
NodeID name_id,
@@ -58,8 +59,6 @@ struct NodeBasedEdge
bool access_restricted : 1;
bool is_split : 1;
TravelMode travel_mode : 4;
NodeBasedEdge() = delete;
};
struct EdgeBasedEdge
@@ -86,6 +85,4 @@ struct EdgeBasedEdge
bool backward : 1;
};
using ImportEdge = NodeBasedEdge;
#endif /* IMPORT_EDGE_HPP */
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2013, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -25,25 +25,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef RAW_ROUTE_DATA_HPP
#define RAW_ROUTE_DATA_HPP
#ifndef RAW_ROUTE_DATA_H
#define RAW_ROUTE_DATA_H
#include "../data_structures/phantom_node.hpp"
#include "../data_structures/travel_mode.hpp"
#include "../data_structures/turn_instructions.hpp"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <osrm/coordinate.hpp>
#include <vector>
struct PathData
{
PathData()
: node(SPECIAL_NODEID), name_id(INVALID_EDGE_WEIGHT),
segment_duration(INVALID_EDGE_WEIGHT),
turn_instruction(TurnInstruction::NoTurn),
travel_mode(TRAVEL_MODE_INACCESSIBLE)
: node(SPECIAL_NODEID), name_id(INVALID_EDGE_WEIGHT), segment_duration(INVALID_EDGE_WEIGHT),
turn_instruction(TurnInstruction::NoTurn), travel_mode(TRAVEL_MODE_INACCESSIBLE)
{
}
@@ -52,8 +50,8 @@ struct PathData
TurnInstruction turn_instruction,
EdgeWeight segment_duration,
TravelMode travel_mode)
: node(node), name_id(name_id), segment_duration(segment_duration), turn_instruction(turn_instruction),
travel_mode(travel_mode)
: node(node), name_id(name_id), segment_duration(segment_duration),
turn_instruction(turn_instruction), travel_mode(travel_mode)
{
}
NodeID node;
@@ -63,7 +61,7 @@ struct PathData
TravelMode travel_mode : 4;
};
struct RawRouteData
struct InternalRouteResult
{
std::vector<std::vector<PathData>> unpacked_path_segments;
std::vector<PathData> unpacked_alternative;
@@ -80,11 +78,10 @@ struct RawRouteData
return (leg != unpacked_path_segments.size() - 1);
}
RawRouteData() :
shortest_path_length(INVALID_EDGE_WEIGHT),
alternative_path_length(INVALID_EDGE_WEIGHT)
InternalRouteResult()
: shortest_path_length(INVALID_EDGE_WEIGHT), alternative_path_length(INVALID_EDGE_WEIGHT)
{
}
};
#endif // RAW_ROUTE_DATA_HPP
#endif // RAW_ROUTE_DATA_H
+2 -2
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -86,7 +86,7 @@ template <typename KeyT, typename ValueT> class LRUCache
result = e.value;
// move to front
itemsInCache.splice(positionMap.find(key)->second, itemsInCache, itemsInCache.begin());
itemsInCache.splice(itemsInCache.begin(), itemsInCache, positionMap.find(key)->second);
positionMap.find(key)->second = itemsInCache.begin();
return true;
}
+123 -159
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -30,7 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "dynamic_graph.hpp"
#include "import_edge.hpp"
#include "../Util/simple_logger.hpp"
#include "../util/simple_logger.hpp"
#include <tbb/parallel_sort.h>
@@ -40,9 +40,9 @@ struct NodeBasedEdgeData
{
NodeBasedEdgeData()
: distance(INVALID_EDGE_WEIGHT), edgeBasedNodeID(SPECIAL_NODEID),
nameID(std::numeric_limits<unsigned>::max()),
isAccessRestricted(false), shortcut(false), forward(false), backward(false),
roundabout(false), ignore_in_grid(false), travel_mode(TRAVEL_MODE_INACCESSIBLE)
nameID(std::numeric_limits<unsigned>::max()), isAccessRestricted(false), shortcut(false),
forward(false), backward(false), roundabout(false), ignore_in_grid(false),
travel_mode(TRAVEL_MODE_INACCESSIBLE)
{
}
@@ -64,7 +64,7 @@ struct NodeBasedEdgeData
backward = temp_flag;
}
bool IsEqualTo(const NodeBasedEdgeData &other) const
bool IsCompatibleTo(const NodeBasedEdgeData &other) const
{
return (forward == other.forward) && (backward == other.backward) &&
(nameID == other.nameID) && (ignore_in_grid == other.ignore_in_grid) &&
@@ -72,25 +72,123 @@ struct NodeBasedEdgeData
}
};
struct SimpleEdgeData
{
SimpleEdgeData() : capacity(0) {}
EdgeWeight capacity;
};
using NodeBasedDynamicGraph = DynamicGraph<NodeBasedEdgeData>;
using SimpleNodeBasedDynamicGraph = DynamicGraph<SimpleEdgeData>;
// Factory method to create NodeBasedDynamicGraph from ImportEdges
inline std::shared_ptr<NodeBasedDynamicGraph>
NodeBasedDynamicGraphFromImportEdges(int number_of_nodes, std::vector<ImportEdge> &input_edge_list)
inline bool validateNeighborHood(const NodeBasedDynamicGraph& graph, const NodeID source)
{
static_assert(sizeof(NodeBasedEdgeData) == 16, "changing node based edge data size changes memory consumption");
for (auto edge = graph.BeginEdges(source); edge < graph.EndEdges(source); ++edge)
{
const auto& data = graph.GetEdgeData(edge);
if (!data.forward && !data.backward)
{
SimpleLogger().Write(logWARNING) << "Invalid edge directions";
return false;
}
auto target = graph.GetTarget(edge);
if (target == SPECIAL_NODEID)
{
SimpleLogger().Write(logWARNING) << "Invalid edge target";
return false;
}
bool found_reverse = false;
for (auto rev_edge = graph.BeginEdges(target); rev_edge < graph.EndEdges(target); ++rev_edge)
{
auto rev_target = graph.GetTarget(rev_edge);
if (rev_target == SPECIAL_NODEID)
{
SimpleLogger().Write(logWARNING) << "Invalid reverse edge target";
return false;
}
if (rev_target != source)
{
continue;
}
if (found_reverse)
{
SimpleLogger().Write(logWARNING) << "Found more than one reverse edge";
return false;
}
const auto& rev_data = graph.GetEdgeData(rev_edge);
// edge is incoming, this must be an outgoing edge
if (data.backward && !rev_data.forward)
{
SimpleLogger().Write(logWARNING) << "Found no outgoing edge to an incoming edge!";
return false;
}
// edge is bi-directional, reverse must be as well
if (data.forward && data.backward && (!rev_data.forward || !rev_data.backward))
{
SimpleLogger().Write(logWARNING) << "Found bi-directional edge that is not bi-directional to both ends";
return false;
}
found_reverse = true;
}
if (!found_reverse)
{
SimpleLogger().Write(logWARNING) << "Could not find reverse edge";
return false;
}
}
return true;
}
// This function checks if the overal graph is undirected (has an edge in each direction).
inline bool validateNodeBasedGraph(const NodeBasedDynamicGraph& graph)
{
for (auto source = 0u; source < graph.GetNumberOfNodes(); ++source)
{
if (!validateNeighborHood(graph, source))
{
return false;
}
}
return true;
}
// Factory method to create NodeBasedDynamicGraph from NodeBasedEdges
// The since DynamicGraph expects directed edges, we need to insert
// two edges for undirected edges.
inline std::shared_ptr<NodeBasedDynamicGraph>
NodeBasedDynamicGraphFromImportEdges(int number_of_nodes, std::vector<NodeBasedEdge> &input_edge_list)
{
static_assert(sizeof(NodeBasedEdgeData) == 16,
"changing node based edge data size changes memory consumption");
DeallocatingVector<NodeBasedDynamicGraph::InputEdge> edges_list;
NodeBasedDynamicGraph::InputEdge edge;
for (const ImportEdge &import_edge : input_edge_list)
// Since DynamicGraph assumes directed edges we have to make sure we transformed
// the compressed edge format into single directed edges. We do this to make sure
// every node also knows its incoming edges, not only its outgoing edges and use the backward=true
// flag to indicate which is which.
//
// We do the transformation in the following way:
//
// if the edge (a, b) is split:
// 1. this edge must be in only one direction, so its a --> b
// 2. there must be another directed edge b --> a somewhere in the data
// if the edge (a, b) is not split:
// 1. this edge be on of a --> b od a <-> b
// (a <-- b gets reducted to b --> a)
// 2. a --> b will be transformed to a --> b and b <-- a
// 3. a <-> b will be transformed to a <-> b and b <-> a (I think a --> b and b <-- a would work as well though)
for (const NodeBasedEdge &import_edge : input_edge_list)
{
// edges that are not forward get converted by flipping the end points
BOOST_ASSERT(import_edge.forward);
if (import_edge.forward)
{
edge.source = import_edge.source;
@@ -98,20 +196,10 @@ NodeBasedDynamicGraphFromImportEdges(int number_of_nodes, std::vector<ImportEdge
edge.data.forward = import_edge.forward;
edge.data.backward = import_edge.backward;
}
else
{
edge.source = import_edge.target;
edge.target = import_edge.source;
edge.data.backward = import_edge.forward;
edge.data.forward = import_edge.backward;
}
if (edge.source == edge.target)
{
continue;
}
BOOST_ASSERT(edge.source != edge.target);
edge.data.distance = (std::max)((int)import_edge.weight, 1);
edge.data.distance = static_cast<int>(import_edge.weight);
BOOST_ASSERT(edge.data.distance > 0);
edge.data.shortcut = false;
edge.data.roundabout = import_edge.roundabout;
@@ -131,140 +219,16 @@ NodeBasedDynamicGraphFromImportEdges(int number_of_nodes, std::vector<ImportEdge
}
}
// remove duplicate edges
tbb::parallel_sort(edges_list.begin(), edges_list.end());
NodeID edge_count = 0;
for (NodeID i = 0; i < edges_list.size(); )
{
const NodeID source = edges_list[i].source;
const NodeID target = edges_list[i].target;
// remove eigenloops
if (source == target)
{
i++;
continue;
}
NodeBasedDynamicGraph::InputEdge forward_edge;
NodeBasedDynamicGraph::InputEdge reverse_edge;
forward_edge = reverse_edge = edges_list[i];
forward_edge.data.forward = reverse_edge.data.backward = true;
forward_edge.data.backward = reverse_edge.data.forward = false;
forward_edge.data.shortcut = reverse_edge.data.shortcut = false;
forward_edge.data.distance = reverse_edge.data.distance =
std::numeric_limits<int>::max();
// remove parallel edges
while (i < edges_list.size() && edges_list[i].source == source && edges_list[i].target == target)
{
if (edges_list[i].data.forward)
{
forward_edge.data.distance =
std::min(edges_list[i].data.distance, forward_edge.data.distance);
}
if (edges_list[i].data.backward)
{
reverse_edge.data.distance =
std::min(edges_list[i].data.distance, reverse_edge.data.distance);
}
++i;
}
// merge edges (s,t) and (t,s) into bidirectional edge
if (forward_edge.data.distance == reverse_edge.data.distance)
{
if ((int)forward_edge.data.distance != std::numeric_limits<int>::max())
{
forward_edge.data.backward = true;
edges_list[edge_count++] = forward_edge;
}
}
else
{ // insert seperate edges
if (((int)forward_edge.data.distance) != std::numeric_limits<int>::max())
{
edges_list[edge_count++] = forward_edge;
}
if ((int)reverse_edge.data.distance != std::numeric_limits<int>::max())
{
edges_list[edge_count++] = reverse_edge;
}
}
}
edges_list.resize(edge_count);
SimpleLogger().Write() << "merged " << edges_list.size() - edge_count << " edges out of " << edges_list.size();
auto graph = std::make_shared<NodeBasedDynamicGraph>(static_cast<NodeBasedDynamicGraph::NodeIterator>(number_of_nodes), edges_list);
return graph;
}
auto graph = std::make_shared<NodeBasedDynamicGraph>(
static_cast<NodeBasedDynamicGraph::NodeIterator>(number_of_nodes), edges_list);
template<class SimpleEdgeT>
inline std::shared_ptr<SimpleNodeBasedDynamicGraph>
SimpleNodeBasedDynamicGraphFromEdges(int number_of_nodes, std::vector<SimpleEdgeT> &input_edge_list)
{
static_assert(sizeof(NodeBasedEdgeData) == 16, "changing node based edge data size changes memory consumption");
tbb::parallel_sort(input_edge_list.begin(), input_edge_list.end());
DeallocatingVector<SimpleNodeBasedDynamicGraph::InputEdge> edges_list;
SimpleNodeBasedDynamicGraph::InputEdge edge;
edge.data.capacity = 1;
for (const SimpleEdgeT &import_edge : input_edge_list)
{
if (import_edge.source == import_edge.target)
{
continue;
}
edge.source = import_edge.source;
edge.target = import_edge.target;
edges_list.push_back(edge);
std::swap(edge.source, edge.target);
edges_list.push_back(edge);
}
#ifndef NDEBUG
BOOST_ASSERT(validateNodeBasedGraph(*graph));
#endif
// remove duplicate edges
tbb::parallel_sort(edges_list.begin(), edges_list.end());
NodeID edge_count = 0;
for (NodeID i = 0; i < edges_list.size(); )
{
const NodeID source = edges_list[i].source;
const NodeID target = edges_list[i].target;
// remove eigenloops
if (source == target)
{
i++;
continue;
}
SimpleNodeBasedDynamicGraph::InputEdge forward_edge;
SimpleNodeBasedDynamicGraph::InputEdge reverse_edge;
forward_edge = reverse_edge = edges_list[i];
forward_edge.data.capacity = reverse_edge.data.capacity = INVALID_EDGE_WEIGHT;
// remove parallel edges
while (i < edges_list.size() && edges_list[i].source == source && edges_list[i].target == target)
{
forward_edge.data.capacity = std::min(edges_list[i].data.capacity, forward_edge.data.capacity);
reverse_edge.data.capacity = std::min(edges_list[i].data.capacity, reverse_edge.data.capacity);
++i;
}
// merge edges (s,t) and (t,s) into bidirectional edge
if (forward_edge.data.capacity == reverse_edge.data.capacity)
{
if ((int)forward_edge.data.capacity != INVALID_EDGE_WEIGHT)
{
edges_list[edge_count++] = forward_edge;
}
}
else
{ // insert seperate edges
if (((int)forward_edge.data.capacity) != INVALID_EDGE_WEIGHT)
{
edges_list[edge_count++] = forward_edge;
}
if ((int)reverse_edge.data.capacity != INVALID_EDGE_WEIGHT)
{
edges_list[edge_count++] = reverse_edge;
}
}
}
SimpleLogger().Write() << "merged " << edges_list.size() - edge_count << " edges out of " << edges_list.size();
auto graph = std::make_shared<SimpleNodeBasedDynamicGraph>(number_of_nodes, edges_list);
return graph;
}
+1 -1
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
+3 -4
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -48,9 +48,8 @@ struct OriginalEdgeData
OriginalEdgeData()
: via_node(std::numeric_limits<unsigned>::max()),
name_id(std::numeric_limits<unsigned>::max()),
turn_instruction(TurnInstruction::NoTurn), compressed_geometry(false),
travel_mode(TRAVEL_MODE_INACCESSIBLE)
name_id(std::numeric_limits<unsigned>::max()), turn_instruction(TurnInstruction::NoTurn),
compressed_geometry(false), travel_mode(TRAVEL_MODE_INACCESSIBLE)
{
}
+3 -3
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -36,7 +36,7 @@ class Percent
public:
explicit Percent(unsigned max_value, unsigned step = 5) { reinit(max_value, step); }
// Reinitializes
// Reinitializes
void reinit(unsigned max_value, unsigned step = 5)
{
m_max_value = max_value;
@@ -53,7 +53,7 @@ class Percent
if (current_value >= m_next_threshold)
{
m_next_threshold += m_percent_interval;
printPercent(current_value / (double)m_max_value * 100);
printPercent(current_value / static_cast<double>(m_max_value) * 100.);
}
if (current_value + 1 == m_max_value)
std::cout << " 100%" << std::endl;
+47 -58
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -27,38 +27,44 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "phantom_node.hpp"
PhantomNode::PhantomNode(NodeID forward_node_id, NodeID reverse_node_id, unsigned name_id,
int forward_weight, int reverse_weight, int forward_offset, int reverse_offset,
unsigned packed_geometry_id, FixedPointCoordinate &location,
unsigned short fwd_segment_position,
TravelMode forward_travel_mode, TravelMode backward_travel_mode) :
forward_node_id(forward_node_id),
reverse_node_id(reverse_node_id),
name_id(name_id),
forward_weight(forward_weight),
reverse_weight(reverse_weight),
forward_offset(forward_offset),
reverse_offset(reverse_offset),
packed_geometry_id(packed_geometry_id),
location(location),
fwd_segment_position(fwd_segment_position),
forward_travel_mode(forward_travel_mode),
backward_travel_mode(backward_travel_mode)
{ }
#include "../typedefs.h"
#include "travel_mode.hpp"
PhantomNode::PhantomNode() :
forward_node_id(SPECIAL_NODEID),
reverse_node_id(SPECIAL_NODEID),
name_id(std::numeric_limits<unsigned>::max()),
forward_weight(INVALID_EDGE_WEIGHT),
reverse_weight(INVALID_EDGE_WEIGHT),
forward_offset(0),
reverse_offset(0),
packed_geometry_id(SPECIAL_EDGEID),
fwd_segment_position(0),
forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
{ }
#include <osrm/coordinate.hpp>
#include <limits>
PhantomNode::PhantomNode(NodeID forward_node_id,
NodeID reverse_node_id,
unsigned name_id,
int forward_weight,
int reverse_weight,
int forward_offset,
int reverse_offset,
unsigned packed_geometry_id,
unsigned component_id,
FixedPointCoordinate &location,
unsigned short fwd_segment_position,
TravelMode forward_travel_mode,
TravelMode backward_travel_mode)
: forward_node_id(forward_node_id), reverse_node_id(reverse_node_id), name_id(name_id),
forward_weight(forward_weight), reverse_weight(reverse_weight),
forward_offset(forward_offset), reverse_offset(reverse_offset),
packed_geometry_id(packed_geometry_id), component_id(component_id), location(location),
fwd_segment_position(fwd_segment_position), forward_travel_mode(forward_travel_mode),
backward_travel_mode(backward_travel_mode)
{
}
PhantomNode::PhantomNode()
: forward_node_id(SPECIAL_NODEID), reverse_node_id(SPECIAL_NODEID),
name_id(std::numeric_limits<unsigned>::max()), forward_weight(INVALID_EDGE_WEIGHT),
reverse_weight(INVALID_EDGE_WEIGHT), forward_offset(0), reverse_offset(0),
packed_geometry_id(SPECIAL_EDGEID), component_id(std::numeric_limits<unsigned>::max()),
fwd_segment_position(0), forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
{
}
int PhantomNode::GetForwardWeightPlusOffset() const
{
@@ -80,38 +86,21 @@ int PhantomNode::GetReverseWeightPlusOffset() const
bool PhantomNode::is_bidirected() const
{
return (forward_node_id != SPECIAL_NODEID) &&
(reverse_node_id != SPECIAL_NODEID);
return (forward_node_id != SPECIAL_NODEID) && (reverse_node_id != SPECIAL_NODEID);
}
bool PhantomNode::is_compressed() const
{
return (forward_offset != 0) || (reverse_offset != 0);
}
bool PhantomNode::is_compressed() const { return (forward_offset != 0) || (reverse_offset != 0); }
bool PhantomNode::is_valid(const unsigned number_of_nodes) const
{
return
location.is_valid() &&
(
(forward_node_id < number_of_nodes) ||
(reverse_node_id < number_of_nodes)
) &&
(
(forward_weight != INVALID_EDGE_WEIGHT) ||
(reverse_weight != INVALID_EDGE_WEIGHT)
) &&
(name_id != INVALID_NAMEID
);
}
bool PhantomNode::is_valid() const
{
return location.is_valid() &&
((forward_node_id < number_of_nodes) || (reverse_node_id < number_of_nodes)) &&
((forward_weight != INVALID_EDGE_WEIGHT) || (reverse_weight != INVALID_EDGE_WEIGHT)) &&
(name_id != INVALID_NAMEID);
}
bool PhantomNode::operator==(const PhantomNode & other) const
{
return location == other.location;
}
bool PhantomNode::is_in_tiny_component() const { return component_id != 0; }
bool PhantomNode::is_valid() const { return location.is_valid() && (name_id != INVALID_NAMEID); }
bool PhantomNode::operator==(const PhantomNode &other) const { return location == other.location; }
+60 -20
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -28,23 +28,55 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef PHANTOM_NODES_H
#define PHANTOM_NODES_H
#include <osrm/Coordinate.h>
#include "../data_structures/travel_mode.hpp"
#include "travel_mode.hpp"
#include "../typedefs.h"
#include <osrm/coordinate.hpp>
#include <iostream>
#include <utility>
#include <vector>
struct PhantomNode
{
PhantomNode(NodeID forward_node_id, NodeID reverse_node_id, unsigned name_id,
int forward_weight, int reverse_weight, int forward_offset, int reverse_offset,
unsigned packed_geometry_id, FixedPointCoordinate &location,
PhantomNode(NodeID forward_node_id,
NodeID reverse_node_id,
unsigned name_id,
int forward_weight,
int reverse_weight,
int forward_offset,
int reverse_offset,
unsigned packed_geometry_id,
unsigned component_id,
FixedPointCoordinate &location,
unsigned short fwd_segment_position,
TravelMode forward_travel_mode, TravelMode backward_travel_mode);
TravelMode forward_travel_mode,
TravelMode backward_travel_mode);
PhantomNode();
template <class OtherT> PhantomNode(const OtherT &other, const FixedPointCoordinate &foot_point)
{
forward_node_id = other.forward_edge_based_node_id;
reverse_node_id = other.reverse_edge_based_node_id;
name_id = other.name_id;
forward_weight = other.forward_weight;
reverse_weight = other.reverse_weight;
forward_offset = other.forward_offset;
reverse_offset = other.reverse_offset;
packed_geometry_id = other.packed_geometry_id;
component_id = other.component_id;
location = foot_point;
fwd_segment_position = other.fwd_segment_position;
forward_travel_mode = other.forward_travel_mode;
backward_travel_mode = other.backward_travel_mode;
}
NodeID forward_node_id;
NodeID reverse_node_id;
unsigned name_id;
@@ -53,6 +85,7 @@ struct PhantomNode
int forward_offset;
int reverse_offset;
unsigned packed_geometry_id;
unsigned component_id;
FixedPointCoordinate location;
unsigned short fwd_segment_position;
TravelMode forward_travel_mode : 4;
@@ -70,11 +103,17 @@ struct PhantomNode
bool is_valid() const;
bool operator==(const PhantomNode & other) const;
bool is_in_tiny_component() const;
bool operator==(const PhantomNode &other) const;
};
using PhantomNodeArray = std::vector<std::vector<PhantomNode>>;
class phantom_node_pair : public std::pair<PhantomNode, PhantomNode>
{
};
struct PhantomNodeLists
{
std::vector<PhantomNode> source_phantom_list;
@@ -87,25 +126,26 @@ struct PhantomNodes
PhantomNode target_phantom;
};
inline std::ostream& operator<<(std::ostream &out, const PhantomNodes & pn)
inline std::ostream &operator<<(std::ostream &out, const PhantomNodes &pn)
{
out << "source_coord: " << pn.source_phantom.location << "\n";
out << "target_coord: " << pn.target_phantom.location << std::endl;
return out;
}
inline std::ostream& operator<<(std::ostream &out, const PhantomNode & pn)
inline std::ostream &operator<<(std::ostream &out, const PhantomNode &pn)
{
out << "node1: " << pn.forward_node_id << ", " <<
"node2: " << pn.reverse_node_id << ", " <<
"name: " << pn.name_id << ", " <<
"fwd-w: " << pn.forward_weight << ", " <<
"rev-w: " << pn.reverse_weight << ", " <<
"fwd-o: " << pn.forward_offset << ", " <<
"rev-o: " << pn.reverse_offset << ", " <<
"geom: " << pn.packed_geometry_id << ", " <<
"pos: " << pn.fwd_segment_position << ", " <<
"loc: " << pn.location;
out << "node1: " << pn.forward_node_id << ", "
<< "node2: " << pn.reverse_node_id << ", "
<< "name: " << pn.name_id << ", "
<< "fwd-w: " << pn.forward_weight << ", "
<< "rev-w: " << pn.reverse_weight << ", "
<< "fwd-o: " << pn.forward_offset << ", "
<< "rev-o: " << pn.reverse_offset << ", "
<< "geom: " << pn.packed_geometry_id << ", "
<< "comp: " << pn.component_id << ", "
<< "pos: " << pn.fwd_segment_position << ", "
<< "loc: " << pn.location;
return out;
}
+8 -10
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -25,11 +25,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef QUERYEDGE_HPP_
#define QUERYEDGE_HPP_
#ifndef QUERYEDGE_HPP
#define QUERYEDGE_HPP
#include "../typedefs.h"
#include <tuple>
struct QueryEdge
{
NodeID source;
@@ -60,13 +62,9 @@ struct QueryEdge
{
}
bool operator<(const QueryEdge &right) const
bool operator<(const QueryEdge &rhs) const
{
if (source != right.source)
{
return source < right.source;
}
return target < right.target;
return std::tie(source, target) < std::tie(rhs.source, rhs.target);
}
bool operator==(const QueryEdge &right) const
@@ -78,4 +76,4 @@ struct QueryEdge
}
};
#endif /* QUERYEDGE_HPP_ */
#endif // QUERYEDGE_HPP
+5 -5
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -30,16 +30,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
#include <osrm/coordinate.hpp>
#include <limits>
struct QueryNode
{
using key_type = NodeID; // type of NodeID
using value_type = int; // type of lat,lons
using value_type = int; // type of lat,lons
explicit QueryNode(int lat, int lon, NodeID node_id) : lat(lat), lon(lon), node_id(node_id) {}
QueryNode()
@@ -78,7 +78,7 @@ struct QueryNode
break;
}
BOOST_ASSERT_MSG(false, "should not happen");
return std::numeric_limits<unsigned>::max();
return std::numeric_limits<int>::lowest();
}
};
+42 -39
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -28,7 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef RANGE_TABLE_HPP
#define RANGE_TABLE_HPP
#include "../Util/integer_range.hpp"
#include "../util/integer_range.hpp"
#include "shared_memory_factory.hpp"
#include "shared_memory_vector_wrapper.hpp"
@@ -41,13 +41,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* and otherwise the compiler gets confused.
*/
template<unsigned BLOCK_SIZE=16, bool USE_SHARED_MEMORY = false> class RangeTable;
template <unsigned BLOCK_SIZE = 16, bool USE_SHARED_MEMORY = false> class RangeTable;
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::ostream& operator<<(std::ostream &out, const RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table);
template <unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::ostream &operator<<(std::ostream &out, const RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table);
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::istream& operator>>(std::istream &in, RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table);
template <unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::istream &operator>>(std::istream &in, RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table);
/**
* Stores adjacent ranges in a compressed format.
@@ -58,33 +58,34 @@ std::istream& operator>>(std::istream &in, RangeTable<BLOCK_SIZE, USE_SHARED_MEM
* But each block consists of an absolute value and BLOCK_SIZE differential values.
* So the effective block size is sizeof(unsigned) + BLOCK_SIZE.
*/
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
class RangeTable
template <unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY> class RangeTable
{
public:
public:
using BlockT = std::array<unsigned char, BLOCK_SIZE>;
using BlockContainerT = typename ShM<BlockT, USE_SHARED_MEMORY>::vector;
using OffsetContainerT = typename ShM<unsigned, USE_SHARED_MEMORY>::vector;
using RangeT = osrm::range<unsigned>;
friend std::ostream& operator<< <>(std::ostream &out, const RangeTable &table);
friend std::istream& operator>> <>(std::istream &in, RangeTable &table);
friend std::ostream &operator<<<>(std::ostream &out, const RangeTable &table);
friend std::istream &operator>><>(std::istream &in, RangeTable &table);
RangeTable() : sum_lengths(0) {}
// for loading from shared memory
explicit RangeTable(OffsetContainerT& external_offsets, BlockContainerT& external_blocks, const unsigned sum_lengths)
: sum_lengths(sum_lengths)
explicit RangeTable(OffsetContainerT &external_offsets,
BlockContainerT &external_blocks,
const unsigned sum_lengths)
: sum_lengths(sum_lengths)
{
block_offsets.swap(external_offsets);
diff_blocks.swap(external_blocks);
}
// construct table from length vector
explicit RangeTable(const std::vector<unsigned>& lengths)
explicit RangeTable(const std::vector<unsigned> &lengths)
{
const unsigned number_of_blocks = [&lengths]() {
const unsigned number_of_blocks = [&lengths]()
{
unsigned num = (lengths.size() + 1) / (BLOCK_SIZE + 1);
if ((lengths.size() + 1) % (BLOCK_SIZE + 1) != 0)
{
@@ -116,8 +117,8 @@ public:
block_sum += last_length;
}
BOOST_ASSERT((block_idx == 0 && block_offsets[block_counter] == lengths_prefix_sum)
|| lengths_prefix_sum == (block_offsets[block_counter]+block_sum));
BOOST_ASSERT((block_idx == 0 && block_offsets[block_counter] == lengths_prefix_sum) ||
lengths_prefix_sum == (block_offsets[block_counter] + block_sum));
// block is full
if (BLOCK_SIZE == block_idx)
@@ -136,7 +137,7 @@ public:
}
// Last block can't be finished because we didn't add the sentinel
BOOST_ASSERT (block_counter == (number_of_blocks - 1));
BOOST_ASSERT(block_counter == (number_of_blocks - 1));
// one block missing: starts with guard value
if (0 == block_idx)
@@ -155,7 +156,8 @@ public:
}
diff_blocks.push_back(block);
BOOST_ASSERT(diff_blocks.size() == number_of_blocks && block_offsets.size() == number_of_blocks);
BOOST_ASSERT(diff_blocks.size() == number_of_blocks &&
block_offsets.size() == number_of_blocks);
sum_lengths = lengths_prefix_sum;
}
@@ -172,7 +174,7 @@ public:
unsigned begin_idx = 0;
unsigned end_idx = 0;
begin_idx = block_offsets[block_idx];
const BlockT& block = diff_blocks[block_idx];
const BlockT &block = diff_blocks[block_idx];
if (internal_idx > 0)
{
begin_idx += PrefixSumAtIndex(internal_idx - 1, block);
@@ -195,9 +197,9 @@ public:
return osrm::irange(begin_idx, end_idx);
}
private:
inline unsigned PrefixSumAtIndex(int index, const BlockT& block) const;
private:
inline unsigned PrefixSumAtIndex(int index, const BlockT &block) const;
// contains offset for each differential block
OffsetContainerT block_offsets;
@@ -206,8 +208,9 @@ private:
unsigned sum_lengths;
};
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
unsigned RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY>::PrefixSumAtIndex(int index, const BlockT& block) const
template <unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
unsigned RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY>::PrefixSumAtIndex(int index,
const BlockT &block) const
{
// this loop looks inefficent, but a modern compiler
// will emit nice SIMD here, at least for sensible block sizes. (I checked.)
@@ -220,39 +223,39 @@ unsigned RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY>::PrefixSumAtIndex(int index,
return sum;
}
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::ostream& operator<<(std::ostream &out, const RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table)
template <unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::ostream &operator<<(std::ostream &out, const RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table)
{
// write number of block
const unsigned number_of_blocks = table.diff_blocks.size();
out.write((char *) &number_of_blocks, sizeof(unsigned));
out.write((char *)&number_of_blocks, sizeof(unsigned));
// write total length
out.write((char *) &table.sum_lengths, sizeof(unsigned));
out.write((char *)&table.sum_lengths, sizeof(unsigned));
// write block offsets
out.write((char *) table.block_offsets.data(), sizeof(unsigned) * table.block_offsets.size());
out.write((char *)table.block_offsets.data(), sizeof(unsigned) * table.block_offsets.size());
// write blocks
out.write((char *) table.diff_blocks.data(), BLOCK_SIZE * table.diff_blocks.size());
out.write((char *)table.diff_blocks.data(), BLOCK_SIZE * table.diff_blocks.size());
return out;
}
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::istream& operator>>(std::istream &in, RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table)
template <unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::istream &operator>>(std::istream &in, RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table)
{
// read number of block
unsigned number_of_blocks;
in.read((char *) &number_of_blocks, sizeof(unsigned));
in.read((char *)&number_of_blocks, sizeof(unsigned));
// read total length
in.read((char *) &table.sum_lengths, sizeof(unsigned));
in.read((char *)&table.sum_lengths, sizeof(unsigned));
table.block_offsets.resize(number_of_blocks);
table.diff_blocks.resize(number_of_blocks);
// read block offsets
in.read((char *) table.block_offsets.data(), sizeof(unsigned) * number_of_blocks);
in.read((char *)table.block_offsets.data(), sizeof(unsigned) * number_of_blocks);
// read blocks
in.read((char *) table.diff_blocks.data(), BLOCK_SIZE * number_of_blocks);
in.read((char *)table.diff_blocks.data(), BLOCK_SIZE * number_of_blocks);
return in;
}
#endif //RANGE_TABLE_HPP
#endif // RANGE_TABLE_HPP
+78 -66
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -28,8 +28,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef RECTANGLE_HPP
#define RECTANGLE_HPP
#include "coordinate_calculation.hpp"
#include <boost/assert.hpp>
#include <osrm/coordinate.hpp>
#include <algorithm>
#include <cstdint>
#include <limits>
@@ -37,15 +41,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// TODO: Make template type, add tests
struct RectangleInt2D
{
RectangleInt2D() : min_lon(std::numeric_limits<int32_t>::max()),
max_lon(std::numeric_limits<int32_t>::min()),
min_lat(std::numeric_limits<int32_t>::max()),
max_lat(std::numeric_limits<int32_t>::min()) {}
RectangleInt2D()
: min_lon(std::numeric_limits<int32_t>::max()),
max_lon(std::numeric_limits<int32_t>::min()),
min_lat(std::numeric_limits<int32_t>::max()), max_lat(std::numeric_limits<int32_t>::min())
{
}
int32_t min_lon, max_lon;
int32_t min_lat, max_lat;
inline void MergeBoundingBoxes(const RectangleInt2D &other)
void MergeBoundingBoxes(const RectangleInt2D &other)
{
min_lon = std::min(min_lon, other.min_lon);
max_lon = std::max(max_lon, other.max_lon);
@@ -57,7 +63,7 @@ struct RectangleInt2D
BOOST_ASSERT(max_lon != std::numeric_limits<int32_t>::min());
}
inline FixedPointCoordinate Centroid() const
FixedPointCoordinate Centroid() const
{
FixedPointCoordinate centroid;
// The coordinates of the midpoints are given by:
@@ -67,7 +73,7 @@ struct RectangleInt2D
return centroid;
}
inline bool Intersects(const RectangleInt2D &other) const
bool Intersects(const RectangleInt2D &other) const
{
FixedPointCoordinate upper_left(other.max_lat, other.min_lon);
FixedPointCoordinate upper_right(other.max_lat, other.max_lon);
@@ -78,7 +84,7 @@ struct RectangleInt2D
Contains(lower_left));
}
inline float GetMinDist(const FixedPointCoordinate &location) const
float GetMinDist(const FixedPointCoordinate &location) const
{
const bool is_contained = Contains(location);
if (is_contained)
@@ -88,66 +94,74 @@ struct RectangleInt2D
enum Direction
{
INVALID = 0,
NORTH = 1,
SOUTH = 2,
EAST = 4,
INVALID = 0,
NORTH = 1,
SOUTH = 2,
EAST = 4,
NORTH_EAST = 5,
SOUTH_EAST = 6,
WEST = 8,
WEST = 8,
NORTH_WEST = 9,
SOUTH_WEST = 10
};
Direction d = INVALID;
if (location.lat > max_lat)
d = (Direction) (d | NORTH);
d = (Direction)(d | NORTH);
else if (location.lat < min_lat)
d = (Direction) (d | SOUTH);
d = (Direction)(d | SOUTH);
if (location.lon > max_lon)
d = (Direction) (d | EAST);
d = (Direction)(d | EAST);
else if (location.lon < min_lon)
d = (Direction) (d | WEST);
d = (Direction)(d | WEST);
BOOST_ASSERT(d != INVALID);
float min_dist = std::numeric_limits<float>::max();
switch (d)
{
case NORTH:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(max_lat, location.lon));
break;
case SOUTH:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(min_lat, location.lon));
break;
case WEST:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(location.lat, min_lon));
break;
case EAST:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(location.lat, max_lon));
break;
case NORTH_EAST:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(max_lat, max_lon));
break;
case NORTH_WEST:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(max_lat, min_lon));
break;
case SOUTH_EAST:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(min_lat, max_lon));
break;
case SOUTH_WEST:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(min_lat, min_lon));
break;
default:
break;
case NORTH:
min_dist = coordinate_calculation::euclidean_distance(
location, FixedPointCoordinate(max_lat, location.lon));
break;
case SOUTH:
min_dist = coordinate_calculation::euclidean_distance(
location, FixedPointCoordinate(min_lat, location.lon));
break;
case WEST:
min_dist = coordinate_calculation::euclidean_distance(
location, FixedPointCoordinate(location.lat, min_lon));
break;
case EAST:
min_dist = coordinate_calculation::euclidean_distance(
location, FixedPointCoordinate(location.lat, max_lon));
break;
case NORTH_EAST:
min_dist = coordinate_calculation::euclidean_distance(
location, FixedPointCoordinate(max_lat, max_lon));
break;
case NORTH_WEST:
min_dist = coordinate_calculation::euclidean_distance(
location, FixedPointCoordinate(max_lat, min_lon));
break;
case SOUTH_EAST:
min_dist = coordinate_calculation::euclidean_distance(
location, FixedPointCoordinate(min_lat, max_lon));
break;
case SOUTH_WEST:
min_dist = coordinate_calculation::euclidean_distance(
location, FixedPointCoordinate(min_lat, min_lon));
break;
default:
break;
}
BOOST_ASSERT(min_dist != std::numeric_limits<float>::max());
BOOST_ASSERT(min_dist < std::numeric_limits<float>::max());
return min_dist;
}
inline float GetMinMaxDist(const FixedPointCoordinate &location) const
float GetMinMaxDist(const FixedPointCoordinate &location) const
{
float min_max_dist = std::numeric_limits<float>::max();
// Get minmax distance to each of the four sides
@@ -156,38 +170,36 @@ struct RectangleInt2D
const FixedPointCoordinate lower_right(min_lat, max_lon);
const FixedPointCoordinate lower_left(min_lat, min_lon);
min_max_dist = std::min(
min_max_dist,
std::max(
FixedPointCoordinate::ApproximateEuclideanDistance(location, upper_left),
FixedPointCoordinate::ApproximateEuclideanDistance(location, upper_right)));
min_max_dist =
std::min(min_max_dist,
std::max(coordinate_calculation::euclidean_distance(location, upper_left),
coordinate_calculation::euclidean_distance(location, upper_right)));
min_max_dist = std::min(
min_max_dist,
std::max(
FixedPointCoordinate::ApproximateEuclideanDistance(location, upper_right),
FixedPointCoordinate::ApproximateEuclideanDistance(location, lower_right)));
min_max_dist =
std::min(min_max_dist,
std::max(coordinate_calculation::euclidean_distance(location, upper_right),
coordinate_calculation::euclidean_distance(location, lower_right)));
min_max_dist = std::min(
min_max_dist,
std::max(FixedPointCoordinate::ApproximateEuclideanDistance(location, lower_right),
FixedPointCoordinate::ApproximateEuclideanDistance(location, lower_left)));
min_max_dist =
std::min(min_max_dist,
std::max(coordinate_calculation::euclidean_distance(location, lower_right),
coordinate_calculation::euclidean_distance(location, lower_left)));
min_max_dist = std::min(
min_max_dist,
std::max(FixedPointCoordinate::ApproximateEuclideanDistance(location, lower_left),
FixedPointCoordinate::ApproximateEuclideanDistance(location, upper_left)));
min_max_dist =
std::min(min_max_dist,
std::max(coordinate_calculation::euclidean_distance(location, lower_left),
coordinate_calculation::euclidean_distance(location, upper_left)));
return min_max_dist;
}
inline bool Contains(const FixedPointCoordinate &location) const
bool Contains(const FixedPointCoordinate &location) const
{
const bool lats_contained = (location.lat >= min_lat) && (location.lat <= max_lat);
const bool lons_contained = (location.lon >= min_lon) && (location.lon <= max_lon);
return lats_contained && lons_contained;
}
inline friend std::ostream &operator<<(std::ostream &out, const RectangleInt2D &rect)
friend std::ostream &operator<<(std::ostream &out, const RectangleInt2D &rect)
{
out << rect.min_lat / COORDINATE_PRECISION << "," << rect.min_lon / COORDINATE_PRECISION
<< " " << rect.max_lat / COORDINATE_PRECISION << ","
+14 -12
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -77,11 +77,15 @@ struct TurnRestriction
}
};
/**
* This is just a wrapper around TurnRestriction used in the extractor.
*
* Could be merged with TurnRestriction. For now the type-destiction makes sense
* as the format in which the restriction is presented in the extractor and in the
* preprocessing is different. (see restriction_parser.cpp)
*/
struct InputRestrictionContainer
{
// EdgeID fromWay;
// EdgeID toWay;
// NodeID via_node;
TurnRestriction restriction;
InputRestrictionContainer(EdgeID fromWay, EdgeID toWay, EdgeID vw)
@@ -107,21 +111,19 @@ struct InputRestrictionContainer
struct CmpRestrictionContainerByFrom
{
typedef InputRestrictionContainer value_type;
inline bool operator()(const InputRestrictionContainer &a,
const InputRestrictionContainer &b) const
using value_type = InputRestrictionContainer;
bool operator()(const InputRestrictionContainer &a, const InputRestrictionContainer &b) const
{
return a.restriction.from.way < b.restriction.from.way;
}
inline value_type max_value() const { return InputRestrictionContainer::max_value(); }
inline value_type min_value() const { return InputRestrictionContainer::min_value(); }
value_type max_value() const { return InputRestrictionContainer::max_value(); }
value_type min_value() const { return InputRestrictionContainer::min_value(); }
};
struct CmpRestrictionContainerByTo
{
typedef InputRestrictionContainer value_type;
inline bool operator()(const InputRestrictionContainer &a,
const InputRestrictionContainer &b) const
using value_type = InputRestrictionContainer;
bool operator()(const InputRestrictionContainer &a, const InputRestrictionContainer &b) const
{
return a.restriction.to.way < b.restriction.to.way;
}
+53 -49
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -27,54 +27,51 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "restriction_map.hpp"
RestrictionMap::RestrictionMap(const std::vector<TurnRestriction> &restriction_list)
: m_count(0)
RestrictionMap::RestrictionMap(const std::vector<TurnRestriction> &restriction_list) : m_count(0)
{
// decompose restriction consisting of a start, via and end node into a
// a pair of starting edge and a list of all end nodes
for (auto &restriction : restriction_list)
{
// decompose restriction consisting of a start, via and end node into a
// a pair of starting edge and a list of all end nodes
for (auto &restriction : restriction_list)
m_restriction_start_nodes.insert(restriction.from.node);
m_no_turn_via_node_set.insert(restriction.via.node);
RestrictionSource restriction_source = {restriction.from.node, restriction.via.node};
std::size_t index;
auto restriction_iter = m_restriction_map.find(restriction_source);
if (restriction_iter == m_restriction_map.end())
{
m_restriction_start_nodes.insert(restriction.from.node);
m_no_turn_via_node_set.insert(restriction.via.node);
RestrictionSource restriction_source = {restriction.from.node, restriction.via.node};
unsigned index;
auto restriction_iter = m_restriction_map.find(restriction_source);
if (restriction_iter == m_restriction_map.end())
{
index = m_restriction_bucket_list.size();
m_restriction_bucket_list.resize(index + 1);
m_restriction_map.emplace(restriction_source, index);
}
else
{
index = restriction_iter->second;
// Map already contains an is_only_*-restriction
if (m_restriction_bucket_list.at(index).begin()->is_only)
{
continue;
}
else if (restriction.flags.is_only)
{
// We are going to insert an is_only_*-restriction. There can be only one.
m_count -= m_restriction_bucket_list.at(index).size();
m_restriction_bucket_list.at(index).clear();
}
}
++m_count;
m_restriction_bucket_list.at(index)
.emplace_back(restriction.to.node, restriction.flags.is_only);
index = m_restriction_bucket_list.size();
m_restriction_bucket_list.resize(index + 1);
m_restriction_map.emplace(restriction_source, index);
}
else
{
index = restriction_iter->second;
// Map already contains an is_only_*-restriction
if (m_restriction_bucket_list.at(index).begin()->is_only)
{
continue;
}
else if (restriction.flags.is_only)
{
// We are going to insert an is_only_*-restriction. There can be only one.
m_count -= m_restriction_bucket_list.at(index).size();
m_restriction_bucket_list.at(index).clear();
}
}
++m_count;
m_restriction_bucket_list.at(index)
.emplace_back(restriction.to.node, restriction.flags.is_only);
}
}
bool RestrictionMap::IsViaNode(const NodeID node) const
{
return m_no_turn_via_node_set.find(node) != m_no_turn_via_node_set.end();
}
// Replaces start edge (v, w) with (u, w). Only start node changes.
void RestrictionMap::FixupStartingTurnRestriction(const NodeID node_u,
const NodeID node_v,
@@ -145,18 +142,25 @@ bool RestrictionMap::CheckIfTurnIsRestricted(const NodeID node_u,
}
const auto restriction_iter = m_restriction_map.find({node_u, node_v});
if (restriction_iter != m_restriction_map.end())
if (restriction_iter == m_restriction_map.end())
{
const unsigned index = restriction_iter->second;
const auto &bucket = m_restriction_bucket_list.at(index);
for (const RestrictionTarget &restriction_target : bucket)
return false;
}
const unsigned index = restriction_iter->second;
const auto &bucket = m_restriction_bucket_list.at(index);
for (const RestrictionTarget &restriction_target : bucket)
{
if (node_w == restriction_target.target_node && // target found
!restriction_target.is_only) // and not an only_-restr.
{
if ((node_w == restriction_target.target_node) && // target found
(!restriction_target.is_only) // and not an only_-restr.
)
{
return true;
}
return true;
}
if (node_w != restriction_target.target_node && // target not found
restriction_target.is_only) // and is an only restriction
{
return true;
}
}
return false;
+17 -26
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -28,14 +28,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef RESTRICTION_MAP_HPP
#define RESTRICTION_MAP_HPP
#include <memory>
#include "restriction.hpp"
#include "../Util/std_hash.hpp"
#include "../util/std_hash.hpp"
#include "../typedefs.h"
#include <boost/assert.hpp>
#include <memory>
#include <unordered_map>
#include <unordered_set>
#include <vector>
@@ -45,9 +44,7 @@ struct RestrictionSource
NodeID start_node;
NodeID via_node;
RestrictionSource(NodeID start, NodeID via) : start_node(start), via_node(via)
{
}
RestrictionSource(NodeID start, NodeID via) : start_node(start), via_node(via) {}
friend inline bool operator==(const RestrictionSource &lhs, const RestrictionSource &rhs)
{
@@ -60,9 +57,7 @@ struct RestrictionTarget
NodeID target_node;
bool is_only;
explicit RestrictionTarget(NodeID target, bool only) : target_node(target), is_only(only)
{
}
explicit RestrictionTarget(NodeID target, bool only) : target_node(target), is_only(only) {}
friend inline bool operator==(const RestrictionTarget &lhs, const RestrictionTarget &rhs)
{
@@ -96,14 +91,15 @@ template <> struct hash<RestrictionTarget>
class RestrictionMap
{
public:
RestrictionMap() : m_count(0) {};
RestrictionMap(const std::vector<TurnRestriction> &restriction_list);
// Replace end v with w in each turn restriction containing u as via node
template<class GraphT>
template <class GraphT>
void FixupArrivingTurnRestriction(const NodeID node_u,
const NodeID node_v,
const NodeID node_w,
const std::shared_ptr<GraphT> &graph)
const GraphT &graph)
{
BOOST_ASSERT(node_u != SPECIAL_NODEID);
BOOST_ASSERT(node_v != SPECIAL_NODEID);
@@ -117,9 +113,9 @@ class RestrictionMap
// find all potential start edges. It is more efficent to get a (small) list
// of potential start edges than iterating over all buckets
std::vector<NodeID> predecessors;
for (const EdgeID current_edge_id : graph->GetAdjacentEdgeRange(node_u))
for (const EdgeID current_edge_id : graph.GetAdjacentEdgeRange(node_u))
{
const NodeID target = graph->GetTarget(current_edge_id);
const NodeID target = graph.GetTarget(current_edge_id);
if (node_v != target)
{
predecessors.push_back(target);
@@ -136,6 +132,7 @@ class RestrictionMap
const unsigned index = restriction_iterator->second;
auto &bucket = m_restriction_bucket_list.at(index);
for (RestrictionTarget &restriction_target : bucket)
{
if (node_v == restriction_target.target_node)
@@ -148,24 +145,18 @@ class RestrictionMap
bool IsViaNode(const NodeID node) const;
// Replaces start edge (v, w) with (u, w). Only start node changes.
void FixupStartingTurnRestriction(const NodeID node_u,
const NodeID node_v,
const NodeID node_w);
void
FixupStartingTurnRestriction(const NodeID node_u, const NodeID node_v, const NodeID node_w);
// Check if edge (u, v) is the start of any turn restriction.
// If so returns id of first target node.
NodeID CheckForEmanatingIsOnlyTurn(const NodeID node_u, const NodeID node_v) const;
// Checks if turn <u,v,w> is actually a turn restriction.
bool CheckIfTurnIsRestricted(const NodeID node_u,
const NodeID node_v,
const NodeID node_w) const;
bool
CheckIfTurnIsRestricted(const NodeID node_u, const NodeID node_v, const NodeID node_w) const;
std::size_t size()
{
return m_count;
}
std::size_t size() { return m_count; }
private:
// check of node is the start of any restriction
@@ -182,4 +173,4 @@ class RestrictionMap
std::unordered_set<NodeID> m_no_turn_via_node_set;
};
#endif //RESTRICTION_MAP_HPP
#endif // RESTRICTION_MAP_HPP
+32 -8
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -25,15 +25,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <osrm/RouteParameters.h>
#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/sequence/intrinsic.hpp>
#include <boost/fusion/include/at_c.hpp>
#include <osrm/route_parameters.hpp>
#include "../algorithms/polyline_compressor.hpp"
RouteParameters::RouteParameters()
: zoom_level(18), print_instructions(false), alternate_route(true), geometry(true),
compression(true), deprecatedAPI(false), uturn_default(false), check_sum(-1), num_results(1)
compression(true), deprecatedAPI(false), uturn_default(false), classify(false),
matching_beta(-1.0), gps_precision(-1.0), check_sum(-1), num_results(1)
{
}
@@ -83,6 +86,12 @@ void RouteParameters::setInstructionFlag(const bool flag) { print_instructions =
void RouteParameters::setService(const std::string &service_string) { service = service_string; }
void RouteParameters::setClassify(const bool flag) { classify = flag; }
void RouteParameters::setMatchingBeta(const double beta) { matching_beta = beta; }
void RouteParameters::setGPSPrecision(const double precision) { gps_precision = precision; }
void RouteParameters::setOutputFormat(const std::string &format) { output_format = format; }
void RouteParameters::setJSONpParameter(const std::string &parameter)
@@ -99,6 +108,15 @@ void RouteParameters::addHint(const std::string &hint)
}
}
void RouteParameters::addTimestamp(const unsigned timestamp)
{
timestamps.resize(coordinates.size());
if (!timestamps.empty())
{
timestamps.back() = timestamp;
}
}
void RouteParameters::setLanguage(const std::string &language_string)
{
language = language_string;
@@ -108,10 +126,16 @@ void RouteParameters::setGeometryFlag(const bool flag) { geometry = flag; }
void RouteParameters::setCompressionFlag(const bool flag) { compression = flag; }
void
RouteParameters::addCoordinate(const boost::fusion::vector<double, double> &transmitted_coordinates)
void RouteParameters::addCoordinate(
const boost::fusion::vector<double, double> &received_coordinates)
{
coordinates.emplace_back(
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<0>(transmitted_coordinates)),
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<1>(transmitted_coordinates)));
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)),
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<1>(received_coordinates)));
}
void RouteParameters::getCoordinatesFromGeometry(const std::string geometry_string)
{
PolylineCompressor pc;
coordinates = pc.decode_string(geometry_string);
}
+10 -4
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -31,6 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "search_engine_data.hpp"
#include "../routing_algorithms/alternative_path.hpp"
#include "../routing_algorithms/many_to_many.hpp"
#include "../routing_algorithms/map_matching.hpp"
#include "../routing_algorithms/shortest_path.hpp"
#include <type_traits>
@@ -45,13 +46,18 @@ template <class DataFacadeT> class SearchEngine
ShortestPathRouting<DataFacadeT> shortest_path;
AlternativeRouting<DataFacadeT> alternative_path;
ManyToManyRouting<DataFacadeT> distance_table;
MapMatching<DataFacadeT> map_matching;
explicit SearchEngine(DataFacadeT *facade)
: facade(facade), shortest_path(facade, engine_working_data),
alternative_path(facade, engine_working_data), distance_table(facade, engine_working_data)
: facade(facade),
shortest_path(facade, engine_working_data),
alternative_path(facade, engine_working_data),
distance_table(facade, engine_working_data),
map_matching(facade, engine_working_data)
{
static_assert(!std::is_pointer<DataFacadeT>::value, "don't instantiate with ptr type");
static_assert(std::is_object<DataFacadeT>::value, "don't instantiate with void, function, or reference");
static_assert(std::is_object<DataFacadeT>::value,
"don't instantiate with void, function, or reference");
}
~SearchEngine() {}
+19 -19
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2013, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -31,63 +31,63 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
void SearchEngineData::InitializeOrClearFirstThreadLocalStorage(const unsigned number_of_nodes)
{
if (forwardHeap.get())
if (forward_heap_1.get())
{
forwardHeap->Clear();
forward_heap_1->Clear();
}
else
{
forwardHeap.reset(new QueryHeap(number_of_nodes));
forward_heap_1.reset(new QueryHeap(number_of_nodes));
}
if (backwardHeap.get())
if (reverse_heap_1.get())
{
backwardHeap->Clear();
reverse_heap_1->Clear();
}
else
{
backwardHeap.reset(new QueryHeap(number_of_nodes));
reverse_heap_1.reset(new QueryHeap(number_of_nodes));
}
}
void SearchEngineData::InitializeOrClearSecondThreadLocalStorage(const unsigned number_of_nodes)
{
if (forwardHeap2.get())
if (forward_heap_2.get())
{
forwardHeap2->Clear();
forward_heap_2->Clear();
}
else
{
forwardHeap2.reset(new QueryHeap(number_of_nodes));
forward_heap_2.reset(new QueryHeap(number_of_nodes));
}
if (backwardHeap2.get())
if (reverse_heap_2.get())
{
backwardHeap2->Clear();
reverse_heap_2->Clear();
}
else
{
backwardHeap2.reset(new QueryHeap(number_of_nodes));
reverse_heap_2.reset(new QueryHeap(number_of_nodes));
}
}
void SearchEngineData::InitializeOrClearThirdThreadLocalStorage(const unsigned number_of_nodes)
{
if (forwardHeap3.get())
if (forward_heap_3.get())
{
forwardHeap3->Clear();
forward_heap_3->Clear();
}
else
{
forwardHeap3.reset(new QueryHeap(number_of_nodes));
forward_heap_3.reset(new QueryHeap(number_of_nodes));
}
if (backwardHeap3.get())
if (reverse_heap_3.get())
{
backwardHeap3->Clear();
reverse_heap_3->Clear();
}
else
{
backwardHeap3.reset(new QueryHeap(number_of_nodes));
reverse_heap_3.reset(new QueryHeap(number_of_nodes));
}
}
+7 -7
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -44,12 +44,12 @@ struct SearchEngineData
using QueryHeap = BinaryHeap<NodeID, NodeID, int, HeapData, UnorderedMapStorage<NodeID, int>>;
using SearchEngineHeapPtr = boost::thread_specific_ptr<QueryHeap>;
static SearchEngineHeapPtr forwardHeap;
static SearchEngineHeapPtr backwardHeap;
static SearchEngineHeapPtr forwardHeap2;
static SearchEngineHeapPtr backwardHeap2;
static SearchEngineHeapPtr forwardHeap3;
static SearchEngineHeapPtr backwardHeap3;
static SearchEngineHeapPtr forward_heap_1;
static SearchEngineHeapPtr reverse_heap_1;
static SearchEngineHeapPtr forward_heap_2;
static SearchEngineHeapPtr reverse_heap_2;
static SearchEngineHeapPtr forward_heap_3;
static SearchEngineHeapPtr reverse_heap_3;
void InitializeOrClearFirstThreadLocalStorage(const unsigned number_of_nodes);
+5 -5
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -25,15 +25,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SEGMENT_INFORMATION_H
#define SEGMENT_INFORMATION_H
#ifndef SEGMENT_INFORMATION_HPP
#define SEGMENT_INFORMATION_HPP
#include "turn_instructions.hpp"
#include "../data_structures/travel_mode.hpp"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <osrm/coordinate.hpp>
// Struct fits everything in one cache line
struct SegmentInformation
@@ -75,4 +75,4 @@ struct SegmentInformation
}
};
#endif /* SEGMENT_INFORMATION_H */
#endif /* SEGMENT_INFORMATION_HPP */
+35 -24
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -28,8 +28,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef SHARED_MEMORY_FACTORY_HPP
#define SHARED_MEMORY_FACTORY_HPP
#include "../Util/OSRMException.h"
#include "../Util/simple_logger.hpp"
#include "../util/osrm_exception.hpp"
#include "../util/simple_logger.hpp"
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
@@ -123,8 +123,8 @@ class SharedMemory
{
Remove(key);
}
shm = boost::interprocess::xsi_shared_memory(
boost::interprocess::open_or_create, key, size);
shm = boost::interprocess::xsi_shared_memory(boost::interprocess::open_or_create, key,
size);
#ifdef __linux__
if (-1 == shmctl(shm.get_shmid(), SHM_LOCK, 0))
{
@@ -150,7 +150,10 @@ class SharedMemory
boost::interprocess::xsi_key key(lock_file().string().c_str(), id);
result = RegionExists(key);
}
catch (...) { result = false; }
catch (...)
{
result = false;
}
return result;
}
@@ -165,8 +168,14 @@ class SharedMemory
static bool RegionExists(const boost::interprocess::xsi_key &key)
{
bool result = true;
try { boost::interprocess::xsi_shared_memory shm(boost::interprocess::open_only, key); }
catch (...) { result = false; }
try
{
boost::interprocess::xsi_shared_memory shm(boost::interprocess::open_only, key);
}
catch (...)
{
result = false;
}
return result;
}
@@ -198,12 +207,12 @@ class SharedMemory
// Windows - specific code
class SharedMemory
{
SharedMemory(const SharedMemory&) = delete;
SharedMemory(const SharedMemory &) = delete;
// Remove shared memory on destruction
class shm_remove
{
private:
shm_remove(const shm_remove&) = delete;
shm_remove(const shm_remove &) = delete;
char *m_shmid;
bool m_initialized;
@@ -242,8 +251,7 @@ class SharedMemory
if (0 == size)
{ // read_only
shm = boost::interprocess::shared_memory_object(
boost::interprocess::open_only,
key,
boost::interprocess::open_only, key,
read_write ? boost::interprocess::read_write : boost::interprocess::read_only);
region = boost::interprocess::mapped_region(
shm, read_write ? boost::interprocess::read_write : boost::interprocess::read_only);
@@ -255,8 +263,8 @@ class SharedMemory
{
Remove(key);
}
shm = boost::interprocess::shared_memory_object(
boost::interprocess::open_or_create, key, boost::interprocess::read_write);
shm = boost::interprocess::shared_memory_object(boost::interprocess::open_or_create,
key, boost::interprocess::read_write);
shm.truncate(size);
region = boost::interprocess::mapped_region(shm, boost::interprocess::read_write);
@@ -274,7 +282,10 @@ class SharedMemory
build_key(id, k);
result = RegionExists(k);
}
catch (...) { result = false; }
catch (...)
{
result = false;
}
return result;
}
@@ -286,20 +297,20 @@ class SharedMemory
}
private:
static void build_key(int id, char *key)
{
sprintf(key, "%s.%d", "osrm.lock", id);
}
static void build_key(int id, char *key) { sprintf(key, "%s.%d", "osrm.lock", id); }
static bool RegionExists(const char *key)
{
bool result = true;
try
{
boost::interprocess::shared_memory_object shm(
boost::interprocess::open_only, key, boost::interprocess::read_write);
boost::interprocess::shared_memory_object shm(boost::interprocess::open_only, key,
boost::interprocess::read_write);
}
catch (...)
{
result = false;
}
catch (...) { result = false; }
return result;
}
@@ -344,7 +355,7 @@ template <class LockFileT = OSRMLockFile> class SharedMemoryFactory_tmpl
{
if (0 == size)
{
throw OSRMException("lock file does not exist, exiting");
throw osrm::exception("lock file does not exist, exiting");
}
else
{
@@ -358,7 +369,7 @@ template <class LockFileT = OSRMLockFile> class SharedMemoryFactory_tmpl
{
SimpleLogger().Write(logWARNING) << "caught exception: " << e.what() << ", code "
<< e.get_error_code();
throw OSRMException(e.what());
throw osrm::exception(e.what());
}
}
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -147,8 +147,8 @@ template <> class SharedMemoryWrapper<bool>
template <typename DataT, bool UseSharedMemory> struct ShM
{
using vector = typename std::conditional<UseSharedMemory,
SharedMemoryWrapper<DataT>,
std::vector<DataT>>::type;
SharedMemoryWrapper<DataT>,
std::vector<DataT>>::type;
};
#endif // SHARED_MEMORY_VECTOR_WRAPPER_HPP
+24 -12
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -30,13 +30,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "percent.hpp"
#include "shared_memory_vector_wrapper.hpp"
#include "../Util/integer_range.hpp"
#include "../util/integer_range.hpp"
#include "../typedefs.h"
#include <boost/assert.hpp>
#include <tbb/parallel_sort.h>
#include <algorithm>
#include <limits>
#include <utility>
@@ -57,8 +55,11 @@ template <typename EdgeDataT, bool UseSharedMemory = false> class StaticGraph
NodeIterator target;
EdgeDataT data;
template<typename... Ts>
InputEdge(NodeIterator source, NodeIterator target, Ts &&...data) : source(source), target(target), data(std::forward<Ts>(data)...) { }
template <typename... Ts>
InputEdge(NodeIterator source, NodeIterator target, Ts &&... data)
: source(source), target(target), data(std::forward<Ts>(data)...)
{
}
bool operator<(const InputEdge &right) const
{
if (source != right.source)
@@ -88,13 +89,12 @@ template <typename EdgeDataT, bool UseSharedMemory = false> class StaticGraph
StaticGraph(const int nodes, std::vector<InputEdge> &graph)
{
tbb::parallel_sort(graph.begin(), graph.end());
number_of_nodes = nodes;
number_of_edges = (EdgeIterator)graph.size();
number_of_edges = static_cast<EdgeIterator>(graph.size());
node_array.resize(number_of_nodes + 1);
EdgeIterator edge = 0;
EdgeIterator position = 0;
for (const auto node : osrm::irange(0u, number_of_nodes+1))
for (const auto node : osrm::irange(0u, number_of_nodes + 1))
{
EdgeIterator last_edge = edge;
while (edge < number_of_edges && graph[edge].source == node)
@@ -109,11 +109,10 @@ template <typename EdgeDataT, bool UseSharedMemory = false> class StaticGraph
for (const auto node : osrm::irange(0u, number_of_nodes))
{
EdgeIterator e = node_array[node + 1].first_edge;
for (EdgeIterator i = node_array[node].first_edge; i != e; ++i)
for (const auto i : osrm::irange(node_array[node].first_edge, e))
{
edge_array[i].target = graph[edge].target;
edge_array[i].data = graph[edge].data;
BOOST_ASSERT(edge_array[i].data.distance > 0);
edge++;
}
}
@@ -140,7 +139,7 @@ template <typename EdgeDataT, bool UseSharedMemory = false> class StaticGraph
return NodeIterator(edge_array[e].target);
}
inline EdgeDataT &GetEdgeData(const EdgeIterator e) { return edge_array[e].data; }
EdgeDataT &GetEdgeData(const EdgeIterator e) { return edge_array[e].data; }
const EdgeDataT &GetEdgeData(const EdgeIterator e) const { return edge_array[e].data; }
@@ -156,6 +155,19 @@ template <typename EdgeDataT, bool UseSharedMemory = false> class StaticGraph
// searches for a specific edge
EdgeIterator FindEdge(const NodeIterator from, const NodeIterator to) const
{
for (const auto i : osrm::irange(BeginEdges(from), EndEdges(from)))
{
if (to == edge_array[i].target)
{
return i;
}
}
return SPECIAL_EDGEID;
}
// searches for a specific edge
EdgeIterator FindSmallestEdge(const NodeIterator from, const NodeIterator to) const
{
EdgeIterator smallest_edge = SPECIAL_EDGEID;
EdgeWeight smallest_weight = INVALID_EDGE_WEIGHT;
+3 -3
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2013, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -138,8 +138,8 @@ class StaticKDTree
continue;
Iterator middle = tree.left + (tree.right - tree.left) / 2;
std::nth_element(
kdtree + tree.left, kdtree + middle, kdtree + tree.right, Less(tree.dimension));
std::nth_element(kdtree + tree.left, kdtree + middle, kdtree + tree.right,
Less(tree.dimension));
s.push(Tree(tree.left, middle, (tree.dimension + 1) % k));
s.push(Tree(middle + 1, tree.right, (tree.dimension + 1) % k));
}
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -28,7 +28,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef TRAVEL_MODE_HPP
#define TRAVEL_MODE_HPP
namespace {
namespace
{
using TravelMode = unsigned char;
static const TravelMode TRAVEL_MODE_INACCESSIBLE = 0;
static const TravelMode TRAVEL_MODE_DEFAULT = 1;
+40
View File
@@ -0,0 +1,40 @@
/*
Copyright (c) 2015, 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 TRIBOOL_HPP
#define TRIBOOL_HPP
namespace osrm
{
enum class tribool : char
{
yes,
no,
indeterminate
};
}
#endif // TRIBOOL_HPP
+22 -7
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -30,10 +30,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
enum class TurnInstruction : unsigned char
{
NoTurn = 0, GoStraight, TurnSlightRight, TurnRight, TurnSharpRight, UTurn,
TurnSharpLeft, TurnLeft, TurnSlightLeft, ReachViaLocation, HeadOn, EnterRoundAbout,
LeaveRoundAbout, StayOnRoundAbout, StartAtEndOfStreet, ReachedYourDestination,
EnterAgainstAllowedDirection, LeaveAgainstAllowedDirection,
NoTurn = 0,
GoStraight,
TurnSlightRight,
TurnRight,
TurnSharpRight,
UTurn,
TurnSharpLeft,
TurnLeft,
TurnSlightLeft,
ReachViaLocation,
HeadOn,
EnterRoundAbout,
LeaveRoundAbout,
StayOnRoundAbout,
StartAtEndOfStreet,
ReachedYourDestination,
EnterAgainstAllowedDirection,
LeaveAgainstAllowedDirection,
InverseAccessRestrictionFlag = 127,
AccessRestrictionFlag = 128,
AccessRestrictionPenalty = 129
@@ -42,7 +56,7 @@ enum class TurnInstruction : unsigned char
struct TurnInstructionsClass
{
TurnInstructionsClass() = delete;
TurnInstructionsClass(const TurnInstructionsClass&) = delete;
TurnInstructionsClass(const TurnInstructionsClass &) = delete;
static inline TurnInstruction GetTurnDirectionOfInstruction(const double angle)
{
@@ -79,7 +93,8 @@ struct TurnInstructionsClass
static inline bool TurnIsNecessary(const TurnInstruction turn_instruction)
{
if (TurnInstruction::NoTurn == turn_instruction || TurnInstruction::StayOnRoundAbout == turn_instruction)
if (TurnInstruction::NoTurn == turn_instruction ||
TurnInstruction::StayOnRoundAbout == turn_instruction)
{
return false;
}
+77
View File
@@ -0,0 +1,77 @@
/*
Copyright (c) 2015, 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 LOWER_BOUND_HPP
#define LOWER_BOUND_HPP
#include <functional>
#include <limits>
#include <queue>
#include <type_traits>
// max pq holds k elements
// insert if key is smaller than max
// if size > k then remove element
// get() always yields a bound to the k smallest element in the stream
template <typename key_type> class upper_bound
{
private:
using parameter_type =
typename std::conditional<std::is_fundamental<key_type>::value, key_type, key_type &>::type;
public:
upper_bound() = delete;
upper_bound(std::size_t size) : size(size) {}
key_type get() const
{
if (queue.size() < size)
{
return std::numeric_limits<key_type>::max();
}
return queue.top();
}
void insert(const parameter_type key)
{
if (key < get())
{
queue.emplace(key);
while (queue.size() > size)
{
queue.pop();
}
}
}
private:
std::priority_queue<key_type, std::vector<key_type>, std::less<key_type>> queue;
const std::size_t size;
};
#endif // LOWER_BOUND_HPP
+7 -7
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2013, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -61,8 +61,8 @@ class XORFastHash
table2.resize(2 << 16);
for (unsigned i = 0; i < (2 << 16); ++i)
{
table1[i] = i;
table2[i] = i;
table1[i] = static_cast<unsigned short>(i);
table2[i] = static_cast<unsigned short>(i);
}
std::random_shuffle(table1.begin(), table1.end());
std::random_shuffle(table2.begin(), table2.end());
@@ -92,10 +92,10 @@ class XORMiniHash
table4.resize(1 << 8);
for (unsigned i = 0; i < (1 << 8); ++i)
{
table1[i] = i;
table2[i] = i;
table3[i] = i;
table4[i] = i;
table1[i] = static_cast<unsigned char>(i);
table2[i] = static_cast<unsigned char>(i);
table3[i] = static_cast<unsigned char>(i);
table4[i] = static_cast<unsigned char>(i);
}
std::random_shuffle(table1.begin(), table1.end());
std::random_shuffle(table2.begin(), table2.end());
+22 -10
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2013, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -38,22 +38,24 @@ template <typename NodeID, typename Key> class XORFastHashStorage
public:
struct HashCell
{
Key key;
NodeID id;
unsigned time;
NodeID id;
Key key;
HashCell()
: key(std::numeric_limits<unsigned>::max()), id(std::numeric_limits<unsigned>::max()),
time(std::numeric_limits<unsigned>::max())
: time(std::numeric_limits<unsigned>::max()), id(std::numeric_limits<unsigned>::max()),
key(std::numeric_limits<unsigned>::max())
{
}
HashCell(const HashCell &other) : key(other.key), id(other.id), time(other.time) {}
HashCell(const HashCell &other) : time(other.key), id(other.id), key(other.time) {}
operator Key() const { return key; }
void operator=(const Key &key_to_insert) { key = key_to_insert; }
void operator=(const Key key_to_insert) { key = key_to_insert; }
};
XORFastHashStorage() = delete;
explicit XORFastHashStorage(size_t) : positions(2 << 16), current_timestamp(0) {}
HashCell &operator[](const NodeID node)
@@ -64,23 +66,33 @@ template <typename NodeID, typename Key> class XORFastHashStorage
++position %= (2 << 16);
}
positions[position].id = node;
positions[position].time = current_timestamp;
positions[position].id = node;
return positions[position];
}
// peek into table, get key for node, think of it as a read-only operator[]
Key peek_index(const NodeID node) const
{
unsigned short position = fast_hasher(node);
while ((positions[position].time == current_timestamp) && (positions[position].id != node))
{
++position %= (2 << 16);
}
return positions[position].key;
}
void Clear()
{
++current_timestamp;
if (std::numeric_limits<unsigned>::max() == current_timestamp)
{
positions.clear();
positions.resize((2 << 16));
positions.resize(2 << 16);
}
}
private:
XORFastHashStorage() : positions(2 << 16), current_timestamp(0) {}
std::vector<HashCell> positions;
XORFastHash fast_hasher;
unsigned current_timestamp;
+29 -24
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -28,21 +28,25 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "data_structures/original_edge_data.hpp"
#include "data_structures/range_table.hpp"
#include "data_structures/query_edge.hpp"
#include "data_structures/query_node.hpp"
#include "data_structures/shared_memory_factory.hpp"
#include "data_structures/shared_memory_vector_wrapper.hpp"
#include "data_structures/static_graph.hpp"
#include "data_structures/static_rtree.hpp"
#include "data_structures/travel_mode.hpp"
#include "data_structures/turn_instructions.hpp"
#include "Server/DataStructures/BaseDataFacade.h"
#include "Server/DataStructures/SharedDataType.h"
#include "Server/DataStructures/SharedBarriers.h"
#include "Util/BoostFileSystemFix.h"
#include "Util/DataStoreOptions.h"
#include "Util/simple_logger.hpp"
#include "Util/FingerPrint.h"
#include "server/data_structures/datafacade_base.hpp"
#include "server/data_structures/shared_datatype.hpp"
#include "server/data_structures/shared_barriers.hpp"
#include "util/boost_filesystem_2_fix.hpp"
#include "util/datastore_options.hpp"
#include "util/simple_logger.hpp"
#include "util/osrm_exception.hpp"
#include "util/fingerprint.hpp"
#include "typedefs.h"
#include <osrm/Coordinate.h>
#include <osrm/coordinate.hpp>
#include <osrm/server_paths.hpp>
using RTreeLeaf = BaseDataFacade<QueryEdge::EdgeData>::RTreeLeaf;
using RTreeNode = StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, true>::vector, true>::TreeNode;
@@ -102,7 +106,8 @@ int main(const int argc, const char *argv[])
const bool lock_flags = MCL_CURRENT | MCL_FUTURE;
if (-1 == mlockall(lock_flags))
{
SimpleLogger().Write(logWARNING) << "Process " << argv[0] << " could not request RAM lock";
SimpleLogger().Write(logWARNING) << "Process " << argv[0]
<< " could not request RAM lock";
}
#endif
try
@@ -133,31 +138,31 @@ int main(const int argc, const char *argv[])
if (server_paths.find("hsgrdata") == server_paths.end())
{
throw OSRMException("no hsgr file found");
throw osrm::exception("no hsgr file found");
}
if (server_paths.find("ramindex") == server_paths.end())
{
throw OSRMException("no ram index file found");
throw osrm::exception("no ram index file found");
}
if (server_paths.find("fileindex") == server_paths.end())
{
throw OSRMException("no leaf index file found");
throw osrm::exception("no leaf index file found");
}
if (server_paths.find("nodesdata") == server_paths.end())
{
throw OSRMException("no nodes file found");
throw osrm::exception("no nodes file found");
}
if (server_paths.find("edgesdata") == server_paths.end())
{
throw OSRMException("no edges file found");
throw osrm::exception("no edges file found");
}
if (server_paths.find("namesdata") == server_paths.end())
{
throw OSRMException("no names file found");
throw osrm::exception("no names file found");
}
if (server_paths.find("geometry") == server_paths.end())
{
throw OSRMException("no geometry file found");
throw osrm::exception("no geometry file found");
}
ServerPaths::const_iterator paths_iterator = server_paths.find("hsgrdata");
@@ -259,9 +264,10 @@ int main(const int argc, const char *argv[])
boost::filesystem::ifstream hsgr_input_stream(hsgr_path, std::ios::binary);
FingerPrint fingerprint_loaded, fingerprint_orig;
FingerPrint fingerprint_valid = FingerPrint::GetValid();
FingerPrint fingerprint_loaded;
hsgr_input_stream.read((char *)&fingerprint_loaded, sizeof(FingerPrint));
if (fingerprint_loaded.TestGraphUtil(fingerprint_orig))
if (fingerprint_loaded.TestGraphUtil(fingerprint_valid))
{
SimpleLogger().Write(logDEBUG) << "Fingerprint checked out ok";
}
@@ -339,8 +345,8 @@ int main(const int argc, const char *argv[])
geometry_input_stream.read((char *)&number_of_geometries_indices, sizeof(unsigned));
shared_layout_ptr->SetBlockSize<unsigned>(SharedDataLayout::GEOMETRIES_INDEX,
number_of_geometries_indices);
boost::iostreams::seek(
geometry_input_stream, number_of_geometries_indices * sizeof(unsigned), BOOST_IOS::cur);
boost::iostreams::seek(geometry_input_stream,
number_of_geometries_indices * sizeof(unsigned), BOOST_IOS::cur);
geometry_input_stream.read((char *)&number_of_compressed_geometries, sizeof(unsigned));
shared_layout_ptr->SetBlockSize<unsigned>(SharedDataLayout::GEOMETRIES_LIST,
number_of_compressed_geometries);
@@ -409,9 +415,8 @@ int main(const int argc, const char *argv[])
unsigned *name_id_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
shared_memory_ptr, SharedDataLayout::NAME_ID_LIST);
TravelMode *travel_mode_ptr =
shared_layout_ptr->GetBlockPtr<TravelMode, true>(
shared_memory_ptr, SharedDataLayout::TRAVEL_MODE);
TravelMode *travel_mode_ptr = shared_layout_ptr->GetBlockPtr<TravelMode, true>(
shared_memory_ptr, SharedDataLayout::TRAVEL_MODE);
TurnInstruction *turn_instructions_ptr =
shared_layout_ptr->GetBlockPtr<TurnInstruction, true>(
+145 -22
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -27,12 +27,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "description_factory.hpp"
#include <osrm/Coordinate.h>
#include "../typedefs.h"
#include "../algorithms/polyline_formatter.hpp"
#include "../data_structures/raw_route_data.hpp"
#include "../data_structures/coordinate_calculation.hpp"
#include "../data_structures/internal_route_result.hpp"
#include "../data_structures/turn_instructions.hpp"
#include "../util/container.hpp"
#include "../util/integer_range.hpp"
#include "../typedefs.h"
DescriptionFactory::DescriptionFactory() : entire_length(0) { via_indices.push_back(0); }
@@ -45,9 +46,8 @@ void DescriptionFactory::SetStartSegment(const PhantomNode &source, const bool t
(traversed_in_reverse ? source.reverse_weight : source.forward_weight);
const TravelMode travel_mode =
(traversed_in_reverse ? source.backward_travel_mode : source.forward_travel_mode);
AppendSegment(
source.location,
PathData(0, source.name_id, TurnInstruction::HeadOn, segment_duration, travel_mode));
AppendSegment(source.location, PathData(0, source.name_id, TurnInstruction::HeadOn,
segment_duration, travel_mode));
BOOST_ASSERT(path_description.back().duration == segment_duration);
}
@@ -60,15 +60,10 @@ void DescriptionFactory::SetEndSegment(const PhantomNode &target,
(traversed_in_reverse ? target.reverse_weight : target.forward_weight);
const TravelMode travel_mode =
(traversed_in_reverse ? target.backward_travel_mode : target.forward_travel_mode);
path_description.emplace_back(target.location,
target.name_id,
segment_duration,
0.f,
path_description.emplace_back(target.location, target.name_id, segment_duration, 0.f,
is_via_location ? TurnInstruction::ReachViaLocation
: TurnInstruction::NoTurn,
true,
true,
travel_mode);
true, true, travel_mode);
BOOST_ASSERT(path_description.back().duration == segment_duration);
}
@@ -99,15 +94,11 @@ void DescriptionFactory::AppendSegment(const FixedPointCoordinate &coordinate,
return path_point.turn_instruction;
}();
path_description.emplace_back(coordinate,
path_point.name_id,
path_point.segment_duration,
0.f,
turn,
path_point.travel_mode);
path_description.emplace_back(coordinate, path_point.name_id, path_point.segment_duration, 0.f,
turn, path_point.travel_mode);
}
JSON::Value DescriptionFactory::AppendGeometryString(const bool return_encoded)
osrm::json::Value DescriptionFactory::AppendGeometryString(const bool return_encoded)
{
if (return_encoded)
{
@@ -122,3 +113,135 @@ void DescriptionFactory::BuildRouteSummary(const double distance, const unsigned
summary.target_name_id = target_phantom.name_id;
summary.BuildDurationAndLengthStrings(distance, time);
}
void DescriptionFactory::Run(const unsigned zoom_level)
{
if (path_description.empty())
{
return;
}
/** starts at index 1 */
path_description[0].length = 0.f;
for (const auto i : osrm::irange<std::size_t>(1, path_description.size()))
{
// move down names by one, q&d hack
path_description[i - 1].name_id = path_description[i].name_id;
path_description[i].length = coordinate_calculation::euclidean_distance(
path_description[i - 1].location, path_description[i].location);
}
/*Simplify turn instructions
Input :
10. Turn left on B 36 for 20 km
11. Continue on B 35; B 36 for 2 km
12. Continue on B 36 for 13 km
becomes:
10. Turn left on B 36 for 35 km
*/
// TODO: rework to check only end and start of string.
// stl string is way to expensive
// unsigned lastTurn = 0;
// for(unsigned i = 1; i < path_description.size(); ++i) {
// string1 = sEngine.GetEscapedNameForNameID(path_description[i].name_id);
// if(TurnInstruction::GoStraight == path_description[i].turn_instruction) {
// if(std::string::npos != string0.find(string1+";")
// || std::string::npos != string0.find(";"+string1)
// || std::string::npos != string0.find(string1+" ;")
// || std::string::npos != string0.find("; "+string1)
// ){
// SimpleLogger().Write() << "->next correct: " << string0 << " contains " <<
// string1;
// for(; lastTurn != i; ++lastTurn)
// path_description[lastTurn].name_id = path_description[i].name_id;
// path_description[i].turn_instruction = TurnInstruction::NoTurn;
// } else if(std::string::npos != string1.find(string0+";")
// || std::string::npos != string1.find(";"+string0)
// || std::string::npos != string1.find(string0+" ;")
// || std::string::npos != string1.find("; "+string0)
// ){
// SimpleLogger().Write() << "->prev correct: " << string1 << " contains " <<
// string0;
// path_description[i].name_id = path_description[i-1].name_id;
// path_description[i].turn_instruction = TurnInstruction::NoTurn;
// }
// }
// if (TurnInstruction::NoTurn != path_description[i].turn_instruction) {
// lastTurn = i;
// }
// string0 = string1;
// }
//
float segment_length = 0.;
EdgeWeight segment_duration = 0;
std::size_t segment_start_index = 0;
for (const auto i : osrm::irange<std::size_t>(1, path_description.size()))
{
entire_length += path_description[i].length;
segment_length += path_description[i].length;
segment_duration += path_description[i].duration;
path_description[segment_start_index].length = segment_length;
path_description[segment_start_index].duration = segment_duration;
if (TurnInstruction::NoTurn != path_description[i].turn_instruction)
{
BOOST_ASSERT(path_description[i].necessary);
segment_length = 0;
segment_duration = 0;
segment_start_index = i;
}
}
// Post-processing to remove empty or nearly empty path segments
if (path_description.size() > 2 &&
std::numeric_limits<float>::epsilon() > path_description.back().length &&
!(path_description.end() - 2)->is_via_location)
{
path_description.pop_back();
path_description.back().necessary = true;
path_description.back().turn_instruction = TurnInstruction::NoTurn;
target_phantom.name_id = (path_description.end() - 2)->name_id;
}
if (path_description.size() > 2 &&
std::numeric_limits<float>::epsilon() > path_description.front().length &&
!(path_description.begin() + 1)->is_via_location)
{
path_description.erase(path_description.begin());
path_description.front().turn_instruction = TurnInstruction::HeadOn;
path_description.front().necessary = true;
start_phantom.name_id = path_description.front().name_id;
}
// Generalize poly line
polyline_generalizer.Run(path_description.begin(), path_description.end(), zoom_level);
// fix what needs to be fixed else
unsigned necessary_segments = 0; // a running index that counts the necessary pieces
osrm::for_each_pair(
path_description, [&](SegmentInformation &first, const SegmentInformation &second)
{
if (!first.necessary)
{
return;
}
++necessary_segments;
if (first.is_via_location)
{ // mark the end of a leg (of several segments)
via_indices.push_back(necessary_segments);
}
const double angle = coordinate_calculation::bearing(first.location, second.location);
first.bearing = static_cast<short>(angle * 10);
});
via_indices.push_back(necessary_segments + 1);
BOOST_ASSERT(via_indices.size() >= 2);
return;
}
+7 -137
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -30,14 +30,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../algorithms/douglas_peucker.hpp"
#include "../data_structures/phantom_node.hpp"
#include "../data_structures/json_container.hpp"
#include "../data_structures/segment_information.hpp"
#include "../data_structures/turn_instructions.hpp"
#include "../typedefs.h"
#include <boost/assert.hpp>
#include <osrm/Coordinate.h>
#include <osrm/coordinate.hpp>
#include <osrm/json_container.hpp>
#include <cmath>
@@ -73,7 +72,7 @@ class DescriptionFactory
{
// compute distance/duration for route summary
distance = static_cast<unsigned>(std::round(raw_distance));
duration = static_cast<unsigned>(std::round(raw_duration / 10.));
duration = static_cast<EdgeWeight>(std::round(raw_duration / 10.));
}
} summary;
@@ -86,141 +85,12 @@ class DescriptionFactory
void SetEndSegment(const PhantomNode &start_phantom,
const bool traversed_in_reverse,
const bool is_via_location = false);
JSON::Value AppendGeometryString(const bool return_encoded);
osrm::json::Value AppendGeometryString(const bool return_encoded);
std::vector<unsigned> const &GetViaIndices() const;
double get_entire_length() const
{
return entire_length;
}
double get_entire_length() const { return entire_length; }
template <class DataFacadeT> void Run(const DataFacadeT *facade, const unsigned zoomLevel)
{
if (path_description.empty())
{
return;
}
/** starts at index 1 */
path_description[0].length = 0;
for (unsigned i = 1; i < path_description.size(); ++i)
{
// move down names by one, q&d hack
path_description[i - 1].name_id = path_description[i].name_id;
path_description[i].length = FixedPointCoordinate::ApproximateEuclideanDistance(
path_description[i - 1].location, path_description[i].location);
}
/*Simplify turn instructions
Input :
10. Turn left on B 36 for 20 km
11. Continue on B 35; B 36 for 2 km
12. Continue on B 36 for 13 km
becomes:
10. Turn left on B 36 for 35 km
*/
// TODO: rework to check only end and start of string.
// stl string is way to expensive
// unsigned lastTurn = 0;
// for(unsigned i = 1; i < path_description.size(); ++i) {
// string1 = sEngine.GetEscapedNameForNameID(path_description[i].name_id);
// if(TurnInstruction::GoStraight == path_description[i].turn_instruction) {
// if(std::string::npos != string0.find(string1+";")
// || std::string::npos != string0.find(";"+string1)
// || std::string::npos != string0.find(string1+" ;")
// || std::string::npos != string0.find("; "+string1)
// ){
// SimpleLogger().Write() << "->next correct: " << string0 << " contains " <<
// string1;
// for(; lastTurn != i; ++lastTurn)
// path_description[lastTurn].name_id = path_description[i].name_id;
// path_description[i].turn_instruction = TurnInstruction::NoTurn;
// } else if(std::string::npos != string1.find(string0+";")
// || std::string::npos != string1.find(";"+string0)
// || std::string::npos != string1.find(string0+" ;")
// || std::string::npos != string1.find("; "+string0)
// ){
// SimpleLogger().Write() << "->prev correct: " << string1 << " contains " <<
// string0;
// path_description[i].name_id = path_description[i-1].name_id;
// path_description[i].turn_instruction = TurnInstruction::NoTurn;
// }
// }
// if (TurnInstruction::NoTurn != path_description[i].turn_instruction) {
// lastTurn = i;
// }
// string0 = string1;
// }
float segment_length = 0.;
unsigned segment_duration = 0;
unsigned segment_start_index = 0;
for (unsigned i = 1; i < path_description.size(); ++i)
{
entire_length += path_description[i].length;
segment_length += path_description[i].length;
segment_duration += path_description[i].duration;
path_description[segment_start_index].length = segment_length;
path_description[segment_start_index].duration = segment_duration;
if (TurnInstruction::NoTurn != path_description[i].turn_instruction)
{
BOOST_ASSERT(path_description[i].necessary);
segment_length = 0;
segment_duration = 0;
segment_start_index = i;
}
}
// Post-processing to remove empty or nearly empty path segments
if (std::numeric_limits<double>::epsilon() > path_description.back().length)
{
if (path_description.size() > 2)
{
path_description.pop_back();
path_description.back().necessary = true;
path_description.back().turn_instruction = TurnInstruction::NoTurn;
target_phantom.name_id = (path_description.end() - 2)->name_id;
}
}
if (std::numeric_limits<double>::epsilon() > path_description.front().length)
{
if (path_description.size() > 2)
{
path_description.erase(path_description.begin());
path_description.front().turn_instruction = TurnInstruction::HeadOn;
path_description.front().necessary = true;
start_phantom.name_id = path_description.front().name_id;
}
}
// Generalize poly line
polyline_generalizer.Run(path_description.begin(), path_description.end(), zoomLevel);
// fix what needs to be fixed else
unsigned necessary_pieces = 0; // a running index that counts the necessary pieces
for (unsigned i = 0; i < path_description.size() - 1 && path_description.size() >= 2; ++i)
{
if (path_description[i].necessary)
{
++necessary_pieces;
if (path_description[i].is_via_location)
{ // mark the end of a leg
via_indices.push_back(necessary_pieces);
}
const double angle =
path_description[i + 1].location.GetBearing(path_description[i].location);
path_description[i].bearing = static_cast<unsigned>(angle * 10);
}
}
via_indices.push_back(necessary_pieces + 1);
BOOST_ASSERT(via_indices.size() >= 2);
// BOOST_ASSERT(0 != necessary_pieces || path_description.empty());
return;
}
void Run(const unsigned zoom_level);
};
#endif /* DESCRIPTION_FACTORY_HPP */
+17 -13
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -28,17 +28,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef DESCRIPTOR_BASE_HPP
#define DESCRIPTOR_BASE_HPP
#include "../data_structures/coordinate_calculation.hpp"
#include "../data_structures/internal_route_result.hpp"
#include "../data_structures/phantom_node.hpp"
#include "../data_structures/raw_route_data.hpp"
#include "../typedefs.h"
#include <osrm/Reply.h>
#include <boost/assert.hpp>
#include <osrm/json_container.hpp>
#include <string>
#include <unordered_map>
#include <vector>
struct DescriptorTable : public std::unordered_map<std::string, unsigned>
{
unsigned get_id(const std::string &key)
@@ -52,22 +54,24 @@ struct DescriptorTable : public std::unordered_map<std::string, unsigned>
}
};
struct DescriptorConfig
{
DescriptorConfig() : instructions(true), geometry(true), encode_geometry(true), zoom_level(18)
{
}
template<class OtherT>
DescriptorConfig(const OtherT &other) : instructions(other.print_instructions),
geometry(other.geometry),
encode_geometry(other.compression),
zoom_level(other.zoom_level) { }
template <class OtherT>
DescriptorConfig(const OtherT &other)
: instructions(other.print_instructions), geometry(other.geometry),
encode_geometry(other.compression), zoom_level(other.zoom_level)
{
BOOST_ASSERT(zoom_level >= 0);
}
bool instructions;
bool geometry;
bool encode_geometry;
unsigned short zoom_level;
short zoom_level;
};
template <class DataFacadeT> class BaseDescriptor
@@ -76,8 +80,8 @@ template <class DataFacadeT> class BaseDescriptor
BaseDescriptor() {}
// Maybe someone can explain the pure virtual destructor thing to me (dennis)
virtual ~BaseDescriptor() {}
virtual void Run(const RawRouteData &raw_route, http::Reply &reply) = 0;
virtual void SetConfig(const DescriptorConfig &config) = 0;
virtual void Run(const InternalRouteResult &raw_route, osrm::json::Object &json_result) = 0;
virtual void SetConfig(const DescriptorConfig &c) = 0;
};
#endif // DESCRIPTOR_BASE_HPP
+20 -18
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -29,8 +29,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define GPX_DESCRIPTOR_HPP
#include "descriptor_base.hpp"
#include "../data_structures/json_container.hpp"
#include "../Util/xml_renderer.hpp"
#include "../util/xml_renderer.hpp"
#include <osrm/json_container.hpp>
#include <iostream>
@@ -40,39 +41,39 @@ template <class DataFacadeT> class GPXDescriptor final : public BaseDescriptor<D
DescriptorConfig config;
DataFacadeT *facade;
void AddRoutePoint(const FixedPointCoordinate &coordinate, JSON::Array &json_result)
void AddRoutePoint(const FixedPointCoordinate &coordinate, osrm::json::Array &json_route)
{
JSON::Object json_lat;
JSON::Object json_lon;
JSON::Array json_row;
osrm::json::Object json_lat;
osrm::json::Object json_lon;
osrm::json::Array json_row;
std::string tmp;
FixedPointCoordinate::convertInternalLatLonToString(coordinate.lat, tmp);
coordinate_calculation::lat_or_lon_to_string(coordinate.lat, tmp);
json_lat.values["_lat"] = tmp;
FixedPointCoordinate::convertInternalLatLonToString(coordinate.lon, tmp);
coordinate_calculation::lat_or_lon_to_string(coordinate.lon, tmp);
json_lon.values["_lon"] = tmp;
json_row.values.push_back(json_lat);
json_row.values.push_back(json_lon);
JSON::Object entry;
osrm::json::Object entry;
entry.values["rtept"] = json_row;
json_result.values.push_back(entry);
json_route.values.push_back(entry);
}
public:
explicit GPXDescriptor(DataFacadeT *facade) : facade(facade) {}
void SetConfig(const DescriptorConfig &c) final { config = c; }
virtual void SetConfig(const DescriptorConfig &c) final { config = c; }
void Run(const RawRouteData &raw_route, http::Reply &reply) final
virtual void Run(const InternalRouteResult &raw_route, osrm::json::Object &json_result) final
{
JSON::Array json_result;
osrm::json::Array json_route;
if (raw_route.shortest_path_length != INVALID_EDGE_WEIGHT)
{
AddRoutePoint(raw_route.segment_end_coordinates.front().source_phantom.location,
json_result);
json_route);
for (const std::vector<PathData> &path_data_vector : raw_route.unpacked_path_segments)
{
@@ -80,13 +81,14 @@ template <class DataFacadeT> class GPXDescriptor final : public BaseDescriptor<D
{
const FixedPointCoordinate current_coordinate =
facade->GetCoordinateOfNode(path_data.node);
AddRoutePoint(current_coordinate, json_result);
AddRoutePoint(current_coordinate, json_route);
}
}
AddRoutePoint(raw_route.segment_end_coordinates.back().target_phantom.location,
json_result);
json_route);
}
JSON::gpx_render(reply.content, json_result);
// osrm::json::gpx_render(reply.content, json_route);
json_result.values["route"] = json_route;
}
};
#endif // GPX_DESCRIPTOR_HPP
+392 -393
View File
@@ -1,393 +1,392 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
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 JSON_DESCRIPTOR_HPP
#define JSON_DESCRIPTOR_HPP
#include "descriptor_base.hpp"
#include "description_factory.hpp"
#include "../algorithms/object_encoder.hpp"
#include "../algorithms/route_name_extraction.hpp"
#include "../data_structures/json_container.hpp"
#include "../data_structures/segment_information.hpp"
#include "../data_structures/turn_instructions.hpp"
#include "../Util/bearing.hpp"
#include "../Util/integer_range.hpp"
#include "../Util/json_renderer.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/StringUtil.h"
#include "../Util/timing_util.hpp"
#include <algorithm>
template <class DataFacadeT> class JSONDescriptor final : public BaseDescriptor<DataFacadeT>
{
private:
DataFacadeT *facade;
DescriptorConfig config;
DescriptionFactory description_factory, alternate_description_factory;
FixedPointCoordinate current;
unsigned entered_restricted_area_count;
struct RoundAbout
{
RoundAbout() : start_index(INT_MAX), name_id(INVALID_NAMEID), leave_at_exit(INT_MAX) {}
int start_index;
unsigned name_id;
int leave_at_exit;
} round_about;
struct Segment
{
Segment() : name_id(INVALID_NAMEID), length(-1), position(0) {}
Segment(unsigned n, int l, unsigned p) : name_id(n), length(l), position(p) {}
unsigned name_id;
int length;
unsigned position;
};
std::vector<Segment> shortest_path_segments, alternative_path_segments;
ExtractRouteNames<DataFacadeT, Segment> GenerateRouteNames;
public:
explicit JSONDescriptor(DataFacadeT *facade) : facade(facade), entered_restricted_area_count(0) {}
void SetConfig(const DescriptorConfig &c) final { config = c; }
unsigned DescribeLeg(const std::vector<PathData> route_leg,
const PhantomNodes &leg_phantoms,
const bool target_traversed_in_reverse,
const bool is_via_leg)
{
unsigned added_element_count = 0;
// Get all the coordinates for the computed route
FixedPointCoordinate current_coordinate;
for (const PathData &path_data : route_leg)
{
current_coordinate = facade->GetCoordinateOfNode(path_data.node);
description_factory.AppendSegment(current_coordinate, path_data);
++added_element_count;
}
description_factory.SetEndSegment(
leg_phantoms.target_phantom, target_traversed_in_reverse, is_via_leg);
++added_element_count;
BOOST_ASSERT((route_leg.size() + 1) == added_element_count);
return added_element_count;
}
void Run(const RawRouteData &raw_route, http::Reply &reply) final
{
JSON::Object json_result;
if (INVALID_EDGE_WEIGHT == raw_route.shortest_path_length)
{
// We do not need to do much, if there is no route ;-)
json_result.values["status"] = 207;
json_result.values["status_message"] = "Cannot find route between points";
JSON::render(reply.content, json_result);
return;
}
// check if first segment is non-zero
std::string road_name = facade->GetEscapedNameForNameID(
raw_route.segment_end_coordinates.front().source_phantom.name_id);
BOOST_ASSERT(raw_route.unpacked_path_segments.size() ==
raw_route.segment_end_coordinates.size());
description_factory.SetStartSegment(
raw_route.segment_end_coordinates.front().source_phantom,
raw_route.source_traversed_in_reverse.front());
json_result.values["status"] = 0;
json_result.values["status_message"] = "Found route between points";
// for each unpacked segment add the leg to the description
for (const auto i : osrm::irange<std::size_t>(0, raw_route.unpacked_path_segments.size()))
{
#ifndef NDEBUG
const int added_segments =
#endif
DescribeLeg(raw_route.unpacked_path_segments[i],
raw_route.segment_end_coordinates[i],
raw_route.target_traversed_in_reverse[i],
raw_route.is_via_leg(i));
BOOST_ASSERT(0 < added_segments);
}
description_factory.Run(facade, config.zoom_level);
if (config.geometry)
{
JSON::Value route_geometry =
description_factory.AppendGeometryString(config.encode_geometry);
json_result.values["route_geometry"] = route_geometry;
}
if (config.instructions)
{
JSON::Array json_route_instructions;
BuildTextualDescription(description_factory,
json_route_instructions,
raw_route.shortest_path_length,
shortest_path_segments);
json_result.values["route_instructions"] = json_route_instructions;
}
description_factory.BuildRouteSummary(description_factory.get_entire_length(),
raw_route.shortest_path_length);
JSON::Object json_route_summary;
json_route_summary.values["total_distance"] = description_factory.summary.distance;
json_route_summary.values["total_time"] = description_factory.summary.duration;
json_route_summary.values["start_point"] =
facade->GetEscapedNameForNameID(description_factory.summary.source_name_id);
json_route_summary.values["end_point"] =
facade->GetEscapedNameForNameID(description_factory.summary.target_name_id);
json_result.values["route_summary"] = json_route_summary;
BOOST_ASSERT(!raw_route.segment_end_coordinates.empty());
JSON::Array json_via_points_array;
JSON::Array json_first_coordinate;
json_first_coordinate.values.push_back(
raw_route.segment_end_coordinates.front().source_phantom.location.lat /
COORDINATE_PRECISION);
json_first_coordinate.values.push_back(
raw_route.segment_end_coordinates.front().source_phantom.location.lon /
COORDINATE_PRECISION);
json_via_points_array.values.push_back(json_first_coordinate);
for (const PhantomNodes &nodes : raw_route.segment_end_coordinates)
{
std::string tmp;
JSON::Array json_coordinate;
json_coordinate.values.push_back(nodes.target_phantom.location.lat /
COORDINATE_PRECISION);
json_coordinate.values.push_back(nodes.target_phantom.location.lon /
COORDINATE_PRECISION);
json_via_points_array.values.push_back(json_coordinate);
}
json_result.values["via_points"] = json_via_points_array;
JSON::Array json_via_indices_array;
std::vector<unsigned> const &shortest_leg_end_indices = description_factory.GetViaIndices();
json_via_indices_array.values.insert(json_via_indices_array.values.end(),
shortest_leg_end_indices.begin(),
shortest_leg_end_indices.end());
json_result.values["via_indices"] = json_via_indices_array;
// only one alternative route is computed at this time, so this is hardcoded
if (INVALID_EDGE_WEIGHT != raw_route.alternative_path_length)
{
json_result.values["found_alternative"] = JSON::True();
BOOST_ASSERT(!raw_route.alt_source_traversed_in_reverse.empty());
alternate_description_factory.SetStartSegment(
raw_route.segment_end_coordinates.front().source_phantom,
raw_route.alt_source_traversed_in_reverse.front());
// Get all the coordinates for the computed route
for (const PathData &path_data : raw_route.unpacked_alternative)
{
current = facade->GetCoordinateOfNode(path_data.node);
alternate_description_factory.AppendSegment(current, path_data);
}
alternate_description_factory.SetEndSegment(
raw_route.segment_end_coordinates.back().target_phantom,
raw_route.alt_source_traversed_in_reverse.back());
alternate_description_factory.Run(facade, config.zoom_level);
if (config.geometry)
{
JSON::Value alternate_geometry_string =
alternate_description_factory.AppendGeometryString(config.encode_geometry);
JSON::Array json_alternate_geometries_array;
json_alternate_geometries_array.values.push_back(alternate_geometry_string);
json_result.values["alternative_geometries"] = json_alternate_geometries_array;
}
// Generate instructions for each alternative (simulated here)
JSON::Array json_alt_instructions;
JSON::Array json_current_alt_instructions;
if (config.instructions)
{
BuildTextualDescription(alternate_description_factory,
json_current_alt_instructions,
raw_route.alternative_path_length,
alternative_path_segments);
json_alt_instructions.values.push_back(json_current_alt_instructions);
json_result.values["alternative_instructions"] = json_alt_instructions;
}
alternate_description_factory.BuildRouteSummary(
alternate_description_factory.get_entire_length(), raw_route.alternative_path_length);
JSON::Object json_alternate_route_summary;
JSON::Array json_alternate_route_summary_array;
json_alternate_route_summary.values["total_distance"] =
alternate_description_factory.summary.distance;
json_alternate_route_summary.values["total_time"] =
alternate_description_factory.summary.duration;
json_alternate_route_summary.values["start_point"] = facade->GetEscapedNameForNameID(
alternate_description_factory.summary.source_name_id);
json_alternate_route_summary.values["end_point"] = facade->GetEscapedNameForNameID(
alternate_description_factory.summary.target_name_id);
json_alternate_route_summary_array.values.push_back(json_alternate_route_summary);
json_result.values["alternative_summaries"] = json_alternate_route_summary_array;
std::vector<unsigned> const &alternate_leg_end_indices =
alternate_description_factory.GetViaIndices();
JSON::Array json_altenative_indices_array;
json_altenative_indices_array.values.insert(json_altenative_indices_array.values.end(),
alternate_leg_end_indices.begin(),
alternate_leg_end_indices.end());
json_result.values["alternative_indices"] = json_altenative_indices_array;
}
else
{
json_result.values["found_alternative"] = JSON::False();
}
// Get Names for both routes
RouteNames route_names =
GenerateRouteNames(shortest_path_segments, alternative_path_segments, facade);
JSON::Array json_route_names;
json_route_names.values.push_back(route_names.shortest_path_name_1);
json_route_names.values.push_back(route_names.shortest_path_name_2);
json_result.values["route_name"] = json_route_names;
if (INVALID_EDGE_WEIGHT != raw_route.alternative_path_length)
{
JSON::Array json_alternate_names_array;
JSON::Array json_alternate_names;
json_alternate_names.values.push_back(route_names.alternative_path_name_1);
json_alternate_names.values.push_back(route_names.alternative_path_name_2);
json_alternate_names_array.values.push_back(json_alternate_names);
json_result.values["alternative_names"] = json_alternate_names_array;
}
JSON::Object json_hint_object;
json_hint_object.values["checksum"] = facade->GetCheckSum();
JSON::Array json_location_hint_array;
std::string hint;
for (const auto i : osrm::irange<std::size_t>(0, raw_route.segment_end_coordinates.size()))
{
ObjectEncoder::EncodeToBase64(raw_route.segment_end_coordinates[i].source_phantom, hint);
json_location_hint_array.values.push_back(hint);
}
ObjectEncoder::EncodeToBase64(raw_route.segment_end_coordinates.back().target_phantom, hint);
json_location_hint_array.values.push_back(hint);
json_hint_object.values["locations"] = json_location_hint_array;
json_result.values["hint_data"] = json_hint_object;
// render the content to the output array
TIMER_START(route_render);
JSON::render(reply.content, json_result);
TIMER_STOP(route_render);
SimpleLogger().Write(logDEBUG) << "rendering took: " << TIMER_MSEC(route_render);
}
// TODO: reorder parameters
inline void BuildTextualDescription(DescriptionFactory &description_factory,
JSON::Array &json_instruction_array,
const int route_length,
std::vector<Segment> &route_segments_list)
{
// Segment information has following format:
//["instruction id","streetname",length,position,time,"length","earth_direction",azimuth]
unsigned necessary_segments_running_index = 0;
round_about.leave_at_exit = 0;
round_about.name_id = 0;
std::string temp_dist, temp_length, temp_duration, temp_bearing, temp_instruction;
// Fetch data from Factory and generate a string from it.
for (const SegmentInformation &segment : description_factory.path_description)
{
JSON::Array json_instruction_row;
TurnInstruction current_instruction = segment.turn_instruction;
entered_restricted_area_count += (current_instruction != segment.turn_instruction);
if (TurnInstructionsClass::TurnIsNecessary(current_instruction))
{
if (TurnInstruction::EnterRoundAbout == current_instruction)
{
round_about.name_id = segment.name_id;
round_about.start_index = necessary_segments_running_index;
}
else
{
std::string current_turn_instruction;
if (TurnInstruction::LeaveRoundAbout == current_instruction)
{
temp_instruction =
cast::integral_to_string(cast::enum_to_underlying(TurnInstruction::EnterRoundAbout));
current_turn_instruction += temp_instruction;
current_turn_instruction += "-";
temp_instruction = cast::integral_to_string(round_about.leave_at_exit + 1);
current_turn_instruction += temp_instruction;
round_about.leave_at_exit = 0;
}
else
{
temp_instruction = cast::integral_to_string(cast::enum_to_underlying(current_instruction));
current_turn_instruction += temp_instruction;
}
json_instruction_row.values.push_back(current_turn_instruction);
json_instruction_row.values.push_back(
facade->GetEscapedNameForNameID(segment.name_id));
json_instruction_row.values.push_back(std::round(segment.length));
json_instruction_row.values.push_back(necessary_segments_running_index);
json_instruction_row.values.push_back(round(segment.duration / 10));
json_instruction_row.values.push_back(
cast::integral_to_string(static_cast<unsigned>(segment.length)) + "m");
const double bearing_value = (segment.bearing / 10.);
json_instruction_row.values.push_back(Bearing::Get(bearing_value));
json_instruction_row.values.push_back(
static_cast<unsigned>(round(bearing_value)));
json_instruction_row.values.push_back(segment.travel_mode);
route_segments_list.emplace_back(
segment.name_id,
static_cast<int>(segment.length),
static_cast<unsigned>(route_segments_list.size()));
json_instruction_array.values.push_back(json_instruction_row);
}
}
else if (TurnInstruction::StayOnRoundAbout == current_instruction)
{
++round_about.leave_at_exit;
}
if (segment.necessary)
{
++necessary_segments_running_index;
}
}
JSON::Array json_last_instruction_row;
temp_instruction = cast::integral_to_string(cast::enum_to_underlying(TurnInstruction::ReachedYourDestination));
json_last_instruction_row.values.push_back(temp_instruction);
json_last_instruction_row.values.push_back("");
json_last_instruction_row.values.push_back(0);
json_last_instruction_row.values.push_back(necessary_segments_running_index - 1);
json_last_instruction_row.values.push_back(0);
json_last_instruction_row.values.push_back("0m");
json_last_instruction_row.values.push_back(Bearing::Get(0.0));
json_last_instruction_row.values.push_back(0.);
json_instruction_array.values.push_back(json_last_instruction_row);
}
};
#endif /* JSON_DESCRIPTOR_HPP */
/*
Copyright (c) 2015, 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 JSON_DESCRIPTOR_HPP
#define JSON_DESCRIPTOR_HPP
#include "descriptor_base.hpp"
#include "description_factory.hpp"
#include "../algorithms/object_encoder.hpp"
#include "../algorithms/route_name_extraction.hpp"
#include "../data_structures/segment_information.hpp"
#include "../data_structures/turn_instructions.hpp"
#include "../util/bearing.hpp"
#include "../util/integer_range.hpp"
#include "../util/json_renderer.hpp"
#include "../util/simple_logger.hpp"
#include "../util/string_util.hpp"
#include "../util/timing_util.hpp"
#include <osrm/json_container.hpp>
#include <algorithm>
template <class DataFacadeT> class JSONDescriptor final : public BaseDescriptor<DataFacadeT>
{
private:
DataFacadeT *facade;
DescriptorConfig config;
DescriptionFactory description_factory, alternate_description_factory;
FixedPointCoordinate current;
unsigned entered_restricted_area_count;
struct RoundAbout
{
RoundAbout() : start_index(INT_MAX), name_id(INVALID_NAMEID), leave_at_exit(INT_MAX) {}
int start_index;
unsigned name_id;
int leave_at_exit;
} round_about;
struct Segment
{
Segment() : name_id(INVALID_NAMEID), length(-1), position(0) {}
Segment(unsigned n, int l, unsigned p) : name_id(n), length(l), position(p) {}
unsigned name_id;
int length;
unsigned position;
};
std::vector<Segment> shortest_path_segments, alternative_path_segments;
ExtractRouteNames<DataFacadeT, Segment> GenerateRouteNames;
public:
explicit JSONDescriptor(DataFacadeT *facade) : facade(facade), entered_restricted_area_count(0)
{
}
virtual void SetConfig(const DescriptorConfig &c) override final { config = c; }
unsigned DescribeLeg(const std::vector<PathData> &route_leg,
const PhantomNodes &leg_phantoms,
const bool target_traversed_in_reverse,
const bool is_via_leg)
{
unsigned added_element_count = 0;
// Get all the coordinates for the computed route
FixedPointCoordinate current_coordinate;
for (const PathData &path_data : route_leg)
{
current_coordinate = facade->GetCoordinateOfNode(path_data.node);
description_factory.AppendSegment(current_coordinate, path_data);
++added_element_count;
}
description_factory.SetEndSegment(leg_phantoms.target_phantom, target_traversed_in_reverse,
is_via_leg);
++added_element_count;
BOOST_ASSERT((route_leg.size() + 1) == added_element_count);
return added_element_count;
}
virtual void Run(const InternalRouteResult &raw_route,
osrm::json::Object &json_result) override final
{
if (INVALID_EDGE_WEIGHT == raw_route.shortest_path_length)
{
// We do not need to do much, if there is no route ;-)
json_result.values["status"] = 207;
json_result.values["status_message"] = "Cannot find route between points";
// osrm::json::render(reply.content, json_result);
return;
}
// check if first segment is non-zero
BOOST_ASSERT(raw_route.unpacked_path_segments.size() ==
raw_route.segment_end_coordinates.size());
description_factory.SetStartSegment(
raw_route.segment_end_coordinates.front().source_phantom,
raw_route.source_traversed_in_reverse.front());
json_result.values["status"] = 0;
json_result.values["status_message"] = "Found route between points";
// for each unpacked segment add the leg to the description
for (const auto i : osrm::irange<std::size_t>(0, raw_route.unpacked_path_segments.size()))
{
#ifndef NDEBUG
const int added_segments =
#endif
DescribeLeg(raw_route.unpacked_path_segments[i],
raw_route.segment_end_coordinates[i],
raw_route.target_traversed_in_reverse[i], raw_route.is_via_leg(i));
BOOST_ASSERT(0 < added_segments);
}
description_factory.Run(config.zoom_level);
if (config.geometry)
{
osrm::json::Value route_geometry =
description_factory.AppendGeometryString(config.encode_geometry);
json_result.values["route_geometry"] = route_geometry;
}
if (config.instructions)
{
osrm::json::Array json_route_instructions;
BuildTextualDescription(description_factory, json_route_instructions,
raw_route.shortest_path_length, shortest_path_segments);
json_result.values["route_instructions"] = json_route_instructions;
}
description_factory.BuildRouteSummary(description_factory.get_entire_length(),
raw_route.shortest_path_length);
osrm::json::Object json_route_summary;
json_route_summary.values["total_distance"] = description_factory.summary.distance;
json_route_summary.values["total_time"] = description_factory.summary.duration;
json_route_summary.values["start_point"] =
facade->get_name_for_id(description_factory.summary.source_name_id);
json_route_summary.values["end_point"] =
facade->get_name_for_id(description_factory.summary.target_name_id);
json_result.values["route_summary"] = json_route_summary;
BOOST_ASSERT(!raw_route.segment_end_coordinates.empty());
osrm::json::Array json_via_points_array;
osrm::json::Array json_first_coordinate;
json_first_coordinate.values.push_back(
raw_route.segment_end_coordinates.front().source_phantom.location.lat /
COORDINATE_PRECISION);
json_first_coordinate.values.push_back(
raw_route.segment_end_coordinates.front().source_phantom.location.lon /
COORDINATE_PRECISION);
json_via_points_array.values.push_back(json_first_coordinate);
for (const PhantomNodes &nodes : raw_route.segment_end_coordinates)
{
std::string tmp;
osrm::json::Array json_coordinate;
json_coordinate.values.push_back(nodes.target_phantom.location.lat /
COORDINATE_PRECISION);
json_coordinate.values.push_back(nodes.target_phantom.location.lon /
COORDINATE_PRECISION);
json_via_points_array.values.push_back(json_coordinate);
}
json_result.values["via_points"] = json_via_points_array;
osrm::json::Array json_via_indices_array;
std::vector<unsigned> const &shortest_leg_end_indices = description_factory.GetViaIndices();
json_via_indices_array.values.insert(json_via_indices_array.values.end(),
shortest_leg_end_indices.begin(),
shortest_leg_end_indices.end());
json_result.values["via_indices"] = json_via_indices_array;
// only one alternative route is computed at this time, so this is hardcoded
if (INVALID_EDGE_WEIGHT != raw_route.alternative_path_length)
{
json_result.values["found_alternative"] = osrm::json::True();
BOOST_ASSERT(!raw_route.alt_source_traversed_in_reverse.empty());
alternate_description_factory.SetStartSegment(
raw_route.segment_end_coordinates.front().source_phantom,
raw_route.alt_source_traversed_in_reverse.front());
// Get all the coordinates for the computed route
for (const PathData &path_data : raw_route.unpacked_alternative)
{
current = facade->GetCoordinateOfNode(path_data.node);
alternate_description_factory.AppendSegment(current, path_data);
}
alternate_description_factory.SetEndSegment(
raw_route.segment_end_coordinates.back().target_phantom,
raw_route.alt_source_traversed_in_reverse.back());
alternate_description_factory.Run(config.zoom_level);
if (config.geometry)
{
osrm::json::Value alternate_geometry_string =
alternate_description_factory.AppendGeometryString(config.encode_geometry);
osrm::json::Array json_alternate_geometries_array;
json_alternate_geometries_array.values.push_back(alternate_geometry_string);
json_result.values["alternative_geometries"] = json_alternate_geometries_array;
}
// Generate instructions for each alternative (simulated here)
osrm::json::Array json_alt_instructions;
osrm::json::Array json_current_alt_instructions;
if (config.instructions)
{
BuildTextualDescription(
alternate_description_factory, json_current_alt_instructions,
raw_route.alternative_path_length, alternative_path_segments);
json_alt_instructions.values.push_back(json_current_alt_instructions);
json_result.values["alternative_instructions"] = json_alt_instructions;
}
alternate_description_factory.BuildRouteSummary(
alternate_description_factory.get_entire_length(),
raw_route.alternative_path_length);
osrm::json::Object json_alternate_route_summary;
osrm::json::Array json_alternate_route_summary_array;
json_alternate_route_summary.values["total_distance"] =
alternate_description_factory.summary.distance;
json_alternate_route_summary.values["total_time"] =
alternate_description_factory.summary.duration;
json_alternate_route_summary.values["start_point"] =
facade->get_name_for_id(alternate_description_factory.summary.source_name_id);
json_alternate_route_summary.values["end_point"] =
facade->get_name_for_id(alternate_description_factory.summary.target_name_id);
json_alternate_route_summary_array.values.push_back(json_alternate_route_summary);
json_result.values["alternative_summaries"] = json_alternate_route_summary_array;
std::vector<unsigned> const &alternate_leg_end_indices =
alternate_description_factory.GetViaIndices();
osrm::json::Array json_altenative_indices_array;
json_altenative_indices_array.values.insert(json_altenative_indices_array.values.end(),
alternate_leg_end_indices.begin(),
alternate_leg_end_indices.end());
json_result.values["alternative_indices"] = json_altenative_indices_array;
}
else
{
json_result.values["found_alternative"] = osrm::json::False();
}
// Get Names for both routes
RouteNames route_names =
GenerateRouteNames(shortest_path_segments, alternative_path_segments, facade);
osrm::json::Array json_route_names;
json_route_names.values.push_back(route_names.shortest_path_name_1);
json_route_names.values.push_back(route_names.shortest_path_name_2);
json_result.values["route_name"] = json_route_names;
if (INVALID_EDGE_WEIGHT != raw_route.alternative_path_length)
{
osrm::json::Array json_alternate_names_array;
osrm::json::Array json_alternate_names;
json_alternate_names.values.push_back(route_names.alternative_path_name_1);
json_alternate_names.values.push_back(route_names.alternative_path_name_2);
json_alternate_names_array.values.push_back(json_alternate_names);
json_result.values["alternative_names"] = json_alternate_names_array;
}
osrm::json::Object json_hint_object;
json_hint_object.values["checksum"] = facade->GetCheckSum();
osrm::json::Array json_location_hint_array;
std::string hint;
for (const auto i : osrm::irange<std::size_t>(0, raw_route.segment_end_coordinates.size()))
{
ObjectEncoder::EncodeToBase64(raw_route.segment_end_coordinates[i].source_phantom,
hint);
json_location_hint_array.values.push_back(hint);
}
ObjectEncoder::EncodeToBase64(raw_route.segment_end_coordinates.back().target_phantom,
hint);
json_location_hint_array.values.push_back(hint);
json_hint_object.values["locations"] = json_location_hint_array;
json_result.values["hint_data"] = json_hint_object;
// render the content to the output array
// TIMER_START(route_render);
// osrm::json::render(reply.content, json_result);
// TIMER_STOP(route_render);
// SimpleLogger().Write(logDEBUG) << "rendering took: " << TIMER_MSEC(route_render);
}
// TODO: reorder parameters
inline void BuildTextualDescription(DescriptionFactory &description_factory,
osrm::json::Array &json_instruction_array,
const int route_length,
std::vector<Segment> &route_segments_list)
{
// Segment information has following format:
//["instruction id","streetname",length,position,time,"length","earth_direction",azimuth]
unsigned necessary_segments_running_index = 0;
round_about.leave_at_exit = 0;
round_about.name_id = 0;
std::string temp_dist, temp_length, temp_duration, temp_bearing, temp_instruction;
// Fetch data from Factory and generate a string from it.
for (const SegmentInformation &segment : description_factory.path_description)
{
osrm::json::Array json_instruction_row;
TurnInstruction current_instruction = segment.turn_instruction;
entered_restricted_area_count += (current_instruction != segment.turn_instruction);
if (TurnInstructionsClass::TurnIsNecessary(current_instruction))
{
if (TurnInstruction::EnterRoundAbout == current_instruction)
{
round_about.name_id = segment.name_id;
round_about.start_index = necessary_segments_running_index;
}
else
{
std::string current_turn_instruction;
if (TurnInstruction::LeaveRoundAbout == current_instruction)
{
temp_instruction = cast::integral_to_string(
cast::enum_to_underlying(TurnInstruction::EnterRoundAbout));
current_turn_instruction += temp_instruction;
current_turn_instruction += "-";
temp_instruction = cast::integral_to_string(round_about.leave_at_exit + 1);
current_turn_instruction += temp_instruction;
round_about.leave_at_exit = 0;
}
else
{
temp_instruction =
cast::integral_to_string(cast::enum_to_underlying(current_instruction));
current_turn_instruction += temp_instruction;
}
json_instruction_row.values.push_back(current_turn_instruction);
json_instruction_row.values.push_back(facade->get_name_for_id(segment.name_id));
json_instruction_row.values.push_back(std::round(segment.length));
json_instruction_row.values.push_back(necessary_segments_running_index);
json_instruction_row.values.push_back(std::round(segment.duration / 10.));
json_instruction_row.values.push_back(
cast::integral_to_string(static_cast<unsigned>(segment.length)) + "m");
const double bearing_value = (segment.bearing / 10.);
json_instruction_row.values.push_back(bearing::get(bearing_value));
json_instruction_row.values.push_back(
static_cast<unsigned>(round(bearing_value)));
json_instruction_row.values.push_back(segment.travel_mode);
route_segments_list.emplace_back(
segment.name_id, static_cast<int>(segment.length),
static_cast<unsigned>(route_segments_list.size()));
json_instruction_array.values.push_back(json_instruction_row);
}
}
else if (TurnInstruction::StayOnRoundAbout == current_instruction)
{
++round_about.leave_at_exit;
}
if (segment.necessary)
{
++necessary_segments_running_index;
}
}
osrm::json::Array json_last_instruction_row;
temp_instruction = cast::integral_to_string(
cast::enum_to_underlying(TurnInstruction::ReachedYourDestination));
json_last_instruction_row.values.push_back(temp_instruction);
json_last_instruction_row.values.push_back("");
json_last_instruction_row.values.push_back(0);
json_last_instruction_row.values.push_back(necessary_segments_running_index - 1);
json_last_instruction_row.values.push_back(0);
json_last_instruction_row.values.push_back("0m");
json_last_instruction_row.values.push_back(bearing::get(0.0));
json_last_instruction_row.values.push_back(0.);
json_instruction_array.values.push_back(json_last_instruction_row);
}
};
#endif /* JSON_DESCRIPTOR_H_ */
+46 -5
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -26,17 +26,58 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "extractor/extractor.hpp"
#include "Util/simple_logger.hpp"
#include "extractor/extractor_options.hpp"
#include "util/simple_logger.hpp"
int main (int argc, char *argv[])
#include <boost/filesystem.hpp>
#include <exception>
int main(int argc, char *argv[])
{
try
{
return Extractor().Run(argc, argv);
LogPolicy::GetInstance().Unmute();
ExtractorConfig extractor_config;
const return_code result = ExtractorOptions::ParseArguments(argc, argv, extractor_config);
if (return_code::fail == result)
{
return 1;
}
if (return_code::exit == result)
{
return 0;
}
ExtractorOptions::GenerateOutputFilesNames(extractor_config);
if (1 > extractor_config.requested_num_threads)
{
SimpleLogger().Write(logWARNING) << "Number of threads must be 1 or larger";
return 1;
}
if (!boost::filesystem::is_regular_file(extractor_config.input_path))
{
SimpleLogger().Write(logWARNING)
<< "Input file " << extractor_config.input_path.string() << " not found!";
return 1;
}
if (!boost::filesystem::is_regular_file(extractor_config.profile_path))
{
SimpleLogger().Write(logWARNING) << "Profile " << extractor_config.profile_path.string()
<< " not found!";
return 1;
}
return extractor(extractor_config).run();
}
catch (const std::exception &e)
{
SimpleLogger().Write(logWARNING) << "[exception] " << e.what();
return 1;
}
}
+560 -365
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -28,12 +28,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "extraction_containers.hpp"
#include "extraction_way.hpp"
#include "../data_structures/coordinate_calculation.hpp"
#include "../data_structures/node_id.hpp"
#include "../data_structures/range_table.hpp"
#include "../Util/OSRMException.h"
#include "../Util/simple_logger.hpp"
#include "../Util/timing_util.hpp"
#include "../util/osrm_exception.hpp"
#include "../util/simple_logger.hpp"
#include "../util/timing_util.hpp"
#include "../util/fingerprint.hpp"
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
@@ -53,6 +55,7 @@ ExtractionContainers::ExtractionContainers()
ExtractionContainers::~ExtractionContainers()
{
// FIXME isn't this done implicitly of the stxxl::vectors go out of scope?
used_node_id_list.clear();
all_nodes_list.clear();
all_edges_list.clear();
@@ -61,378 +64,570 @@ ExtractionContainers::~ExtractionContainers()
way_start_end_id_list.clear();
}
/**
* Processes the collected data and serializes it.
* At this point nodes are still referenced by their OSM id.
*
* - map start-end nodes of ways to ways used int restrictions to compute compressed
* trippe representation
* - filter nodes list to nodes that are referenced by ways
* - merge edges with nodes to include location of start/end points and serialize
*
*/
void ExtractionContainers::PrepareData(const std::string &output_file_name,
const std::string &restrictions_file_name)
const std::string &restrictions_file_name,
const std::string &name_file_name)
{
try
{
unsigned number_of_used_nodes = 0;
unsigned number_of_used_edges = 0;
std::cout << "[extractor] Sorting used nodes ... " << std::flush;
TIMER_START(sorting_used_nodes);
stxxl::sort(used_node_id_list.begin(), used_node_id_list.end(), Cmp(), stxxl_memory);
TIMER_STOP(sorting_used_nodes);
std::cout << "ok, after " << TIMER_SEC(sorting_used_nodes) << "s" << std::endl;
std::cout << "[extractor] Erasing duplicate nodes ... " << std::flush;
TIMER_START(erasing_dups);
auto new_end = std::unique(used_node_id_list.begin(), used_node_id_list.end());
used_node_id_list.resize(new_end - used_node_id_list.begin());
TIMER_STOP(erasing_dups);
std::cout << "ok, after " << TIMER_SEC(erasing_dups) << "s" << std::endl;
std::cout << "[extractor] Sorting all nodes ... " << std::flush;
TIMER_START(sorting_nodes);
stxxl::sort(all_nodes_list.begin(),
all_nodes_list.end(),
ExternalMemoryNodeSTXXLCompare(),
stxxl_memory);
TIMER_STOP(sorting_nodes);
std::cout << "ok, after " << TIMER_SEC(sorting_nodes) << "s" << std::endl;
std::cout << "[extractor] Sorting used ways ... " << std::flush;
TIMER_START(sort_ways);
stxxl::sort(way_start_end_id_list.begin(),
way_start_end_id_list.end(),
FirstAndLastSegmentOfWayStxxlCompare(),
stxxl_memory);
TIMER_STOP(sort_ways);
std::cout << "ok, after " << TIMER_SEC(sort_ways) << "s" << std::endl;
std::cout << "[extractor] Sorting " << restrictions_list.size() << " restrictions. by from... " << std::flush;
TIMER_START(sort_restrictions);
stxxl::sort(restrictions_list.begin(),
restrictions_list.end(),
CmpRestrictionContainerByFrom(),
stxxl_memory);
TIMER_STOP(sort_restrictions);
std::cout << "ok, after " << TIMER_SEC(sort_restrictions) << "s" << std::endl;
std::cout << "[extractor] Fixing restriction starts ... " << std::flush;
TIMER_START(fix_restriction_starts);
auto restrictions_iterator = restrictions_list.begin();
auto way_start_and_end_iterator = way_start_end_id_list.begin();
while (way_start_and_end_iterator != way_start_end_id_list.end() &&
restrictions_iterator != restrictions_list.end())
{
if (way_start_and_end_iterator->way_id < restrictions_iterator->restriction.from.way)
{
++way_start_and_end_iterator;
continue;
}
if (way_start_and_end_iterator->way_id > restrictions_iterator->restriction.from.way)
{
++restrictions_iterator;
continue;
}
BOOST_ASSERT(way_start_and_end_iterator->way_id == restrictions_iterator->restriction.from.way);
const NodeID via_node_id = restrictions_iterator->restriction.via.node;
if (way_start_and_end_iterator->first_segment_source_id == via_node_id)
{
restrictions_iterator->restriction.from.node =
way_start_and_end_iterator->first_segment_source_id;
}
else if (way_start_and_end_iterator->first_segment_source_id == via_node_id)
{
restrictions_iterator->restriction.from.node =
way_start_and_end_iterator->first_segment_source_id;
}
else if (way_start_and_end_iterator->last_segment_source_id == via_node_id)
{
restrictions_iterator->restriction.from.node =
way_start_and_end_iterator->last_segment_target_id;
}
else if (way_start_and_end_iterator->last_segment_target_id == via_node_id)
{
restrictions_iterator->restriction.from.node = way_start_and_end_iterator->last_segment_source_id;
}
++restrictions_iterator;
}
TIMER_STOP(fix_restriction_starts);
std::cout << "ok, after " << TIMER_SEC(fix_restriction_starts) << "s" << std::endl;
std::cout << "[extractor] Sorting restrictions. by to ... " << std::flush;
TIMER_START(sort_restrictions_to);
stxxl::sort(restrictions_list.begin(),
restrictions_list.end(),
CmpRestrictionContainerByTo(),
stxxl_memory);
TIMER_STOP(sort_restrictions_to);
std::cout << "ok, after " << TIMER_SEC(sort_restrictions_to) << "s" << std::endl;
unsigned number_of_useable_restrictions = 0;
std::cout << "[extractor] Fixing restriction ends ... " << std::flush;
TIMER_START(fix_restriction_ends);
restrictions_iterator = restrictions_list.begin();
way_start_and_end_iterator = way_start_end_id_list.begin();
while (way_start_and_end_iterator != way_start_end_id_list.end() &&
restrictions_iterator != restrictions_list.end())
{
if (way_start_and_end_iterator->way_id < restrictions_iterator->restriction.to.way)
{
++way_start_and_end_iterator;
continue;
}
if (way_start_and_end_iterator->way_id > restrictions_iterator->restriction.to.way)
{
++restrictions_iterator;
continue;
}
NodeID via_node_id = restrictions_iterator->restriction.via.node;
if (way_start_and_end_iterator->last_segment_source_id == via_node_id)
{
restrictions_iterator->restriction.to.node = way_start_and_end_iterator->last_segment_target_id;
}
else if (way_start_and_end_iterator->last_segment_target_id == via_node_id)
{
restrictions_iterator->restriction.to.node = way_start_and_end_iterator->last_segment_source_id;
}
else if (way_start_and_end_iterator->first_segment_source_id == via_node_id)
{
restrictions_iterator->restriction.to.node = way_start_and_end_iterator->first_segment_target_id;
}
else if (way_start_and_end_iterator->first_segment_target_id == via_node_id)
{
restrictions_iterator->restriction.to.node = way_start_and_end_iterator->first_segment_source_id;
}
if (std::numeric_limits<unsigned>::max() != restrictions_iterator->restriction.from.node &&
std::numeric_limits<unsigned>::max() != restrictions_iterator->restriction.to.node)
{
++number_of_useable_restrictions;
}
++restrictions_iterator;
}
TIMER_STOP(fix_restriction_ends);
std::cout << "ok, after " << TIMER_SEC(fix_restriction_ends) << "s" << std::endl;
SimpleLogger().Write() << "usable restrictions: " << number_of_useable_restrictions;
// serialize restrictions
std::ofstream restrictions_out_stream;
restrictions_out_stream.open(restrictions_file_name.c_str(), std::ios::binary);
restrictions_out_stream.write((char *)&fingerprint, sizeof(FingerPrint));
restrictions_out_stream.write((char *)&number_of_useable_restrictions, sizeof(unsigned));
for(const auto & restriction_container : restrictions_list)
{
if (std::numeric_limits<unsigned>::max() != restriction_container.restriction.from.node &&
std::numeric_limits<unsigned>::max() != restriction_container.restriction.to.node)
{
restrictions_out_stream.write((char *)&(restriction_container.restriction),
sizeof(TurnRestriction));
}
}
restrictions_out_stream.close();
std::ofstream file_out_stream;
file_out_stream.open(output_file_name.c_str(), std::ios::binary);
const FingerPrint fingerprint = FingerPrint::GetValid();
file_out_stream.write((char *)&fingerprint, sizeof(FingerPrint));
file_out_stream.write((char *)&number_of_used_nodes, sizeof(unsigned));
std::cout << "[extractor] Confirming/Writing used nodes ... " << std::flush;
TIMER_START(write_nodes);
// identify all used nodes by a merging step of two sorted lists
auto node_iterator = all_nodes_list.begin();
auto node_id_iterator = used_node_id_list.begin();
while (node_id_iterator != used_node_id_list.end() && node_iterator != all_nodes_list.end())
{
if (*node_id_iterator < node_iterator->node_id)
{
++node_id_iterator;
continue;
}
if (*node_id_iterator > node_iterator->node_id)
{
++node_iterator;
continue;
}
BOOST_ASSERT(*node_id_iterator == node_iterator->node_id);
file_out_stream.write((char *)&(*node_iterator), sizeof(ExternalMemoryNode));
PrepareNodes();
WriteNodes(file_out_stream);
PrepareEdges();
WriteEdges(file_out_stream);
++number_of_used_nodes;
++node_id_iterator;
++node_iterator;
}
TIMER_STOP(write_nodes);
std::cout << "ok, after " << TIMER_SEC(write_nodes) << "s" << std::endl;
std::cout << "[extractor] setting number of nodes ... " << std::flush;
std::ios::pos_type previous_file_position = file_out_stream.tellp();
file_out_stream.seekp(std::ios::beg + sizeof(FingerPrint));
file_out_stream.write((char *)&number_of_used_nodes, sizeof(unsigned));
file_out_stream.seekp(previous_file_position);
std::cout << "ok" << std::endl;
// Sort edges by start.
std::cout << "[extractor] Sorting edges by start ... " << std::flush;
TIMER_START(sort_edges_by_start);
stxxl::sort(all_edges_list.begin(), all_edges_list.end(), CmpEdgeByStartID(), stxxl_memory);
TIMER_STOP(sort_edges_by_start);
std::cout << "ok, after " << TIMER_SEC(sort_edges_by_start) << "s" << std::endl;
std::cout << "[extractor] Setting start coords ... " << std::flush;
TIMER_START(set_start_coords);
file_out_stream.write((char *)&number_of_used_edges, sizeof(unsigned));
// Traverse list of edges and nodes in parallel and set start coord
node_iterator = all_nodes_list.begin();
auto edge_iterator = all_edges_list.begin();
while (edge_iterator != all_edges_list.end() && node_iterator != all_nodes_list.end())
{
if (edge_iterator->start < node_iterator->node_id)
{
++edge_iterator;
continue;
}
if (edge_iterator->start > node_iterator->node_id)
{
node_iterator++;
continue;
}
BOOST_ASSERT(edge_iterator->start == node_iterator->node_id);
edge_iterator->source_coordinate.lat = node_iterator->lat;
edge_iterator->source_coordinate.lon = node_iterator->lon;
++edge_iterator;
}
TIMER_STOP(set_start_coords);
std::cout << "ok, after " << TIMER_SEC(set_start_coords) << "s" << std::endl;
// Sort Edges by target
std::cout << "[extractor] Sorting edges by target ... " << std::flush;
TIMER_START(sort_edges_by_target);
stxxl::sort(all_edges_list.begin(), all_edges_list.end(), CmpEdgeByTargetID(), stxxl_memory);
TIMER_STOP(sort_edges_by_target);
std::cout << "ok, after " << TIMER_SEC(sort_edges_by_target) << "s" << std::endl;
std::cout << "[extractor] Setting target coords ... " << std::flush;
TIMER_START(set_target_coords);
// Traverse list of edges and nodes in parallel and set target coord
node_iterator = all_nodes_list.begin();
edge_iterator = all_edges_list.begin();
while (edge_iterator != all_edges_list.end() && node_iterator != all_nodes_list.end())
{
if (edge_iterator->target < node_iterator->node_id)
{
++edge_iterator;
continue;
}
if (edge_iterator->target > node_iterator->node_id)
{
++node_iterator;
continue;
}
BOOST_ASSERT(edge_iterator->target == node_iterator->node_id);
if (edge_iterator->source_coordinate.lat != std::numeric_limits<int>::min() &&
edge_iterator->source_coordinate.lon != std::numeric_limits<int>::min())
{
BOOST_ASSERT(edge_iterator->speed != -1);
edge_iterator->target_coordinate.lat = node_iterator->lat;
edge_iterator->target_coordinate.lon = node_iterator->lon;
const double distance = FixedPointCoordinate::ApproximateEuclideanDistance(
edge_iterator->source_coordinate.lat,
edge_iterator->source_coordinate.lon,
node_iterator->lat,
node_iterator->lon);
const double weight = (distance * 10.) / (edge_iterator->speed / 3.6);
int integer_weight = std::max(
1,
(int)std::floor(
(edge_iterator->is_duration_set ? edge_iterator->speed : weight) + .5));
int integer_distance = std::max(1, (int)distance);
short zero = 0;
short one = 1;
file_out_stream.write((char *)&edge_iterator->start, sizeof(unsigned));
file_out_stream.write((char *)&edge_iterator->target, sizeof(unsigned));
file_out_stream.write((char *)&integer_distance, sizeof(int));
switch (edge_iterator->direction)
{
case ExtractionWay::notSure:
file_out_stream.write((char *)&zero, sizeof(short));
break;
case ExtractionWay::oneway:
file_out_stream.write((char *)&one, sizeof(short));
break;
case ExtractionWay::bidirectional:
file_out_stream.write((char *)&zero, sizeof(short));
break;
case ExtractionWay::opposite:
file_out_stream.write((char *)&one, sizeof(short));
break;
default:
throw OSRMException("edge has broken direction");
}
file_out_stream.write((char *)&integer_weight, sizeof(int));
file_out_stream.write((char *)&edge_iterator->name_id, sizeof(unsigned));
file_out_stream.write((char *)&edge_iterator->is_roundabout, sizeof(bool));
file_out_stream.write((char *)&edge_iterator->is_in_tiny_cc, sizeof(bool));
file_out_stream.write((char *)&edge_iterator->is_access_restricted, sizeof(bool));
// cannot take adress of bit field, so use local
const TravelMode travel_mode = edge_iterator->travel_mode;
file_out_stream.write((char *)&travel_mode, sizeof(TravelMode));
file_out_stream.write((char *)&edge_iterator->is_split, sizeof(bool));
++number_of_used_edges;
}
++edge_iterator;
}
TIMER_STOP(set_target_coords);
std::cout << "ok, after " << TIMER_SEC(set_target_coords) << "s" << std::endl;
std::cout << "[extractor] setting number of edges ... " << std::flush;
file_out_stream.seekp(previous_file_position);
file_out_stream.write((char *)&number_of_used_edges, sizeof(unsigned));
file_out_stream.close();
std::cout << "ok" << std::endl;
std::cout << "[extractor] writing street name index ... " << std::flush;
TIMER_START(write_name_index);
std::string name_file_streamName = (output_file_name + ".names");
boost::filesystem::ofstream name_file_stream(name_file_streamName, std::ios::binary);
PrepareRestrictions();
WriteRestrictions(restrictions_file_name);
unsigned total_length = 0;
std::vector<unsigned> name_lengths;
for (const std::string &temp_string : name_list)
{
const unsigned string_length = std::min(static_cast<unsigned>(temp_string.length()), 255u);
name_lengths.push_back(string_length);
total_length += string_length;
}
RangeTable<> table(name_lengths);
name_file_stream << table;
name_file_stream.write((char*) &total_length, sizeof(unsigned));
// write all chars consecutively
for (const std::string &temp_string : name_list)
{
const unsigned string_length = std::min(static_cast<unsigned>(temp_string.length()), 255u);
name_file_stream.write(temp_string.c_str(), string_length);
}
name_file_stream.close();
TIMER_STOP(write_name_index);
std::cout << "ok, after " << TIMER_SEC(write_name_index) << "s" << std::endl;
SimpleLogger().Write() << "Processed " << number_of_used_nodes << " nodes and "
<< number_of_used_edges << " edges";
WriteNames(name_file_name);
}
catch (const std::exception &e)
{
std::cerr << "Caught Execption:" << e.what() << std::endl;
}
catch (const std::exception &e) { std::cerr << "Caught Execption:" << e.what() << std::endl; }
}
void ExtractionContainers::WriteNames(const std::string& names_file_name) const
{
std::cout << "[extractor] writing street name index ... " << std::flush;
TIMER_START(write_name_index);
boost::filesystem::ofstream name_file_stream(names_file_name, std::ios::binary);
unsigned total_length = 0;
std::vector<unsigned> name_lengths;
for (const std::string &temp_string : name_list)
{
const unsigned string_length =
std::min(static_cast<unsigned>(temp_string.length()), 255u);
name_lengths.push_back(string_length);
total_length += string_length;
}
// builds and writes the index
RangeTable<> name_index_range(name_lengths);
name_file_stream << name_index_range;
name_file_stream.write((char *)&total_length, sizeof(unsigned));
// write all chars consecutively
for (const std::string &temp_string : name_list)
{
const unsigned string_length =
std::min(static_cast<unsigned>(temp_string.length()), 255u);
name_file_stream.write(temp_string.c_str(), string_length);
}
name_file_stream.close();
TIMER_STOP(write_name_index);
std::cout << "ok, after " << TIMER_SEC(write_name_index) << "s" << std::endl;
}
void ExtractionContainers::PrepareNodes()
{
std::cout << "[extractor] Sorting used nodes ... " << std::flush;
TIMER_START(sorting_used_nodes);
stxxl::sort(used_node_id_list.begin(), used_node_id_list.end(), Cmp(), stxxl_memory);
TIMER_STOP(sorting_used_nodes);
std::cout << "ok, after " << TIMER_SEC(sorting_used_nodes) << "s" << std::endl;
std::cout << "[extractor] Erasing duplicate nodes ... " << std::flush;
TIMER_START(erasing_dups);
auto new_end = std::unique(used_node_id_list.begin(), used_node_id_list.end());
used_node_id_list.resize(new_end - used_node_id_list.begin());
TIMER_STOP(erasing_dups);
std::cout << "ok, after " << TIMER_SEC(erasing_dups) << "s" << std::endl;
std::cout << "[extractor] Building node id map ... " << std::flush;
TIMER_START(id_map);
external_to_internal_node_id_map.reserve(used_node_id_list.size());
for (NodeID i = 0u; i < used_node_id_list.size(); ++i)
external_to_internal_node_id_map[used_node_id_list[i]] = i;
TIMER_STOP(id_map);
std::cout << "ok, after " << TIMER_SEC(id_map) << "s" << std::endl;
std::cout << "[extractor] Sorting all nodes ... " << std::flush;
TIMER_START(sorting_nodes);
stxxl::sort(all_nodes_list.begin(), all_nodes_list.end(), ExternalMemoryNodeSTXXLCompare(),
stxxl_memory);
TIMER_STOP(sorting_nodes);
std::cout << "ok, after " << TIMER_SEC(sorting_nodes) << "s" << std::endl;
}
void ExtractionContainers::PrepareEdges()
{
// Sort edges by start.
std::cout << "[extractor] Sorting edges by start ... " << std::flush;
TIMER_START(sort_edges_by_start);
stxxl::sort(all_edges_list.begin(), all_edges_list.end(), CmpEdgeByStartID(), stxxl_memory);
TIMER_STOP(sort_edges_by_start);
std::cout << "ok, after " << TIMER_SEC(sort_edges_by_start) << "s" << std::endl;
std::cout << "[extractor] Setting start coords ... " << std::flush;
TIMER_START(set_start_coords);
// Traverse list of edges and nodes in parallel and set start coord
auto node_iterator = all_nodes_list.begin();
auto edge_iterator = all_edges_list.begin();
while (edge_iterator != all_edges_list.end() && node_iterator != all_nodes_list.end())
{
if (edge_iterator->result.source < node_iterator->node_id)
{
edge_iterator->result.source = SPECIAL_NODEID;
++edge_iterator;
continue;
}
if (edge_iterator->result.source > node_iterator->node_id)
{
node_iterator++;
continue;
}
// remove loops
if (edge_iterator->result.source == edge_iterator->result.target)
{
edge_iterator->result.source = SPECIAL_NODEID;
edge_iterator->result.target = SPECIAL_NODEID;
++edge_iterator;
continue;
}
BOOST_ASSERT(edge_iterator->result.source == node_iterator->node_id);
// assign new node id
auto id_iter = external_to_internal_node_id_map.find(node_iterator->node_id);
BOOST_ASSERT(id_iter != external_to_internal_node_id_map.end());
edge_iterator->result.source = id_iter->second;
edge_iterator->source_coordinate.lat = node_iterator->lat;
edge_iterator->source_coordinate.lon = node_iterator->lon;
++edge_iterator;
}
TIMER_STOP(set_start_coords);
std::cout << "ok, after " << TIMER_SEC(set_start_coords) << "s" << std::endl;
// Sort Edges by target
std::cout << "[extractor] Sorting edges by target ... " << std::flush;
TIMER_START(sort_edges_by_target);
stxxl::sort(all_edges_list.begin(), all_edges_list.end(), CmpEdgeByTargetID(),
stxxl_memory);
TIMER_STOP(sort_edges_by_target);
std::cout << "ok, after " << TIMER_SEC(sort_edges_by_target) << "s" << std::endl;
// Compute edge weights
std::cout << "[extractor] Computing edge weights ... " << std::flush;
TIMER_START(compute_weights);
node_iterator = all_nodes_list.begin();
edge_iterator = all_edges_list.begin();
while (edge_iterator != all_edges_list.end() && node_iterator != all_nodes_list.end())
{
// skip all invalid edges
if (edge_iterator->result.source == SPECIAL_NODEID)
{
++edge_iterator;
continue;
}
if (edge_iterator->result.target < node_iterator->node_id)
{
edge_iterator->result.target = SPECIAL_NODEID;
++edge_iterator;
continue;
}
if (edge_iterator->result.target > node_iterator->node_id)
{
++node_iterator;
continue;
}
BOOST_ASSERT(edge_iterator->result.target == node_iterator->node_id);
BOOST_ASSERT(edge_iterator->weight_data.speed >= 0);
BOOST_ASSERT(edge_iterator->source_coordinate.lat != std::numeric_limits<int>::min());
BOOST_ASSERT(edge_iterator->source_coordinate.lon != std::numeric_limits<int>::min());
const double distance = coordinate_calculation::euclidean_distance(
edge_iterator->source_coordinate.lat, edge_iterator->source_coordinate.lon,
node_iterator->lat, node_iterator->lon);
const double weight = [distance](const InternalExtractorEdge::WeightData& data) {
switch (data.type)
{
case InternalExtractorEdge::WeightType::EDGE_DURATION:
case InternalExtractorEdge::WeightType::WAY_DURATION:
return data.duration * 10.;
break;
case InternalExtractorEdge::WeightType::SPEED:
return (distance * 10.) / (data.speed / 3.6);
break;
case InternalExtractorEdge::WeightType::INVALID:
osrm::exception("invalid weight type");
}
return -1.0;
}(edge_iterator->weight_data);
auto& edge = edge_iterator->result;
edge.weight = std::max(1, static_cast<int>(std::floor(weight + .5)));
// assign new node id
auto id_iter = external_to_internal_node_id_map.find(node_iterator->node_id);
BOOST_ASSERT(id_iter != external_to_internal_node_id_map.end());
edge.target = id_iter->second;
// orient edges consistently: source id < target id
// important for multi-edge removal
if (edge.source > edge.target)
{
std::swap(edge.source, edge.target);
// std::swap does not work with bit-fields
bool temp = edge.forward;
edge.forward = edge.backward;
edge.backward = temp;
}
++edge_iterator;
}
TIMER_STOP(compute_weights);
std::cout << "ok, after " << TIMER_SEC(compute_weights) << "s" << std::endl;
// Sort edges by start.
std::cout << "[extractor] Sorting edges by renumbered start ... " << std::flush;
TIMER_START(sort_edges_by_renumbered_start);
stxxl::sort(all_edges_list.begin(), all_edges_list.end(), CmpEdgeByStartThenTargetID(), stxxl_memory);
TIMER_STOP(sort_edges_by_renumbered_start);
std::cout << "ok, after " << TIMER_SEC(sort_edges_by_renumbered_start) << "s" << std::endl;
BOOST_ASSERT(all_edges_list.size() > 0);
for (unsigned i = 0; i < all_edges_list.size();)
{
// only invalid edges left
if (all_edges_list[i].result.source == SPECIAL_NODEID)
{
break;
}
// skip invalid edges
if (all_edges_list[i].result.target == SPECIAL_NODEID)
{
continue;
}
unsigned start_idx = i;
NodeID source = all_edges_list[i].result.source;
NodeID target = all_edges_list[i].result.target;
int min_forward_weight = std::numeric_limits<int>::max();
int min_backward_weight = std::numeric_limits<int>::max();
unsigned min_forward_idx = std::numeric_limits<unsigned>::max();
unsigned min_backward_idx = std::numeric_limits<unsigned>::max();
// find minimal edge in both directions
while (all_edges_list[i].result.source == source &&
all_edges_list[i].result.target == target)
{
if (all_edges_list[i].result.forward && all_edges_list[i].result.weight < min_forward_weight)
{
min_forward_idx = i;
}
if (all_edges_list[i].result.backward && all_edges_list[i].result.weight < min_backward_weight)
{
min_backward_idx = i;
}
// this also increments the outer loop counter!
i++;
}
BOOST_ASSERT(min_forward_idx == std::numeric_limits<unsigned>::max() || min_forward_idx < i);
BOOST_ASSERT(min_backward_idx == std::numeric_limits<unsigned>::max() || min_backward_idx < i);
BOOST_ASSERT(min_backward_idx != std::numeric_limits<unsigned>::max() ||
min_forward_idx != std::numeric_limits<unsigned>::max());
if (min_backward_idx == min_forward_idx)
{
all_edges_list[min_forward_idx].result.is_split = false;
all_edges_list[min_forward_idx].result.forward = true;
all_edges_list[min_forward_idx].result.backward = true;
}
else
{
bool has_forward = min_forward_idx != std::numeric_limits<unsigned>::max();
bool has_backward = min_backward_idx != std::numeric_limits<unsigned>::max();
if (has_forward)
{
all_edges_list[min_forward_idx].result.forward = true;
all_edges_list[min_forward_idx].result.backward = false;
all_edges_list[min_forward_idx].result.is_split = has_backward;
}
if (has_backward)
{
std::swap(all_edges_list[min_backward_idx].result.source,
all_edges_list[min_backward_idx].result.target);
all_edges_list[min_backward_idx].result.forward = true;
all_edges_list[min_backward_idx].result.backward = false;
all_edges_list[min_backward_idx].result.is_split = has_forward;
}
}
// invalidate all unused edges
for (unsigned j = start_idx; j < i; j++)
{
if (j == min_forward_idx || j == min_backward_idx)
{
continue;
}
all_edges_list[j].result.source = SPECIAL_NODEID;
all_edges_list[j].result.target = SPECIAL_NODEID;
}
}
}
void ExtractionContainers::WriteEdges(std::ofstream& file_out_stream) const
{
std::cout << "[extractor] Writing used egdes ... " << std::flush;
TIMER_START(write_edges);
// Traverse list of edges and nodes in parallel and set target coord
unsigned number_of_used_edges = 0;
auto start_position = file_out_stream.tellp();
file_out_stream.write((char *)&number_of_used_edges, sizeof(unsigned));
for (const auto& edge : all_edges_list)
{
if (edge.result.source == SPECIAL_NODEID || edge.result.target == SPECIAL_NODEID)
{
continue;
}
file_out_stream.write((char*) &edge.result, sizeof(NodeBasedEdge));
number_of_used_edges++;
}
TIMER_STOP(write_edges);
std::cout << "ok, after " << TIMER_SEC(write_edges) << "s" << std::endl;
std::cout << "[extractor] setting number of edges ... " << std::flush;
file_out_stream.seekp(start_position);
file_out_stream.write((char *)&number_of_used_edges, sizeof(unsigned));
std::cout << "ok" << std::endl;
SimpleLogger().Write() << "Processed " << number_of_used_edges << " edges";
}
void ExtractionContainers::WriteNodes(std::ofstream& file_out_stream) const
{
unsigned number_of_used_nodes = 0;
// write dummy value, will be overwritten later
file_out_stream.write((char *)&number_of_used_nodes, sizeof(unsigned));
std::cout << "[extractor] Confirming/Writing used nodes ... " << std::flush;
TIMER_START(write_nodes);
// identify all used nodes by a merging step of two sorted lists
auto node_iterator = all_nodes_list.begin();
auto node_id_iterator = used_node_id_list.begin();
while (node_id_iterator != used_node_id_list.end() && node_iterator != all_nodes_list.end())
{
if (*node_id_iterator < node_iterator->node_id)
{
++node_id_iterator;
continue;
}
if (*node_id_iterator > node_iterator->node_id)
{
++node_iterator;
continue;
}
BOOST_ASSERT(*node_id_iterator == node_iterator->node_id);
file_out_stream.write((char *)&(*node_iterator), sizeof(ExternalMemoryNode));
++number_of_used_nodes;
++node_id_iterator;
++node_iterator;
}
TIMER_STOP(write_nodes);
std::cout << "ok, after " << TIMER_SEC(write_nodes) << "s" << std::endl;
std::cout << "[extractor] setting number of nodes ... " << std::flush;
std::ios::pos_type previous_file_position = file_out_stream.tellp();
file_out_stream.seekp(std::ios::beg + sizeof(FingerPrint));
file_out_stream.write((char *)&number_of_used_nodes, sizeof(unsigned));
file_out_stream.seekp(previous_file_position);
std::cout << "ok" << std::endl;
SimpleLogger().Write() << "Processed " << number_of_used_nodes << " nodes";
}
void ExtractionContainers::WriteRestrictions(const std::string& path) const
{
// serialize restrictions
std::ofstream restrictions_out_stream;
unsigned written_restriction_count = 0;
restrictions_out_stream.open(path.c_str(), std::ios::binary);
const FingerPrint fingerprint = FingerPrint::GetValid();
restrictions_out_stream.write((char *)&fingerprint, sizeof(FingerPrint));
const auto count_position = restrictions_out_stream.tellp();
restrictions_out_stream.write((char *)&written_restriction_count, sizeof(unsigned));
for (const auto &restriction_container : restrictions_list)
{
if (SPECIAL_NODEID != restriction_container.restriction.from.node &&
SPECIAL_NODEID != restriction_container.restriction.via.node &&
SPECIAL_NODEID != restriction_container.restriction.to.node)
{
restrictions_out_stream.write((char *)&(restriction_container.restriction),
sizeof(TurnRestriction));
++written_restriction_count;
}
}
restrictions_out_stream.seekp(count_position);
restrictions_out_stream.write((char *)&written_restriction_count, sizeof(unsigned));
restrictions_out_stream.close();
SimpleLogger().Write() << "usable restrictions: " << written_restriction_count;
}
void ExtractionContainers::PrepareRestrictions()
{
std::cout << "[extractor] Sorting used ways ... " << std::flush;
TIMER_START(sort_ways);
stxxl::sort(way_start_end_id_list.begin(), way_start_end_id_list.end(),
FirstAndLastSegmentOfWayStxxlCompare(), stxxl_memory);
TIMER_STOP(sort_ways);
std::cout << "ok, after " << TIMER_SEC(sort_ways) << "s" << std::endl;
std::cout << "[extractor] Sorting " << restrictions_list.size()
<< " restriction. by from... " << std::flush;
TIMER_START(sort_restrictions);
stxxl::sort(restrictions_list.begin(), restrictions_list.end(),
CmpRestrictionContainerByFrom(), stxxl_memory);
TIMER_STOP(sort_restrictions);
std::cout << "ok, after " << TIMER_SEC(sort_restrictions) << "s" << std::endl;
std::cout << "[extractor] Fixing restriction starts ... " << std::flush;
TIMER_START(fix_restriction_starts);
auto restrictions_iterator = restrictions_list.begin();
auto way_start_and_end_iterator = way_start_end_id_list.cbegin();
while (way_start_and_end_iterator != way_start_end_id_list.cend() &&
restrictions_iterator != restrictions_list.end())
{
if (way_start_and_end_iterator->way_id < restrictions_iterator->restriction.from.way)
{
++way_start_and_end_iterator;
continue;
}
if (way_start_and_end_iterator->way_id > restrictions_iterator->restriction.from.way)
{
SimpleLogger().Write(LogLevel::logDEBUG) << "Restriction references invalid way: " << restrictions_iterator->restriction.from.way;
restrictions_iterator->restriction.from.node = SPECIAL_NODEID;
++restrictions_iterator;
continue;
}
BOOST_ASSERT(way_start_and_end_iterator->way_id ==
restrictions_iterator->restriction.from.way);
// we do not remap the via id yet, since we will need it for the to node as well
const NodeID via_node_id = restrictions_iterator->restriction.via.node;
// check if via is actually valid, if not invalidate
auto via_id_iter = external_to_internal_node_id_map.find(via_node_id);
if(via_id_iter == external_to_internal_node_id_map.end())
{
SimpleLogger().Write(LogLevel::logDEBUG) << "Restriction references invalid node: " << restrictions_iterator->restriction.via.node;
restrictions_iterator->restriction.via.node = SPECIAL_NODEID;
++restrictions_iterator;
continue;
}
if (way_start_and_end_iterator->first_segment_source_id == via_node_id)
{
// assign new from node id
auto id_iter = external_to_internal_node_id_map.find(
way_start_and_end_iterator->first_segment_target_id);
BOOST_ASSERT(id_iter != external_to_internal_node_id_map.end());
restrictions_iterator->restriction.from.node = id_iter->second;
}
else if (way_start_and_end_iterator->last_segment_target_id == via_node_id)
{
// assign new from node id
auto id_iter = external_to_internal_node_id_map.find(
way_start_and_end_iterator->last_segment_source_id);
BOOST_ASSERT(id_iter != external_to_internal_node_id_map.end());
restrictions_iterator->restriction.from.node = id_iter->second;
}
++restrictions_iterator;
}
TIMER_STOP(fix_restriction_starts);
std::cout << "ok, after " << TIMER_SEC(fix_restriction_starts) << "s" << std::endl;
std::cout << "[extractor] Sorting restrictions. by to ... " << std::flush;
TIMER_START(sort_restrictions_to);
stxxl::sort(restrictions_list.begin(), restrictions_list.end(),
CmpRestrictionContainerByTo(), stxxl_memory);
TIMER_STOP(sort_restrictions_to);
std::cout << "ok, after " << TIMER_SEC(sort_restrictions_to) << "s" << std::endl;
std::cout << "[extractor] Fixing restriction ends ... " << std::flush;
TIMER_START(fix_restriction_ends);
restrictions_iterator = restrictions_list.begin();
way_start_and_end_iterator = way_start_end_id_list.cbegin();
while (way_start_and_end_iterator != way_start_end_id_list.cend() &&
restrictions_iterator != restrictions_list.end())
{
if (way_start_and_end_iterator->way_id < restrictions_iterator->restriction.to.way)
{
++way_start_and_end_iterator;
continue;
}
if (restrictions_iterator->restriction.from.node == SPECIAL_NODEID ||
restrictions_iterator->restriction.via.node == SPECIAL_NODEID)
{
++restrictions_iterator;
continue;
}
if (way_start_and_end_iterator->way_id > restrictions_iterator->restriction.to.way)
{
SimpleLogger().Write(LogLevel::logDEBUG) << "Restriction references invalid way: " << restrictions_iterator->restriction.to.way;
restrictions_iterator->restriction.to.way = SPECIAL_NODEID;
++restrictions_iterator;
continue;
}
BOOST_ASSERT(way_start_and_end_iterator->way_id ==
restrictions_iterator->restriction.to.way);
const NodeID via_node_id = restrictions_iterator->restriction.via.node;
// assign new via node id
auto via_id_iter = external_to_internal_node_id_map.find(via_node_id);
BOOST_ASSERT(via_id_iter != external_to_internal_node_id_map.end());
restrictions_iterator->restriction.via.node = via_id_iter->second;
if (way_start_and_end_iterator->first_segment_source_id == via_node_id)
{
auto to_id_iter = external_to_internal_node_id_map.find(
way_start_and_end_iterator->first_segment_target_id);
BOOST_ASSERT(to_id_iter != external_to_internal_node_id_map.end());
restrictions_iterator->restriction.to.node = to_id_iter->second;
}
else if (way_start_and_end_iterator->last_segment_target_id == via_node_id)
{
auto to_id_iter = external_to_internal_node_id_map.find(
way_start_and_end_iterator->last_segment_source_id);
BOOST_ASSERT(to_id_iter != external_to_internal_node_id_map.end());
restrictions_iterator->restriction.to.node = to_id_iter->second;
}
++restrictions_iterator;
}
TIMER_STOP(fix_restriction_ends);
std::cout << "ok, after " << TIMER_SEC(fix_restriction_ends) << "s" << std::endl;
}
+28 -11
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -32,24 +32,40 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "first_and_last_segment_of_way.hpp"
#include "../data_structures/external_memory_node.hpp"
#include "../data_structures/restriction.hpp"
#include "../Util/FingerPrint.h"
#include <stxxl/vector>
#include <unordered_map>
/**
* Uses external memory containers from stxxl to store all the data that
* is collected by the extractor callbacks.
*
* The data is the filtered, aggregated and finally written to disk.
*/
class ExtractionContainers
{
#ifndef _MSC_VER
constexpr static unsigned stxxl_memory = ((sizeof(std::size_t) == 4) ? std::numeric_limits<int>::max() : std::numeric_limits<unsigned>::max());
constexpr static unsigned stxxl_memory =
((sizeof(std::size_t) == 4) ? std::numeric_limits<int>::max()
: std::numeric_limits<unsigned>::max());
#else
const static unsigned stxxl_memory = ((sizeof(std::size_t) == 4) ? INT_MAX : UINT_MAX);
#endif
void PrepareNodes();
void PrepareRestrictions();
void PrepareEdges();
void WriteNodes(std::ofstream& file_out_stream) const;
void WriteRestrictions(const std::string& restrictions_file_name) const;
void WriteEdges(std::ofstream& file_out_stream) const;
void WriteNames(const std::string& names_file_name) const;
public:
using STXXLNodeIDVector = stxxl::vector<NodeID>;
using STXXLNodeVector = stxxl::vector<ExternalMemoryNode>;
using STXXLEdgeVector = stxxl::vector<InternalExtractorEdge>;
using STXXLStringVector = stxxl::vector<std::string>;
using STXXLRestrictionsVector = stxxl::vector<InputRestrictionContainer>;
using STXXLWayIDStartEndVector = stxxl::vector<FirstAndLastSegmentOfWay>;
using STXXLNodeIDVector = stxxl::vector<NodeID>;
using STXXLNodeVector = stxxl::vector<ExternalMemoryNode>;
using STXXLEdgeVector = stxxl::vector<InternalExtractorEdge>;
using STXXLStringVector = stxxl::vector<std::string>;
using STXXLRestrictionsVector = stxxl::vector<InputRestrictionContainer>;
using STXXLWayIDStartEndVector = stxxl::vector<FirstAndLastSegmentOfWay>;
STXXLNodeIDVector used_node_id_list;
STXXLNodeVector all_nodes_list;
@@ -57,14 +73,15 @@ class ExtractionContainers
STXXLStringVector name_list;
STXXLRestrictionsVector restrictions_list;
STXXLWayIDStartEndVector way_start_end_id_list;
const FingerPrint fingerprint;
std::unordered_map<NodeID, NodeID> external_to_internal_node_id_map;
ExtractionContainers();
~ExtractionContainers();
void PrepareData(const std::string &output_file_name,
const std::string &restrictions_file_name);
const std::string &restrictions_file_name,
const std::string &names_file_name);
};
#endif /* EXTRACTION_CONTAINERS_HPP */

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