Compare commits

..

181 Commits

Author SHA1 Message Date
Daniel J. Hofmann e1e76d04d1 Adds round trip tests for RFC 4648 Test Vectors and equality checks 2016-03-23 22:47:22 +01:00
Daniel J. Hofmann 451bbe3021 Makes hint Equatable and Printable for tests 2016-03-23 22:47:22 +01:00
Daniel J. Hofmann 88a76aaecf Make Hint encoding safe for passing them as GET parameter in URLs
Thanks @TheMarex for flagging this!
2016-03-23 22:42:28 +01:00
Daniel J. Hofmann 87428f8fc9 Completely re-write base64 logic, make API suck less in doing so 2016-03-23 22:42:12 +01:00
Daniel J. Hofmann 6c9ddde682 RFC 4648 Test Vectors 2016-03-23 22:41:10 +01:00
Daniel J. Hofmann b4b148e3dc Object Encoder -> Base64, kill false dependencies while doing so 2016-03-23 22:40:59 +01:00
Daniel J. Hofmann 4a84ca3197 Adapts Hint encoding and decoding to new fixed data facade 2016-03-23 22:40:45 +01:00
Daniel J. Hofmann df182ebc38 Formats parameter parser unit tests 2016-03-23 22:40:32 +01:00
Patrick Niklaus c86864976c Fix hint size 2016-03-23 22:36:20 +01:00
Patrick Niklaus c3dd77d32b Always safe the absolute path to .fileIndex 2016-03-23 22:18:11 +01:00
Patrick Niklaus 2357d1c095 Merge pull request #2137 from noblige/rewrite/new-api
fixed compilation error on debian jessie with boost 1.54
2016-03-23 14:35:36 -04:00
Patrick Niklaus 7cd70679f1 Install storage_config.hpp 2016-03-23 19:19:00 +01:00
Aleksei Potov 08c1ac0daf compilation error on debian jessie with boost 1.54 2016-03-23 17:55:56 +00:00
Daniel Patterson 48237b30ea Fix boost geometry constructor.
Versions older than 1.58 don't support the initializer-list form.
2016-03-23 10:47:06 -07:00
Moritz Kobitzsch cac1298864 syncronize geometry and steps after post-processing 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch 83e6679d61 added list of intersections to the step-maneuver, not in api so far 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch f3ea86b611 fix initial maneuvers 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch f3de53c363 post processing moved onto route-steps, looses sync with geometry segments 2016-03-23 17:52:51 +01:00
Patrick Niklaus 19434d42b4 Simplify the timestamp handling 2016-03-23 17:52:51 +01:00
Patrick Niklaus ea24ea64f2 Check all streams 2016-03-23 17:52:51 +01:00
Patrick Niklaus 39f5cf1c22 std::string -> boost::filesystem::path 2016-03-23 17:52:51 +01:00
Patrick Niklaus 91384ecd8c Only allow to specify the common base path 2016-03-23 17:52:51 +01:00
Patrick Niklaus 5c28eabbe0 print -> io.write 2016-03-23 17:52:51 +01:00
Patrick Niklaus 42dd45b29b Address PR comments
Renamed lua_function_exists and removes unused print function
2016-03-23 17:52:51 +01:00
Patrick Niklaus 6f4095f23f Use uturn default from .properties file 2016-03-23 17:52:51 +01:00
Patrick Niklaus 9c6c02d85b Adds .properties file to osrm-extract ouput
This file contains global properties set by the lua
profile, such as enabling uturns at vias and penalties.
This file will be consumed by the server.
2016-03-23 17:52:51 +01:00
Patrick Niklaus 47afe60e5f Use global uturns parameter.
Instead of previously per-via settings like uturns=true;false;true;; it
now only supports a global setting uturns=true.
2016-03-23 17:52:51 +01:00
Moritz Kobitzsch 0471ace55d improves consistency of fork handling 2016-03-23 17:52:51 +01:00
Patrick Niklaus 49e2a4ec07 Make gcc 4.8 happy and disable protected because of lambdas 2016-03-23 17:52:51 +01:00
Daniel Patterson 991c5f5d5d Properly clip lines so that we don't get crazy coords with long linestrings (relative to tile coords) 2016-03-23 17:52:51 +01:00
Daniel Patterson 87c77e7d77 Include edge duration information. 2016-03-23 17:52:51 +01:00
Patrick Niklaus 2cf120fc49 Implement viewport code to fix simplification
This fixes #2083
2016-03-23 17:52:51 +01:00
Patrick Niklaus d4eaea1e7d Add tests for coordinate transformation 2016-03-23 17:52:51 +01:00
Patrick Niklaus 51a13675d4 Consolidate math functions 2016-03-23 17:52:51 +01:00
Patrick Niklaus af4cb96aa5 get_name_for_id -> GetNameForID 2016-03-23 17:52:51 +01:00
Patrick Niklaus 439a7ba661 Simplfy name change announcement 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch a0ff0b1258 fix division by zero 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch 1cc9a2f4a1 restructured to only return valid turns to the outside + cleanup 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch a3cf7f09e8 less new names, forks consider road classes, api clean-up 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch 831a536224 implement basic turn handling 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch 7df00683e1 implements relative position feature based on coordinates 2016-03-23 17:52:51 +01:00
Patrick Niklaus 0c0803c77b Don't sum up durations of merged steps since we do that in a different place now 2016-03-23 17:52:51 +01:00
Patrick Niklaus 7c5d56afcb Fix foward/backwad swap 2016-03-23 17:52:51 +01:00
Patrick Niklaus 892b9dff4a Limit zoomlevel to 18 2016-03-23 17:52:51 +01:00
Patrick Niklaus 04a8c1833c Fix shared memory 2016-03-23 17:52:51 +01:00
Patrick Niklaus c217ff815c Fixup for last commit 2016-03-23 17:52:51 +01:00
Daniel Patterson 893c9f7326 Enables the use of multiple segment-speed-files on the osrm-contract
command line, and exposes the file name used for each edge in the debug
tiles.
2016-03-23 17:52:51 +01:00
Patrick Niklaus 84fa7ae353 Fix ingestion fixed duration values from UnpackPath 2016-03-23 17:52:51 +01:00
Patrick Niklaus bb3256573b Fix durations in UnpackPath 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch 96d9ef3951 fixes a broken assertion 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch 11572702e9 fix merging of turn instructions 2016-03-23 17:52:51 +01:00
Patrick Niklaus 6d16bb5b25 Include reverse edges again 2016-03-23 17:52:51 +01:00
Patrick Niklaus 89eb2a3778 Formating and logging changes for turn classification 2016-03-23 17:52:51 +01:00
Patrick Niklaus 87408cfd73 Handle case of dead-end edges by inserting an invalid turn 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch dd4066c46e report depart/arrive in addition to waypoint 2016-03-23 17:52:51 +01:00
Patrick Niklaus 3f559211a4 Only install necessary headers 2016-03-23 17:52:51 +01:00
Daniel J. Hofmann 5892c6ea09 Adds the license preamble for all publicly installed eaders, closes #2036 2016-03-23 17:52:51 +01:00
Patrick Niklaus dea0063a56 Remove the encoder/decoder dependecy from Hint 2016-03-23 17:52:51 +01:00
Patrick Niklaus eec270968e Rename alternative -> alternatives 2016-03-23 17:52:51 +01:00
Patrick Niklaus 056a7422e0 Remove obsolete debug information 2016-03-23 17:52:51 +01:00
Patrick Niklaus 3d3fea768c Just return NoSegment in map matching if all candidates are empty 2016-03-23 17:52:51 +01:00
Patrick Niklaus 1a6c16fea1 Add failing test for map matching of outlier 2016-03-23 17:52:51 +01:00
Patrick Niklaus 3c56385ba8 Fix missing capitalization of error codes 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch 1947671ae3 encapsulated into class 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch 3189f24a17 improving fork handling on three-way turns 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch dd5c730a01 fix comparison for ramps on three-way turns 2016-03-23 17:52:51 +01:00
Patrick Niklaus da1dbcfb34 Minor auto iterator cleanup 2016-03-23 17:52:51 +01:00
Patrick Niklaus 8f5091f711 Don't pass down unsnapped coordinates. All information is already there 2016-03-23 17:52:51 +01:00
Patrick Niklaus 0da7302d62 Fix camMergeTrivially 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch f0b40c1948 fixes roundabout counting 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch ecefb4a20e fixes assignment for basic turn types / invalid ramp assignment 2016-03-23 17:52:51 +01:00
Patrick Niklaus 9b1861e017 Add edge id assertions 2016-03-23 17:52:51 +01:00
Patrick Niklaus 4fb041391f Don't pass shared_ptr down to functions
"Don’t pass a smart pointer as a function parameter unless you want to
use or manipulate the smart pointer itself, such as to share or transfer
ownership."

Source:
http://herbsutter.com/2013/06/05/gotw-91-solution-smart-pointer-parameters/
2016-03-23 17:52:51 +01:00
Patrick Niklaus 64cc7d8aac Move bearing to public namespace 2016-03-23 17:52:51 +01:00
Daniel J. Hofmann 556223d43b Properly includes needed headers in turn analysis interface 2016-03-23 17:52:51 +01:00
Daniel J. Hofmann 0b1e82105e Const-correctnes for compressed geometry iterator 2016-03-23 17:52:51 +01:00
Daniel J. Hofmann c9ad8736b0 Use stdint and using type-alias for discrete angle 2016-03-23 17:52:51 +01:00
Daniel J. Hofmann cded2501a5 Hide functional road classification based on tags in implementation file 2016-03-23 17:52:51 +01:00
Daniel J. Hofmann 4d94ec2792 Inline initialize functional road classification hash table 2016-03-23 17:52:51 +01:00
Daniel J. Hofmann 7970bc4ad6 256 functional road classes should be enough 2016-03-23 17:52:51 +01:00
Daniel J. Hofmann f84ce976ea Moves route assembly into implementation file 2016-03-23 17:52:51 +01:00
Daniel J. Hofmann ce9a4666f3 Fixes remaining engine/guidance includes 2016-03-23 17:52:51 +01:00
Daniel J. Hofmann ff55b4e001 Fixes accumulate living in <numeric> and not <algorithm> 2016-03-23 17:52:51 +01:00
Daniel J. Hofmann 8040af329b Puts step maneuver handling into implementation file 2016-03-23 17:52:51 +01:00
Daniel J. Hofmann b8c059b5c2 Removes penalizing move 2016-03-23 17:52:51 +01:00
Daniel J. Hofmann 4e2e2059b1 Uses static_casts for underlying type in post processing 2016-03-23 17:52:51 +01:00
Daniel J. Hofmann 922599a8ca Fix asymmetry in min/max from using -max 2016-03-23 17:52:51 +01:00
Daniel J. Hofmann 5bc0595591 Adapts MakeResponse to not pass vector by pointer 2016-03-23 17:52:51 +01:00
Daniel J. Hofmann 0f600c9262 Fixes multi-line comment 2016-03-23 17:52:51 +01:00
Daniel J. Hofmann 9338d418c8 Runs scripts/format.sh 2016-03-23 17:52:51 +01:00
Patrick Niklaus 4d56b8ff0d Fix coodinate include and unused warnings 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch 92b4f14db6 start of four way turns 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch a1f1da4c16 improved fork handling 2016-03-23 17:52:51 +01:00
Patrick Niklaus c337d55d45 Fix crash on extracting Berlin in guidance 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch be5f231641 bugfixing/classification 2016-03-23 17:52:51 +01:00
Patrick Niklaus c19fae4a43 Big Restructuring / Cleanup 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch 0831e71438 starting on conflict resolution 2016-03-23 17:52:51 +01:00
Lauren Budorick c44a370dd3 Fixes for gcc compiling, temporary hacks to remove later 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch 9f5e79501e handle segregated roads (merge for turn analysis) 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch cf5e722578 structural changes, motorway handling 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch f12bb2fa2f enter and exit roundabout feature - currently not showing turn 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch 28d878ed23 migrated out of edge based graph factory 2016-03-23 17:52:51 +01:00
Moritz Kobitzsch 6db16e950a relative waypoint locations 2016-03-23 17:52:14 +01:00
Moritz Kobitzsch 862f8d6ff3 handling of roundabouts (simple version) 2016-03-23 17:52:14 +01:00
Moritz Kobitzsch 8c67dd4504 advanced guidance on 5.0 2016-03-23 17:52:14 +01:00
Patrick Niklaus 23d79bde54 Fix numerical problems with polyline 2016-03-23 17:50:13 +01:00
Patrick Niklaus 410d561b4c Fix table response format to return null + double in seconds 2016-03-23 17:50:13 +01:00
Patrick Niklaus 8ab38b126c Return NoMatch 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann c13f1aa89d Provides ctor from base path for EngineConfig, fixes #2030 2016-03-23 17:50:13 +01:00
Patrick Niklaus b4bf0ec5fe Add support for tile plugin 2016-03-23 17:50:13 +01:00
Patrick Niklaus f7b7dbf51a Preliminary integration of the tile plugin 2016-03-23 17:50:13 +01:00
Patrick Niklaus 41c9f94e5f sources and destinations can be empty actually 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann 77adbca138 Fixes coordinate, source and destination validation by means of backporting #2041 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann f3e06b41dd Fixes ownership semantics and forwarding references misplacements in the JSON factory 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann ee4b8618f8 Unwrap function call from identity lambda 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann 58973a4fd1 Uses JSON's String constructor for polyline encoding 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann 4b8017d412 Passes coordinates by value 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann 64d4d58a0d Asserts on unknown TurnInstruction 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann 5d83fa1e4c Fixes header includes in the JSON factory 2016-03-23 17:50:13 +01:00
Dane Springmeyer 7a6aa6f1a7 fix compile of osrm-components 2016-03-23 17:50:13 +01:00
Patrick Niklaus e5d964492a Fix if the last coordinate is not found 2016-03-23 17:50:13 +01:00
Patrick Niklaus bb2baa82aa Allocate correct table size 2016-03-23 17:50:13 +01:00
Patrick Niklaus 0b5875a412 Fix travel mode passing from profiles up to the API 2016-03-23 17:50:13 +01:00
Patrick Niklaus 9a2b8cb16d Fix geometries type in steps 2016-03-23 17:50:13 +01:00
Patrick Niklaus 5fb6db7a9a Fix table parameter parsing 2016-03-23 17:50:13 +01:00
Patrick Niklaus c1647c99c8 Fix behaviour of table if sources/destinations arrays are empty 2016-03-23 17:50:13 +01:00
Patrick Niklaus 39d6c33b32 Fuck. this. shit. 2016-03-23 17:50:13 +01:00
Patrick Niklaus 9b75f618e8 Change stream operator of strong typedef 2016-03-23 17:50:13 +01:00
Patrick Niklaus 225049ffa7 Fix stream operator for coordinate 2016-03-23 17:50:13 +01:00
Patrick Niklaus 2df832a95e Add stream operator to Rectangle 2016-03-23 17:50:13 +01:00
Patrick Niklaus 75912b3662 Add euclideanDistance to coordinate_calculation 2016-03-23 17:50:13 +01:00
Patrick Niklaus c9a19c954e Simplify static_rtree tests 2016-03-23 17:50:13 +01:00
Patrick Niklaus 9a19086926 First round of lat,lng -> lng,lat switcheroo 2016-03-23 17:50:13 +01:00
Patrick Niklaus 90e8a3e1dc Add rectangle unit test 2016-03-23 17:50:13 +01:00
Patrick Niklaus 0270ee59b4 Fix match and trip API response 2016-03-23 17:50:13 +01:00
Patrick Niklaus 5728af4a2a Fix out-of-bounds write in map_matching 2016-03-23 17:50:13 +01:00
Dane Springmeyer 6cf19ac4cf Fix compile on OS X 2016-03-23 17:50:13 +01:00
Patrick Niklaus 3f81f6b441 Finish the nearest plugin 2016-03-23 17:50:13 +01:00
Patrick Niklaus 669aa9e672 Initialize NearestParameters correctly 2016-03-23 17:50:13 +01:00
Patrick Niklaus 1d3afd5c38 Adapt to feedback in #519 2016-03-23 17:50:13 +01:00
Patrick Niklaus c53a448589 Add trip plugin 2016-03-23 17:50:13 +01:00
Patrick Niklaus cb82376083 Hook up map matching 2016-03-23 17:50:13 +01:00
Patrick Niklaus 9d10490613 First compiling version of map_match plugin 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann 1cc7d3ddfb Adapts example/example.cpp to new osrm api 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann aad3d8aa1e Install _all_ transitively from public headers included header 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann 9258791811 Fix missing headers in hint.hpp 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann 19d5912a93 Adds $prefix/include/osrm to include dirs so that transitive header includes without osrm prefix can be found 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann a4770feac4 Adapt the example to include all osrm public headers 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann c8c6f8c2e7 Fixes missing public header installations 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann d7f9c31d0b Fix forward declarations in publicly facing osrm header 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann 44b802c053 Enable all plugins with aStatus::Error return code fallback for not implemented ones 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann 99f18051f6 Adds publicly facing alias headers for parameters 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann 99f94969aa Temporarily comment out match.cpp as to not break the build process 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann bc6d5bbde2 We don't need templates at all, this is not CRTP? 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann 6aa5ab5904 Fix classes for service member function definitions 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann 0c64503218 Service skeletons for nearest, trip, match 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann e15ba88c0b Fix grammar constraint and enable all plugin links 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann 2f9d1d3db2 Plugin grammar skeletons 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann 42e6e974ac Enforce parameter and grammar type to catch subtle bugs 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann 5a97e7a7ce Link parameters to grammars 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann 8c54794d5a Require a BaseParameters type at compile time via enable_if 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann e377a19c10 Adapts Nearest plugin to new API 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann 0fb6e9bf3f Fix deleting incomplete type and make Engine moveable only 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann d6a8690425 Adapts publicly facing new API 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann cc65446785 Adapts NearestParameters to new API 2016-03-23 17:50:13 +01:00
Patrick Niklaus 487df70eb3 Initial non-building match plugin 2016-03-23 17:50:13 +01:00
Lauren Budorick aa79c41804 Include numeric in assemble_overview.cpp (needed on OSX for std::accumulate) 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann 7faadb1233 Semantic action handler requires passing optional by value and fusion::vector2 2016-03-23 17:50:13 +01:00
Patrick Niklaus 5c8a895471 Add tests for bearing parsing 2016-03-23 17:50:13 +01:00
Patrick Niklaus e932a8253a Add table service 2016-03-23 17:50:13 +01:00
Patrick Niklaus 84097964b7 Add table API 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann c2a35b35ad Optional<T> semantic action handler takes T argument 2016-03-23 17:50:13 +01:00
Patrick Niklaus f6612e2afa Fix parameter parsing tests 2016-03-23 17:50:13 +01:00
Patrick Niklaus 09378f28fd Fix table plugin 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann 01ddfbcba3 First take at distance table API re-write 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann 0468d7a7c5 Adapts TableParameters and its validation to new API 2016-03-23 17:50:13 +01:00
Patrick Niklaus 39bc0fd330 Add viaroute suport for new API 2016-03-23 17:50:13 +01:00
Patrick Niklaus 53dbb1eac2 Also exclude the compressed flag from the data format 2016-03-23 17:50:13 +01:00
Patrick Niklaus f5bc843fe6 Remove geometry indicator 2016-03-23 17:50:13 +01:00
Daniel J. Hofmann c78dff9a15 Write out unsigned with a check for edge counter overflow 2016-03-19 00:27:55 +01:00
Daniel J. Hofmann 25fea558ba Fixes the edge-based-graph factory's edge counter serialization.
The counter for original edges is of type `std::size_t`, but we
serialized `sizeof(unsigned)` number of bytes out to the `.osrm.edges`
file.

We should probably check all writes (analogous for reads) and make the
count parameter dependent on `sizeof(variable)`.

    ag '\.write\((.*), sizeof\((.*)\)\);'
2016-03-19 00:27:55 +01:00
68 changed files with 1559 additions and 1345 deletions
+4 -2
View File
@@ -80,7 +80,7 @@ add_executable(osrm-extract src/tools/extract.cpp)
add_executable(osrm-contract src/tools/contract.cpp)
add_executable(osrm-routed src/tools/routed.cpp $<TARGET_OBJECTS:SERVER> $<TARGET_OBJECTS:UTIL>)
add_executable(osrm-datastore src/tools/store.cpp $<TARGET_OBJECTS:UTIL>)
add_library(osrm src/osrm/osrm.cpp $<TARGET_OBJECTS:ENGINE> $<TARGET_OBJECTS:UTIL>)
add_library(osrm src/osrm/osrm.cpp $<TARGET_OBJECTS:ENGINE> $<TARGET_OBJECTS:UTIL> $<TARGET_OBJECTS:STORAGE>)
add_library(osrm_extract $<TARGET_OBJECTS:EXTRACTOR> $<TARGET_OBJECTS:UTIL>)
add_library(osrm_contract $<TARGET_OBJECTS:CONTRACTOR> $<TARGET_OBJECTS:UTIL>)
add_library(osrm_store $<TARGET_OBJECTS:STORAGE> $<TARGET_OBJECTS:UTIL>)
@@ -94,6 +94,7 @@ add_executable(server-tests EXCLUDE_FROM_ALL unit_tests/server_tests.cpp ${Serve
# Benchmarks
add_executable(rtree-bench EXCLUDE_FROM_ALL src/benchmarks/static_rtree.cpp $<TARGET_OBJECTS:UTIL>)
target_include_directories(engine-tests PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/unit_tests)
target_include_directories(util-tests PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/unit_tests)
target_include_directories(rtree-bench PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/unit_tests)
@@ -381,9 +382,10 @@ set(EngineHeader include/engine/status.hpp include/engine/engine_config.hpp incl
set(UtilHeader include/util/coordinate.hpp include/util/json_container.hpp include/util/typedefs.hpp include/util/strong_typedef.hpp)
set(ExtractorHeader include/extractor/extractor.hpp include/extractor/extractor_config.hpp include/extractor/travel_mode.hpp)
set(ContractorHeader include/contractor/contractor.hpp include/contractor/contractor_config.hpp)
#set(StorageHeader include/storage/storage.hpp include/storage/storage_config.hpp)
set(StorageHeader include/storage/storage.hpp include/storage/storage_config.hpp)
install(FILES ${EngineHeader} DESTINATION include/osrm/engine)
install(FILES ${UtilHeader} DESTINATION include/osrm/util)
install(FILES ${StorageHeader} DESTINATION include/osrm/storage)
install(FILES ${ExtractorHeader} DESTINATION include/osrm/extractor)
install(FILES ${ContractorHeader} DESTINATION include/osrm/contractor)
install(FILES ${LibraryGlob} DESTINATION include/osrm)
+2 -1
View File
@@ -29,7 +29,8 @@ int main(int argc, const char *argv[]) try
using namespace osrm;
// Configure based on a .osrm base path, and no datasets in shared mem from osrm-datastore
EngineConfig config{argv[1]};
EngineConfig config;
config.storage_config = {argv[1]};
config.use_shared_memory = false;
// Routing machine with several services (such as Route, Table, Nearest, Trip, Match)
+31 -3
View File
@@ -72,7 +72,7 @@ class RouteAPI : public BaseAPI
}
util::json::Object MakeRoute(const std::vector<PhantomNodes> &segment_end_coordinates,
std::vector<std::vector<PathData>> unpacked_path_segments,
const std::vector<std::vector<PathData>> &unpacked_path_segments,
const std::vector<bool> &source_traversed_in_reverse,
const std::vector<bool> &target_traversed_in_reverse) const
{
@@ -82,7 +82,6 @@ class RouteAPI : public BaseAPI
legs.reserve(number_of_legs);
leg_geometries.reserve(number_of_legs);
unpacked_path_segments = guidance::postProcess(std::move(unpacked_path_segments));
for (auto idx : util::irange(0UL, number_of_legs))
{
const auto &phantoms = segment_end_coordinates[idx];
@@ -98,14 +97,43 @@ class RouteAPI : public BaseAPI
if (parameters.steps)
{
leg.steps = guidance::assembleSteps(
auto steps = guidance::assembleSteps(
BaseAPI::facade, path_data, leg_geometry, phantoms.source_phantom,
phantoms.target_phantom, reversed_source, reversed_target);
/* Perform step-based post-processing.
*
* Using post-processing on basis of route-steps for a single leg at a time
* comes at the cost that we cannot count the correct exit for roundabouts.
* We can only emit the exit nr/intersections up to/starting at a part of the leg.
* If a roundabout is not terminated in a leg, we will end up with a enter-roundabout
* and exit-roundabout-nr where the exit nr is out of sync with the previous enter.
*
* | S |
* * *
* ----* * ----
* T
* ----* * ----
* V * *
* | |
* | |
*
* Coming from S via V to T, we end up with the legs S->V and V->T. V-T will say to take
* the second exit, even though counting from S it would be the third.
* For S, we only emit `roundabout` without an exit number, showing that we enter a roundabout
* to find a via point.
* The same exit will be emitted, though, if we should start routing at S, making
* the overall response consistent.
*/
leg.steps = guidance::postProcess(std::move(steps));
leg_geometry = guidance::resyncGeometry(std::move(leg_geometry),leg.steps);
}
leg_geometries.push_back(std::move(leg_geometry));
legs.push_back(std::move(leg));
}
auto route = guidance::assembleRoute(legs);
boost::optional<util::json::Value> json_overview;
if (parameters.overview != RouteParameters::OverviewType::False)
+4 -5
View File
@@ -60,10 +60,10 @@ struct RouteParameters : public BaseParameters
const bool alternatives_,
const GeometriesType geometries_,
const OverviewType overview_,
std::vector<boost::optional<bool>> uturns_,
const boost::optional<bool> uturns_,
Args... args_)
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
geometries{geometries_}, overview{overview_}, uturns{std::move(uturns_)}
geometries{geometries_}, overview{overview_}, uturns{uturns_}
{
}
@@ -71,12 +71,11 @@ struct RouteParameters : public BaseParameters
bool alternatives = true;
GeometriesType geometries = GeometriesType::Polyline;
OverviewType overview = OverviewType::Simplified;
std::vector<boost::optional<bool>> uturns;
boost::optional<bool> uturns;
bool IsValid() const
{
return coordinates.size() >= 2 && BaseParameters::IsValid() &&
(uturns.empty() || uturns.size() == coordinates.size());
return coordinates.size() >= 2 && BaseParameters::IsValid();
}
};
}
+126
View File
@@ -0,0 +1,126 @@
#ifndef OSRM_BASE64_HPP
#define OSRM_BASE64_HPP
#include <string>
#include <iterator>
#include <type_traits>
#include <cstddef>
#include <climits>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/range/algorithm/copy.hpp>
// RFC 4648 "The Base16, Base32, and Base64 Data Encodings"
// See: https://tools.ietf.org/html/rfc4648
// Implementation adapted from: http://stackoverflow.com/a/28471421
// The C++ standard guarantees none of this by default, but we need it in the following.
static_assert(CHAR_BIT == 8u, "we assume a byte holds 8 bits");
static_assert(sizeof(char) == 1u, "we assume a char is one byte large");
namespace osrm
{
namespace engine
{
// Encoding Implementation
// Encodes a chunk of memory to Base64.
inline std::string encodeBase64(const unsigned char *first, std::size_t size)
{
using namespace boost::archive::iterators;
const std::string bytes{first, first + size};
using Iter = base64_from_binary<transform_width<std::string::const_iterator, 6, 8>>;
Iter view_first{begin(bytes)};
Iter view_last{end(bytes)};
std::string encoded{view_first, view_last};
return encoded.append((3 - size % 3) % 3, '=');
}
// C++11 standard 3.9.1/1: Plain char, signed char, and unsigned char are three distinct types
// Overload for signed char catches (not only but also) C-string literals.
inline std::string encodeBase64(const signed char *first, std::size_t size)
{
return encodeBase64(reinterpret_cast<const unsigned char *>(first), size);
}
// Overload for char catches (not only but also) C-string literals.
inline std::string encodeBase64(const char *first, std::size_t size)
{
return encodeBase64(reinterpret_cast<const unsigned char *>(first), size);
}
// Convenience specialization, encoding from string instead of byte-dumping it.
inline std::string encodeBase64(const std::string &x) { return encodeBase64(x.data(), x.size()); }
// Encode any sufficiently trivial object to Base64.
template <typename T> std::string encodeBase64Bytewise(const T &x)
{
#if not defined __GNUC__ or __GNUC__ > 4
static_assert(std::is_trivially_copyable<T>::value, "requires a trivially copyable type");
#endif
return encodeBase64(reinterpret_cast<const unsigned char *>(&x), sizeof(T));
}
// Decoding Implementation
// Decodes into a chunk of memory that is at least as large as the input.
template <typename OutputIter> void decodeBase64(const std::string &encoded, OutputIter out)
{
using namespace boost::archive::iterators;
using namespace boost::algorithm;
using Iter = transform_width<binary_from_base64<std::string::const_iterator>, 8, 6>;
Iter view_first{begin(encoded)};
Iter view_last{end(encoded)};
const auto null = [](const unsigned char c)
{
return c == '\0';
};
const auto bytes = trim_right_copy_if(std::string{view_first, view_last}, null);
boost::copy(bytes, out);
}
// Convenience specialization, filling string instead of byte-dumping into it.
inline std::string decodeBase64(const std::string &encoded)
{
std::string rv;
decodeBase64(encoded, std::back_inserter(rv));
return rv;
}
// Decodes from Base 64 to any sufficiently trivial object.
template <typename T> T decodeBase64Bytewise(const std::string &encoded)
{
#if not defined __GNUC__ or __GNUC__ > 4
static_assert(std::is_trivially_copyable<T>::value, "requires a trivially copyable type");
#endif
T x;
decodeBase64(encoded, reinterpret_cast<unsigned char *>(&x));
return x;
}
} // ns engine
} // ns osrm
#endif /* OSRM_BASE64_HPP */
@@ -143,6 +143,8 @@ class BaseDataFacade
virtual std::size_t GetCoreSize() const = 0;
virtual std::string GetTimestamp() const = 0;
virtual bool GetUTurnsDefault() const = 0;
};
}
}
@@ -9,6 +9,7 @@
#include "engine/geospatial_query.hpp"
#include "extractor/original_edge_data.hpp"
#include "extractor/profile_properties.hpp"
#include "extractor/query_node.hpp"
#include "contractor/query_edge.hpp"
#include "util/shared_memory_vector_wrapper.hpp"
@@ -79,6 +80,7 @@ class InternalDataFacade final : public BaseDataFacade
util::ShM<unsigned, false>::vector m_segment_weights;
util::ShM<uint8_t, false>::vector m_datasource_list;
util::ShM<std::string, false>::vector m_datasource_names;
extractor::ProfileProperties m_profile_properties;
boost::thread_specific_ptr<InternalRTree> m_static_rtree;
boost::thread_specific_ptr<InternalGeospatialQuery> m_geospatial_query;
@@ -86,26 +88,26 @@ class InternalDataFacade final : public BaseDataFacade
boost::filesystem::path file_index_path;
util::RangeTable<16, false> m_name_table;
void LoadProfileProperties(const boost::filesystem::path &properties_path)
{
boost::filesystem::ifstream in_stream(properties_path);
if (!in_stream)
{
throw util::exception("Could not open " + properties_path.string() + " for reading.");
}
in_stream.read(reinterpret_cast<char*>(&m_profile_properties), sizeof(m_profile_properties));
}
void LoadTimestamp(const boost::filesystem::path &timestamp_path)
{
if (boost::filesystem::exists(timestamp_path))
util::SimpleLogger().Write() << "Loading Timestamp";
boost::filesystem::ifstream timestamp_stream(timestamp_path);
if (!timestamp_stream)
{
util::SimpleLogger().Write() << "Loading Timestamp";
boost::filesystem::ifstream timestamp_stream(timestamp_path);
if (!timestamp_stream)
{
util::SimpleLogger().Write(logWARNING) << timestamp_path << " not found";
}
getline(timestamp_stream, m_timestamp);
}
if (m_timestamp.empty())
{
m_timestamp = "n/a";
}
if (25 < m_timestamp.length())
{
m_timestamp.resize(25);
throw util::exception("Could not open " + timestamp_path.string() + " for reading.");
}
getline(timestamp_stream, m_timestamp);
}
void LoadGraph(const boost::filesystem::path &hsgr_path)
@@ -218,28 +220,33 @@ class InternalDataFacade final : public BaseDataFacade
void LoadDatasourceInfo(const boost::filesystem::path &datasource_names_file,
const boost::filesystem::path &datasource_indexes_file)
{
std::ifstream datasources_stream(datasource_indexes_file.c_str(), std::ios::binary);
if (datasources_stream)
boost::filesystem::ifstream datasources_stream(datasource_indexes_file, std::ios::binary);
if (!datasources_stream)
{
std::size_t number_of_datasources = 0;
datasources_stream.read(reinterpret_cast<char *>(&number_of_datasources),
sizeof(std::size_t));
if (number_of_datasources > 0)
{
m_datasource_list.resize(number_of_datasources);
datasources_stream.read(reinterpret_cast<char *>(&(m_datasource_list[0])),
number_of_datasources * sizeof(uint8_t));
}
throw util::exception("Could not open " + datasource_indexes_file.string() + " for reading!");
}
BOOST_ASSERT(datasources_stream);
std::size_t number_of_datasources = 0;
datasources_stream.read(reinterpret_cast<char *>(&number_of_datasources),
sizeof(std::size_t));
if (number_of_datasources > 0)
{
m_datasource_list.resize(number_of_datasources);
datasources_stream.read(reinterpret_cast<char *>(&(m_datasource_list[0])),
number_of_datasources * sizeof(uint8_t));
}
std::ifstream datasourcenames_stream(datasource_names_file.c_str(), std::ios::binary);
if (datasourcenames_stream)
boost::filesystem::ifstream datasourcenames_stream(datasource_names_file, std::ios::binary);
if (!datasourcenames_stream)
{
std::string name;
while (std::getline(datasourcenames_stream, name))
{
m_datasource_names.push_back(name);
}
throw util::exception("Could not open " + datasource_names_file.string() + " for reading!");
}
BOOST_ASSERT(datasourcenames_stream);
std::string name;
while (std::getline(datasourcenames_stream, name))
{
m_datasource_names.push_back(std::move(name));
}
}
@@ -276,52 +283,35 @@ class InternalDataFacade final : public BaseDataFacade
m_geospatial_query.reset();
}
explicit InternalDataFacade(
const std::unordered_map<std::string, boost::filesystem::path> &server_paths)
explicit InternalDataFacade(const storage::StorageConfig& config)
{
// cache end iterator to quickly check .find against
const auto end_it = end(server_paths);
const auto file_for = [&server_paths, &end_it](const std::string &path)
{
const auto it = server_paths.find(path);
if (it == end_it || !boost::filesystem::is_regular_file(it->second))
throw util::exception("no valid " + path + " file given in ini file");
return it->second;
};
const auto optional_file_for = [&server_paths, &end_it](const std::string &path)
{
const auto it = server_paths.find(path);
if (it == end_it)
throw util::exception("no valid " + path + " file given in ini file");
return it->second;
};
ram_index_path = file_for("ramindex");
file_index_path = file_for("fileindex");
ram_index_path = config.ram_index_path;
file_index_path = config.file_index_path;
util::SimpleLogger().Write() << "loading graph data";
LoadGraph(file_for("hsgrdata"));
LoadGraph(config.hsgr_data_path);
util::SimpleLogger().Write() << "loading edge information";
LoadNodeAndEdgeInformation(file_for("nodesdata"), file_for("edgesdata"));
LoadNodeAndEdgeInformation(config.nodes_data_path, config.edges_data_path);
util::SimpleLogger().Write() << "loading core information";
LoadCoreInformation(file_for("coredata"));
LoadCoreInformation(config.core_data_path);
util::SimpleLogger().Write() << "loading geometries";
LoadGeometries(file_for("geometries"));
LoadGeometries(config.geometries_path);
util::SimpleLogger().Write() << "loading datasource info";
LoadDatasourceInfo(optional_file_for("datasource_names"),
optional_file_for("datasource_indexes"));
LoadDatasourceInfo(config.datasource_names_path,
config.datasource_indexes_path);
util::SimpleLogger().Write() << "loading timestamp";
LoadTimestamp(file_for("timestamp"));
LoadTimestamp(config.timestamp_path);
util::SimpleLogger().Write() << "loading profile properties";
LoadProfileProperties(config.properties_path);
util::SimpleLogger().Write() << "loading street names";
LoadStreetNames(file_for("namesdata"));
LoadStreetNames(config.names_data_path);
}
// search graph access
@@ -652,16 +642,14 @@ class InternalDataFacade final : public BaseDataFacade
virtual std::string GetDatasourceName(const uint8_t datasource_name_id) const override final
{
if (m_datasource_names.empty() || datasource_name_id > m_datasource_names.size())
{
if (datasource_name_id == 0)
return "lua profile";
return "UNKNOWN";
}
BOOST_ASSERT(m_datasource_names.size() >= 1);
BOOST_ASSERT(m_datasource_names.size() > datasource_name_id);
return m_datasource_names[datasource_name_id];
}
std::string GetTimestamp() const override final { return m_timestamp; }
bool GetUTurnsDefault() const override final { return m_profile_properties.allow_u_turn_at_via; }
};
}
}
@@ -8,6 +8,7 @@
#include "storage/shared_memory.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "extractor/profile_properties.hpp"
#include "engine/geospatial_query.hpp"
#include "util/range_table.hpp"
@@ -68,6 +69,7 @@ class SharedDataFacade final : public BaseDataFacade
std::unique_ptr<storage::SharedMemory> m_layout_memory;
std::unique_ptr<storage::SharedMemory> m_large_memory;
std::string m_timestamp;
extractor::ProfileProperties* m_profile_properties;
std::shared_ptr<util::ShM<util::Coordinate, true>::vector> m_coordinate_list;
util::ShM<NodeID, true>::vector m_via_node_list;
@@ -98,6 +100,12 @@ class SharedDataFacade final : public BaseDataFacade
util::SimpleLogger().Write() << "set checksum: " << m_check_sum;
}
void LoadProfileProperties()
{
m_profile_properties =
data_layout->GetBlockPtr<extractor::ProfileProperties>(shared_memory, storage::SharedDataLayout::PROPERTIES);
}
void LoadTimestamp()
{
auto timestamp_ptr =
@@ -343,6 +351,7 @@ class SharedDataFacade final : public BaseDataFacade
LoadViaNodeList();
LoadNames();
LoadCoreInformation();
LoadProfileProperties();
util::SimpleLogger().Write() << "number of geometries: "
<< m_coordinate_list->size();
@@ -684,16 +693,11 @@ class SharedDataFacade final : public BaseDataFacade
virtual std::string GetDatasourceName(const uint8_t datasource_name_id) const override final
{
BOOST_ASSERT(m_datasource_name_offsets.size() >= 1);
BOOST_ASSERT(m_datasource_name_offsets.size() > datasource_name_id);
std::string result;
if (m_datasource_name_offsets.empty() ||
datasource_name_id > m_datasource_name_offsets.size())
{
if (datasource_name_id == 0)
return "lua profile";
return "UNKNOWN";
}
result.reserve(m_datasource_name_lengths[datasource_name_id]);
std::copy(m_datasource_name_data.begin() + m_datasource_name_offsets[datasource_name_id],
m_datasource_name_data.begin() + m_datasource_name_offsets[datasource_name_id] +
m_datasource_name_lengths[datasource_name_id],
@@ -703,6 +707,8 @@ class SharedDataFacade final : public BaseDataFacade
}
std::string GetTimestamp() const override final { return m_timestamp; }
bool GetUTurnsDefault() const override final { return m_profile_properties->allow_u_turn_at_via; }
};
}
}
+4 -18
View File
@@ -28,9 +28,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ENGINE_CONFIG_HPP
#define ENGINE_CONFIG_HPP
#include "storage/storage_config.hpp"
#include <boost/filesystem/path.hpp>
#include <unordered_map>
#include <string>
namespace osrm
@@ -41,24 +42,9 @@ namespace engine
struct EngineConfig
{
EngineConfig() = default;
bool IsValid() const;
EngineConfig(const boost::filesystem::path &base)
: server_paths{{"ramindex", base.string() + ".ramIndex"},
{"fileindex", base.string() + ".fileIndex"},
{"hsgrdata", base.string() + ".hsgr"},
{"nodesdata", base.string() + ".nodes"},
{"edgesdata", base.string() + ".edges"},
{"coredata", base.string() + ".core"},
{"geometries", base.string() + ".geometry"},
{"timestamp", base.string() + ".timestamp"},
{"datasource_names", base.string() + ".datasource_names"},
{"datasource_indexes", base.string() + ".datasource_indexes"},
{"namesdata", base.string() + ".names"}}
{
}
std::unordered_map<std::string, boost::filesystem::path> server_paths;
storage::StorageConfig storage_config;
int max_locations_trip = -1;
int max_locations_viaroute = -1;
int max_locations_distance_table = -1;
@@ -51,7 +51,8 @@ LegGeometry assembleGeometry(const DataFacadeT &facade,
current_distance +=
util::coordinate_calculation::haversineDistance(prev_coordinate, coordinate);
if (!isSilent(path_point.turn_instruction))
// all changes to this check have to be matched with assemble_steps
if (path_point.turn_instruction.type != extractor::guidance::TurnType::NoTurn)
{
geometry.segment_distances.push_back(current_distance);
geometry.segment_offsets.push_back(geometry.locations.size());
+28 -32
View File
@@ -25,10 +25,13 @@ namespace guidance
namespace detail
{
StepManeuver stepManeuverFromGeometry(extractor::guidance::TurnInstruction instruction,
const WaypointType waypoint_type,
const LegGeometry &leg_geometry,
const std::size_t segment_index,
const unsigned exit);
const std::size_t segment_index);
StepManeuver stepManeuverFromGeometry(extractor::guidance::TurnInstruction instruction,
const WaypointType waypoint_type,
const LegGeometry &leg_geometry);
} // ns detail
template <typename DataFacadeT>
@@ -40,7 +43,7 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
const bool source_traversed_in_reverse,
const bool target_traversed_in_reverse)
{
const double constexpr ZERO_DURACTION = 0., ZERO_DISTANCE = 0., NO_BEARING = 0.;
const double constexpr ZERO_DURATION = 0., ZERO_DISTANCE = 0.;
const EdgeWeight source_duration =
source_traversed_in_reverse ? source_node.reverse_weight : source_node.forward_weight;
const auto source_mode = source_traversed_in_reverse ? source_node.backward_travel_mode
@@ -68,8 +71,7 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
distance_to_start >= MINIMAL_RELATIVE_DISTANCE &&
distance_to_start <= MAXIMAL_RELATIVE_DISTANCE
? angleToDirectionModifier(util::coordinate_calculation::computeAngle(
source_node.input_location, leg_geometry.locations[0],
leg_geometry.locations[1]))
source_node.input_location, leg_geometry.locations[0], leg_geometry.locations[1]))
: extractor::guidance::DirectionModifier::UTurn;
if (leg_data.size() > 0)
@@ -78,7 +80,8 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
StepManeuver maneuver = detail::stepManeuverFromGeometry(
extractor::guidance::TurnInstruction{extractor::guidance::TurnType::NoTurn,
initial_modifier},
WaypointType::Depart, leg_geometry, segment_index, INVALID_EXIT_NR);
WaypointType::Depart, leg_geometry);
maneuver.location = source_node.location;
// PathData saves the information we need of the segment _before_ the turn,
// but a RouteStep is with regard to the segment after the turn.
@@ -89,7 +92,8 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
{
segment_duration += path_point.duration_until_turn;
if (path_point.turn_instruction != extractor::guidance::TurnInstruction::NO_TURN())
// all changes to this check have to be matched with assemble_geometry
if (path_point.turn_instruction.type != extractor::guidance::TurnType::NoTurn)
{
BOOST_ASSERT(segment_duration >= 0);
const auto name = facade.GetNameForID(path_point.name_id);
@@ -103,8 +107,7 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1});
maneuver = detail::stepManeuverFromGeometry(path_point.turn_instruction,
WaypointType::None, leg_geometry,
segment_index, path_point.exit);
leg_geometry, segment_index);
segment_index++;
segment_duration = 0;
}
@@ -130,13 +133,10 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
// |---| source_duration
// |---------| target_duration
StepManeuver maneuver = {source_node.location,
NO_BEARING,
NO_BEARING,
extractor::guidance::TurnInstruction{
extractor::guidance::TurnType::NoTurn, initial_modifier},
WaypointType::Depart,
INVALID_EXIT_NR};
StepManeuver maneuver = detail::stepManeuverFromGeometry(
extractor::guidance::TurnInstruction{extractor::guidance::TurnType::NoTurn,
initial_modifier},
WaypointType::Depart, leg_geometry);
int duration = target_duration - source_duration;
BOOST_ASSERT(duration >= 0);
@@ -162,21 +162,17 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
target_node.input_location))
: extractor::guidance::DirectionModifier::UTurn;
// This step has length zero, the only reason we need it is the target location
steps.push_back(
RouteStep{target_node.name_id,
facade.GetNameForID(target_node.name_id),
ZERO_DURACTION,
ZERO_DISTANCE,
target_mode,
StepManeuver{target_node.location,
NO_BEARING,
NO_BEARING,
extractor::guidance::TurnInstruction{
extractor::guidance::TurnType::NoTurn, final_modifier},
WaypointType::Arrive,
INVALID_EXIT_NR},
leg_geometry.locations.size(),
leg_geometry.locations.size()});
auto final_maneuver = detail::stepManeuverFromGeometry(
extractor::guidance::TurnInstruction{extractor::guidance::TurnType::NoTurn, final_modifier},
WaypointType::Arrive, leg_geometry);
steps.push_back(RouteStep{target_node.name_id,
facade.GetNameForID(target_node.name_id),
ZERO_DURATION,
ZERO_DISTANCE,
target_mode,
final_maneuver,
leg_geometry.locations.size(),
leg_geometry.locations.size()});
return steps;
}
+11 -2
View File
@@ -1,7 +1,8 @@
#ifndef ENGINE_GUIDANCE_POST_PROCESSING_HPP
#define ENGINE_GUIDANCE_POST_PROCESSING_HPP
#include "engine/internal_route_result.hpp"
#include "engine/guidance/route_step.hpp"
#include "engine/guidance/leg_geometry.hpp"
#include <vector>
@@ -12,7 +13,15 @@ namespace engine
namespace guidance
{
std::vector<std::vector<PathData>> postProcess(std::vector<std::vector<PathData>> path_data);
// passed as none-reference to modify in-place and move out again
std::vector<RouteStep> postProcess(std::vector<RouteStep> steps);
// postProcess will break the connection between the leg geometry
// for which a segment is supposed to represent exactly the coordinates
// between routing maneuvers and the route steps itself.
// If required, we can get both in sync again using this function.
// Move in LegGeometry for modification in place.
LegGeometry resyncGeometry(LegGeometry leg_geometry, const std::vector<RouteStep> &steps);
} // namespace guidance
} // namespace engine
+10
View File
@@ -5,6 +5,7 @@
#include "extractor/guidance/turn_instruction.hpp"
#include <cstdint>
#include <vector>
namespace osrm
{
@@ -20,6 +21,14 @@ enum class WaypointType : std::uint8_t
Depart,
};
//A represenetation of intermediate intersections
struct IntermediateIntersection
{
double duration;
double distance;
util::Coordinate location;
};
struct StepManeuver
{
util::Coordinate location;
@@ -28,6 +37,7 @@ struct StepManeuver
extractor::guidance::TurnInstruction instruction;
WaypointType waypoint_type;
unsigned exit;
std::vector<IntermediateIntersection> intersections;
};
} // namespace guidance
} // namespace engine
+15 -7
View File
@@ -34,36 +34,44 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include <cstdint>
#include <iosfwd>
namespace osrm
{
namespace engine
{
// Fwd. decls.
namespace datafacade
{
struct BaseDataFacade;
}
// Is returned as a temporary identifier for snapped coodinates
struct Hint
{
PhantomNode phantom;
std::uint32_t data_checksum;
template <typename DataFacadeT>
bool IsValid(const util::Coordinate new_input_coordinates, DataFacadeT &facade) const
{
return phantom.IsValid(facade.GetNumberOfNodes(), new_input_coordinates) &&
facade.GetCheckSum() == data_checksum;
}
bool IsValid(const util::Coordinate new_input_coordinates,
const datafacade::BaseDataFacade &facade) const;
std::string ToBase64() const;
static Hint FromBase64(const std::string &base64Hint);
friend bool operator==(const Hint &, const Hint &);
friend std::ostream &operator<<(std::ostream &, const Hint &);
};
#ifndef _MSC_VER
static_assert(sizeof(Hint) == 60 + 4, "Hint is bigger than expected");
constexpr std::size_t ENCODED_HINT_SIZE = 88;
static_assert(ENCODED_HINT_SIZE / 4 * 3 >= sizeof(Hint),
"ENCODED_HINT_SIZE does not match size of Hint");
#else
// PhantomNode is bigger under windows because MSVC does not support bit packing
constexpr std::size_t ENCODED_HINT_SIZE = 84;
static_assert(sizeof(Hint) == 64 + 4, "Hint is bigger than expected");
constexpr std::size_t ENCODED_HINT_SIZE = 92;
static_assert(ENCODED_HINT_SIZE / 4 * 3 >= sizeof(Hint),
"ENCODED_HINT_SIZE does not match size of Hint");
#endif
-2
View File
@@ -29,8 +29,6 @@ struct PathData
extractor::guidance::TurnInstruction turn_instruction;
// travel mode of the street that leads to the turn
extractor::TravelMode travel_mode : 4;
// exit ID of highway exit, roundabout exit, intersection nr
unsigned exit;
};
struct InternalRouteResult
-91
View File
@@ -1,91 +0,0 @@
#ifndef OBJECT_ENCODER_HPP
#define OBJECT_ENCODER_HPP
#include <boost/assert.hpp>
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <algorithm>
#include <iterator>
#include <string>
#include <vector>
#include <cstdint>
#include <climits>
namespace osrm
{
namespace engine
{
namespace detail
{
static_assert(CHAR_BIT == 8u, "we assume a byte holds 8 bits");
static_assert(sizeof(char) == 1u, "we assume a char is one byte large");
using Base64FromBinary = boost::archive::iterators::base64_from_binary<
boost::archive::iterators::transform_width<const char *, // sequence of chars
6, // get view of 6 bit
8 // from sequence of 8 bit
>>;
using BinaryFromBase64 = boost::archive::iterators::transform_width<
boost::archive::iterators::binary_from_base64<std::string::const_iterator>,
8, // get a view of 8 bit
6 // from a sequence of 6 bit
>;
} // ns detail
template <typename T> std::string encodeBase64(const T &x)
{
#if not defined __GNUC__ or __GNUC__ > 4
static_assert(std::is_trivially_copyable<T>::value, "requires a trivially copyable type");
#endif
std::vector<unsigned char> bytes{reinterpret_cast<const char *>(&x),
reinterpret_cast<const char *>(&x) + sizeof(T)};
BOOST_ASSERT(!bytes.empty());
std::size_t bytes_to_pad{0};
while (bytes.size() % 3 != 0)
{
bytes_to_pad += 1;
bytes.push_back(0);
}
BOOST_ASSERT(bytes_to_pad == 0 || bytes_to_pad == 1 || bytes_to_pad == 2);
BOOST_ASSERT_MSG(0 == bytes.size() % 3, "base64 input data size is not a multiple of 3");
std::string encoded{detail::Base64FromBinary{bytes.data()},
detail::Base64FromBinary{bytes.data() + (bytes.size() - bytes_to_pad)}};
std::replace(begin(encoded), end(encoded), '+', '-');
std::replace(begin(encoded), end(encoded), '/', '_');
return encoded;
}
template <typename T> T decodeBase64(std::string encoded)
{
#if not defined __GNUC__ or __GNUC__ > 4
static_assert(std::is_trivially_copyable<T>::value, "requires a trivially copyable type");
#endif
std::replace(begin(encoded), end(encoded), '-', '+');
std::replace(begin(encoded), end(encoded), '_', '/');
T rv;
std::copy(detail::BinaryFromBase64{begin(encoded)},
detail::BinaryFromBase64{begin(encoded) + encoded.length()},
reinterpret_cast<char *>(&rv));
return rv;
}
} // ns engine
} // ns osrm
#endif /* OBJECT_ENCODER_HPP */
+2
View File
@@ -187,6 +187,8 @@ struct PhantomNode
#ifndef _MSC_VER
static_assert(sizeof(PhantomNode) == 60, "PhantomNode has more padding then expected");
#else
static_assert(sizeof(PhantomNode) == 64, "PhantomNode has more padding then expected");
#endif
using PhantomNodePair = std::pair<PhantomNode, PhantomNode>;
-1
View File
@@ -5,7 +5,6 @@
#include "engine/plugins/plugin_base.hpp"
#include "engine/api/route_api.hpp"
#include "engine/object_encoder.hpp"
#include "engine/search_engine_data.hpp"
#include "engine/routing_algorithms/shortest_path.hpp"
#include "engine/routing_algorithms/alternative_path.hpp"
@@ -321,8 +321,7 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
{
unpacked_path.push_back(
PathData{id_vector[i], name_index, weight_vector[i],
extractor::guidance::TurnInstruction::NO_TURN(), travel_mode,
INVALID_EXIT_NR});
extractor::guidance::TurnInstruction::NO_TURN(), travel_mode});
}
BOOST_ASSERT(unpacked_path.size() > 0);
unpacked_path.back().turn_instruction = turn_instruction;
@@ -396,8 +395,7 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
id_vector[i], phantom_node_pair.target_phantom.name_id, weight_vector[i],
extractor::guidance::TurnInstruction::NO_TURN(),
target_traversed_in_reverse ? phantom_node_pair.target_phantom.backward_travel_mode
: phantom_node_pair.target_phantom.forward_travel_mode,
INVALID_EXIT_NR});
: phantom_node_pair.target_phantom.forward_travel_mode});
}
if (is_local_path && unpacked_path.size() > 0)
@@ -237,14 +237,10 @@ class ShortestPathRouting final
}
}
static const constexpr bool UTURN_DEFAULT = false;
void operator()(const std::vector<PhantomNodes> &phantom_nodes_vector,
const std::vector<boost::optional<bool>> &uturn_indicators,
const boost::optional<bool> uturns,
InternalRouteResult &raw_route_data) const
{
BOOST_ASSERT(uturn_indicators.empty() ||
uturn_indicators.size() == phantom_nodes_vector.size() + 1);
engine_working_data.InitializeOrClearFirstThreadLocalStorage(
super::facade->GetNumberOfNodes());
engine_working_data.InitializeOrClearSecondThreadLocalStorage(
@@ -270,7 +266,7 @@ class ShortestPathRouting final
std::vector<NodeID> total_packed_path_to_reverse;
std::vector<std::size_t> packed_leg_to_reverse_begin;
const bool use_uturn_indicators = !uturn_indicators.empty();
const bool allow_u_turn_at_via = uturns ? *uturns : super::facade->GetUTurnsDefault();
std::size_t current_leg = 0;
// this implements a dynamic program that finds the shortest route through
@@ -286,12 +282,6 @@ class ShortestPathRouting final
const auto &source_phantom = phantom_node_pair.source_phantom;
const auto &target_phantom = phantom_node_pair.target_phantom;
const bool use_uturn_default =
!use_uturn_indicators || !uturn_indicators[current_leg + 1];
const bool allow_u_turn_at_via =
(use_uturn_default && UTURN_DEFAULT) ||
(!use_uturn_default && *uturn_indicators[current_leg + 1]);
bool search_to_forward_node = target_phantom.forward_node_id != SPECIAL_NODEID;
bool search_to_reverse_node = target_phantom.reverse_node_id != SPECIAL_NODEID;
@@ -4,7 +4,7 @@
#define EDGE_BASED_GRAPH_FACTORY_HPP_
#include "extractor/edge_based_edge.hpp"
#include "extractor/speed_profile.hpp"
#include "extractor/profile_properties.hpp"
#include "extractor/restriction_map.hpp"
#include "extractor/compressed_edge_container.hpp"
#include "extractor/edge_based_node.hpp"
@@ -52,7 +52,7 @@ class EdgeBasedGraphFactory
const std::unordered_set<NodeID> &traffic_lights,
std::shared_ptr<const RestrictionMap> restriction_map,
const std::vector<QueryNode> &node_info_list,
SpeedProfileProperties speed_profile,
ProfileProperties profile_properties,
const util::NameTable &name_table);
void Run(const std::string &original_edge_data_filename,
@@ -106,7 +106,7 @@ class EdgeBasedGraphFactory
const std::unordered_set<NodeID> &m_traffic_lights;
const CompressedEdgeContainer &m_compressed_edge_container;
SpeedProfileProperties speed_profile;
ProfileProperties profile_properties;
const util::NameTable &name_table;
+6 -2
View File
@@ -40,6 +40,8 @@ namespace osrm
namespace extractor
{
struct ProfileProperties;
class Extractor
{
public:
@@ -49,13 +51,15 @@ class Extractor
private:
ExtractorConfig config;
void SetupScriptingEnvironment(lua_State *myLuaState, SpeedProfileProperties &speed_profile);
std::pair<std::size_t, std::size_t>
BuildEdgeExpandedGraph(std::vector<QueryNode> &internal_to_external_node_map,
BuildEdgeExpandedGraph(lua_State* lua_state,
const ProfileProperties& profile_properties,
std::vector<QueryNode> &internal_to_external_node_map,
std::vector<EdgeBasedNode> &node_based_edge_list,
std::vector<bool> &node_is_startpoint,
std::vector<EdgeWeight> &edge_based_node_weights,
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list);
void WriteProfileProperties(const std::string& output_path, const ProfileProperties& properties) const;
void WriteNodeMapping(const std::vector<QueryNode> &internal_to_external_node_map);
void FindComponents(unsigned max_edge_id,
const util::DeallocatingVector<EdgeBasedEdge> &edges,
+2
View File
@@ -71,6 +71,7 @@ struct ExtractorConfig
edge_segment_lookup_path = basepath + ".osrm.edge_segment_lookup";
edge_penalty_path = basepath + ".osrm.edge_penalties";
edge_based_node_weights_output_path = basepath + ".osrm.enw";
profile_properties_output_path = basepath + ".osrm.properties";
}
boost::filesystem::path config_file_path;
@@ -88,6 +89,7 @@ struct ExtractorConfig
std::string node_output_path;
std::string rtree_nodes_output_path;
std::string rtree_leafs_output_path;
std::string profile_properties_output_path;
unsigned requested_num_threads;
unsigned small_component_size;
-5
View File
@@ -3,7 +3,6 @@
#include "util/typedefs.hpp"
#include "extractor/speed_profile.hpp"
#include "util/node_based_graph.hpp"
#include <memory>
@@ -22,8 +21,6 @@ class GraphCompressor
using EdgeData = util::NodeBasedDynamicGraph::EdgeData;
public:
GraphCompressor(SpeedProfileProperties speed_profile);
void Compress(const std::unordered_set<NodeID> &barrier_nodes,
const std::unordered_set<NodeID> &traffic_lights,
RestrictionMap &restriction_map,
@@ -34,8 +31,6 @@ class GraphCompressor
void PrintStatistics(unsigned original_number_of_nodes,
unsigned original_number_of_edges,
const util::NodeBasedDynamicGraph &graph) const;
SpeedProfileProperties speed_profile;
};
}
}
+48
View File
@@ -0,0 +1,48 @@
#ifndef PROFILE_PROPERTIES_HPP
#define PROFILE_PROPERTIES_HPP
#include <boost/numeric/conversion/cast.hpp>
namespace osrm
{
namespace extractor
{
struct ProfileProperties
{
ProfileProperties()
: traffic_signal_penalty(0), u_turn_penalty(0), allow_u_turn_at_via(false), use_turn_restrictions(false)
{
}
double GetUturnPenalty() const
{
return u_turn_penalty / 10.;
}
void SetUturnPenalty(const double u_turn_penalty_)
{
u_turn_penalty = boost::numeric_cast<int>(u_turn_penalty_ * 10.);
}
double GetTrafficSignalPenalty() const
{
return traffic_signal_penalty / 10.;
}
void SetTrafficSignalPenalty(const double traffic_signal_penalty_)
{
traffic_signal_penalty = boost::numeric_cast<int>(traffic_signal_penalty_ * 10.);
}
//! penalty to cross a traffic light in deci-seconds
int traffic_signal_penalty;
//! penalty to do a uturn in deci-seconds
int u_turn_penalty;
bool allow_u_turn_at_via;
bool use_turn_restrictions;
};
}
}
#endif
+3 -2
View File
@@ -19,6 +19,8 @@ namespace osrm
namespace extractor
{
class ProfileProperties;
/**
* Parses the relations that represents turn restrictions.
*
@@ -40,11 +42,10 @@ namespace extractor
class RestrictionParser
{
public:
RestrictionParser(lua_State *lua_state);
RestrictionParser(lua_State *lua_state, const ProfileProperties& properties);
boost::optional<InputRestrictionContainer> TryParse(const osmium::Relation &relation) const;
private:
void ReadUseRestrictionsSetting(lua_State *lua_state);
void ReadRestrictionExceptions(lua_State *lua_state);
bool ShouldIgnoreRestriction(const std::string &except_tag_string) const;
+15 -3
View File
@@ -1,6 +1,11 @@
#ifndef SCRIPTING_ENVIRONMENT_HPP
#define SCRIPTING_ENVIRONMENT_HPP
#include "extractor/profile_properties.hpp"
#include "extractor/raster_source.hpp"
#include "util/lua_util.hpp"
#include <string>
#include <memory>
#include <mutex>
@@ -23,18 +28,25 @@ namespace extractor
class ScriptingEnvironment
{
public:
struct Context
{
ProfileProperties properties;
SourceContainer sources;
util::LuaState state;
};
explicit ScriptingEnvironment(const std::string &file_name);
ScriptingEnvironment(const ScriptingEnvironment &) = delete;
ScriptingEnvironment &operator=(const ScriptingEnvironment &) = delete;
lua_State *GetLuaState();
Context &GetContex();
private:
void InitLuaState(lua_State *lua_state);
void InitContext(Context &context);
std::mutex init_mutex;
std::string file_name;
tbb::enumerable_thread_specific<std::shared_ptr<lua_State>> script_contexts;
tbb::enumerable_thread_specific<std::unique_ptr<Context>> script_contexts;
};
}
}
-23
View File
@@ -1,23 +0,0 @@
#ifndef SPEED_PROFILE_PROPERTIES_HPP
#define SPEED_PROFILE_PROPERTIES_HPP
namespace osrm
{
namespace extractor
{
struct SpeedProfileProperties
{
SpeedProfileProperties()
: traffic_signal_penalty(0), u_turn_penalty(0), has_turn_penalty_function(false)
{
}
int traffic_signal_penalty;
int u_turn_penalty;
bool has_turn_penalty_function;
};
}
}
#endif
+38
View File
@@ -0,0 +1,38 @@
/*
Copyright (c) 2016, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GLOBAL_STORAGE_CONFIG_HPP
#define GLOBAL_STORAGE_CONFIG_HPP
#include "storage/storage_config.hpp"
namespace osrm
{
using storage::StorageConfig;
}
#endif
@@ -27,7 +27,7 @@ struct RouteParametersGrammar : public BaseParametersGrammar
using AlternativeT = bool;
using GeometriesT = engine::api::RouteParameters::GeometriesType;
using OverviewT = engine::api::RouteParameters::OverviewType;
using UturnsT = std::vector<boost::optional<bool>>;
using UturnsT = bool;
RouteParametersGrammar() : BaseParametersGrammar(root_rule, parameters)
{
@@ -72,9 +72,9 @@ struct RouteParametersGrammar : public BaseParametersGrammar
overview_rule = qi::lit("overview=simplified")[set_simplified_type] |
qi::lit("overview=full")[set_full_type] |
qi::lit("overview=false")[set_false_type];
uturns_rule = qi::lit("uturns=") >> -qi::bool_ % ";";
uturns_rule = qi::lit("uturns=default") | (qi::lit("uturns=") >> qi::bool_)[set_uturns];
route_rule = steps_rule[set_steps] | alternatives_rule[set_alternatives] | geometries_rule |
overview_rule | uturns_rule[set_uturns];
overview_rule | uturns_rule;
root_rule =
query_rule >> -qi::lit(".json") >> -(qi::lit("?") >> (route_rule | base_rule) % '&');
+1
View File
@@ -41,6 +41,7 @@ struct SharedDataLayout
DATASOURCE_NAME_DATA,
DATASOURCE_NAME_OFFSETS,
DATASOURCE_NAME_LENGTHS,
PROPERTIES,
NUM_BLOCKS
};
+4 -4
View File
@@ -1,24 +1,24 @@
#ifndef STORAGE_HPP
#define STORAGE_HPP
#include "storage/storage_config.hpp"
#include <boost/filesystem/path.hpp>
#include <unordered_map>
#include <string>
namespace osrm
{
namespace storage
{
using DataPaths = std::unordered_map<std::string, boost::filesystem::path>;
class Storage
{
public:
Storage(const DataPaths &data_paths);
Storage(StorageConfig config);
int Run();
private:
DataPaths paths;
StorageConfig config;
};
}
}
+32
View File
@@ -0,0 +1,32 @@
#ifndef STORAGE_CONFIG_HPP
#define STORAGE_CONFIG_HPP
#include <boost/filesystem/path.hpp>
namespace osrm
{
namespace storage
{
struct StorageConfig
{
StorageConfig() = default;
StorageConfig(const boost::filesystem::path &base);
bool IsValid() const;
boost::filesystem::path ram_index_path;
boost::filesystem::path file_index_path;
boost::filesystem::path hsgr_data_path;
boost::filesystem::path nodes_data_path;
boost::filesystem::path edges_data_path;
boost::filesystem::path core_data_path;
boost::filesystem::path geometries_path;
boost::filesystem::path timestamp_path;
boost::filesystem::path datasource_names_path;
boost::filesystem::path datasource_indexes_path;
boost::filesystem::path names_data_path;
boost::filesystem::path properties_path;
};
}
}
#endif
+11 -2
View File
@@ -18,10 +18,19 @@ namespace osrm
namespace util
{
template <typename T> void LUA_print(T output) { std::cout << "[LUA] " << output << std::endl; }
struct LuaState
{
LuaState() : handle{::luaL_newstate(), &::lua_close} { luaL_openlibs(*this); }
operator lua_State *() { return handle.get(); }
operator lua_State const *() const { return handle.get(); }
using handle_type = std::unique_ptr<lua_State, decltype(&::lua_close)>;
handle_type handle;
};
// Check if the lua function <name> is defined
inline bool lua_function_exists(lua_State *lua_state, const char *name)
inline bool luaFunctionExists(lua_State *lua_state, const char *name)
{
luabind::object globals_table = luabind::globals(lua_state);
luabind::object lua_function = globals_table[name];
-251
View File
@@ -1,251 +0,0 @@
#ifndef ROUTED_OPTIONS_HPP
#define ROUTED_OPTIONS_HPP
#include "util/version.hpp"
#include "util/exception.hpp"
#include "util/simple_logger.hpp"
#include <boost/any.hpp>
#include <boost/program_options.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/convenience.hpp>
#include <unordered_map>
#include <fstream>
#include <string>
namespace osrm
{
namespace util
{
const static unsigned INIT_OK_START_ENGINE = 0;
const static unsigned INIT_OK_DO_NOT_START_ENGINE = 1;
const static unsigned INIT_FAILED = -1;
inline void
populate_base_path(std::unordered_map<std::string, boost::filesystem::path> &server_paths)
{
// populate the server_path object
auto path_iterator = server_paths.find("base");
// if a base path has been set, we populate it.
if (path_iterator != server_paths.end())
{
const std::string base_string = path_iterator->second.string();
SimpleLogger().Write() << "populating base path: " << base_string;
server_paths["hsgrdata"] = base_string + ".hsgr";
BOOST_ASSERT(server_paths.find("hsgrdata") != server_paths.end());
server_paths["nodesdata"] = base_string + ".nodes";
BOOST_ASSERT(server_paths.find("nodesdata") != server_paths.end());
server_paths["coredata"] = base_string + ".core";
BOOST_ASSERT(server_paths.find("coredata") != server_paths.end());
server_paths["edgesdata"] = base_string + ".edges";
BOOST_ASSERT(server_paths.find("edgesdata") != server_paths.end());
server_paths["geometries"] = base_string + ".geometry";
BOOST_ASSERT(server_paths.find("geometries") != server_paths.end());
server_paths["ramindex"] = base_string + ".ramIndex";
BOOST_ASSERT(server_paths.find("ramindex") != server_paths.end());
server_paths["fileindex"] = base_string + ".fileIndex";
BOOST_ASSERT(server_paths.find("fileindex") != server_paths.end());
server_paths["namesdata"] = base_string + ".names";
BOOST_ASSERT(server_paths.find("namesdata") != server_paths.end());
server_paths["timestamp"] = base_string + ".timestamp";
BOOST_ASSERT(server_paths.find("timestamp") != server_paths.end());
server_paths["datasource_indexes"] = base_string + ".datasource_indexes";
BOOST_ASSERT(server_paths.find("timestamp") != server_paths.end());
server_paths["datasource_names"] = base_string + ".datasource_names";
BOOST_ASSERT(server_paths.find("timestamp") != server_paths.end());
}
// check if files are give and whether they exist at all
path_iterator = server_paths.find("hsgrdata");
if (path_iterator == server_paths.end() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw exception(".hsgr not found");
}
path_iterator = server_paths.find("nodesdata");
if (path_iterator == server_paths.end() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw exception(".nodes not found");
}
path_iterator = server_paths.find("edgesdata");
if (path_iterator == server_paths.end() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw exception(".edges not found");
}
path_iterator = server_paths.find("geometries");
if (path_iterator == server_paths.end() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw exception(".geometry not found");
}
path_iterator = server_paths.find("ramindex");
if (path_iterator == server_paths.end() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw exception(".ramIndex not found");
}
path_iterator = server_paths.find("fileindex");
if (path_iterator == server_paths.end() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw exception(".fileIndex not found");
}
path_iterator = server_paths.find("namesdata");
if (path_iterator == server_paths.end() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw exception(".namesIndex not found");
}
SimpleLogger().Write() << "HSGR file:\t" << server_paths["hsgrdata"];
SimpleLogger().Write(logDEBUG) << "Nodes file:\t" << server_paths["nodesdata"];
SimpleLogger().Write(logDEBUG) << "Edges file:\t" << server_paths["edgesdata"];
SimpleLogger().Write(logDEBUG) << "Geometry file:\t" << server_paths["geometries"];
SimpleLogger().Write(logDEBUG) << "RAM file:\t" << server_paths["ramindex"];
SimpleLogger().Write(logDEBUG) << "Index file:\t" << server_paths["fileindex"];
SimpleLogger().Write(logDEBUG) << "Names file:\t" << server_paths["namesdata"];
SimpleLogger().Write(logDEBUG) << "Timestamp file:\t" << server_paths["timestamp"];
}
// generate boost::program_options object for the routing part
inline unsigned
GenerateServerProgramOptions(const int argc,
const char *argv[],
std::unordered_map<std::string, boost::filesystem::path> &paths,
std::string &ip_address,
int &ip_port,
int &requested_num_threads,
bool &use_shared_memory,
bool &trial,
int &max_locations_trip,
int &max_locations_viaroute,
int &max_locations_distance_table,
int &max_locations_map_matching)
{
using boost::program_options::value;
using boost::filesystem::path;
// 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", value<boost::filesystem::path>(&paths["config"])->default_value("server.ini"),
"Path to a configuration file") //
("trial", value<bool>(&trial)->implicit_value(true), "Quit after initialization");
// declare a group of options that will be allowed on command line
boost::program_options::options_description config_options("Configuration");
config_options.add_options() //
("hsgrdata", value<boost::filesystem::path>(&paths["hsgrdata"]), ".hsgr file") //
("nodesdata", value<boost::filesystem::path>(&paths["nodesdata"]), ".nodes file") //
("edgesdata", value<boost::filesystem::path>(&paths["edgesdata"]), ".edges file") //
("geometry", value<boost::filesystem::path>(&paths["geometries"]), ".geometry file") //
("ramindex", value<boost::filesystem::path>(&paths["ramindex"]), ".ramIndex file") //
("fileindex", value<boost::filesystem::path>(&paths["fileindex"]),
"File index file") //
("namesdata", value<boost::filesystem::path>(&paths["namesdata"]),
".names file") //
("timestamp", value<boost::filesystem::path>(&paths["timestamp"]),
".timestamp file") //
("ip,i", value<std::string>(&ip_address)->default_value("0.0.0.0"),
"IP address") //
("port,p", value<int>(&ip_port)->default_value(5000),
"TCP/IP port") //
("threads,t", value<int>(&requested_num_threads)->default_value(8),
"Number of threads to use") //
("shared-memory,s",
value<bool>(&use_shared_memory)->implicit_value(true)->default_value(false),
"Load data from shared memory") //
("max-viaroute-size", value<int>(&max_locations_viaroute)->default_value(500),
"Max. locations supported in viaroute query") //
("max-trip-size", value<int>(&max_locations_trip)->default_value(100),
"Max. locations supported in trip query") //
("max-table-size", value<int>(&max_locations_distance_table)->default_value(100),
"Max. locations supported in distance table query") //
("max-matching-size", value<int>(&max_locations_map_matching)->default_value(100),
"Max. locations supported in map matching query");
// hidden options, will be allowed on command line, but will not be shown to the user
boost::program_options::options_description hidden_options("Hidden options");
hidden_options.add_options()("base,b", value<boost::filesystem::path>(&paths["base"]),
"base path to .osrm file");
// positional option
boost::program_options::positional_options_description positional_options;
positional_options.add("base", 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 visible_options(
boost::filesystem::basename(argv[0]) + " <base.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);
if (option_variables.count("version"))
{
SimpleLogger().Write() << OSRM_VERSION;
return INIT_OK_DO_NOT_START_ENGINE;
}
if (option_variables.count("help"))
{
SimpleLogger().Write() << visible_options;
return INIT_OK_DO_NOT_START_ENGINE;
}
boost::program_options::notify(option_variables);
if (1 > requested_num_threads)
{
throw exception("Number of threads must be a positive number");
}
if (2 > max_locations_distance_table)
{
throw exception("Max location for distance table must be at least two");
}
if (max_locations_map_matching > 0 && 2 > max_locations_map_matching)
{
throw exception("Max location for map matching must be at least two");
}
if (!use_shared_memory && option_variables.count("base"))
{
return INIT_OK_START_ENGINE;
}
else if (use_shared_memory && !option_variables.count("base"))
{
return INIT_OK_START_ENGINE;
}
else if (use_shared_memory && option_variables.count("base"))
{
SimpleLogger().Write(logWARNING) << "Shared memory settings conflict with path settings.";
}
SimpleLogger().Write() << visible_options;
return INIT_OK_DO_NOT_START_ENGINE;
}
}
}
#endif // ROUTED_OPTIONS_HPP
+4 -3
View File
@@ -91,9 +91,10 @@ surface_speeds = {
}
-- these need to be global because they are accesed externaly
traffic_signal_penalty = 2
use_turn_restrictions = false
u_turn_penalty = 20
properties.traffic_signal_penalty = 2
properties.use_turn_restrictions = false
properties.u_turn_penalty = 20
properties.allow_u_turn_at_via = true
local obey_oneway = true
local ignore_areas = true
+9 -9
View File
@@ -128,20 +128,20 @@ maxspeed_table = {
["uk:motorway"] = (70*1609)/1000
}
-- these need to be global because they are accesed externaly
u_turn_penalty = 20
traffic_signal_penalty = 2
use_turn_restrictions = true
-- set profile properties
properties.u_turn_penalty = 20
properties.traffic_signal_penalty = 2
properties.use_turn_restrictions = true
side_road_speed_multiplier = 0.8
local side_road_speed_multiplier = 0.8
local turn_penalty = 10
local turn_penalty = 10
-- Note: this biases right-side driving. Should be
-- inverted for left-driving countries.
local turn_bias = 1.2
local turn_bias = 1.2
local obey_oneway = true
local ignore_areas = true
local obey_oneway = true
local ignore_areas = true
local abs = math.abs
local min = math.min
+5 -3
View File
@@ -64,9 +64,11 @@ leisure_speeds = {
["track"] = walking_speed
}
traffic_signal_penalty = 2
u_turn_penalty = 2
use_turn_restrictions = false
properties.traffic_signal_penalty = 2
properties.u_turn_penalty = 2
properties.use_turn_restrictions = false
properties.allow_u_turn_at_via = true
local fallback_names = true
function get_exceptions(vector)
+4 -4
View File
@@ -32,15 +32,15 @@ end
function segment_function (source, target, distance, weight)
local sourceData = sources:interpolate(raster_source, source.lon, source.lat)
local targetData = sources:interpolate(raster_source, target.lon, target.lat)
print ("evaluating segment: " .. sourceData.datum .. " " .. targetData.datum)
io.write("evaluating segment: " .. sourceData.datum .. " " .. targetData.datum .. "\n")
local invalid = sourceData.invalid_data()
if sourceData.datum ~= invalid and targetData.datum ~= invalid then
local slope = math.abs(sourceData.datum - targetData.datum) / distance
print (" slope: " .. slope)
print (" was speed: " .. weight.speed)
io.write(" slope: " .. slope .. "\n")
io.write(" was speed: " .. weight.speed .. "\n")
weight.speed = weight.speed * (1 - (slope * 5))
print (" new speed: " .. weight.speed)
io.write(" new speed: " .. weight.speed .. "\n")
end
end
+4 -4
View File
@@ -32,15 +32,15 @@ end
function segment_function (source, target, distance, weight)
local sourceData = sources:query(raster_source, source.lon, source.lat)
local targetData = sources:query(raster_source, target.lon, target.lat)
print ("evaluating segment: " .. sourceData.datum .. " " .. targetData.datum)
io.write("evaluating segment: " .. sourceData.datum .. " " .. targetData.datum .. "\n")
local invalid = sourceData.invalid_data()
if sourceData.datum ~= invalid and targetData.datum ~= invalid then
local slope = math.abs(sourceData.datum - targetData.datum) / distance
print (" slope: " .. slope)
print (" was speed: " .. weight.speed)
io.write(" slope: " .. slope .. "\n")
io.write(" was speed: " .. weight.speed .. "\n")
weight.speed = weight.speed * (1 - (slope * 5))
print (" new speed: " .. weight.speed)
io.write(" new speed: " .. weight.speed .. "\n")
end
end
+4 -7
View File
@@ -16,13 +16,10 @@ speed_profile = {
-- these settings are read directly by osrm
take_minimum_of_speeds = true
obey_oneway = true
obey_barriers = true
use_turn_restrictions = true
ignore_areas = true -- future feature
traffic_signal_penalty = 7 -- seconds
u_turn_penalty = 20
properties.allow_u_turn_at_via = false
properties.use_turn_restrictions = true
properties.traffic_signal_penalty = 7 -- seconds
properties.u_turn_penalty = 20
function limit_speed(speed, limits)
-- don't use ipairs(), since it stops at the first nil value
+28 -21
View File
@@ -173,6 +173,10 @@ std::size_t Contractor::LoadEdgeExpandedGraph(
std::unordered_map<std::pair<OSMNodeID, OSMNodeID>, std::pair<unsigned, uint8_t>>
segment_speed_lookup;
// If we update the edge weights, this file will hold the datasource information
// for each segment
std::vector<uint8_t> m_geometry_datasource;
if (update_edge_weights)
{
uint8_t file_id = 1;
@@ -264,7 +268,7 @@ std::size_t Contractor::LoadEdgeExpandedGraph(
// CSV file that supplied the value that gets used for that segment, then
// we write out this list so that it can be returned by the debugging
// vector tiles later on.
std::vector<uint8_t> m_geometry_datasource(m_geometry_list.size(), 0);
m_geometry_datasource.resize(m_geometry_list.size(), 0);
// Now, we iterate over all the segments stored in the StaticRTree, updating
// the packed geometry weights in the `.geometries` file (note: we do not
@@ -402,33 +406,36 @@ std::size_t Contractor::LoadEdgeExpandedGraph(
number_of_compressed_geometries *
sizeof(extractor::CompressedEdgeContainer::CompressedEdge));
}
}
{
std::ofstream datasource_stream(datasource_indexes_filename, std::ios::binary);
if (!datasource_stream)
{
throw util::exception("Failed to open " + datasource_indexes_filename +
" for writing");
}
auto number_of_datasource_entries = m_geometry_datasource.size();
datasource_stream.write(reinterpret_cast<const char *>(&number_of_datasource_entries),
sizeof(number_of_datasource_entries));
if (number_of_datasource_entries > 0)
{
std::ofstream datasource_stream(datasource_indexes_filename, std::ios::binary);
if (!datasource_stream)
{
throw util::exception("Failed to open " + datasource_indexes_filename +
" for writing");
}
auto number_of_datasource_entries = m_geometry_datasource.size();
datasource_stream.write(reinterpret_cast<const char *>(&number_of_datasource_entries),
sizeof(number_of_datasource_entries));
datasource_stream.write(reinterpret_cast<char *>(&(m_geometry_datasource[0])),
number_of_datasource_entries * sizeof(uint8_t));
}
}
{
std::ofstream datasource_stream(datasource_names_filename, std::ios::binary);
if (!datasource_stream)
{
std::ofstream datasource_stream(datasource_names_filename, std::ios::binary);
if (!datasource_stream)
{
throw util::exception("Failed to open " + datasource_names_filename +
" for writing");
}
datasource_stream << "lua profile" << std::endl;
for (auto const &name : segment_speed_filenames)
{
datasource_stream << name << std::endl;
}
throw util::exception("Failed to open " + datasource_names_filename +
" for writing");
}
datasource_stream << "lua profile" << std::endl;
for (auto const &name : segment_speed_filenames)
{
datasource_stream << name << std::endl;
}
}
+6
View File
@@ -149,6 +149,12 @@ util::json::Object makeStepManeuver(const guidance::StepManeuver &maneuver)
step_maneuver.values["bearing_after"] = maneuver.bearing_after;
if (maneuver.exit != 0)
step_maneuver.values["exit"] = maneuver.exit;
// TODO currently we need this to comply with the api.
// We should move this to an additional entry, the moment we
// actually compute the correct locations of the intersections
if (!maneuver.intersections.empty() && maneuver.exit == 0)
step_maneuver.values["exit"] = maneuver.intersections.size();
return step_maneuver;
}
+5 -3
View File
@@ -18,7 +18,6 @@
#include "storage/shared_barriers.hpp"
#include "util/make_unique.hpp"
#include "util/routed_options.hpp"
#include "util/simple_logger.hpp"
#include <boost/assert.hpp>
@@ -136,8 +135,11 @@ Engine::Engine(EngineConfig &config)
}
else
{
util::populate_base_path(config.server_paths);
query_data_facade = util::make_unique<datafacade::InternalDataFacade>(config.server_paths);
if (!config.storage_config.IsValid())
{
throw util::exception("Invalid file paths given!");
}
query_data_facade = util::make_unique<datafacade::InternalDataFacade>(config.storage_config);
}
// Register plugins
+27
View File
@@ -0,0 +1,27 @@
#include "engine/engine_config.hpp"
namespace osrm
{
namespace engine
{
bool EngineConfig::IsValid() const
{
const bool all_path_are_empty =
storage_config.ram_index_path.empty() && storage_config.file_index_path.empty() &&
storage_config.hsgr_data_path.empty() && storage_config.nodes_data_path.empty() &&
storage_config.edges_data_path.empty() && storage_config.core_data_path.empty() &&
storage_config.geometries_path.empty() && storage_config.timestamp_path.empty() &&
storage_config.datasource_names_path.empty() &&
storage_config.datasource_indexes_path.empty() && storage_config.names_data_path.empty();
const bool limits_valid =
(max_locations_distance_table == -1 || max_locations_distance_table > 2) &&
(max_locations_map_matching == -1 || max_locations_map_matching > 2) &&
(max_locations_trip == -1 || max_locations_trip > 2) &&
(max_locations_viaroute == -1 || max_locations_viaroute > 2);
return ((use_shared_memory && all_path_are_empty) || storage_config.IsValid()) && limits_valid;
}
}
}
+46 -4
View File
@@ -12,15 +12,49 @@ namespace guidance
{
namespace detail
{
StepManeuver stepManeuverFromGeometry(extractor::guidance::TurnInstruction instruction,
const WaypointType waypoint_type,
const LegGeometry &leg_geometry)
{
BOOST_ASSERT(waypoint_type != WaypointType::None);
BOOST_ASSERT(leg_geometry.locations.size() >= 2);
double pre_turn_bearing = 0, post_turn_bearing = 0;
Coordinate turn_coordinate;
if (waypoint_type == WaypointType::Arrive)
{
turn_coordinate = leg_geometry.locations.front();
const auto post_turn_coordinate = *(leg_geometry.locations.begin() + 1);
post_turn_bearing =
util::coordinate_calculation::bearing(turn_coordinate, post_turn_coordinate);
}
else
{
BOOST_ASSERT(waypoint_type == WaypointType::Depart);
turn_coordinate = leg_geometry.locations.back();
const auto pre_turn_coordinate = *(leg_geometry.locations.end() - 2);
pre_turn_bearing =
util::coordinate_calculation::bearing(pre_turn_coordinate, turn_coordinate);
}
return StepManeuver{
std::move(turn_coordinate),
pre_turn_bearing,
post_turn_bearing,
std::move(instruction),
waypoint_type,
INVALID_EXIT_NR,
{} // no intermediate intersections
};
}
StepManeuver stepManeuverFromGeometry(extractor::guidance::TurnInstruction instruction,
const LegGeometry &leg_geometry,
const std::size_t segment_index,
const unsigned exit)
const std::size_t segment_index)
{
auto turn_index = leg_geometry.BackIndex(segment_index);
BOOST_ASSERT(turn_index > 0);
BOOST_ASSERT(turn_index < leg_geometry.locations.size());
BOOST_ASSERT(turn_index + 1 < leg_geometry.locations.size());
// TODO chose a bigger look-a-head to smooth complex geometry
const auto pre_turn_coordinate = leg_geometry.locations[turn_index - 1];
@@ -32,7 +66,15 @@ StepManeuver stepManeuverFromGeometry(extractor::guidance::TurnInstruction instr
const double post_turn_bearing =
util::coordinate_calculation::bearing(turn_coordinate, post_turn_coordinate);
return StepManeuver{turn_coordinate, pre_turn_bearing, post_turn_bearing, instruction, waypoint_type, exit};
return StepManeuver{
std::move(turn_coordinate),
pre_turn_bearing,
post_turn_bearing,
std::move(instruction),
WaypointType::None,
INVALID_EXIT_NR,
{} // no intermediate intersections
};
}
} // ns detail
} // ns engine
+258 -153
View File
@@ -4,8 +4,11 @@
#include "engine/guidance/toolkit.hpp"
#include <boost/assert.hpp>
#include <boost/range/algorithm_ext/erase.hpp>
#include <iostream>
#include <vector>
#include <cstddef>
#include <utility>
using TurnInstruction = osrm::extractor::guidance::TurnInstruction;
using TurnType = osrm::extractor::guidance::TurnType;
@@ -20,194 +23,296 @@ namespace guidance
namespace detail
{
bool canMergeTrivially(const PathData &destination, const PathData &source)
bool canMergeTrivially(const RouteStep &destination, const RouteStep &source)
{
return destination.exit == 0 && destination.name_id == source.name_id &&
destination.travel_mode == source.travel_mode && isSilent(source.turn_instruction);
return destination.maneuver.exit == 0 && destination.name_id == source.name_id &&
isSilent(source.maneuver.instruction);
}
PathData forwardInto(PathData destination, const PathData &source)
RouteStep forwardInto(RouteStep destination, const RouteStep &source)
{
// Merge a turn into a silent turn
// Overwrites turn instruction and increases exit NR
destination.exit = source.exit;
destination.duration += source.duration;
destination.distance += source.distance;
destination.geometry_begin = std::min(destination.geometry_begin, source.geometry_begin);
destination.geometry_end = std::max(destination.geometry_end, source.geometry_end);
return destination;
}
PathData accumulateInto(PathData destination, const PathData &source)
void fixFinalRoundabout(std::vector<RouteStep> &steps)
{
// Merge a turn into a silent turn
// Overwrites turn instruction and increases exit NR
BOOST_ASSERT(canMergeTrivially(destination, source));
destination.exit = source.exit + 1;
return destination;
}
PathData mergeInto(PathData destination, const PathData &source)
{
if (source.turn_instruction == TurnInstruction::NO_TURN())
for (std::size_t propagation_index = steps.size() - 1; propagation_index > 0;
--propagation_index)
{
BOOST_ASSERT(canMergeTrivially(destination, source));
return detail::forwardInto(destination, source);
}
if (source.turn_instruction.type == TurnType::Suppressed)
{
return detail::forwardInto(destination, source);
}
if (source.turn_instruction.type == TurnType::StayOnRoundabout)
{
return detail::forwardInto(destination, source);
}
if (entersRoundabout(source.turn_instruction))
{
return detail::forwardInto(destination, source);
}
return destination;
}
} // namespace detail
void print(const std::vector<std::vector<PathData>> &leg_data)
{
std::cout << "Path\n";
int legnr = 0;
for (const auto &leg : leg_data)
{
std::cout << "\tLeg: " << ++legnr << "\n";
int segment = 0;
for (const auto &data : leg)
auto &propagation_step = steps[propagation_index];
if (entersRoundabout(propagation_step.maneuver.instruction))
{
const auto type = static_cast<int>(data.turn_instruction.type);
const auto modifier = static_cast<int>(data.turn_instruction.direction_modifier);
std::cout << "\t\t[" << ++segment << "]: " << type << " " << modifier
<< " exit: " << data.exit << "\n";
propagation_step.maneuver.exit = 0;
propagation_step.geometry_end = steps.back().geometry_begin;
break;
}
else if (propagation_step.maneuver.instruction.type == TurnType::StayOnRoundabout)
{
// TODO this operates on the data that is in the instructions.
// We are missing out on the final segment after the last stay-on-roundabout
// instruction though. it is not contained somewhere until now
steps[propagation_index - 1] =
forwardInto(std::move(steps[propagation_index - 1]), propagation_step);
propagation_step.maneuver.instruction =
TurnInstruction::NO_TURN(); // mark intermediate instructions invalid
}
}
std::cout << std::endl;
}
std::vector<std::vector<PathData>> postProcess(std::vector<std::vector<PathData>> leg_data)
bool setUpRoundabout(RouteStep &step)
{
if (leg_data.empty())
return leg_data;
// basic entry into a roundabout
// Special case handling, if an entry is directly tied to an exit
const auto instruction = step.maneuver.instruction;
if (instruction.type == TurnType::EnterRotaryAtExit ||
instruction.type == TurnType::EnterRoundaboutAtExit)
{
step.maneuver.exit = 1;
// prevent futher special case handling of these two.
if (instruction.type == TurnType::EnterRotaryAtExit)
step.maneuver.instruction = TurnType::EnterRotary;
else
step.maneuver.instruction = TurnType::EnterRoundabout;
}
#define PRINT_DEBUG 0
unsigned carry_exit = 0;
#if PRINT_DEBUG
if (leavesRoundabout(instruction))
{
step.maneuver.exit = 1; // count the otherwise missing exit
if (instruction.type == TurnType::EnterRotaryAtExit)
step.maneuver.instruction = TurnType::EnterRotary;
else
step.maneuver.instruction = TurnType::EnterRoundabout;
return false;
}
else
{
return true;
}
}
void closeOffRoundabout(const bool on_roundabout,
std::vector<RouteStep> &steps,
const std::size_t step_index)
{
auto &step = steps[step_index];
step.maneuver.exit += 1;
if (!on_roundabout)
{
// We reached a special case that requires the addition of a special route step in
// the beginning.
// We started in a roundabout, so to announce the exit, we move use the exit
// instruction and
// move it right to the beginning to make sure to immediately announce the exit.
BOOST_ASSERT(leavesRoundabout(steps[1].maneuver.instruction) ||
steps[1].maneuver.instruction.type == TurnType::StayOnRoundabout);
steps[0].geometry_end = 1;
steps[1] = detail::forwardInto(steps[1], steps[0]);
steps[0].duration = 0;
steps[0].distance = 0;
steps[1].maneuver.instruction.type = step.maneuver.instruction.type == TurnType::ExitRotary
? TurnType::EnterRotary
: TurnType::EnterRoundabout;
}
// Normal exit from the roundabout, or exit from a previously fixed roundabout.
// Propagate the index back to the entering
// location and
// prepare the current silent set of instructions for removal.
if (step_index > 1)
{
// The very first route-step is head, so we cannot iterate past that one
for (std::size_t propagation_index = step_index - 1; propagation_index > 0;
--propagation_index)
{
auto &propagation_step = steps[propagation_index];
propagation_step = detail::forwardInto(propagation_step, steps[propagation_index + 1]);
if (entersRoundabout(propagation_step.maneuver.instruction))
{
// TODO at this point, we can remember the additional name for a rotary
// This requires some initial thought on the data format, though
propagation_step.maneuver.exit = step.maneuver.exit;
propagation_step.geometry_end = step.geometry_end;
propagation_step.name = step.name;
propagation_step.name_id = step.name_id;
break;
}
else
{
BOOST_ASSERT(propagation_step.maneuver.instruction.type =
TurnType::StayOnRoundabout);
propagation_step.maneuver.instruction =
TurnInstruction::NO_TURN(); // mark intermediate instructions invalid
}
}
// remove exit
step.maneuver.instruction = TurnInstruction::NO_TURN();
}
}
} // namespace detail
void print(const std::vector<RouteStep> &steps)
{
std::cout << "Path\n";
int segment = 0;
for (const auto &step : steps)
{
const auto type = static_cast<int>(step.maneuver.instruction.type);
const auto modifier = static_cast<int>(step.maneuver.instruction.direction_modifier);
std::cout << "\t[" << ++segment << "]: " << type << " " << modifier
<< " Duration: " << step.duration << " Distance: " << step.distance
<< " Geometry: " << step.geometry_begin << " " << step.geometry_end
<< " exit: " << step.maneuver.exit
<< " Intersections: " << step.maneuver.intersections.size() << " [";
for (auto intersection : step.maneuver.intersections)
std::cout << "(" << intersection.duration << " " << intersection.distance << ")";
std::cout << "] name[" << step.name_id << "]: " << step.name << std::endl;
}
}
// Every Step Maneuver consists of the information until the turn.
// This list contains a set of instructions, called silent, which should
// not be part of the final output.
// They are required for maintenance purposes. We can calculate the number
// of exits to pass in a roundabout and the number of intersections
// that we come across.
std::vector<RouteStep> postProcess(std::vector<RouteStep> steps)
{
// the steps should always include the first/last step in form of a location
BOOST_ASSERT(steps.size() >= 2);
if (steps.size() == 2)
return steps;
#define OSRM_POST_PROCESSING_PRINT_DEBUG 0
#if OSRM_POST_PROCESSING_PRINT_DEBUG
std::cout << "[POSTPROCESSING ITERATION]" << std::endl;
std::cout << "Input\n";
print(leg_data);
print(steps);
#endif
// Count Street Exits forward
bool on_roundabout = false;
for (auto &path_data : leg_data)
// adds an intersection to the initial route step
// It includes the length of the last step, until the intersection
// Also updates the length of the respective segment
auto addIntersection =
[](RouteStep into, const RouteStep &last_step, const RouteStep &intersection)
{
if (not path_data.empty())
path_data[0].exit = carry_exit;
into.maneuver.intersections.push_back(
{last_step.duration, last_step.distance, intersection.maneuver.location});
for (std::size_t data_index = 0; data_index + 1 < path_data.size(); ++data_index)
return detail::forwardInto(std::move(into), intersection);
};
// count the exits forward. if enter/exit roundabout happen both, no further treatment is
// required. We might end up with only one of them (e.g. starting within a roundabout)
// or having a via-point in the roundabout.
// In this case, exits are numbered from the start of the lag.
std::size_t last_valid_instruction = 0;
for (std::size_t step_index = 0; step_index < steps.size(); ++step_index)
{
auto &step = steps[step_index];
const auto instruction = step.maneuver.instruction;
if (entersRoundabout(instruction))
{
if (entersRoundabout(path_data[data_index].turn_instruction))
last_valid_instruction = step_index;
on_roundabout = detail::setUpRoundabout(step);
if (on_roundabout && step_index + 1 < steps.size())
steps[step_index + 1].maneuver.exit = step.maneuver.exit;
}
else if (instruction.type == TurnType::StayOnRoundabout)
{
// increase the exit number we require passing the exit
step.maneuver.exit += 1;
if (step_index + 1 < steps.size())
steps[step_index + 1].maneuver.exit = step.maneuver.exit;
}
else if (leavesRoundabout(instruction))
{
if (!on_roundabout)
{
path_data[data_index].exit += 1;
on_roundabout = true;
// in case the we are not on a roundabout, the very first instruction
// after the depart will be transformed into a roundabout and become
// the first valid instruction
last_valid_instruction = 1;
}
if (isSilent(path_data[data_index].turn_instruction) &&
path_data[data_index].turn_instruction != TurnInstruction::NO_TURN())
{
path_data[data_index].exit += 1;
}
if (leavesRoundabout(path_data[data_index].turn_instruction))
{
if (!on_roundabout)
{
BOOST_ASSERT(leg_data[0][0].turn_instruction.type ==
TurnInstruction::NO_TURN());
if (path_data[data_index].turn_instruction.type == TurnType::ExitRoundabout)
leg_data[0][0].turn_instruction.type = TurnType::EnterRoundabout;
if (path_data[data_index].turn_instruction.type == TurnType::ExitRotary)
leg_data[0][0].turn_instruction.type = TurnType::EnterRotary;
path_data[data_index].exit += 1;
}
on_roundabout = false;
}
if (path_data[data_index].turn_instruction.type == TurnType::EnterRoundaboutAtExit)
{
path_data[data_index].exit += 1;
path_data[data_index].turn_instruction.type = TurnType::EnterRoundabout;
}
else if (path_data[data_index].turn_instruction.type == TurnType::EnterRotaryAtExit)
{
path_data[data_index].exit += 1;
path_data[data_index].turn_instruction.type = TurnType::EnterRotary;
}
if (isSilent(path_data[data_index].turn_instruction) ||
entersRoundabout(path_data[data_index].turn_instruction))
{
path_data[data_index + 1] =
detail::mergeInto(path_data[data_index + 1], path_data[data_index]);
}
carry_exit = path_data[data_index].exit;
detail::closeOffRoundabout(on_roundabout, steps, step_index);
on_roundabout = false;
}
else if (instruction.type == TurnType::Suppressed)
{
// count intersections. We cannot use exit, since intersections can follow directly
// after a roundabout
steps[last_valid_instruction] = addIntersection(
std::move(steps[last_valid_instruction]), steps[step_index - 1], step);
step.maneuver.instruction = TurnInstruction::NO_TURN();
}
else if (!isSilent(instruction))
{
// Remember the last non silent instruction
last_valid_instruction = step_index;
}
}
#if PRINT_DEBUG
// unterminated roundabout
// Move backwards through the instructions until the start and remove the exit number
// A roundabout without exit translates to enter-roundabout.
if (on_roundabout)
{
detail::fixFinalRoundabout(steps);
}
// finally clean up the post-processed instructions.
// Remove all invalid instructions from the set of instructions.
// An instruction is invalid, if its NO_TURN and has WaypointType::None.
// Two valid NO_TURNs exist in each leg in the form of Depart/Arrive
// keep valid instructions
const auto not_is_valid = [](const RouteStep &step)
{
return step.maneuver.instruction == TurnInstruction::NO_TURN() &&
step.maneuver.waypoint_type == WaypointType::None;
};
boost::remove_erase_if(steps, not_is_valid);
#if OSRM_POST_PROCESSING_PRINT_DEBUG
std::cout << "Merged\n";
print(leg_data);
print(steps);
#endif
on_roundabout = false;
// Move Roundabout exit numbers to front
for (auto rev_itr = leg_data.rbegin(); rev_itr != leg_data.rend(); ++rev_itr)
return steps;
}
LegGeometry resyncGeometry(LegGeometry leg_geometry, const std::vector<RouteStep> &steps)
{
// The geometry uses an adjacency array-like structure for representation.
// To sync it back up with the steps, we cann add a segment for every step.
leg_geometry.segment_offsets.clear();
leg_geometry.segment_distances.clear();
leg_geometry.segment_offsets.push_back(0);
for (const auto &step : steps)
{
auto &path_data = *rev_itr;
for (std::size_t data_index = path_data.size(); data_index > 1; --data_index)
{
if (entersRoundabout(path_data[data_index - 1].turn_instruction))
{
if (!on_roundabout && !leavesRoundabout(path_data[data_index - 1].turn_instruction))
path_data[data_index - 1].exit = 0;
on_roundabout = false;
}
if (on_roundabout)
{
path_data[data_index - 2].exit = path_data[data_index - 1].exit;
}
if (leavesRoundabout(path_data[data_index - 1].turn_instruction) &&
!entersRoundabout(path_data[data_index - 1].turn_instruction))
{
path_data[data_index - 2].exit = path_data[data_index - 1].exit;
on_roundabout = true;
}
}
auto prev_leg = std::next(rev_itr);
if (!path_data.empty() && prev_leg != leg_data.rend())
{
if (on_roundabout && path_data[0].exit)
prev_leg->back().exit = path_data[0].exit;
}
leg_geometry.segment_distances.push_back(step.distance);
// the leg geometry does not follow the begin/end-convetion. So we have to subtract one
// to get the back-index.
leg_geometry.segment_offsets.push_back(step.geometry_end - 1);
}
#if PRINT_DEBUG
std::cout << "Move To Front\n";
print(leg_data);
#endif
// silence silent turns for good
for (auto &path_data : leg_data)
{
for (auto &data : path_data)
{
if (isSilent(data.turn_instruction) || (leavesRoundabout(data.turn_instruction) &&
!entersRoundabout(data.turn_instruction)))
{
data.turn_instruction = TurnInstruction::NO_TURN();
data.exit = 0;
}
}
}
//remove the data fromt the reached-target step again
leg_geometry.segment_offsets.pop_back();
leg_geometry.segment_distances.pop_back();
return leg_data;
return leg_geometry;
}
} // namespace guidance
+45 -5
View File
@@ -1,20 +1,60 @@
#include "engine/hint.hpp"
#include "engine/object_encoder.hpp"
#include "engine/base64.hpp"
#include "engine/datafacade/datafacade_base.hpp"
#include <boost/assert.hpp>
#include <iterator>
#include <algorithm>
#include <ostream>
#include <tuple>
namespace osrm
{
namespace engine
{
std::string Hint::ToBase64() const { return encodeBase64(*this); }
bool Hint::IsValid(const util::Coordinate new_input_coordinates,
const datafacade::BaseDataFacade &facade) const
{
auto is_same_input_coordinate = new_input_coordinates.lon == phantom.input_location.lon &&
new_input_coordinates.lat == phantom.input_location.lat;
return is_same_input_coordinate && phantom.IsValid(facade.GetNumberOfNodes()) &&
facade.GetCheckSum() == data_checksum;
}
std::string Hint::ToBase64() const
{
auto base64 = encodeBase64Bytewise(*this);
// Make safe for usage as GET parameter in URLs
std::replace(begin(base64), end(base64), '+', '-');
std::replace(begin(base64), end(base64), '/', '_');
return base64;
}
Hint Hint::FromBase64(const std::string &base64Hint)
{
BOOST_ASSERT_MSG(base64Hint.size() == ENCODED_HINT_SIZE, "Hint has invalid size");
auto decoded = decodeBase64<Hint>(base64Hint);
return decoded;
}
// We need mutability but don't want to change the API
auto encoded = base64Hint;
// Reverses above encoding we need for GET parameters in URL
std::replace(begin(encoded), end(encoded), '-', '+');
std::replace(begin(encoded), end(encoded), '_', '/');
return decodeBase64Bytewise<Hint>(encoded);
}
bool operator==(const Hint &lhs, const Hint &rhs)
{
return std::tie(lhs.phantom, lhs.data_checksum) ==
std::tie(rhs.phantom, rhs.data_checksum);
}
std::ostream &operator<<(std::ostream &out, const Hint &hint) { return out << hint.ToBase64(); }
} // ns engine
} // ns osrm
-1
View File
@@ -4,7 +4,6 @@
#include "engine/map_matching/bayes_classifier.hpp"
#include "engine/api/match_parameters.hpp"
#include "engine/api/match_api.hpp"
#include "engine/object_encoder.hpp"
#include "util/coordinate_calculation.hpp"
#include "util/integer_range.hpp"
#include "util/json_logger.hpp"
-1
View File
@@ -2,7 +2,6 @@
#include "engine/api/table_parameters.hpp"
#include "engine/api/table_api.hpp"
#include "engine/object_encoder.hpp"
#include "engine/routing_algorithms/many_to_many.hpp"
#include "engine/search_engine_data.hpp"
#include "util/string_util.hpp"
+50 -6
View File
@@ -3,6 +3,11 @@
#include "util/coordinate_calculation.hpp"
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/multi/geometries/multi_linestring.hpp>
#include <protozero/varint.hpp>
#include <protozero/pbf_writer.hpp>
@@ -23,6 +28,7 @@ namespace detail
{
// Vector tiles are 4096 virtual pixels on each side
const constexpr double VECTOR_TILE_EXTENT = 4096.0;
const constexpr double VECTOR_TILE_BUFFER = 128.0;
// Simple container class for WSG84 coordinates
template <typename T> struct Point final
@@ -67,6 +73,14 @@ struct point_type_i final
using FixedLine = std::vector<detail::Point<std::int32_t>>;
using FloatLine = std::vector<detail::Point<double>>;
typedef boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> point_t;
typedef boost::geometry::model::linestring<point_t> linestring_t;
typedef boost::geometry::model::box<point_t> box_t;
typedef boost::geometry::model::multi_linestring<linestring_t> multi_linestring_t;
const static box_t clip_box(point_t(-detail::VECTOR_TILE_BUFFER, -detail::VECTOR_TILE_BUFFER),
point_t(detail::VECTOR_TILE_EXTENT + detail::VECTOR_TILE_BUFFER,
detail::VECTOR_TILE_EXTENT + detail::VECTOR_TILE_BUFFER));
// from mapnik-vector-tile
// Encodes a linestring using protobuf zigzag encoding
inline bool encodeLinestring(const FixedLine &line,
@@ -111,7 +125,9 @@ FixedLine coordinatesToTileLine(const util::Coordinate start,
static_cast<double>(util::toFloating(start.lat)));
geo_line.emplace_back(static_cast<double>(util::toFloating(target.lon)),
static_cast<double>(util::toFloating(target.lat)));
FixedLine tile_line;
linestring_t unclipped_line;
for (auto const &pt : geo_line)
{
double px_merc = pt.x * mercator::DEGREE_TO_PX;
@@ -123,8 +139,29 @@ FixedLine coordinatesToTileLine(const util::Coordinate start,
const auto py = std::round(
((tile_bbox.maxy - py_merc) * mercator::TILE_SIZE / tile_bbox.height()) *
detail::VECTOR_TILE_EXTENT / util::coordinate_calculation::mercator::TILE_SIZE);
tile_line.emplace_back(px, py);
boost::geometry::append(unclipped_line, point_t(px, py));
}
multi_linestring_t clipped_line;
boost::geometry::intersection(clip_box, unclipped_line, clipped_line);
FixedLine tile_line;
// b::g::intersection might return a line with one point if the
// original line was very short and coords were dupes
if (!clipped_line.empty() && clipped_line[0].size() == 2)
{
if (clipped_line[0].size() == 2)
{
for (const auto &p : clipped_line[0])
{
tile_line.emplace_back(p.get<0>(), p.get<1>());
}
}
}
return tile_line;
}
}
@@ -317,6 +354,7 @@ Status TilePlugin::HandleRequest(const api::TileParameters &parameters, std::str
duration); // duration value offset
}
{
// Encode the geometry for the feature
protozero::packed_field_uint32 geometry(feature_writer, 4);
encodeLinestring(tile_line, geometry, start_x, start_y);
@@ -334,8 +372,11 @@ Status TilePlugin::HandleRequest(const api::TileParameters &parameters, std::str
static_cast<std::uint32_t>(round(length / forward_weight * 10 * 3.6));
auto tile_line = coordinatesToTileLine(a, b, tile_bbox);
encode_tile_line(tile_line, speed_kmh, weight_offsets[forward_weight],
forward_datasource, start_x, start_y);
if (!tile_line.empty())
{
encode_tile_line(tile_line, speed_kmh, weight_offsets[forward_weight],
forward_datasource, start_x, start_y);
}
}
// Repeat the above for the coordinates reversed and using the `reverse`
@@ -350,8 +391,11 @@ Status TilePlugin::HandleRequest(const api::TileParameters &parameters, std::str
static_cast<std::uint32_t>(round(length / reverse_weight * 10 * 3.6));
auto tile_line = coordinatesToTileLine(b, a, tile_bbox);
encode_tile_line(tile_line, speed_kmh, weight_offsets[reverse_weight],
reverse_datasource, start_x, start_y);
if (!tile_line.empty())
{
encode_tile_line(tile_line, speed_kmh, weight_offsets[reverse_weight],
reverse_datasource, start_x, start_y);
}
}
}
}
+1 -13
View File
@@ -135,19 +135,7 @@ InternalRouteResult TripPlugin::ComputeRoute(const std::vector<PhantomNode> &sna
}
BOOST_ASSERT(min_route.segment_end_coordinates.size() == trip.size());
std::vector<boost::optional<bool>> uturns;
if (parameters.uturns.size() > 0)
{
uturns.resize(trip.size() + 1);
std::transform(trip.begin(), trip.end(), uturns.begin(), [&parameters](const NodeID idx)
{
return parameters.uturns[idx];
});
BOOST_ASSERT(uturns.size() > 0);
uturns.back() = parameters.uturns[trip.front()];
}
shortest_path(min_route.segment_end_coordinates, uturns, min_route);
shortest_path(min_route.segment_end_coordinates, parameters.uturns, min_route);
BOOST_ASSERT_MSG(min_route.shortest_path_length < INVALID_EDGE_WEIGHT, "unroutable route");
return min_route;
-1
View File
@@ -1,7 +1,6 @@
#include "engine/plugins/viaroute.hpp"
#include "engine/datafacade/datafacade_base.hpp"
#include "engine/api/route_api.hpp"
#include "engine/object_encoder.hpp"
#include "engine/status.hpp"
#include "util/for_each_pair.hpp"
+29 -22
View File
@@ -12,6 +12,7 @@
#include "extractor/guidance/toolkit.hpp"
#include <boost/assert.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <algorithm>
#include <cmath>
@@ -34,13 +35,13 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
const std::unordered_set<NodeID> &traffic_lights,
std::shared_ptr<const RestrictionMap> restriction_map,
const std::vector<QueryNode> &node_info_list,
SpeedProfileProperties speed_profile,
ProfileProperties profile_properties,
const util::NameTable &name_table)
: m_max_edge_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)), m_barrier_nodes(barrier_nodes),
m_traffic_lights(traffic_lights), m_compressed_edge_container(compressed_edge_container),
speed_profile(std::move(speed_profile)), name_table(name_table)
profile_properties(std::move(profile_properties)), name_table(name_table)
{
}
@@ -207,7 +208,7 @@ unsigned EdgeBasedGraphFactory::RenumberEdges()
// oneway streets always require this self-loop. Other streets only if a u-turn plus
// traversal
// of the street takes longer than the loop
m_edge_based_node_weights.push_back(edge_data.distance + speed_profile.u_turn_penalty);
m_edge_based_node_weights.push_back(edge_data.distance + profile_properties.u_turn_penalty);
BOOST_ASSERT(numbered_edges_count < m_node_based_graph->GetNumberOfEdges());
edge_data.edge_id = numbered_edges_count;
@@ -276,6 +277,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
{
util::SimpleLogger().Write() << "generating edge-expanded edges";
BOOST_ASSERT(lua_state != nullptr);
const bool use_turn_function = util::luaFunctionExists(lua_state, "turn_function");
std::size_t node_based_edge_counter = 0;
std::size_t original_edges_counter = 0;
restricted_turns_counter = 0;
@@ -292,8 +296,10 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
edge_penalty_file.open(edge_fixed_penalties_filename.c_str(), std::ios::binary);
}
// writes a dummy value that is updated later
edge_data_file.write((char *)&original_edges_counter, sizeof(unsigned));
// Writes a dummy value at the front that is updated later with the total length
const unsigned length_prefix_empty_space{0};
edge_data_file.write(reinterpret_cast<const char *>(&length_prefix_empty_space),
sizeof(length_prefix_empty_space));
std::vector<OriginalEdgeData> original_edge_data_vector;
original_edge_data_vector.reserve(1024 * 1024);
@@ -335,15 +341,15 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
unsigned distance = edge_data1.distance;
if (m_traffic_lights.find(node_v) != m_traffic_lights.end())
{
distance += speed_profile.traffic_signal_penalty;
distance += profile_properties.traffic_signal_penalty;
}
const int turn_penalty = GetTurnPenalty(turn_angle, lua_state);
const int turn_penalty = use_turn_function ? GetTurnPenalty(turn_angle, lua_state) : 0;
const auto turn_instruction = turn.instruction;
if (guidance::isUturn(turn_instruction))
{
distance += speed_profile.u_turn_penalty;
distance += profile_properties.u_turn_penalty;
}
distance += turn_penalty;
@@ -419,8 +425,13 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
FlushVectorToStream(edge_data_file, original_edge_data_vector);
// Finally jump back to the empty space at the beginning and write length prefix
edge_data_file.seekp(std::ios::beg);
edge_data_file.write((char *)&original_edges_counter, sizeof(unsigned));
const auto length_prefix = boost::numeric_cast<unsigned>(original_edges_counter);
static_assert(sizeof(length_prefix_empty_space) == sizeof(length_prefix), "type mismatch");
edge_data_file.write(reinterpret_cast<const char *>(&length_prefix), sizeof(length_prefix));
util::SimpleLogger().Write() << "Generated " << m_edge_based_node_list.size()
<< " edge based nodes";
@@ -438,20 +449,16 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
int EdgeBasedGraphFactory::GetTurnPenalty(double angle, lua_State *lua_state) const
{
if (speed_profile.has_turn_penalty_function)
BOOST_ASSERT(lua_state != nullptr);
try
{
try
{
// call lua profile to compute turn penalty
double penalty =
luabind::call_function<double>(lua_state, "turn_function", 180. - angle);
return static_cast<int>(penalty);
}
catch (const luabind::error &er)
{
util::SimpleLogger().Write(logWARNING) << er.what();
}
// call lua profile to compute turn penalty
double penalty = luabind::call_function<double>(lua_state, "turn_function", 180. - angle);
return boost::numeric_cast<int>(penalty);
}
catch (const luabind::error &er)
{
util::SimpleLogger().Write(logWARNING) << er.what();
}
return 0;
}
+3 -1
View File
@@ -288,6 +288,8 @@ void ExtractionContainers::PrepareEdges(lua_State *segment_state)
const auto all_edges_list_end_ = all_edges_list.end();
const auto all_nodes_list_end_ = all_nodes_list.end();
const auto has_segment_function = util::luaFunctionExists(segment_state, "segment_function");
while (edge_iterator != all_edges_list_end_ && node_iterator != all_nodes_list_end_)
{
// skip all invalid edges
@@ -323,7 +325,7 @@ void ExtractionContainers::PrepareEdges(lua_State *segment_state)
edge_iterator->source_coordinate,
util::Coordinate(node_iterator->lon, node_iterator->lat));
if (util::lua_function_exists(segment_state, "segment_function"))
if (has_segment_function)
{
luabind::call_function<void>(
segment_state, "segment_function", boost::cref(edge_iterator->source_coordinate),
+32 -66
View File
@@ -48,6 +48,7 @@
#include <unordered_map>
#include <vector>
#include <bitset>
#include <chrono>
namespace osrm
{
@@ -75,6 +76,9 @@ namespace extractor
*/
int Extractor::run()
{
// setup scripting environment
ScriptingEnvironment scripting_environment(config.profile_path.string().c_str());
try
{
util::LogPolicy::GetInstance().Unmute();
@@ -89,9 +93,6 @@ int Extractor::run()
util::SimpleLogger().Write() << "Profile: " << config.profile_path.filename().string();
util::SimpleLogger().Write() << "Threads: " << number_of_threads;
// setup scripting environment
ScriptingEnvironment scripting_environment(config.profile_path.string().c_str());
ExtractionContainers extraction_containers;
auto extractor_callbacks = util::make_unique<ExtractorCallbacks>(extraction_containers);
@@ -107,15 +108,12 @@ int Extractor::run()
util::SimpleLogger().Write() << "Parsing in progress..";
TIMER_START(parsing);
lua_State *segment_state = scripting_environment.GetLuaState();
auto& main_context = scripting_environment.GetContex();
if (util::lua_function_exists(segment_state, "source_function"))
// setup raster sources
if (util::luaFunctionExists(main_context.state, "source_function"))
{
// bind a single instance of SourceContainer class to relevant lua state
SourceContainer sources;
luabind::globals(segment_state)["sources"] = sources;
luabind::call_function<void>(segment_state, "source_function");
luabind::call_function<void>(main_context.state, "source_function");
}
std::string generator = header.get("generator");
@@ -142,7 +140,7 @@ int Extractor::run()
tbb::concurrent_vector<boost::optional<InputRestrictionContainer>> resulting_restrictions;
// setup restriction parser
const RestrictionParser restriction_parser(scripting_environment.GetLuaState());
const RestrictionParser restriction_parser(main_context.state, main_context.properties);
while (const osmium::memory::Buffer buffer = reader.read())
{
@@ -165,7 +163,7 @@ int Extractor::run()
{
ExtractionNode result_node;
ExtractionWay result_way;
lua_State *local_state = scripting_environment.GetLuaState();
auto& local_context = scripting_environment.GetContex();
for (auto x = range.begin(), end = range.end(); x != end; ++x)
{
@@ -177,7 +175,7 @@ int Extractor::run()
result_node.clear();
++number_of_nodes;
luabind::call_function<void>(
local_state, "node_function",
local_context.state, "node_function",
boost::cref(static_cast<const osmium::Node &>(*entity)),
boost::ref(result_node));
resulting_nodes.push_back(std::make_pair(x, result_node));
@@ -186,7 +184,7 @@ int Extractor::run()
result_way.clear();
++number_of_ways;
luabind::call_function<void>(
local_state, "way_function",
local_context.state, "way_function",
boost::cref(static_cast<const osmium::Way &>(*entity)),
boost::ref(result_way));
resulting_ways.push_back(std::make_pair(x, result_way));
@@ -238,26 +236,29 @@ int Extractor::run()
}
extraction_containers.PrepareData(config.output_file_name, config.restriction_file_name,
config.names_file_name, segment_state);
config.names_file_name, main_context.state);
WriteProfileProperties(config.profile_properties_output_path, main_context.properties);
TIMER_STOP(extracting);
util::SimpleLogger().Write() << "extraction finished after " << TIMER_SEC(extracting)
<< "s";
}
// we do this for scoping
// TODO move to own functions
catch (const std::exception &e)
{
util::SimpleLogger().Write(logWARNING) << e.what();
return 1;
}
try
{
// Transform the node-based graph that OSM is based on into an edge-based graph
// that is better for routing. Every edge becomes a node, and every valid
// movement (e.g. turn from A->B, and B->A) becomes an edge
//
//
// // Create a new lua state
auto& main_context = scripting_environment.GetContex();
util::SimpleLogger().Write() << "Generating edge-expanded graph representation";
@@ -268,7 +269,9 @@ int Extractor::run()
std::vector<bool> node_is_startpoint;
std::vector<EdgeWeight> edge_based_node_weights;
std::vector<QueryNode> internal_to_external_node_map;
auto graph_size = BuildEdgeExpandedGraph(internal_to_external_node_map,
auto graph_size = BuildEdgeExpandedGraph(main_context.state,
main_context.properties,
internal_to_external_node_map,
edge_based_node_list, node_is_startpoint,
edge_based_node_weights, edge_based_edge_list);
@@ -314,46 +317,15 @@ int Extractor::run()
return 0;
}
/**
\brief Setups scripting environment (lua-scripting)
Also initializes speed profile.
*/
void Extractor::SetupScriptingEnvironment(lua_State *lua_state,
SpeedProfileProperties &speed_profile)
void Extractor::WriteProfileProperties(const std::string& output_path, const ProfileProperties& properties) const
{
// open utility libraries string library;
luaL_openlibs(lua_state);
// adjust lua load path
util::luaAddScriptFolderToLoadPath(lua_state, config.profile_path.string().c_str());
// Now call our function in a lua script
if (0 != luaL_dofile(lua_state, config.profile_path.string().c_str()))
boost::filesystem::ofstream out_stream(output_path);
if (!out_stream)
{
std::stringstream msg;
msg << lua_tostring(lua_state, -1) << " occurred in scripting block";
throw util::exception(msg.str());
throw util::exception("Could not open " + output_path + " for writing.");
}
if (0 != luaL_dostring(lua_state, "return traffic_signal_penalty\n"))
{
std::stringstream msg;
msg << lua_tostring(lua_state, -1) << " occurred in scripting block";
throw util::exception(msg.str());
}
speed_profile.traffic_signal_penalty = 10 * lua_tointeger(lua_state, -1);
util::SimpleLogger().Write(logDEBUG) << "traffic_signal_penalty: "
<< speed_profile.traffic_signal_penalty;
if (0 != luaL_dostring(lua_state, "return u_turn_penalty\n"))
{
std::stringstream msg;
msg << lua_tostring(lua_state, -1) << " occurred in scripting block";
throw util::exception(msg.str());
}
speed_profile.u_turn_penalty = 10 * lua_tointeger(lua_state, -1);
speed_profile.has_turn_penalty_function = util::lua_function_exists(lua_state, "turn_function");
out_stream.write(reinterpret_cast<const char*>(&properties), sizeof(properties));
}
void Extractor::FindComponents(unsigned max_edge_id,
@@ -496,18 +468,14 @@ Extractor::LoadNodeBasedGraph(std::unordered_set<NodeID> &barrier_nodes,
\brief Building an edge-expanded graph from node-based input and turn restrictions
*/
std::pair<std::size_t, std::size_t>
Extractor::BuildEdgeExpandedGraph(std::vector<QueryNode> &internal_to_external_node_map,
Extractor::BuildEdgeExpandedGraph(lua_State* lua_state,
const ProfileProperties& profile_properties,
std::vector<QueryNode> &internal_to_external_node_map,
std::vector<EdgeBasedNode> &node_based_edge_list,
std::vector<bool> &node_is_startpoint,
std::vector<EdgeWeight> &edge_based_node_weights,
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list)
{
lua_State *lua_state = luaL_newstate();
luabind::open(lua_state);
SpeedProfileProperties speed_profile;
SetupScriptingEnvironment(lua_state, speed_profile);
std::unordered_set<NodeID> barrier_nodes;
std::unordered_set<NodeID> traffic_lights;
@@ -516,7 +484,7 @@ Extractor::BuildEdgeExpandedGraph(std::vector<QueryNode> &internal_to_external_n
LoadNodeBasedGraph(barrier_nodes, traffic_lights, internal_to_external_node_map);
CompressedEdgeContainer compressed_edge_container;
GraphCompressor graph_compressor(speed_profile);
GraphCompressor graph_compressor;
graph_compressor.Compress(barrier_nodes, traffic_lights, *restriction_map, *node_based_graph,
compressed_edge_container);
@@ -527,14 +495,12 @@ Extractor::BuildEdgeExpandedGraph(std::vector<QueryNode> &internal_to_external_n
EdgeBasedGraphFactory edge_based_graph_factory(
node_based_graph, compressed_edge_container, barrier_nodes, traffic_lights,
std::const_pointer_cast<RestrictionMap const>(restriction_map),
internal_to_external_node_map, speed_profile, name_table);
internal_to_external_node_map, profile_properties, name_table);
edge_based_graph_factory.Run(config.edge_output_path, lua_state,
config.edge_segment_lookup_path, config.edge_penalty_path,
config.generate_edge_lookup);
lua_close(lua_state);
edge_based_graph_factory.GetEdgeBasedEdges(edge_based_edge_list);
edge_based_graph_factory.GetEdgeBasedNodes(node_based_edge_list);
edge_based_graph_factory.GetStartPointMarkers(node_is_startpoint);
-5
View File
@@ -13,11 +13,6 @@ namespace osrm
namespace extractor
{
GraphCompressor::GraphCompressor(SpeedProfileProperties speed_profile)
: speed_profile(std::move(speed_profile))
{
}
void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
const std::unordered_set<NodeID> &traffic_lights,
RestrictionMap &restriction_map,
+77 -43
View File
@@ -268,8 +268,9 @@ TurnAnalysis::fallbackTurnAssignmentMotorway(std::vector<ConnectedRoad> intersec
return intersection;
}
std::vector<ConnectedRoad> TurnAnalysis::handleFromMotorway(
const EdgeID via_edge, std::vector<ConnectedRoad> intersection) const
std::vector<ConnectedRoad>
TurnAnalysis::handleFromMotorway(const EdgeID via_edge,
std::vector<ConnectedRoad> intersection) const
{
const auto &in_data = node_based_graph.GetEdgeData(via_edge);
BOOST_ASSERT(detail::isMotorwayClass(in_data.road_classification.road_class));
@@ -519,8 +520,9 @@ std::vector<ConnectedRoad> TurnAnalysis::handleFromMotorway(
return intersection;
}
std::vector<ConnectedRoad> TurnAnalysis::handleMotorwayRamp(
const EdgeID via_edge, std::vector<ConnectedRoad> intersection) const
std::vector<ConnectedRoad>
TurnAnalysis::handleMotorwayRamp(const EdgeID via_edge,
std::vector<ConnectedRoad> intersection) const
{
auto num_valid_turns = countValid(intersection);
// ramp straight into a motorway/ramp
@@ -659,8 +661,9 @@ std::vector<ConnectedRoad> TurnAnalysis::handleMotorwayRamp(
return intersection;
}
std::vector<ConnectedRoad> TurnAnalysis::handleMotorwayJunction(
const EdgeID via_edge, std::vector<ConnectedRoad> intersection) const
std::vector<ConnectedRoad>
TurnAnalysis::handleMotorwayJunction(const EdgeID via_edge,
std::vector<ConnectedRoad> intersection) const
{
// BOOST_ASSERT(!intersection[0].entry_allowed); //This fails due to @themarex handling of dead
// end
@@ -798,7 +801,8 @@ TurnAnalysis::handleThreeWayTurn(const EdgeID via_edge,
{
return (angularDeviation(road.turn.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE &&
angularDeviation(other.turn.angle, STRAIGHT_ANGLE) > 85) ||
(angularDeviation(road.turn.angle,STRAIGHT_ANGLE) < std::numeric_limits<double>::epsilon()) ||
(angularDeviation(road.turn.angle, STRAIGHT_ANGLE) <
std::numeric_limits<double>::epsilon()) ||
(angularDeviation(other.turn.angle, STRAIGHT_ANGLE) /
angularDeviation(road.turn.angle, STRAIGHT_ANGLE) >
1.4);
@@ -1004,10 +1008,10 @@ TurnAnalysis::handleThreeWayTurn(const EdgeID via_edge,
getTurnDirection(intersection[2].turn.angle)};
}
}
// unnamed intersections or basic three way turn
// unnamed intersections or basic three way turn
// remain at basic turns
// TODO handle obviousness, Handle Merges
// remain at basic turns
// TODO handle obviousness, Handle Merges
return intersection;
}
@@ -1505,43 +1509,47 @@ void TurnAnalysis::assignFork(const EdgeID via_edge,
node_based_graph.GetEdgeData(left.turn.eid).road_classification.road_class);
const bool low_priority_right = isLowPriorityRoadClass(
node_based_graph.GetEdgeData(right.turn.eid).road_classification.road_class);
{ // left fork
if ((angularDeviation(left.turn.angle, STRAIGHT_ANGLE) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION &&
angularDeviation(right.turn.angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE))
{
// left side is actually straight
const auto &out_data = node_based_graph.GetEdgeData(left.turn.eid);
if ((angularDeviation(left.turn.angle, STRAIGHT_ANGLE) <
MAXIMAL_ALLOWED_NO_TURN_DEVIATION &&
angularDeviation(right.turn.angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE))
if (requiresAnnouncement(in_data, out_data))
{
if (requiresAnnouncement(in_data, out_data))
if (low_priority_right && !low_priority_left)
{
if (low_priority_right && !low_priority_left)
left.turn.instruction = getInstructionForObvious(3, via_edge, left);
else
{
if (low_priority_left && !low_priority_right)
left.turn.instruction = {TurnType::Turn, DirectionModifier::SlightLeft};
else
left.turn.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
}
left.turn.instruction = getInstructionForObvious(3, via_edge, left);
right.turn.instruction = {findBasicTurnType(via_edge, right),
DirectionModifier::SlightRight};
}
else
{
left.turn.instruction = {TurnType::Suppressed, DirectionModifier::Straight};
if (low_priority_left && !low_priority_right)
{
left.turn.instruction = {findBasicTurnType(via_edge, left),
DirectionModifier::SlightLeft};
right.turn.instruction = {findBasicTurnType(via_edge, right),
DirectionModifier::SlightRight};
}
else
{
left.turn.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
right.turn.instruction = {TurnType::Fork, DirectionModifier::SlightRight};
}
}
}
else
{
if (low_priority_right && !low_priority_left)
left.turn.instruction = {TurnType::Suppressed, DirectionModifier::SlightLeft};
else
{
if (low_priority_left && !low_priority_right)
left.turn.instruction = {TurnType::Turn, DirectionModifier::SlightLeft};
else
left.turn.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
}
left.turn.instruction = {TurnType::Suppressed, DirectionModifier::Straight};
right.turn.instruction = {findBasicTurnType(via_edge, right),
DirectionModifier::SlightRight};
}
}
{ // right fork
else if (angularDeviation(right.turn.angle, STRAIGHT_ANGLE) <
MAXIMAL_ALLOWED_NO_TURN_DEVIATION &&
angularDeviation(left.turn.angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE)
{
// right side is actually straight
const auto &out_data = node_based_graph.GetEdgeData(right.turn.eid);
if (angularDeviation(right.turn.angle, STRAIGHT_ANGLE) <
MAXIMAL_ALLOWED_NO_TURN_DEVIATION &&
@@ -1550,31 +1558,57 @@ void TurnAnalysis::assignFork(const EdgeID via_edge,
if (requiresAnnouncement(in_data, out_data))
{
if (low_priority_left && !low_priority_right)
{
left.turn.instruction = {findBasicTurnType(via_edge, left),
DirectionModifier::SlightLeft};
right.turn.instruction = getInstructionForObvious(3, via_edge, right);
}
else
{
if (low_priority_right && !low_priority_left)
right.turn.instruction = {TurnType::Turn, DirectionModifier::SlightRight};
{
left.turn.instruction = {findBasicTurnType(via_edge, left),
DirectionModifier::SlightLeft};
right.turn.instruction = {findBasicTurnType(via_edge, right),
DirectionModifier::SlightRight};
}
else
{
right.turn.instruction = {TurnType::Fork, DirectionModifier::SlightRight};
left.turn.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
}
}
}
else
{
right.turn.instruction = {TurnType::Suppressed, DirectionModifier::Straight};
left.turn.instruction = {findBasicTurnType(via_edge, left),
DirectionModifier::SlightLeft};
}
}
}
else
{
// left side of fork
if (low_priority_right && !low_priority_left)
left.turn.instruction = {TurnType::Suppressed, DirectionModifier::SlightLeft};
else
{
if (low_priority_left && !low_priority_right)
right.turn.instruction = {TurnType::Suppressed, DirectionModifier::SlightLeft};
left.turn.instruction = {TurnType::Turn, DirectionModifier::SlightLeft};
else
{
if (low_priority_right && !low_priority_left)
right.turn.instruction = {TurnType::Turn, DirectionModifier::SlightRight};
else
right.turn.instruction = {TurnType::Fork, DirectionModifier::SlightRight};
}
left.turn.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
}
// right side of fork
if (low_priority_left && !low_priority_right)
right.turn.instruction = {TurnType::Suppressed, DirectionModifier::SlightLeft};
else
{
if (low_priority_right && !low_priority_left)
right.turn.instruction = {TurnType::Turn, DirectionModifier::SlightRight};
else
right.turn.instruction = {TurnType::Fork, DirectionModifier::SlightRight};
}
}
}
+4 -23
View File
@@ -1,5 +1,5 @@
#include "extractor/restriction_parser.hpp"
#include "extractor/extraction_way.hpp"
#include "extractor/profile_properties.hpp"
#include "extractor/external_memory_node.hpp"
#include "util/lua_util.hpp"
@@ -33,37 +33,18 @@ int luaErrorCallback(lua_State *lua_state)
}
}
RestrictionParser::RestrictionParser(lua_State *lua_state) : use_turn_restrictions(true)
RestrictionParser::RestrictionParser(lua_State *lua_state, const ProfileProperties &properties)
: use_turn_restrictions(properties.use_turn_restrictions)
{
ReadUseRestrictionsSetting(lua_state);
if (use_turn_restrictions)
{
ReadRestrictionExceptions(lua_state);
}
}
void RestrictionParser::ReadUseRestrictionsSetting(lua_State *lua_state)
{
if (0 == luaL_dostring(lua_state, "return use_turn_restrictions\n") &&
lua_isboolean(lua_state, -1))
{
use_turn_restrictions = lua_toboolean(lua_state, -1);
}
if (use_turn_restrictions)
{
util::SimpleLogger().Write() << "Using turn restrictions";
}
else
{
util::SimpleLogger().Write() << "Ignoring turn restrictions";
}
}
void RestrictionParser::ReadRestrictionExceptions(lua_State *lua_state)
{
if (util::lua_function_exists(lua_state, "get_exceptions"))
if (util::luaFunctionExists(lua_state, "get_exceptions"))
{
luabind::set_pcall_callback(&luaErrorCallback);
// get list of turn restriction exceptions
+93 -82
View File
@@ -6,7 +6,9 @@
#include "extractor/internal_extractor_edge.hpp"
#include "extractor/external_memory_node.hpp"
#include "extractor/raster_source.hpp"
#include "extractor/profile_properties.hpp"
#include "util/lua_util.hpp"
#include "util/make_unique.hpp"
#include "util/exception.hpp"
#include "util/simple_logger.hpp"
#include "util/typedefs.hpp"
@@ -56,117 +58,126 @@ ScriptingEnvironment::ScriptingEnvironment(const std::string &file_name) : file_
util::SimpleLogger().Write() << "Using script " << file_name;
}
void ScriptingEnvironment::InitLuaState(lua_State *lua_state)
void ScriptingEnvironment::InitContext(ScriptingEnvironment::Context &context)
{
typedef double (osmium::Location::*location_member_ptr_type)() const;
luabind::open(lua_state);
luabind::open(context.state);
// open utility libraries string library;
luaL_openlibs(lua_state);
luaL_openlibs(context.state);
util::luaAddScriptFolderToLoadPath(lua_state, file_name.c_str());
util::luaAddScriptFolderToLoadPath(context.state, file_name.c_str());
// Add our function to the state's global scope
luabind::module(
lua_state)[luabind::def("print", util::LUA_print<std::string>),
luabind::def("durationIsValid", durationIsValid),
luabind::def("parseDuration", parseDuration),
luabind::class_<TravelMode>("mode")
.enum_("enums")[luabind::value("inaccessible", TRAVEL_MODE_INACCESSIBLE),
luabind::value("driving", TRAVEL_MODE_DRIVING),
luabind::value("cycling", TRAVEL_MODE_CYCLING),
luabind::value("walking", TRAVEL_MODE_WALKING),
luabind::value("ferry", TRAVEL_MODE_FERRY),
luabind::value("train", TRAVEL_MODE_TRAIN),
luabind::value("pushing_bike", TRAVEL_MODE_PUSHING_BIKE),
luabind::value("movable_bridge", TRAVEL_MODE_MOVABLE_BRIDGE),
luabind::value("steps_up", TRAVEL_MODE_STEPS_UP),
luabind::value("steps_down", TRAVEL_MODE_STEPS_DOWN),
luabind::value("river_up", TRAVEL_MODE_RIVER_UP),
luabind::value("river_down", TRAVEL_MODE_RIVER_DOWN),
luabind::value("route", TRAVEL_MODE_ROUTE)],
luabind::class_<SourceContainer>("sources")
.def(luabind::constructor<>())
.def("load", &SourceContainer::loadRasterSource)
.def("query", &SourceContainer::getRasterDataFromSource)
.def("interpolate", &SourceContainer::getRasterInterpolateFromSource),
luabind::class_<const float>("constants")
.enum_("enums")[luabind::value("precision", COORDINATE_PRECISION)],
luabind::module(context.state)
[luabind::def("durationIsValid", durationIsValid),
luabind::def("parseDuration", parseDuration),
luabind::class_<TravelMode>("mode")
.enum_("enums")[luabind::value("inaccessible", TRAVEL_MODE_INACCESSIBLE),
luabind::value("driving", TRAVEL_MODE_DRIVING),
luabind::value("cycling", TRAVEL_MODE_CYCLING),
luabind::value("walking", TRAVEL_MODE_WALKING),
luabind::value("ferry", TRAVEL_MODE_FERRY),
luabind::value("train", TRAVEL_MODE_TRAIN),
luabind::value("pushing_bike", TRAVEL_MODE_PUSHING_BIKE),
luabind::value("movable_bridge", TRAVEL_MODE_MOVABLE_BRIDGE),
luabind::value("steps_up", TRAVEL_MODE_STEPS_UP),
luabind::value("steps_down", TRAVEL_MODE_STEPS_DOWN),
luabind::value("river_up", TRAVEL_MODE_RIVER_UP),
luabind::value("river_down", TRAVEL_MODE_RIVER_DOWN),
luabind::value("route", TRAVEL_MODE_ROUTE)],
luabind::class_<SourceContainer>("sources")
.def(luabind::constructor<>())
.def("load", &SourceContainer::loadRasterSource)
.def("query", &SourceContainer::getRasterDataFromSource)
.def("interpolate", &SourceContainer::getRasterInterpolateFromSource),
luabind::class_<const float>("constants")
.enum_("enums")[luabind::value("precision", COORDINATE_PRECISION)],
luabind::class_<std::vector<std::string>>("vector").def(
"Add", static_cast<void (std::vector<std::string>::*)(const std::string &)>(
&std::vector<std::string>::push_back)),
luabind::class_<ProfileProperties>("ProfileProperties")
.def(luabind::constructor<>())
.property("traffic_signal_penalty", &ProfileProperties::GetTrafficSignalPenalty,
&ProfileProperties::SetTrafficSignalPenalty)
.property("u_turn_penalty", &ProfileProperties::GetUturnPenalty,
&ProfileProperties::SetUturnPenalty)
.def_readwrite("allow_u_turn_at_via", &ProfileProperties::allow_u_turn_at_via),
luabind::class_<osmium::Location>("Location")
.def<location_member_ptr_type>("lat", &osmium::Location::lat)
.def<location_member_ptr_type>("lon", &osmium::Location::lon),
luabind::class_<std::vector<std::string>>("vector")
.def("Add", static_cast<void (std::vector<std::string>::*)(const std::string &)>(
&std::vector<std::string>::push_back)),
luabind::class_<osmium::Node>("Node")
// .def<node_member_ptr_type>("tags", &osmium::Node::tags)
.def("location", &osmium::Node::location)
.def("get_value_by_key", &osmium::Node::get_value_by_key)
.def("get_value_by_key", &get_value_by_key<osmium::Node>)
.def("id", &osmium::Node::id),
luabind::class_<osmium::Location>("Location")
.def<location_member_ptr_type>("lat", &osmium::Location::lat)
.def<location_member_ptr_type>("lon", &osmium::Location::lon),
luabind::class_<ExtractionNode>("ResultNode")
.def_readwrite("traffic_lights", &ExtractionNode::traffic_lights)
.def_readwrite("barrier", &ExtractionNode::barrier),
luabind::class_<osmium::Node>("Node")
// .def<node_member_ptr_type>("tags", &osmium::Node::tags)
.def("location", &osmium::Node::location)
.def("get_value_by_key", &osmium::Node::get_value_by_key)
.def("get_value_by_key", &get_value_by_key<osmium::Node>)
.def("id", &osmium::Node::id),
luabind::class_<ExtractionWay>("ResultWay")
// .def(luabind::constructor<>())
.def_readwrite("forward_speed", &ExtractionWay::forward_speed)
.def_readwrite("backward_speed", &ExtractionWay::backward_speed)
.def_readwrite("name", &ExtractionWay::name)
.def_readwrite("roundabout", &ExtractionWay::roundabout)
.def_readwrite("is_access_restricted", &ExtractionWay::is_access_restricted)
.def_readwrite("is_startpoint", &ExtractionWay::is_startpoint)
.def_readwrite("duration", &ExtractionWay::duration)
.property("forward_mode", &ExtractionWay::get_forward_mode,
&ExtractionWay::set_forward_mode)
.property("backward_mode", &ExtractionWay::get_backward_mode,
&ExtractionWay::set_backward_mode),
luabind::class_<osmium::Way>("Way")
.def("get_value_by_key", &osmium::Way::get_value_by_key)
.def("get_value_by_key", &get_value_by_key<osmium::Way>)
.def("id", &osmium::Way::id),
luabind::class_<InternalExtractorEdge>("EdgeSource")
.def_readonly("source_coordinate", &InternalExtractorEdge::source_coordinate)
.def_readwrite("weight_data", &InternalExtractorEdge::weight_data),
luabind::class_<InternalExtractorEdge::WeightData>("WeightData")
.def_readwrite("speed", &InternalExtractorEdge::WeightData::speed),
luabind::class_<ExternalMemoryNode>("EdgeTarget")
.property("lon", &lonToDouble<ExternalMemoryNode>)
.property("lat", &latToDouble<ExternalMemoryNode>),
luabind::class_<util::Coordinate>("Coordinate")
.property("lon", &lonToDouble<util::Coordinate>)
.property("lat", &latToDouble<util::Coordinate>),
luabind::class_<RasterDatum>("RasterDatum")
.def_readonly("datum", &RasterDatum::datum)
.def("invalid_data", &RasterDatum::get_invalid)];
luabind::class_<ExtractionNode>("ResultNode")
.def_readwrite("traffic_lights", &ExtractionNode::traffic_lights)
.def_readwrite("barrier", &ExtractionNode::barrier),
if (0 != luaL_dofile(lua_state, file_name.c_str()))
luabind::class_<ExtractionWay>("ResultWay")
// .def(luabind::constructor<>())
.def_readwrite("forward_speed", &ExtractionWay::forward_speed)
.def_readwrite("backward_speed", &ExtractionWay::backward_speed)
.def_readwrite("name", &ExtractionWay::name)
.def_readwrite("roundabout", &ExtractionWay::roundabout)
.def_readwrite("is_access_restricted", &ExtractionWay::is_access_restricted)
.def_readwrite("is_startpoint", &ExtractionWay::is_startpoint)
.def_readwrite("duration", &ExtractionWay::duration)
.property("forward_mode", &ExtractionWay::get_forward_mode,
&ExtractionWay::set_forward_mode)
.property("backward_mode", &ExtractionWay::get_backward_mode,
&ExtractionWay::set_backward_mode),
luabind::class_<osmium::Way>("Way")
.def("get_value_by_key", &osmium::Way::get_value_by_key)
.def("get_value_by_key", &get_value_by_key<osmium::Way>)
.def("id", &osmium::Way::id),
luabind::class_<InternalExtractorEdge>("EdgeSource")
.def_readonly("source_coordinate", &InternalExtractorEdge::source_coordinate)
.def_readwrite("weight_data", &InternalExtractorEdge::weight_data),
luabind::class_<InternalExtractorEdge::WeightData>("WeightData")
.def_readwrite("speed", &InternalExtractorEdge::WeightData::speed),
luabind::class_<ExternalMemoryNode>("EdgeTarget")
.property("lon", &lonToDouble<ExternalMemoryNode>)
.property("lat", &latToDouble<ExternalMemoryNode>),
luabind::class_<util::Coordinate>("Coordinate")
.property("lon", &lonToDouble<util::Coordinate>)
.property("lat", &latToDouble<util::Coordinate>),
luabind::class_<RasterDatum>("RasterDatum")
.def_readonly("datum", &RasterDatum::datum)
.def("invalid_data", &RasterDatum::get_invalid)];
luabind::globals(context.state)["properties"] = &context.properties;
luabind::globals(context.state)["sources"] = &context.sources;
if (0 != luaL_dofile(context.state, file_name.c_str()))
{
luabind::object error_msg(luabind::from_stack(lua_state, -1));
luabind::object error_msg(luabind::from_stack(context.state, -1));
std::ostringstream error_stream;
error_stream << error_msg;
throw util::exception("ERROR occurred in profile script:\n" + error_stream.str());
}
}
lua_State *ScriptingEnvironment::GetLuaState()
ScriptingEnvironment::Context &ScriptingEnvironment::GetContex()
{
std::lock_guard<std::mutex> lock(init_mutex);
bool initialized = false;
auto &ref = script_contexts.local(initialized);
if (!initialized)
{
std::shared_ptr<lua_State> state(luaL_newstate(), lua_close);
ref = state;
InitLuaState(ref.get());
ref = util::make_unique<Context>();
InitContext(*ref);
}
luabind::set_pcall_callback(&luaErrorCallback);
return ref.get();
return *ref;
}
}
}
+1 -3
View File
@@ -25,9 +25,7 @@ std::string getWrongOptionHelp(const engine::api::RouteParameters &parameters)
constrainParamSize(PARAMETER_SIZE_MISMATCH_MSG, "bearings",
parameters.bearings, coord_size, help) ||
constrainParamSize(PARAMETER_SIZE_MISMATCH_MSG, "radiuses",
parameters.radiuses, coord_size, help) ||
constrainParamSize(PARAMETER_SIZE_MISMATCH_MSG, "uturns",
parameters.uturns, coord_size, help);
parameters.radiuses, coord_size, help);
if (!param_size_mismatch && parameters.coordinates.size() < 2)
{
+69 -128
View File
@@ -2,6 +2,7 @@
#include "util/range_table.hpp"
#include "contractor/query_edge.hpp"
#include "extractor/query_node.hpp"
#include "extractor/profile_properties.hpp"
#include "extractor/compressed_edge_container.hpp"
#include "util/shared_memory_vector_wrapper.hpp"
#include "util/static_graph.hpp"
@@ -72,10 +73,12 @@ void deleteRegion(const SharedDataType region)
}
}
Storage::Storage(const DataPaths &paths_) : paths(paths_) {}
Storage::Storage(StorageConfig config_) : config(std::move(config_)) {}
int Storage::Run()
{
BOOST_ASSERT_MSG(config.IsValid(), "Invalid storage config");
util::LogPolicy::GetInstance().Unmute();
SharedBarriers barrier;
@@ -99,94 +102,6 @@ int Storage::Run()
barrier.pending_update_mutex.unlock();
}
if (paths.find("hsgrdata") == paths.end())
{
throw util::exception("no hsgr file found");
}
if (paths.find("ramindex") == paths.end())
{
throw util::exception("no ram index file found");
}
if (paths.find("fileindex") == paths.end())
{
throw util::exception("no leaf index file found");
}
if (paths.find("nodesdata") == paths.end())
{
throw util::exception("no nodes file found");
}
if (paths.find("edgesdata") == paths.end())
{
throw util::exception("no edges file found");
}
if (paths.find("namesdata") == paths.end())
{
throw util::exception("no names file found");
}
if (paths.find("geometry") == paths.end())
{
throw util::exception("no geometry file found");
}
if (paths.find("core") == paths.end())
{
throw util::exception("no core file found");
}
if (paths.find("datasource_indexes") == paths.end())
{
throw util::exception("no datasource_indexes file found");
}
if (paths.find("datasource_names") == paths.end())
{
throw util::exception("no datasource_names file found");
}
auto paths_iterator = paths.find("hsgrdata");
BOOST_ASSERT(paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &hsgr_path = paths_iterator->second;
paths_iterator = paths.find("timestamp");
BOOST_ASSERT(paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &timestamp_path = paths_iterator->second;
paths_iterator = paths.find("ramindex");
BOOST_ASSERT(paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &ram_index_path = paths_iterator->second;
paths_iterator = paths.find("fileindex");
BOOST_ASSERT(paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path index_file_path_absolute =
boost::filesystem::canonical(paths_iterator->second);
const std::string &file_index_path = index_file_path_absolute.string();
paths_iterator = paths.find("nodesdata");
BOOST_ASSERT(paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &nodes_data_path = paths_iterator->second;
paths_iterator = paths.find("edgesdata");
BOOST_ASSERT(paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &edges_data_path = paths_iterator->second;
paths_iterator = paths.find("namesdata");
BOOST_ASSERT(paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &names_data_path = paths_iterator->second;
paths_iterator = paths.find("geometry");
BOOST_ASSERT(paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &geometries_data_path = paths_iterator->second;
paths_iterator = paths.find("core");
BOOST_ASSERT(paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &core_marker_path = paths_iterator->second;
paths_iterator = paths.find("datasource_indexes");
BOOST_ASSERT(paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &datasource_indexes_path = paths_iterator->second;
paths_iterator = paths.find("datasource_names");
BOOST_ASSERT(paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &datasource_names_path = paths_iterator->second;
// determine segment to use
bool segment2_in_use = SharedMemory::RegionExists(LAYOUT_2);
const storage::SharedDataType layout_region = [&]
@@ -209,14 +124,19 @@ int Storage::Run()
// Allocate a memory layout in shared memory, deallocate previous
auto *layout_memory = makeSharedMemory(layout_region, sizeof(SharedDataLayout));
auto shared_layout_ptr = new (layout_memory->Ptr()) SharedDataLayout();
auto absolute_file_index_path = boost::filesystem::absolute(config.file_index_path);
shared_layout_ptr->SetBlockSize<char>(SharedDataLayout::FILE_INDEX_PATH,
file_index_path.length() + 1);
absolute_file_index_path.string().length() + 1);
// collect number of elements to store in shared memory object
util::SimpleLogger().Write() << "load names from: " << names_data_path;
util::SimpleLogger().Write() << "load names from: " << config.names_data_path;
// number of entries in name index
boost::filesystem::ifstream name_stream(names_data_path, std::ios::binary);
boost::filesystem::ifstream name_stream(config.names_data_path, std::ios::binary);
if (!name_stream)
{
throw util::exception("Could not open " + config.names_data_path.string() + " for reading.");
}
unsigned name_blocks = 0;
name_stream.read((char *)&name_blocks, sizeof(unsigned));
shared_layout_ptr->SetBlockSize<unsigned>(SharedDataLayout::NAME_OFFSETS, name_blocks);
@@ -230,7 +150,11 @@ int Storage::Run()
shared_layout_ptr->SetBlockSize<char>(SharedDataLayout::NAME_CHAR_LIST, number_of_chars);
// Loading information for original edges
boost::filesystem::ifstream edges_input_stream(edges_data_path, std::ios::binary);
boost::filesystem::ifstream edges_input_stream(config.edges_data_path, std::ios::binary);
if (!edges_input_stream)
{
throw util::exception("Could not open " + config.edges_data_path.string() + " for reading.");
}
unsigned number_of_original_edges = 0;
edges_input_stream.read((char *)&number_of_original_edges, sizeof(unsigned));
@@ -244,7 +168,11 @@ int Storage::Run()
shared_layout_ptr->SetBlockSize<extractor::guidance::TurnInstruction>(
SharedDataLayout::TURN_INSTRUCTION, number_of_original_edges);
boost::filesystem::ifstream hsgr_input_stream(hsgr_path, std::ios::binary);
boost::filesystem::ifstream hsgr_input_stream(config.hsgr_data_path, std::ios::binary);
if (!hsgr_input_stream)
{
throw util::exception("Could not open " + config.hsgr_data_path.string() + " for reading.");
}
util::FingerPrint fingerprint_valid = util::FingerPrint::GetValid();
util::FingerPrint fingerprint_loaded;
@@ -279,39 +207,27 @@ int Storage::Run()
number_of_graph_edges);
// load rsearch tree size
boost::filesystem::ifstream tree_node_file(ram_index_path, std::ios::binary);
boost::filesystem::ifstream tree_node_file(config.ram_index_path, std::ios::binary);
uint32_t tree_size = 0;
tree_node_file.read((char *)&tree_size, sizeof(uint32_t));
shared_layout_ptr->SetBlockSize<RTreeNode>(SharedDataLayout::R_SEARCH_TREE, tree_size);
// load profile properties
shared_layout_ptr->SetBlockSize<extractor::ProfileProperties>(SharedDataLayout::PROPERTIES, 1);
// load timestamp size
boost::filesystem::ifstream timestamp_stream(config.timestamp_path);
std::string m_timestamp;
if (boost::filesystem::exists(timestamp_path))
{
boost::filesystem::ifstream timestamp_stream(timestamp_path);
if (!timestamp_stream)
{
util::SimpleLogger().Write(logWARNING) << timestamp_path
<< " not found. setting to default";
}
else
{
getline(timestamp_stream, m_timestamp);
}
}
if (m_timestamp.empty())
{
m_timestamp = "n/a";
}
if (25 < m_timestamp.length())
{
m_timestamp.resize(25);
}
getline(timestamp_stream, m_timestamp);
shared_layout_ptr->SetBlockSize<char>(SharedDataLayout::TIMESTAMP, m_timestamp.length());
// load core marker size
boost::filesystem::ifstream core_marker_file(core_marker_path, std::ios::binary);
boost::filesystem::ifstream core_marker_file(config.core_data_path, std::ios::binary);
if (!core_marker_file)
{
throw util::exception("Could not open " + config.core_data_path.string() + " for reading.");
}
uint32_t number_of_core_markers = 0;
core_marker_file.read((char *)&number_of_core_markers, sizeof(uint32_t));
@@ -319,14 +235,22 @@ int Storage::Run()
number_of_core_markers);
// load coordinate size
boost::filesystem::ifstream nodes_input_stream(nodes_data_path, std::ios::binary);
boost::filesystem::ifstream nodes_input_stream(config.nodes_data_path, std::ios::binary);
if (!nodes_input_stream)
{
throw util::exception("Could not open " + config.core_data_path.string() + " for reading.");
}
unsigned coordinate_list_size = 0;
nodes_input_stream.read((char *)&coordinate_list_size, sizeof(unsigned));
shared_layout_ptr->SetBlockSize<util::Coordinate>(SharedDataLayout::COORDINATE_LIST,
coordinate_list_size);
// load geometries sizes
std::ifstream geometry_input_stream(geometries_data_path.string().c_str(), std::ios::binary);
boost::filesystem::ifstream geometry_input_stream(config.geometries_path, std::ios::binary);
if (!geometry_input_stream)
{
throw util::exception("Could not open " + config.geometries_path.string() + " for reading.");
}
unsigned number_of_geometries_indices = 0;
unsigned number_of_compressed_geometries = 0;
@@ -341,8 +265,12 @@ int Storage::Run()
// load datasource sizes. This file is optional, and it's non-fatal if it doesn't
// exist.
std::ifstream geometry_datasource_input_stream(datasource_indexes_path.c_str(),
std::ios::binary);
boost::filesystem::ifstream geometry_datasource_input_stream(config.datasource_indexes_path,
std::ios::binary);
if (!geometry_datasource_input_stream)
{
throw util::exception("Could not open " + config.datasource_indexes_path.string() + " for reading.");
}
std::size_t number_of_compressed_datasources = 0;
if (geometry_datasource_input_stream)
{
@@ -354,7 +282,12 @@ int Storage::Run()
// Load datasource name sizes. This file is optional, and it's non-fatal if it doesn't
// exist
std::ifstream datasource_names_input_stream(datasource_names_path.c_str(), std::ios::binary);
boost::filesystem::ifstream datasource_names_input_stream(config.datasource_names_path,
std::ios::binary);
if (!datasource_names_input_stream)
{
throw util::exception("Could not open " + config.datasource_names_path.string() + " for reading.");
}
std::vector<char> m_datasource_name_data;
std::vector<std::size_t> m_datasource_name_offsets;
std::vector<std::size_t> m_datasource_name_lengths;
@@ -370,11 +303,11 @@ int Storage::Run()
}
}
shared_layout_ptr->SetBlockSize<char>(SharedDataLayout::DATASOURCE_NAME_DATA,
m_datasource_name_data.size());
m_datasource_name_data.size());
shared_layout_ptr->SetBlockSize<std::size_t>(SharedDataLayout::DATASOURCE_NAME_OFFSETS,
m_datasource_name_offsets.size());
m_datasource_name_offsets.size());
shared_layout_ptr->SetBlockSize<std::size_t>(SharedDataLayout::DATASOURCE_NAME_LENGTHS,
m_datasource_name_lengths.size());
m_datasource_name_lengths.size());
// allocate shared memory block
util::SimpleLogger().Write() << "allocating shared memory of "
@@ -397,7 +330,7 @@ int Storage::Run()
file_index_path_ptr +
shared_layout_ptr->GetBlockSize(SharedDataLayout::FILE_INDEX_PATH),
0);
std::copy(file_index_path.begin(), file_index_path.end(), file_index_path_ptr);
std::copy(absolute_file_index_path.string().begin(), absolute_file_index_path.string().end(), file_index_path_ptr);
// Loading street names
unsigned *name_offsets_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
@@ -504,8 +437,7 @@ int Storage::Run()
shared_memory_ptr, SharedDataLayout::DATASOURCE_NAME_DATA);
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::DATASOURCE_NAME_DATA) > 0)
{
std::cout << "Copying "
<< (m_datasource_name_data.end() - m_datasource_name_data.begin())
std::cout << "Copying " << (m_datasource_name_data.end() - m_datasource_name_data.begin())
<< " chars into name data ptr\n";
std::copy(m_datasource_name_data.begin(), m_datasource_name_data.end(),
datasource_name_data_ptr);
@@ -605,6 +537,15 @@ int Storage::Run()
}
hsgr_input_stream.close();
// load profile properties
auto profile_properties_ptr = shared_layout_ptr->GetBlockPtr<extractor::ProfileProperties, true>(shared_memory_ptr, SharedDataLayout::PROPERTIES);
boost::filesystem::ifstream profile_properties_stream(config.properties_path);
if (!profile_properties_stream)
{
util::exception("Could not open " + config.properties_path.string() + " for reading!");
}
profile_properties_stream.read(reinterpret_cast<char*>(profile_properties_ptr), sizeof(extractor::ProfileProperties));
// acquire lock
SharedMemory *data_type_memory =
makeSharedMemory(CURRENT_REGIONS, sizeof(SharedDataTimestamp), true, false);
+38
View File
@@ -0,0 +1,38 @@
#include "storage/storage_config.hpp"
#include <boost/filesystem/operations.hpp>
namespace osrm
{
namespace storage
{
StorageConfig::StorageConfig(const boost::filesystem::path &base)
: ram_index_path{base.string() + ".ramIndex"}, file_index_path{base.string() + ".fileIndex"},
hsgr_data_path{base.string() + ".hsgr"}, nodes_data_path{base.string() + ".nodes"},
edges_data_path{base.string() + ".edges"}, core_data_path{base.string() + ".core"},
geometries_path{base.string() + ".geometry"}, timestamp_path{base.string() + ".timestamp"},
datasource_names_path{base.string() + ".datasource_names"},
datasource_indexes_path{base.string() + ".datasource_indexes"},
names_data_path{base.string() + ".names"},
properties_path{base.string() + ".properties"}
{
}
bool StorageConfig::IsValid() const
{
return boost::filesystem::is_regular_file(ram_index_path) &&
boost::filesystem::is_regular_file(file_index_path) &&
boost::filesystem::is_regular_file(hsgr_data_path) &&
boost::filesystem::is_regular_file(nodes_data_path) &&
boost::filesystem::is_regular_file(edges_data_path) &&
boost::filesystem::is_regular_file(core_data_path) &&
boost::filesystem::is_regular_file(geometries_path) &&
boost::filesystem::is_regular_file(timestamp_path) &&
boost::filesystem::is_regular_file(datasource_names_path) &&
boost::filesystem::is_regular_file(datasource_indexes_path) &&
boost::filesystem::is_regular_file(names_data_path) &&
boost::filesystem::is_regular_file(properties_path);
}
}
}
+132 -5
View File
@@ -1,10 +1,14 @@
#include "server/server.hpp"
#include "util/routed_options.hpp"
#include "util/make_unique.hpp"
#include "util/simple_logger.hpp"
#include "util/version.hpp"
#include "osrm/osrm.hpp"
#include "osrm/engine_config.hpp"
#include "osrm/storage_config.hpp"
#include <boost/any.hpp>
#include <boost/program_options.hpp>
#ifdef __linux__
#include <sys/mman.h>
@@ -19,6 +23,7 @@
#include <iostream>
#include <new>
#include <thread>
#include <string>
#ifdef _WIN32
boost::function0<void> console_ctrl_function;
@@ -41,6 +46,111 @@ BOOL WINAPI console_ctrl_handler(DWORD ctrl_type)
using namespace osrm;
const static unsigned INIT_OK_START_ENGINE = 0;
const static unsigned INIT_OK_DO_NOT_START_ENGINE = 1;
const static unsigned INIT_FAILED = -1;
// generate boost::program_options object for the routing part
inline unsigned
generateServerProgramOptions(const int argc,
const char *argv[],
boost::filesystem::path &base_path,
std::string &ip_address,
int &ip_port,
int &requested_num_threads,
bool &use_shared_memory,
bool &trial,
int &max_locations_trip,
int &max_locations_viaroute,
int &max_locations_distance_table,
int &max_locations_map_matching)
{
using boost::program_options::value;
using boost::filesystem::path;
// 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") //
("trial", value<bool>(&trial)->implicit_value(true), "Quit after initialization");
// declare a group of options that will be allowed on command line
boost::program_options::options_description config_options("Configuration");
config_options.add_options() //
("ip,i", value<std::string>(&ip_address)->default_value("0.0.0.0"),
"IP address") //
("port,p", value<int>(&ip_port)->default_value(5000),
"TCP/IP port") //
("threads,t", value<int>(&requested_num_threads)->default_value(8),
"Number of threads to use") //
("shared-memory,s",
value<bool>(&use_shared_memory)->implicit_value(true)->default_value(false),
"Load data from shared memory") //
("max-viaroute-size", value<int>(&max_locations_viaroute)->default_value(500),
"Max. locations supported in viaroute query") //
("max-trip-size", value<int>(&max_locations_trip)->default_value(100),
"Max. locations supported in trip query") //
("max-table-size", value<int>(&max_locations_distance_table)->default_value(100),
"Max. locations supported in distance table query") //
("max-matching-size", value<int>(&max_locations_map_matching)->default_value(100),
"Max. locations supported in map matching query");
// hidden options, will be allowed on command line, but will not be shown to the user
boost::program_options::options_description hidden_options("Hidden options");
hidden_options.add_options()("base,b", value<boost::filesystem::path>(&base_path),
"base path to .osrm file");
// positional option
boost::program_options::positional_options_description positional_options;
positional_options.add("base", 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 visible_options(
boost::filesystem::path(argv[0]).stem().string() + " <base.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);
if (option_variables.count("version"))
{
util::SimpleLogger().Write() << OSRM_VERSION;
return INIT_OK_DO_NOT_START_ENGINE;
}
if (option_variables.count("help"))
{
util::SimpleLogger().Write() << visible_options;
return INIT_OK_DO_NOT_START_ENGINE;
}
boost::program_options::notify(option_variables);
if (!use_shared_memory && option_variables.count("base"))
{
return INIT_OK_START_ENGINE;
}
else if (use_shared_memory && !option_variables.count("base"))
{
return INIT_OK_START_ENGINE;
}
else if (use_shared_memory && option_variables.count("base"))
{
util::SimpleLogger().Write(logWARNING) << "Shared memory settings conflict with path settings.";
}
util::SimpleLogger().Write() << visible_options;
return INIT_OK_DO_NOT_START_ENGINE;
}
int main(int argc, const char *argv[]) try
{
util::LogPolicy::GetInstance().Unmute();
@@ -50,19 +160,36 @@ int main(int argc, const char *argv[]) try
int ip_port, requested_thread_num;
EngineConfig config;
const unsigned init_result = util::GenerateServerProgramOptions(
argc, argv, config.server_paths, ip_address, ip_port, requested_thread_num,
boost::filesystem::path base_path;
const unsigned init_result = generateServerProgramOptions(
argc, argv, base_path, ip_address, ip_port, requested_thread_num,
config.use_shared_memory, trial_run, config.max_locations_trip,
config.max_locations_viaroute, config.max_locations_distance_table,
config.max_locations_map_matching);
if (init_result == util::INIT_OK_DO_NOT_START_ENGINE)
if (init_result == INIT_OK_DO_NOT_START_ENGINE)
{
return EXIT_SUCCESS;
}
if (init_result == util::INIT_FAILED)
if (init_result == INIT_FAILED)
{
return EXIT_FAILURE;
}
if (!base_path.empty())
{
config.storage_config = storage::StorageConfig(base_path);
}
if(!config.IsValid())
{
if (base_path.empty() != config.use_shared_memory)
{
util::SimpleLogger().Write(logWARNING) << "Path settings and shared memory conflicts.";
}
else
{
util::SimpleLogger().Write(logWARNING) << "Invalid config options.";
}
return EXIT_FAILURE;
}
#ifdef __linux__
struct MemoryLocker final
+11 -157
View File
@@ -10,7 +10,7 @@
using namespace osrm;
// generate boost::program_options object for the routing part
bool generateDataStoreOptions(const int argc, const char *argv[], storage::DataPaths &paths)
bool generateDataStoreOptions(const int argc, const char *argv[], boost::filesystem::path& base_path)
{
// declare a group of options that will be allowed only on command line
boost::program_options::options_description generic_options("Options");
@@ -20,36 +20,11 @@ bool generateDataStoreOptions(const int argc, const char *argv[], storage::DataP
// declare a group of options that will be allowed both on command line
// as well as in a config file
boost::program_options::options_description config_options("Configuration");
config_options.add_options()(
"hsgrdata", boost::program_options::value<boost::filesystem::path>(&paths["hsgrdata"]),
".hsgr file")("nodesdata",
boost::program_options::value<boost::filesystem::path>(&paths["nodesdata"]),
".nodes file")(
"edgesdata", boost::program_options::value<boost::filesystem::path>(&paths["edgesdata"]),
".edges file")("geometry",
boost::program_options::value<boost::filesystem::path>(&paths["geometry"]),
".geometry file")(
"ramindex", boost::program_options::value<boost::filesystem::path>(&paths["ramindex"]),
".ramIndex file")(
"fileindex", boost::program_options::value<boost::filesystem::path>(&paths["fileindex"]),
".fileIndex file")("core",
boost::program_options::value<boost::filesystem::path>(&paths["core"]),
".core file")(
"namesdata", boost::program_options::value<boost::filesystem::path>(&paths["namesdata"]),
".names file")("timestamp",
boost::program_options::value<boost::filesystem::path>(&paths["timestamp"]),
".timestamp file")(
"datasource_names",
boost::program_options::value<boost::filesystem::path>(&paths["datasource_names"]),
".datasource_names file")(
"datasource_indexes",
boost::program_options::value<boost::filesystem::path>(&paths["datasource_indexes"]),
".datasource_indexes file");
// hidden options, will be allowed on command line but will not be shown to the user
boost::program_options::options_description hidden_options("Hidden options");
hidden_options.add_options()(
"base,b", boost::program_options::value<boost::filesystem::path>(&paths["base"]),
"base,b", boost::program_options::value<boost::filesystem::path>(&base_path),
"base path to .osrm file");
// positional option
@@ -93,132 +68,6 @@ bool generateDataStoreOptions(const int argc, const char *argv[], storage::DataP
boost::program_options::notify(option_variables);
auto path_iterator = paths.find("base");
BOOST_ASSERT(paths.end() != path_iterator);
std::string base_string = path_iterator->second.string();
path_iterator = paths.find("hsgrdata");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".hsgr";
}
path_iterator = paths.find("nodesdata");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".nodes";
}
path_iterator = paths.find("edgesdata");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".edges";
}
path_iterator = paths.find("geometry");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".geometry";
}
path_iterator = paths.find("ramindex");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".ramIndex";
}
path_iterator = paths.find("fileindex");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".fileIndex";
}
path_iterator = paths.find("core");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".core";
}
path_iterator = paths.find("namesdata");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".names";
}
path_iterator = paths.find("timestamp");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".timestamp";
}
path_iterator = paths.find("datasource_indexes");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".datasource_indexes";
}
path_iterator = paths.find("datasource_names");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".datasource_names";
}
path_iterator = paths.find("hsgrdata");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .hsgr file must be specified");
}
path_iterator = paths.find("nodesdata");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .nodes file must be specified");
}
path_iterator = paths.find("edgesdata");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .edges file must be specified");
}
path_iterator = paths.find("geometry");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .geometry file must be specified");
}
path_iterator = paths.find("ramindex");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .ramindex file must be specified");
}
path_iterator = paths.find("fileindex");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .fileindex file must be specified");
}
path_iterator = paths.find("namesdata");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .names file must be specified");
}
path_iterator = paths.find("timestamp");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .timestamp file must be specified");
}
return true;
}
@@ -226,13 +75,18 @@ int main(const int argc, const char *argv[]) try
{
util::LogPolicy::GetInstance().Unmute();
storage::DataPaths paths;
if (!generateDataStoreOptions(argc, argv, paths))
boost::filesystem::path base_path;
if (!generateDataStoreOptions(argc, argv, base_path))
{
return EXIT_SUCCESS;
}
storage::Storage storage(paths);
storage::StorageConfig config(base_path);
if (!config.IsValid())
{
util::SimpleLogger().Write(logWARNING) << "Invalid file path given!";
return EXIT_FAILURE;
}
storage::Storage storage(std::move(config));
return storage.Run();
}
catch (const std::bad_alloc &e)
+74
View File
@@ -0,0 +1,74 @@
#include "engine/base64.hpp"
#include "engine/hint.hpp"
#include "mocks/mock_datafacade.hpp"
#include <boost/test/unit_test.hpp>
#include <boost/test/test_case_template.hpp>
#include <iostream>
#include <algorithm>
// RFC 4648 "The Base16, Base32, and Base64 Data Encodings"
BOOST_AUTO_TEST_SUITE(base64)
// For test vectors see section 10: https://tools.ietf.org/html/rfc4648#section-10
BOOST_AUTO_TEST_CASE(rfc4648_test_vectors)
{
using namespace osrm::engine;
BOOST_CHECK_EQUAL(encodeBase64(""), "");
BOOST_CHECK_EQUAL(encodeBase64("f"), "Zg==");
BOOST_CHECK_EQUAL(encodeBase64("fo"), "Zm8=");
BOOST_CHECK_EQUAL(encodeBase64("foo"), "Zm9v");
BOOST_CHECK_EQUAL(encodeBase64("foob"), "Zm9vYg==");
BOOST_CHECK_EQUAL(encodeBase64("fooba"), "Zm9vYmE=");
BOOST_CHECK_EQUAL(encodeBase64("foobar"), "Zm9vYmFy");
}
BOOST_AUTO_TEST_CASE(rfc4648_test_vectors_roundtrip)
{
using namespace osrm::engine;
BOOST_CHECK_EQUAL(decodeBase64(encodeBase64("")), "");
BOOST_CHECK_EQUAL(decodeBase64(encodeBase64("f")), "f");
BOOST_CHECK_EQUAL(decodeBase64(encodeBase64("fo")), "fo");
BOOST_CHECK_EQUAL(decodeBase64(encodeBase64("foo")), "foo");
BOOST_CHECK_EQUAL(decodeBase64(encodeBase64("foob")), "foob");
BOOST_CHECK_EQUAL(decodeBase64(encodeBase64("fooba")), "fooba");
BOOST_CHECK_EQUAL(decodeBase64(encodeBase64("foobar")), "foobar");
}
BOOST_AUTO_TEST_CASE(hint_encoding_decoding_roundtrip)
{
using namespace osrm::engine;
osrm::test::MockDataFacade facade;
Hint hint{{}, {}, facade.GetCheckSum()};
const auto base64 = hint.ToBase64();
BOOST_CHECK(0 == std::count(begin(base64), end(base64), '+'));
BOOST_CHECK(0 == std::count(begin(base64), end(base64), '/'));
const auto decoded = Hint::FromBase64(base64);
BOOST_CHECK_EQUAL(hint, decoded);
}
BOOST_AUTO_TEST_CASE(hint_encoding_decoding_roundtrip_bytewise)
{
using namespace osrm::engine;
osrm::test::MockDataFacade facade;
Hint hint{{}, {}, facade.GetCheckSum()};
const auto decoded = Hint::FromBase64(hint.ToBase64());
BOOST_CHECK(std::equal(reinterpret_cast<const unsigned char *>(&hint),
reinterpret_cast<const unsigned char *>(&hint) + sizeof(Hint),
reinterpret_cast<const unsigned char *>(&decoded)));
}
BOOST_AUTO_TEST_SUITE_END()
+1
View File
@@ -103,6 +103,7 @@ class MockDataFacadeT final : public osrm::engine::datafacade::BaseDataFacade<Ed
std::string get_name_for_id(const unsigned /* name_id */) const { return ""; }
std::size_t GetCoreSize() const { return 0; }
std::string GetTimestamp() const { return ""; }
bool GetUTurnsDefault() const override { return true; }
};
using MockDataFacade = MockDataFacadeT<contractor::QueryEdge::EdgeData>;
+14 -13
View File
@@ -132,7 +132,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
BOOST_CHECK_EQUAL(reference_1.alternatives, result_1->alternatives);
BOOST_CHECK_EQUAL(reference_1.geometries, result_1->geometries);
BOOST_CHECK_EQUAL(reference_1.overview, result_1->overview);
CHECK_EQUAL_RANGE(reference_1.uturns, result_1->uturns);
BOOST_CHECK_EQUAL(reference_1.uturns, result_1->uturns);
CHECK_EQUAL_RANGE(reference_1.bearings, result_1->bearings);
CHECK_EQUAL_RANGE(reference_1.radiuses, result_1->radiuses);
CHECK_EQUAL_RANGE(reference_1.coordinates, result_1->coordinates);
@@ -146,25 +146,26 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
BOOST_CHECK_EQUAL(reference_2.alternatives, result_2->alternatives);
BOOST_CHECK_EQUAL(reference_2.geometries, result_2->geometries);
BOOST_CHECK_EQUAL(reference_2.overview, result_2->overview);
CHECK_EQUAL_RANGE(reference_2.uturns, result_2->uturns);
BOOST_CHECK_EQUAL(reference_2.uturns, result_2->uturns);
CHECK_EQUAL_RANGE(reference_2.bearings, result_2->bearings);
CHECK_EQUAL_RANGE(reference_2.radiuses, result_2->radiuses);
CHECK_EQUAL_RANGE(reference_2.coordinates, result_2->coordinates);
std::vector<boost::optional<bool>> uturns_3 = {true, false, boost::none};
engine::api::RouteParameters reference_3{
false, false, engine::api::RouteParameters::GeometriesType::GeoJSON,
engine::api::RouteParameters::OverviewType::False, uturns_3};
engine::api::RouteParameters reference_3{false,
false,
engine::api::RouteParameters::GeometriesType::GeoJSON,
engine::api::RouteParameters::OverviewType::False,
true};
reference_3.coordinates = coords_1;
auto result_3 = api::parseParameters<engine::api::RouteParameters>(
"1,2;3,4?steps=false&alternatives=false&geometries=geojson&overview=false&uturns=true;"
"1,2;3,4?steps=false&alternatives=false&geometries=geojson&overview=false&uturns=true"
"false;");
BOOST_CHECK(result_3);
BOOST_CHECK_EQUAL(reference_3.steps, result_3->steps);
BOOST_CHECK_EQUAL(reference_3.alternatives, result_3->alternatives);
BOOST_CHECK_EQUAL(reference_3.geometries, result_3->geometries);
BOOST_CHECK_EQUAL(reference_3.overview, result_3->overview);
CHECK_EQUAL_RANGE(reference_3.uturns, result_3->uturns);
BOOST_CHECK_EQUAL(reference_3.uturns, result_3->uturns);
CHECK_EQUAL_RANGE(reference_3.bearings, result_3->bearings);
CHECK_EQUAL_RANGE(reference_3.radiuses, result_3->radiuses);
CHECK_EQUAL_RANGE(reference_3.coordinates, result_3->coordinates);
@@ -180,7 +181,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
true,
engine::api::RouteParameters::GeometriesType::Polyline,
engine::api::RouteParameters::OverviewType::Simplified,
std::vector<boost::optional<bool>>{},
boost::optional<bool>{},
coords_1,
hints_4,
std::vector<boost::optional<double>>{},
@@ -196,7 +197,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
BOOST_CHECK_EQUAL(reference_4.alternatives, result_4->alternatives);
BOOST_CHECK_EQUAL(reference_4.geometries, result_4->geometries);
BOOST_CHECK_EQUAL(reference_4.overview, result_4->overview);
CHECK_EQUAL_RANGE(reference_4.uturns, result_4->uturns);
BOOST_CHECK_EQUAL(reference_4.uturns, result_4->uturns);
CHECK_EQUAL_RANGE(reference_4.bearings, result_4->bearings);
CHECK_EQUAL_RANGE(reference_4.radiuses, result_4->radiuses);
CHECK_EQUAL_RANGE(reference_4.coordinates, result_4->coordinates);
@@ -208,7 +209,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
true,
engine::api::RouteParameters::GeometriesType::Polyline,
engine::api::RouteParameters::OverviewType::Simplified,
std::vector<boost::optional<bool>>{},
boost::optional<bool>{},
coords_1,
std::vector<boost::optional<engine::Hint>>{},
std::vector<boost::optional<double>>{},
@@ -220,7 +221,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
BOOST_CHECK_EQUAL(reference_5.alternatives, result_5->alternatives);
BOOST_CHECK_EQUAL(reference_5.geometries, result_5->geometries);
BOOST_CHECK_EQUAL(reference_5.overview, result_5->overview);
CHECK_EQUAL_RANGE(reference_5.uturns, result_5->uturns);
BOOST_CHECK_EQUAL(reference_5.uturns, result_5->uturns);
CHECK_EQUAL_RANGE(reference_5.bearings, result_5->bearings);
CHECK_EQUAL_RANGE(reference_5.radiuses, result_5->radiuses);
CHECK_EQUAL_RANGE(reference_5.coordinates, result_5->coordinates);
@@ -238,7 +239,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
BOOST_CHECK_EQUAL(reference_6.alternatives, result_6->alternatives);
BOOST_CHECK_EQUAL(reference_6.geometries, result_6->geometries);
BOOST_CHECK_EQUAL(reference_6.overview, result_6->overview);
CHECK_EQUAL_RANGE(reference_6.uturns, result_6->uturns);
BOOST_CHECK_EQUAL(reference_6.uturns, result_6->uturns);
CHECK_EQUAL_RANGE(reference_6.bearings, result_6->bearings);
CHECK_EQUAL_RANGE(reference_6.radiuses, result_6->radiuses);
CHECK_EQUAL_RANGE(reference_6.coordinates, result_6->coordinates);