Compare commits

...

450 Commits

Author SHA1 Message Date
Dennis Luxen d42772a261 bump variant dependency 2014-10-20 16:02:26 +02:00
Dennis Luxen c1136099a9 fix link order to make symbol available in libosrm 2014-10-20 13:26:51 +02:00
Dennis Luxen 06f8a975c0 prevent double compile of dependent compile units 2014-10-20 13:04:44 +02:00
Dennis Luxen c8cd8775f6 Merge branch 'develop' of github.com:Project-OSRM/osrm-backend into develop 2014-10-20 12:54:12 +02:00
Dennis Luxen f9900c91bd Merge branch 'alex85k-mingw-support' into develop 2014-10-20 12:53:09 +02:00
Dennis Luxen accaf6e77e Merge branch 'mingw-support' of https://github.com/alex85k/Project-OSRM into alex85k-mingw-support 2014-10-20 12:52:45 +02:00
Dennis Luxen 8490e297a9 add todo marker 2014-10-20 11:39:23 +02:00
Dennis Luxen 6d3a4b5f6c deactivate inactive includes 2014-10-20 11:25:50 +02:00
Dennis Luxen 1f36206f45 replace boost::get<> call with proper function call to mapbox::variant 2014-10-20 11:25:34 +02:00
Dennis Luxen 952e10936c rename variable 2014-10-20 10:58:45 +02:00
Dennis Luxen 2b3093a687 reformat file according to guidelines 2014-10-20 10:32:57 +02:00
Dennis Luxen d7e25772b0 remove left-over boost::noncopyable and replace by c++11 ctor deletes. 2014-10-20 10:20:58 +02:00
Dennis Luxen c66c9b0353 Merge branch 'alex85k-warning-fix' into develop 2014-10-20 10:13:36 +02:00
alex85k bbde0d75da remove unused variable in Windows code 2014-10-18 19:19:26 +06:00
alex85k c3aec4f627 do not use gcc-ar for MinGW 4.9 2014-10-18 19:13:46 +06:00
alex85k 113852eed4 use math defines on Mingw 2014-10-18 18:47:17 +06:00
Dennis Luxen 6b9b2c1468 Merge pull request #1231 from Project-OSRM/testing/smarter_caching
smarter caching of test files
2014-10-17 15:59:08 +02:00
Emil Tin 2c87b295ff add raketask for clearing test cache files 2014-10-17 15:13:06 +02:00
Emil Tin 93767d68f8 remove debug output 2014-10-17 15:07:56 +02:00
Emil Tin cc3646ca16 fix tests that use {base} expansion 2014-10-17 15:07:56 +02:00
Emil Tin 48333f73d5 rename rather than copy then when possible 2014-10-17 15:07:56 +02:00
Emil Tin 1f4241a63d smarter caching of test files 2014-10-17 15:07:56 +02:00
Dennis Luxen 8eccfaa034 fix a number of implicit conversions 2014-10-17 14:19:33 +02:00
Dennis Luxen 438d1af12a fix implicit type conversios 2014-10-17 13:03:49 +02:00
Dennis Luxen 5be6ef380f replace shared_ptr instances to make intent of single owner more obvious 2014-10-17 12:35:53 +02:00
Dennis Luxen 76419ed2fc remove unneeded member variable 2014-10-17 12:32:18 +02:00
Dennis Luxen 4684921e51 fix implicit casts 2014-10-17 12:31:02 +02:00
Dennis Luxen edd8caa2bf compile Fingerprint only once 2014-10-17 12:30:11 +02:00
Dennis Luxen cb5575ae89 remove compile-time time stamps, rely on git SHA instead, fixes #1229 2014-10-17 10:57:00 +02:00
Dennis Luxen 42e726dec5 reformat according to styleguide 2014-10-16 17:49:10 +02:00
Dennis Luxen e3d33aa171 add const keywords where possible 2014-10-16 17:43:05 +02:00
Dennis Luxen f2ceeb35da fixes issue #1167, odd routing instructions
- the turn angle for compressed edges was not computed from the uncompressed geometry
- for a given turn (a,b,c) the last compressed node for edge (a,b) and the first packed node for (b,c) is returned
- adds a cucumber test to guard against regression
2014-10-16 15:58:58 +02:00
Dennis Luxen 577cf5ddc4 retrieve first and last nodes of a compressed segment 2014-10-16 15:42:33 +02:00
Dennis Luxen 91ced39233 replace shared_ptrs with std::unique_ptr<> in Prepare 2014-10-16 12:10:43 +02:00
Dennis Luxen 4b6cb0b8b8 replace raw ptrs with std::unique_ptr<> in Prepare 2014-10-16 12:10:12 +02:00
Dennis Luxen fb81302382 fix typo: Lunux->Linux 2014-10-16 11:52:16 +02:00
Dennis Luxen dfc81f65ee Merge pull request #889 from Project-OSRM/experimental/cuke_datastore
use osrm-datastore for testing, keep osrm-routed runnning
2014-10-15 15:41:38 +02:00
Dennis Luxen 909db4c861 replace inline with anonynmous namespace to avoid duplicate symbols during linking 2014-10-15 15:15:40 +02:00
Dennis Luxen 4277eed1b6 Revert "remove whitespace from package description"
This reverts commit 6f5703a5fe.
2014-10-15 13:21:42 +02:00
Dennis Luxen 6f5703a5fe remove whitespace from package description 2014-10-15 12:55:40 +02:00
Dennis Luxen f7469f298d add a tail to the oneway circle to avoid edge cases 2014-10-15 11:33:43 +02:00
Dennis Luxen b29d5df7a2 simplify conditional operation, remove useless parantheses 2014-10-15 10:43:58 +02:00
Dennis Luxen 549ba65861 catch a number of uncaught exceptions 2014-10-15 10:23:48 +02:00
Dennis Luxen a9d99cbe54 fix inverted logic 2014-10-14 18:03:24 +02:00
Emil Tin 8438024370 avoid unnessecary process check 2014-10-14 16:05:06 +02:00
Dennis Luxen e6a00ddcfd rethrow exception, refactor default block in fully covered switch statement 2014-10-14 15:59:18 +02:00
Emil Tin 71b967d243 test both datastore and direct data load 2014-10-14 15:35:14 +02:00
Dennis Luxen 1fc1e9590a throw an exception instead of false asserts 2014-10-14 12:52:11 +02:00
Dennis Luxen 0a0099fb41 rename variable, break long lines 2014-10-14 12:49:50 +02:00
Dennis Luxen b890d394ad Add range based CRC32 computation for iterable objects 2014-10-13 18:18:15 +02:00
Dennis Luxen a7fd37ae76 make Descriptor classes final 2014-10-13 18:17:24 +02:00
Dennis Luxen 41fafae21d mark Plugin classes as final 2014-10-13 17:29:53 +02:00
Dennis Luxen a38c007f51 throw instead of assert(false) 2014-10-13 17:20:34 +02:00
Dennis Luxen c7ee402b0e make link tests less brittle, no overlapping paths 2014-10-13 14:56:17 +02:00
Dennis Luxen 1c19796e3e fix container.hpp to properly use std::next and std::end 2014-10-13 13:54:40 +02:00
Emil Tin 76fb0cb965 get process handling up to date 2014-10-13 11:19:49 +02:00
Dennis Luxen 23c79f5cc9 reformat StaticRTreeBench.cpp 2014-10-13 11:15:22 +02:00
Emil Tin 14eac50261 remove datastore test 2014-10-13 11:10:40 +02:00
Emil Tin cf3eae1c91 disable failing test 2014-10-13 10:58:03 +02:00
Emil Tin db06cdb4ce adjust datastore testing 2014-10-13 10:58:03 +02:00
Emil Tin 7ba8e51fa9 use osrm-database during testing 2014-10-13 10:58:03 +02:00
Dennis Luxen bc6466cc36 fix test to inlcude renamed headers 2014-10-13 09:45:07 +02:00
Dennis Luxen 4fbefaef9a catch an uncaught exception and give git revision in springclean tool 2014-10-13 09:42:47 +02:00
Dennis Luxen be11d3325d add mutex include 2014-10-10 19:38:59 +02:00
Dennis Luxen 274140d309 refactor SimpleLogger into simple_logger compile unit 2014-10-10 19:32:49 +02:00
Dennis Luxen ed960ccc8d refactor angle computation into class/compile unit 2014-10-10 18:47:28 +02:00
Dennis Luxen f2b72113c1 refactor ContainerUtil into container.hpp 2014-10-10 18:24:13 +02:00
Dennis Luxen 67a8d30e87 renamed file 2014-10-10 18:19:10 +02:00
Dennis Luxen dafd0e5db7 rewrite NumericUtils into floating_point.hpp 2014-10-10 18:18:56 +02:00
Dennis Luxen d6d10cbf06 reformat Coordinate class 2014-10-10 18:00:09 +02:00
Dennis Luxen 3d3ba86be4 Merge pull request #1212 from Project-OSRM/fix_997
implements and fixes #997: support base path for c'tor
2014-10-10 17:17:41 +02:00
Dennis Luxen 52ed8a7ed0 move springclean functionality in its own tools, remove from datastore 2014-10-10 16:55:24 +02:00
Dennis Luxen 9449c99e25 enable partitioning on LTO, good riddance GCC 4.7 2014-10-10 10:46:43 +02:00
Dennis Luxen 4c0846734e rework the population and checking of base paths 2014-10-10 10:41:06 +02:00
Dennis Luxen 4c64f5fe62 remove shared memory indicator member, use unique_ptr for barriers 2014-10-10 10:41:06 +02:00
Dennis Luxen 9455ea0547 fix initialization of use_shared_memory 2014-10-10 10:41:06 +02:00
Dennis Luxen c3b54a63c3 remove ServerPaths member from OSRM_impl. pass it by value to c'tor 2014-10-10 10:41:06 +02:00
Dennis Luxen b9e1d3116c implements and fixes #997
- ServerPaths object can be populated by passing base path to OSRM
- reduces code/functionality duplication in node-OSRM
2014-10-10 10:41:05 +02:00
Dennis Luxen 5bb7e62a7c fix test on 'some' Intel FPU 2014-10-10 10:36:24 +02:00
Dennis Luxen a443f3a0bb add barrier checkpoint to the white list of passable tags 2014-10-10 10:34:34 +02:00
Dennis Luxen 440244eed8 use double precision fp math for mercartor projection and point-line projections (for now), fixes #1191 2014-10-09 18:58:58 +02:00
Dennis Luxen 2b9e25300f disable checking for empty data sets to make tests pass in debug mode, #889 2014-10-09 17:27:41 +02:00
Dennis Luxen de264dbf94 untangle includes 2014-10-09 14:08:12 +02:00
Dennis Luxen 848b773e24 fix reloading of RTree from shared memory, potentially fixes a number of issue from #889 2014-10-08 19:20:15 +02:00
Dennis Luxen d92f022041 remove implicit inline keyword from header files 2014-10-08 14:47:51 +02:00
Dennis Luxen 57fab61789 move casts from/to string into static class 2014-10-08 14:47:22 +02:00
Dennis Luxen ec8f977ebe reformat StringUtil.h 2014-10-08 12:48:20 +02:00
Dennis Luxen 8dc85e7641 use C++11 type traits to reduce code size in integral->string conversion 2014-10-08 12:40:56 +02:00
Dennis Luxen 4e00ebcd74 Merge pull request #1211 from Project-OSRM/fix_1173
Fix and close #1173
2014-10-08 11:44:48 +02:00
Dennis Luxen 335e719b5d pick compressed edge-weights in correct order 2014-10-08 11:01:58 +02:00
Dennis Luxen 415f8ef2d8 add test-case for bug 2014-10-08 11:01:33 +02:00
Dennis Luxen 17615d1d4a Merge pull request #1209 from Project-OSRM/test/links
test link speeds
2014-10-07 18:08:23 +02:00
Emil Tin 5072252c72 test link speeds 2014-10-07 17:05:39 +02:00
Dennis Luxen 46e93770c9 Merge pull request #1208 from Project-OSRM/feature/surfaces
surface, tracktype, smoothness tags in car profile, closes #955, #1208, #389.
2014-10-07 15:11:55 +02:00
Emil Tin fe43734811 use nil for unlimited surface speeds 2014-10-07 13:50:53 +02:00
Emil Tin 0df81c49d5 surface, tracktype, smoothness tags in car profile 2014-10-07 10:43:47 +02:00
Dennis Luxen 5653516b32 traverse *_link roads at a significantly lower speed than the main link, fixes #1174 2014-10-06 13:42:30 +02:00
Dennis Luxen 22da5be08e Merge branch 'frodrigo-develop' into develop 2014-10-06 09:43:11 +02:00
Dennis Luxen 862656aecc Merge branch 'develop' of https://github.com/frodrigo/osrm-backend into frodrigo-develop 2014-10-06 09:42:55 +02:00
Frédéric Rodrigo ec119a6d52 Add test for maxspeed like 'countrycode:zone type' for car profile 2014-10-04 21:17:18 +02:00
Frédéric Rodrigo 6b98b5f4c7 Parse maxspeed value like FR:urban on car profile 2014-10-04 14:12:14 +02:00
Dennis Luxen 5effe95f2c reformat JSONContainer.h 2014-10-03 11:13:50 +02:00
Dennis Luxen f22e3fd3ff mark Renderer c'tors in JSONContainer as explicit 2014-10-03 11:02:28 +02:00
Dennis Luxen 0047040af9 encapsulate base64 encoding into class to remove static functions from global namespace 2014-10-03 10:38:37 +02:00
Dennis Luxen 60987e6b9b mark c'tors explicit 2014-10-03 10:27:24 +02:00
Dennis Luxen 27d5e2b219 fix include order 2014-10-03 10:23:21 +02:00
Dennis Luxen 53fd0c3a55 fix initialization of EdgeBasedGraphFactory 2014-10-03 10:21:15 +02:00
Dennis Luxen 63456a6d4f fix position of include guard 2014-10-03 10:19:45 +02:00
Dennis Luxen d4cd3c2f7b remove superflous include 2014-10-03 10:17:02 +02:00
Dennis Luxen dbf7137a1a fix include guard name 2014-10-03 10:15:03 +02:00
Dennis Luxen 785891c315 fix name of include guard 2014-10-03 10:03:44 +02:00
Dennis Luxen b7417ec954 fix name of include guard 2014-10-03 10:02:36 +02:00
Dennis Luxen 61b861f0e5 fix name of include guard 2014-10-03 10:01:24 +02:00
Dennis Luxen 0fea0738bf remove superflous inline keyword 2014-10-03 09:59:04 +02:00
Dennis Luxen 4f25d29815 use nullptr instead of NULL 2014-10-03 09:56:07 +02:00
Dennis Luxen 28302a5040 unique_ptr<T> should be unique_ptr<T[]> when used with array 2014-10-02 19:26:57 +02:00
Dennis Luxen 9cc5ca5c58 fix name of include guard 2014-10-02 19:24:43 +02:00
Dennis Luxen 4c4e60b3c9 fix name of include guard 2014-10-02 19:24:06 +02:00
Dennis Luxen 5689a96602 make c'tors of Descriptors explicit 2014-10-02 19:22:02 +02:00
Dennis Luxen 8b57db467a move c'tor should not take const argument 2014-10-02 19:19:52 +02:00
Dennis Luxen 50339e53e2 rename variable across all ifdef paths 2014-09-30 14:52:16 +02:00
Dennis Luxen bc9f5189a5 use irange based for loop in DouglasPeucker run 2014-09-30 14:42:55 +02:00
Dennis Luxen fee83fee40 rename short variable and reformat, OCLint 2014-09-30 14:30:15 +02:00
Dennis Luxen cd5112ab0e rename short variable, OCLint 2014-09-30 14:28:00 +02:00
Dennis Luxen a43b88f9a2 reformat 2014-09-30 14:22:11 +02:00
Dennis Luxen c20fd5dcaa fix short variable name, OCLint 2014-09-30 14:21:24 +02:00
Dennis Luxen f12e296c09 fix short variable name, OCLint 2014-09-30 14:19:49 +02:00
Dennis Luxen 9c3a572646 link unlocking tool against Threads 2014-09-29 16:59:09 +02:00
Dennis Luxen 6175faa9a4 Merge pull request #1202 from Project-OSRM/fix_1192
Fix and close #1192
2014-09-29 12:27:52 +02:00
Dennis Luxen af02fc6bbe add tests for ferry durations 2014-09-29 11:44:51 +02:00
Dennis Luxen cc0bbc42a2 add duration to backward speed, fixes #1192 2014-09-29 11:37:36 +02:00
Dennis Luxen fd747c7340 propagate Lua include dir when compile-checking Luabind, fixes #1196 2014-09-25 12:58:23 +02:00
Dennis Luxen bd33202972 make routing algorithm classes final 2014-09-24 16:03:52 +02:00
Dennis Luxen f6f0de0e38 pimpl OSRM lib with std::unique_ptr 2014-09-24 13:17:55 +02:00
Dennis Luxen 881041800b remove superflous include 2014-09-23 09:41:28 +02:00
Dennis Luxen 11f3ac16f6 add some formatting 2014-09-23 09:41:10 +02:00
Dennis Luxen 969bf95230 Merge pull request #1194 from Project-OSRM/better_luabind_check
better checking for luabind compilation, fixes some OSX woes
2014-09-19 17:08:39 +02:00
Dennis Luxen abc6b4180c better checking for luabind compilation, fixes some OSX woes 2014-09-19 16:33:24 +02:00
Dennis Luxen f74d762a92 Merge branch 'alex85k-luabind-check' into develop 2014-09-19 09:57:56 +02:00
Dennis Luxen f00892ed66 Merge branch 'luabind-check' of https://github.com/alex85k/Project-OSRM into alex85k-luabind-check 2014-09-19 09:57:43 +02:00
alex85k f14c6e6845 Auto-detect Lua compatible with installed Luabind 2014-09-18 23:34:51 +06:00
Dennis Luxen b1bbf2ef84 add relational operators 2014-09-18 11:10:23 +02:00
Dennis Luxen 201062cade make width of computation depend on base type, i.e. if its 64bit then use 64bit math 2014-09-18 10:19:40 +02:00
Dennis Luxen 8cb9198bcf allow a 64bit base type 2014-09-18 09:43:11 +02:00
Dennis Luxen f5e53c0452 make cast operators explicit 2014-09-18 09:42:38 +02:00
Dennis Luxen 41d9c00f70 FixedPointNumber implementation 2014-09-17 19:20:15 +02:00
Dennis Luxen b52f392c92 Merge branch 'srajkovic-stefan-rajkovic-multiple-nearest-points' into develop 2014-09-16 12:33:06 +02:00
Dennis Luxen efaa3b5ab2 Merge branch 'stefan-rajkovic-multiple-nearest-points' of https://github.com/srajkovic/osrm-backend into srajkovic-stefan-rajkovic-multiple-nearest-points
Conflicts:
	DataStructures/RouteParameters.cpp
	Server/APIGrammar.h
2014-09-16 12:32:40 +02:00
Dennis Luxen 36f3d8d6ac Merge pull request #1187 from Project-OSRM/upgrade_protobuf_appveyor
2nd try: upgrade to protobuf 2.5.0 on appveyor
2014-09-15 20:10:57 +02:00
Dennis Luxen e469afa4a9 upgrade to protobuf 2.5.0 on appveyor 2014-09-15 16:21:37 +02:00
Dennis Luxen 9d4b0caa5b fix #1181, uncompressed geometries regressed into array of strings 2014-09-15 14:27:27 +02:00
Dennis Luxen 392c07951e some renaming of member functions to remove ambiguity 2014-09-15 14:23:43 +02:00
Dennis Luxen 8e72c3d81e Merge pull request #1184 from Project-OSRM/cmake_object_library
use object libraries in cmake, bump cmake to 2.8.8+
2014-09-15 13:15:12 +02:00
Dennis Luxen 02428f1e06 add object library to benchmarks 2014-09-15 12:21:13 +02:00
Dennis Luxen b3aa513563 manually install cmake on Travis 2014-09-15 12:14:32 +02:00
Dennis Luxen b8b08cb114 use object libraries in cmake, bump cmake to 2.8.8+ 2014-09-15 11:34:55 +02:00
Dennis Luxen ebbbf1059d Revert "disable LUA 5.2", cf. #1179
This reverts commit 994bd0a910.
2014-09-15 10:24:44 +02:00
Dennis Luxen 37297076f8 Merge pull request #1177 from joto/patch-3
Add object_types to some tags.
2014-09-07 23:15:03 +02:00
Jochen Topf a75b2df6fe Add object_types to some tags.
The newest taginfo understand an `object_types` field to restrict the key/value to certain types of OSM objects.
2014-09-07 20:39:56 +02:00
Dennis Luxen 9ccd0f0282 bump variant version 2014-09-04 16:19:00 +02:00
Dennis Luxen e57d9f2e2e Merge pull request #1157 from Project-OSRM/fix/spelling_of_edge
fix spelling of 'edge'
2014-08-31 11:25:56 +02:00
Emil Tin cf593ba9f9 fix spelling of edge in SharedDataFacade 2014-08-31 09:09:12 +02:00
Dennis Luxen 9eb862a6a4 Merge pull request #1172 from joto/patch-2
Update taginfo.json
2014-08-25 22:07:08 +02:00
Jochen Topf bc84e08da5 Update taginfo.json 2014-08-25 21:55:07 +02:00
Dennis Luxen 24dae2f096 fix URL 2014-08-22 10:43:25 +02:00
Dennis Luxen ab24d6bd96 add JSON file for taginfo analysis 2014-08-22 10:42:43 +02:00
Dennis Luxen 7782c80c4f implement missing loading of TravelMode vector into shared memory 2014-08-22 10:31:47 +02:00
Dennis Luxen 994bd0a910 disable LUA 5.2 2014-08-22 10:31:47 +02:00
Stefan Rajkovic bc9dcba4d4 Removed unnecessary whitespace 2014-08-21 13:24:04 -04:00
Dennis Luxen 85c244ed08 Merge pull request #1166 from Project-OSRM/server_instance_unique_ptr
keep server instance in a shared_ptr
2014-08-21 19:22:37 +02:00
Stefan Rajkovic 495196193c Uses range based check for number of results 2014-08-21 13:19:05 -04:00
Stefan Rajkovic def1e5e1d8 Set restrictions on number of results possible, so 0 < number <= 100. 2014-08-21 13:15:13 -04:00
Dennis Luxen 2727091e47 Merge pull request #1154 from Project-OSRM/feature/travel_mode
travel mode, closes #569, #603 and #606. Great job!
2014-08-21 15:12:02 +02:00
Dennis Luxen d7fbd416ba fix expected values of backward speed in test 2014-08-21 12:18:19 +02:00
Dennis Luxen 6a09ce1613 fix comparison in car speed profile 2014-08-21 12:17:03 +02:00
Emil Tin 774e6346e7 more robust check for parsed ways 2014-08-20 17:10:40 +02:00
Dennis Luxen 05b939760c Revert "use more osrm::irange"
This reverts commit d6c6fbfe03.
2014-08-20 15:47:48 +02:00
Dennis Luxen d6c6fbfe03 use more osrm::irange 2014-08-20 15:34:10 +02:00
Dennis Luxen bb3cbf2dda fix indentation, remove superflous else clause 2014-08-20 14:01:40 +02:00
Dennis Luxen 39d96a45aa fix lambda syntax 2014-08-20 12:14:31 +02:00
Dennis Luxen 6a8c5c8869 fix typo 2014-08-20 11:57:46 +02:00
Dennis Luxen 96318bbe11 switch from unique to shared ptr 2014-08-20 11:57:31 +02:00
Emil Tin 00dd2463fd use lambda to decide turn value 2014-08-20 11:48:47 +02:00
Emil Tin bcd55626ef make accessors const, add comments 2014-08-20 11:37:47 +02:00
Dennis Luxen 8f8cb6a52f keep server instance in a unique_ptr 2014-08-20 11:24:29 +02:00
Emil Tin 2e3d33dfcd remove type from more structs, remove asserts 2014-08-20 11:08:59 +02:00
Emil Tin 1e40cd6f0b remove type assertion 2014-08-20 11:08:59 +02:00
Emil Tin 6e2608b2f2 fix cuke support file 2014-08-20 11:08:59 +02:00
Emil Tin 60d80cf261 code style fixes 2014-08-20 11:08:59 +02:00
Emil Tin 9c23fd4a31 remove accidentially added file 2014-08-20 11:08:59 +02:00
Emil Tin fccb1aad32 remove type attribute 2014-08-20 11:08:59 +02:00
Emil Tin 2780ff31b5 fix bug with mode of 1st instruction 2014-08-20 11:08:59 +02:00
Emil Tin c37c8dc21d add mode test 2014-08-20 11:08:59 +02:00
Emil Tin 6ee7a81f10 update foot profile, add ferry mode 2014-08-20 11:08:58 +02:00
Emil Tin 3d94638d86 update car profile, add ferry mode 2014-08-20 11:08:58 +02:00
Emil Tin 418ff95543 fix initialization order 2014-08-20 11:08:58 +02:00
Emil Tin 221113cbb7 fix assert 2014-08-20 11:08:58 +02:00
Emil Tin 13ea12cf6e fix unit test 2014-08-20 11:08:58 +02:00
Dennis Luxen 1945aae4dc reorder members of SegmentInformation, remove bit fields where possible 2014-08-20 11:08:58 +02:00
Emil Tin 30362cfc0c update lua interface to speed and mode 2014-08-20 11:08:58 +02:00
Emil Tin 6cdc590db5 typedef instead of enum for TravelMode to avoid gcc warnings 2014-08-20 11:08:58 +02:00
Emil Tin eb122a2b8c tidy feature file 2014-08-20 11:08:58 +02:00
Emil Tin feaf8711d3 announce mode changes 2014-08-20 11:08:58 +02:00
Emil Tin 6e364ff0ba rename travel mode None to Inaccessible 2014-08-20 11:08:58 +02:00
Emil Tin 6f6aff7493 remove direction field from ExtractionWay 2014-08-20 11:08:58 +02:00
Emil Tin 207cddd50b use enum for TravelMode 2014-08-20 11:08:58 +02:00
Emil Tin 35988d8f09 fix problem with mode of first instruction 2014-08-20 11:08:42 +02:00
Emil Tin bea63028c7 remove bitfield from SegmentInformation, works around compile err 2014-08-20 11:08:42 +02:00
Emil Tin 0244060806 add a few tests 2014-08-20 11:08:42 +02:00
Emil Tin bfdc296f43 reduce failing test 2014-08-20 11:08:42 +02:00
Emil Tin 8e625a5d07 rename test 2014-08-20 11:08:42 +02:00
Emil Tin 3460bd0ba9 fix problems with mode, 1 failing test left 2014-08-20 11:08:42 +02:00
Emil Tin 4dd0377eb8 fix compilation of tests 2014-08-20 11:08:42 +02:00
Emil Tin 6e1ab9fe3a profile fixes 2014-08-20 11:08:42 +02:00
Emil Tin 7a2d214cc4 reactivate assert of sizeof(NodeBasedEdgeData) 2014-08-20 11:08:42 +02:00
Emil Tin 62495a6de4 remove comment 2014-08-20 11:08:42 +02:00
Emil Tin 8ea88468f3 remove unneeded methods 2014-08-20 11:08:42 +02:00
Emil Tin 687892890b remove spurious comment 2014-08-20 11:08:42 +02:00
Emil Tin ff0dfacc48 fix initialization order to avoid compiler warning 2014-08-20 11:08:42 +02:00
Emil Tin 235a52032a more tests passing 2014-08-20 11:08:42 +02:00
Emil Tin a5ee7e78f6 fixes 2014-08-20 11:08:41 +02:00
Emil Tin 181dbe8493 improve tests for travel mode 2014-08-20 11:08:41 +02:00
Emil Tin dae9c9a7ed use 4 bits for travel mode 2014-08-20 11:08:41 +02:00
Emil Tin 6d6d299ea4 most tests passing 2014-08-20 11:08:41 +02:00
Emil Tin 6fd615b9cd first cut at porting travel mode, some tests fail 2014-08-20 11:08:41 +02:00
Emil Tin d09394ed52 add failing tests for travel mode 2014-08-20 11:08:41 +02:00
Emil Tin 3e6f27d173 rename contra_flow to travel_mode, use unsigned char 2014-08-20 11:08:41 +02:00
Dennis Luxen 82c2ae5441 first round of replacing deprecated typedefs with much nicer using statements 2014-08-19 13:01:38 +02:00
Dennis Luxen 7edf2bb2c2 Merge pull request #1164 from Project-OSRM/appveyor_nuget
Install protoc on both Travis and AppVeyor.
2014-08-19 11:00:23 +02:00
Dennis Luxen c9607b99a3 install protoc thru nuget 2014-08-19 10:11:32 +02:00
Dennis Luxen 2fe1a84dd4 adding protobuf compiler to dependencies, used in branches 2014-08-19 09:56:49 +02:00
Dennis Luxen c63218a889 add final/override keyword where possible to help compiler de-virtualize function calls 2014-08-18 10:19:33 +02:00
Dennis Luxen 5efa9664db Revert "fixing line endings"
This reverts commit dc75469e78.
2014-08-15 18:53:00 +02:00
Dennis Luxen dc75469e78 fixing line endings 2014-08-15 18:47:26 +02:00
Dennis Luxen 9d1e21b5ad Merge pull request #1104 from Project-OSRM/experimental/mapbox_variant
Experimental/mapbox variant
2014-08-14 18:57:53 +02:00
Dennis Luxen 27a367c733 enter build directory before calling tests 2014-08-14 17:29:11 +02:00
Dennis Luxen ffa0ace2a7 build tests by running msbuild on tests project file 2014-08-14 17:29:10 +02:00
Dennis Luxen 074e1e992c build test target explicitly on AppVeyor 2014-08-14 17:29:10 +02:00
Dennis Luxen cdd72c7e56 fast forward variant lib 2014-08-14 17:29:10 +02:00
Dennis Luxen a5e99a95a3 remove constexpr workaround as minimum req. is now Nov 2013 CTP 2014-08-14 17:29:10 +02:00
Dennis Luxen 1de736019d make canary static const instead of constexpr 2014-08-14 17:29:10 +02:00
Dennis Luxen d6b2712070 make msbuild less verbose 2014-08-14 17:29:10 +02:00
Dennis Luxen eda8f4ccec make integer literals static const instead of constexpr 2014-08-14 17:29:10 +02:00
Dennis Luxen 7e3f476407 use 64bit cmake generator 2014-08-14 17:29:10 +02:00
Dennis Luxen e10f36d5f0 use explicit OSRM.sln filename 2014-08-14 17:29:10 +02:00
Dennis Luxen 1bfd9abda3 replace nmake by msbuild 2014-08-14 17:29:10 +02:00
Dennis Luxen 4a1a10fde8 use Nov 2013 CTP to build 2014-08-14 17:29:10 +02:00
Dennis Luxen 4c3cb76ced remove remnants of boost::variant 2014-08-14 17:29:10 +02:00
Dennis Luxen e2794e9f06 initial checkin of mapbox::util::variant 2014-08-14 17:29:10 +02:00
Dennis Luxen 7d2c627ad2 replace boost::variant w/ mapbox::util::variant 2014-08-14 17:29:10 +02:00
Dennis Luxen b310e0f718 apply some reformatting 2014-08-14 17:12:58 +02:00
Dennis Luxen 18915ae2bd make dummy __get_cpuid available on Windows 2014-08-14 17:12:58 +02:00
Dennis Luxen 5dbda8f519 refactoring of IteratorBasedCRC32, fixes #1140 2014-08-14 17:12:58 +02:00
Dennis Luxen 82ce9dfc04 reactivate software-based CRC32 on x64 platforms without SSE4.2 2014-08-14 17:12:57 +02:00
Dennis Luxen ad5cd564ab even more reformatting 2014-08-13 16:11:56 +02:00
Dennis Luxen 6f01f580ca fix several errors reported by OCLint:
- rename variable with short name
- fix inverted logic
- rename members in SpeedProfile
2014-08-13 11:02:36 +02:00
Dennis Luxen d5130d9fe4 reformatting DescriptionFactory.cpp 2014-08-13 11:02:36 +02:00
Dennis Luxen 0341a0d5e7 reformatting DescriptionFactory.cpp 2014-08-12 19:29:54 +02:00
Dennis Luxen 32191fb05a also build tests on Travis 2014-08-12 16:17:27 +02:00
Dennis Luxen 1592fe377a Merge pull request #1150 from Project-OSRM/feature/announce_via_locations
implements announcement of waypoints, closes #584
2014-08-12 11:49:51 +02:00
Dennis Luxen 5add28410f Adapt test cases to output of way points
- waypoints are now announced in the route guidance
- implements #584
2014-08-12 09:27:17 +02:00
Dennis Luxen d54a55c12b implements announcement of waypoints, closes #584 2014-08-11 20:29:15 +02:00
Dennis Luxen aab5e8430f ignore package related files 2014-08-11 16:16:56 +02:00
Dennis Luxen 2e20fdb462 allow building of packages 2014-08-11 16:16:56 +02:00
Dennis Luxen 2ac3da7a90 update minimum compiler to gcc 4.8, take 2 2014-08-11 09:42:29 +02:00
Dennis Luxen 399b79bab2 update minimum compiler to gcc 4.8 2014-08-11 09:39:35 +02:00
Stefan Rajkovic b9eb936cac Uses current JSON format if number of results requested is 1 2014-08-08 14:06:06 -04:00
Stefan Rajkovic 38117df11b Added ability to get multiple points from /nearest by using num_results argument 2014-08-08 13:58:30 -04:00
Dennis Luxen 27d729baf0 use a return value in Prepare::BuildEdgeExpandedGraph instead of parameter re-assignment 2014-08-08 13:00:39 +02:00
Dennis Luxen d408a64c8c rename variable to have a longer, more telling name in Prepare 2014-08-08 12:41:57 +02:00
Dennis Luxen 9aeb28066d fix inverted logic 2014-08-07 19:19:21 +02:00
Dennis Luxen 6fb7c8687e fixes #1107, turn restriction combination including overlaps and one-ways 2014-08-07 18:34:56 +02:00
Dennis Luxen d9666008e3 remove left-over debug output 2014-08-07 18:17:35 +02:00
Dennis Luxen e132230651 add some minor comments to Range 2014-08-07 17:39:53 +02:00
Dennis Luxen c2877a0c22 use std::shared_ptr instead of raw ptr 2014-08-07 13:40:43 +02:00
Dennis Luxen 251fc3ec68 apply some more constness 2014-08-07 12:02:57 +02:00
Dennis Luxen 287f0a3b68 minor edit 2014-08-07 12:01:32 +02:00
Dennis Luxen b03d9fe987 replace INT_MAX by proper typedef 2014-08-07 12:01:31 +02:00
Dennis Luxen 98372ef33f replace boost::irange in Tools 2014-08-05 18:06:15 +02:00
Dennis Luxen d00f4afb84 replace C limits with STL-defined and typedef'ed limits 2014-08-05 17:20:01 +02:00
Dennis Luxen d4bf02c882 replace boost integer range 2014-08-05 17:19:09 +02:00
Dennis Luxen 284e671163 add convenience class for integer range 2014-08-04 17:27:34 +02:00
Dennis Luxen 0f112e5c9d untangle includes 2014-08-04 13:23:37 +02:00
Dennis Luxen 759449b4be remove an unneeded check in JSONDescriptor 2014-08-01 15:59:45 +02:00
Dennis Luxen 9c03f919a3 Merge pull request #1138 from dmbreaker/fix/alter_route_end
Fixes alternative route end-point (http://imgur.com/ZQhwTZi)
2014-07-31 17:07:08 +02:00
Dennis Luxen c9afd9a281 make dummy date in generated test files valid 2014-07-31 16:41:38 +02:00
dmbreaker a999cb9db9 Fixes alternative route end-point (http://imgur.com/ZQhwTZi) 2014-07-31 16:10:02 +04:00
Dennis Luxen fdc5bd6195 add try catch, fixes coverity issues 1229132 and 1229133 2014-07-30 11:28:36 +02:00
Dennis Luxen e1d94eee21 Merge branch 'Zhdanovich-scc_develop' into develop 2014-07-30 09:42:55 +02:00
Kirill Zhdanovich 885f237217 Apply diff https://github.com/Project-OSRM/osrm-backend/pull/1133 to develop branch 2014-07-29 22:12:59 +02:00
Dennis Luxen 5860a4e28e clear external vector after use, closes #1131 2014-07-28 16:15:21 +02:00
Dennis Luxen 2bebed44ff use stxxl as external data store instead of hand-rolled code in /tmp 2014-07-28 15:58:50 +02:00
Dennis Luxen 4990e544cf add a distinct tool to check if hsgr file is valid, closes #1081 2014-07-28 14:51:33 +02:00
Dennis Luxen 8010506d4e remove reverted include 2014-07-28 14:20:17 +02:00
Dennis Luxen f2f7abb9a8 remove reverted include 2014-07-28 14:19:16 +02:00
Dennis Luxen 85f6ab869e Revert "let ServerFactory return unique ptr instead of raw ptr"
This reverts commit cc7c6b9ece.
2014-07-28 14:08:54 +02:00
Dennis Luxen fc87b0a11e enabling defaultctor for Server 2014-07-28 12:04:11 +02:00
Dennis Luxen 79bc071754 enabling default copy ctor for Server 2014-07-28 11:24:49 +02:00
Dennis Luxen 797243fc9c return unique ptr instead of raw ptr 2014-07-28 11:03:53 +02:00
Dennis Luxen cc7c6b9ece let ServerFactory return unique ptr instead of raw ptr 2014-07-28 10:15:22 +02:00
Dennis Luxen 279071e5bb re-add pairwise container traversal 2014-07-28 10:14:24 +02:00
Dennis Luxen 426374ff8a register all classes at once in LUA environment 2014-07-24 18:26:40 +02:00
Dennis Luxen 1508874ebc return early if way is not either highway=* or route=* in car profile. Estimated cost saving 10% 2014-07-24 18:00:37 +02:00
Dennis Luxen bbe440cacd fix implcit conversion in DynamicGraph 2014-07-24 11:29:03 +02:00
Dennis Luxen e647e73af9 fix implcit conversion in RestrictionMap 2014-07-24 11:25:43 +02:00
Dennis Luxen 696ddfde0e mark temporaries const 2014-07-24 11:23:33 +02:00
Dennis Luxen 37d6257524 fix implicit conversion in TemporaryStorage 2014-07-24 11:23:03 +02:00
Dennis Luxen faee894052 add a couple of consts to range based for loops 2014-07-24 10:15:04 +02:00
Dennis Luxen 61f16b8c5e remove code duplication 2014-07-24 09:56:20 +02:00
Dennis Luxen 85eb38e755 reformatting code according to guidelines 2014-07-23 19:28:04 +02:00
Dennis Luxen a87cf60dfc move common code into Util header 2014-07-23 19:25:09 +02:00
Dennis Luxen 3b135447f3 use typedef Edgeweight instead of raw int 2014-07-23 14:50:45 +02:00
Dennis Luxen 0c3713f7e5 Merge branch 'TheMarex-boost-test' into develop 2014-07-22 18:55:33 +02:00
Patrick Niklaus 4d0571fd73 Fix win32 linking and run test automatically in AppVayor 2014-07-22 18:23:43 +02:00
Patrick Niklaus 4722988bf0 Try including typedefs 2014-07-22 17:17:56 +02:00
Patrick Niklaus 61151535e6 Fix include in RangeTableTest 2014-07-22 17:17:56 +02:00
Patrick Niklaus bcff6c192c Remove template paramters and constexpr in test
Stops clang from complaining about non-constexpr.
2014-07-22 17:17:56 +02:00
Patrick Niklaus 020d0cfb49 Revert "Change StaticRTree serialization constructor to static function"
This makes clang 3.4 crash on ubuntu because it can not handle lambda
expressions + binding in static member functions correctly.

This reverts commit d6dd6693b18e042c0068da579dcc64d1e5a2e002.
2014-07-22 17:17:56 +02:00
Patrick Niklaus d38e3bd729 Add tests and benchmarks to appveyor 2014-07-22 17:17:56 +02:00
Patrick Niklaus 84a604f70b Add test for new GetMinDist 2014-07-22 17:17:56 +02:00
Patrick Niklaus 782baf54a3 Remove perpendicular distance call
Since we know that the MBB is axis aligned we can compute
the distance to the line segments a lot simpler.
2014-07-22 17:17:56 +02:00
Patrick Niklaus d754e4eeca Add benchmark for StaticRTree
Build with 'make benchmarks'
2014-07-22 17:17:56 +02:00
Patrick Niklaus db98f6191e Prepare alrady writes the correct number of nodes 2014-07-22 17:17:56 +02:00
Patrick Niklaus b453a42f77 Fixed perpendicular distance calculation of segment endpoint is on equator 2014-07-22 17:17:56 +02:00
Patrick Niklaus 2a6585e664 Add regression test for 'gap' querry bug 2014-07-22 17:17:56 +02:00
Patrick Niklaus bc013925b8 Consider points on the edge of the rectangle as inside 2014-07-22 17:17:56 +02:00
Patrick Niklaus 8108ecc4d3 Add test for StaticRTree 2014-07-22 17:17:56 +02:00
Patrick Niklaus 1c80584206 Fix GetMinDistance 2014-07-22 17:17:56 +02:00
Patrick Niklaus a3dd9c3e57 Change StaticRTree serialization constructor to static function
Since the constructor does not satisfy the requirements for a
constructor (the RTree is not properly initialized) make it a
static function instead.
2014-07-22 17:17:56 +02:00
Patrick Niklaus 8f05fc0a84 Make tuning constants template agruments in StaticRTree 2014-07-22 17:17:56 +02:00
Patrick Niklaus 3c4feecda0 Make fstream non-static and StaticRTree thread-specific instead 2014-07-22 17:17:56 +02:00
Patrick Niklaus e776a51c73 Added test for StaticGraph 2014-07-22 17:17:56 +02:00
Patrick Niklaus 129e8ef98a Fix small errors in StaticGraph 2014-07-22 17:17:56 +02:00
Patrick Niklaus 69134f6d6a Add test for RangeTable 2014-07-22 17:17:56 +02:00
Patrick Niklaus b32062f875 Fix typo in RangeTable 2014-07-22 17:17:56 +02:00
Patrick Niklaus 8d46ee85f1 Add test for BinaryHeap 2014-07-22 17:17:56 +02:00
Patrick Niklaus 9f9fde1f2b Fix missing include in BinaryHeap 2014-07-22 17:17:56 +02:00
Emil Tin 2b041e09ac tests uturn query param 2014-07-22 13:24:26 +02:00
Emil Tin 73b32bb45e enable setting query params in cuke tests 2014-07-22 13:24:26 +02:00
Dennis Luxen 11e6e74f09 fix implicit conversion 2014-07-22 12:56:24 +02:00
Dennis Luxen bf3e3f0c3d fix segfault when index into packed geometry ran out of bounds 2014-07-22 11:59:31 +02:00
Dennis Luxen 2656acc321 produce stack trace if script fails during setup. partially implements #1128 2014-07-21 15:46:19 +02:00
Dennis Luxen e46c9be79f dont fail if script does not define member 2014-07-21 15:44:57 +02:00
Dennis Luxen 507167d5c1 use 64bit int types to not lose precision in for loop counting variables 2014-07-21 13:14:05 +02:00
Dennis Luxen fc90162f69 fix typo, thx @joto, see #1126 2014-07-21 10:55:13 +02:00
Dennis Luxen 1e8fb7a38c Updated README to reflect new location 2014-07-21 10:50:41 +02:00
Dennis Luxen afb6c5a09d comparison between signed and unsigned integer expressions 2014-07-18 13:58:37 +02:00
Dennis Luxen 2255ab0a37 remove unneede include 2014-07-18 11:38:05 +02:00
Dennis Luxen a6ab042078 use parallel sorting for DeallocatingVector 2014-07-18 11:37:07 +02:00
Dennis Luxen 480f70c049 fix down-sizing in resize operation 2014-07-18 11:20:27 +02:00
Dennis Luxen 0592897859 rework assignment/copy operator, add operator[] to DeallocatingVector RA-iterator 2014-07-18 10:59:46 +02:00
Dennis Luxen d5a9f8e177 refactor DeallocatingVector, apply boost::iterator_facade 2014-07-17 18:26:14 +02:00
Dennis Luxen 5840829cdc refactor DeallocatingVector, apply boost::iterator_facade 2014-07-17 18:25:23 +02:00
Dennis Luxen fd0946b770 remove unneeded includes, fix variable names 2014-07-17 14:14:14 +02:00
Dennis Luxen 293b462fd2 add timing to SCC generation 2014-07-17 11:27:06 +02:00
Dennis Luxen 3db50fdd54 rename variables in SCC class, add const to variables, reformat 2014-07-17 11:16:26 +02:00
Dennis Luxen 1540e6518c rename variables in SCC class to be more legible 2014-07-17 11:07:35 +02:00
Dennis Luxen 8b30c13cd9 make sure edges are put into shapefile once and only once. 2014-07-17 10:48:30 +02:00
Dennis Luxen a7eb89b2f0 reformat SCC class, make sure road distances are not counted twice 2014-07-17 10:43:21 +02:00
Dennis Luxen 53c102e1e9 use boost::irange and range based for loop in // for (NodeID node = 0; node < last_node; ++node) 2014-07-17 10:30:56 +02:00
Dennis Luxen 7d90737921 remove zombie code from StronglyConnectedComponents.h 2014-07-17 10:27:47 +02:00
Dennis Luxen e281f88f2e remove zombie code from StronglyConnectedComponents.h 2014-07-17 10:27:23 +02:00
Dennis Luxen 16c5c7bbb4 set projection to EPSG:4326 for created shapefile 2014-07-17 10:26:27 +02:00
Dennis Luxen 7d4dfd87f1 add c'tor to TarjanEdgeData, use emplace_back in-place construction of edges 2014-07-17 10:25:39 +02:00
Dennis Luxen 6156bf0f9d make uturn parameter optional 2014-07-16 13:01:25 +02:00
Dennis Luxen ee1fdca52e implement path query with uturns at via nodes 2014-07-16 12:53:33 +02:00
Dennis Luxen 95b5bcbd49 add and parse U-turn parameters in servers APIGrammar 2014-07-16 12:48:11 +02:00
Dennis Luxen 0c529361a3 add member variable/functions to store information if uturns are allowed 2014-07-16 12:47:10 +02:00
Dennis Luxen 7110acc94f add initialization to QueryEdge::EdgeData 2014-07-16 09:44:09 +02:00
Dennis Luxen 1188002bcb downcast position explicitly to unsigned 2014-07-15 16:48:04 +02:00
Dennis Luxen b47a3f15ce fix initialization on Windows, i.e. cannot convert from bool to bool& 2014-07-15 15:37:30 +02:00
Dennis Luxen 695a2a2b6e use correctly sized 64bit integer and avoid unintended (implicit up/down casts) 2014-07-15 15:25:44 +02:00
Dennis Luxen c8b4ef3eed add two tests for turn restrictions starting/ending on the same segment 2014-07-15 15:10:13 +02:00
Dennis Luxen 6091248493 fix range initialization on Windows 2014-07-15 15:06:34 +02:00
Dennis Luxen 32fd507ad9 apply more emplace_backs and range based for loops to Contractor 2014-07-15 12:06:52 +02:00
Dennis Luxen 0ee77a37d1 make DynamicGraph::InputEdge c'tor variadic, forward args to EdgeData type 2014-07-15 11:50:08 +02:00
Dennis Luxen 05241544c5 make DeallocatingVector::emplace_back variadic and forward Args to contained element 2014-07-15 11:47:58 +02:00
Dennis Luxen 495c872489 add c'tors to QueryEdge and its EdgeData 2014-07-15 11:46:26 +02:00
Dennis Luxen 8c09edfdbd add minor reformatting 2014-07-15 11:42:27 +02:00
Dennis Luxen 67722cf788 make c'tor of DynamicGraph::InputEdge variadic to be more flexible against changing EdgeData types 2014-07-14 17:35:26 +02:00
Dennis Luxen 8e3484b873 rename ContractorEdgeData members 2014-07-14 17:35:02 +02:00
Dennis Luxen 4622aebabb reorder members for potentially tighter alignment 2014-07-14 17:31:50 +02:00
Dennis Luxen 96f29c27cd make c'tor of StaticGraph::InputEdge variadic to be more flexible against changing EdgeData types 2014-07-14 17:16:28 +02:00
Dennis Luxen 3de98f7a9d prevent in-source builds 2014-07-14 16:21:16 +02:00
Dennis Luxen 2b33fcd92d add c'tor to InputEdge of StaticGraph 2014-07-14 14:49:53 +02:00
Dennis Luxen b1ffcd4350 rename member to distance 2014-07-14 14:44:24 +02:00
Dennis Luxen fd500001fb Revert "also build tools on Windows"
This reverts commit 54a757a917.
2014-07-14 14:43:07 +02:00
Dennis Luxen 54a757a917 also build tools on Windows 2014-07-14 14:35:51 +02:00
Dennis Luxen 98dfc218d9 install tools if activated 2014-07-11 15:25:26 +02:00
Dennis Luxen f6f0f1fb72 fix signed/unsigned comparison in assertion 2014-07-11 14:04:09 +02:00
Dennis Luxen 218c810860 rename variable in XMLParser to make sure its name reflects the actual content 2014-07-11 14:03:38 +02:00
Dennis Luxen c836b6df3b fix SCC computation in debug mode by clearing a vector 2014-07-11 14:01:28 +02:00
Dennis Luxen 637bab29c6 transform negative numbers to positives by *(-1) 2014-07-11 14:00:33 +02:00
Dennis Luxen 0061b3fcbf remove unneeded member in Extractor, move to function scope 2014-07-11 10:10:50 +02:00
Dennis Luxen 2a19ded9d5 reformat Prepare.h/cpp with clang-format 2014-07-10 15:24:30 +02:00
Dennis Luxen bda9de0775 use boost::irange and range based for loop 2014-07-10 15:22:02 +02:00
Dennis Luxen 7047610a45 header untangling 2014-07-10 15:17:57 +02:00
Dennis Luxen 903d6f9e12 make instance of Prepare object an rvalue, remove dead code 2014-07-10 15:08:55 +02:00
Dennis Luxen 7d61bb2868 Merge branch 'dmbreaker-feature/prepare' into develop 2014-07-10 15:07:24 +02:00
Dennis Luxen def7164cad Merge branch 'feature/prepare' of https://github.com/dmbreaker/Project-OSRM into dmbreaker-feature/prepare 2014-07-10 15:07:15 +02:00
Dennis Luxen fc399e01fe explicitly cast segment length from float to int 2014-07-10 15:06:20 +02:00
Dennis Luxen ffdc3eee2d use proper float literal instead of implicit cast from int 2014-07-10 15:01:38 +02:00
Dennis Luxen 1f6f44ab01 include untangling of Extractor 2014-07-10 14:45:59 +02:00
Dennis Luxen 19740758c9 Merge branch 'dmbreaker-feature/extractor' into develop 2014-07-10 14:32:20 +02:00
Dennis Luxen f618660d24 Merge branch 'feature/extractor' of https://github.com/dmbreaker/Project-OSRM into dmbreaker-feature/extractor 2014-07-10 14:32:09 +02:00
Dennis Luxen f50dbe298a properly initialize variable 2014-07-10 14:03:20 +02:00
Dennis Luxen c324fbace4 path searches were pruned too early, fixes #1117 2014-07-10 13:56:36 +02:00
Dennis Luxen d05152af71 Merge pull request #1109 from DennisOSRM/fix/update_rspec_style
update rspec matchers to use expect()
2014-07-05 15:40:37 +02:00
Dennis Luxen bf228b4ae4 fix integer range to have correct end 2014-07-04 17:41:56 +02:00
Dennis Luxen ba0c17e287 make sure all node-based edges are serialized in forward fashion 2014-07-04 17:33:18 +02:00
Dennis Luxen 6cfbd4cefe fix unpacking of local path 2014-07-04 17:31:22 +02:00
Dennis Luxen e17a2e79a0 use range based for w/ integer ranges where possible 2014-07-04 17:23:45 +02:00
Dennis Luxen 72d709ae6c use explicit NodeID type in SharedDataFacade 2014-07-04 17:20:04 +02:00
Dennis Luxen 08ca450c40 change simplified graph loader to return a list of coordinates 2014-07-04 17:19:01 +02:00
dmbreaker a2951659ac prepare.cpp refactoring 2014-07-03 15:29:15 +04:00
dmbreaker 3a6af3810f One more blank line. 2014-07-03 10:23:43 +04:00
dmbreaker 3973554f07 Added blank lines between includes. 2014-07-03 10:23:43 +04:00
dmbreaker 718cba2e36 Trying to fix win-build 2014-07-03 10:23:43 +04:00
dmbreaker d2a70d1504 Removed pragma, reorganized includes. 2014-07-03 10:23:43 +04:00
dmbreaker 4bc847ac42 extractor.cpp refactored a bit 2014-07-03 10:23:43 +04:00
Dennis Luxen c3621edf9c refactor DynamicGraph to use integer ranges where possible 2014-07-02 16:58:19 +02:00
Dennis Luxen a64f2de9e1 add function to add a node into DynamicGraph 2014-07-02 15:27:09 +02:00
Dennis Luxen ce684cf9d4 fixes #1110, linker issues on CentOS 2014-07-02 14:38:02 +02:00
Dennis Luxen 1d1be10f16 add functions to load graph into simplified data structures 2014-07-02 14:36:20 +02:00
Dennis Luxen a09f97c9d5 remove OpenMP library linking 2014-07-02 14:34:44 +02:00
Dennis Luxen 48da2d2dfb add some comment to datastore 2014-07-02 11:21:34 +02:00
Dennis Luxen 36c0edea2a collapse if statement in datastore 2014-07-02 11:18:45 +02:00
Dennis Luxen 3568dc2083 use auto keyword to make code more legible 2014-07-02 11:07:29 +02:00
Dennis Luxen 51ad72a432 remove superflous include 2014-07-02 11:06:55 +02:00
Dennis Luxen 9ce970df8f use default keyword to get rid of compiler warning of not returning a value in a non-void function 2014-07-01 16:51:18 +02:00
Dennis Luxen cfa4d80dd7 make comparion of loop safe against underflows 2014-07-01 16:30:05 +02:00
Dennis Luxen 885cd05f1a fix data race in SimpleLogger by making state indicator variable atomic 2014-07-01 16:15:56 +02:00
Dennis Luxen 21188725d5 apply a bit of code refactoring to SCC implementation 2014-07-01 15:16:41 +02:00
Dennis Luxen 70f257b62f add BUILD_TOOLS flag, retire WITH_TOOLS soon 2014-07-01 15:16:41 +02:00
Dennis Luxen e8fb8e13df deactivate unused code 2014-07-01 15:16:41 +02:00
Dennis Luxen 7b7b93e9ba remove debug.bin generation 2014-07-01 15:16:41 +02:00
Dennis Luxen 4014da3cc5 make facade d'tors virtual 2014-07-01 14:26:29 +02:00
Dennis Luxen 410120adee close LUA context to avoid memory leak on shutdown 2014-07-01 14:26:02 +02:00
Dennis Luxen a98e65aa1e make variables const 2014-07-01 13:27:08 +02:00
Emil Tin dba9998118 update rspec matchers to use expect() 2014-06-30 20:43:51 +02:00
Dennis Luxen 1c75ce5911 reformat according w/ clang-format 2014-06-30 19:25:45 +02:00
Dennis Luxen 33b30aeb95 Merge branch 'fix/shared_mem_warnings' into develop 2014-06-30 19:23:30 +02:00
Dennis Luxen abd8d3459a Merge branch 'develop' into fix/shared_mem_warnings 2014-06-30 19:23:15 +02:00
Dennis Luxen 471698c59f fix picking of second route name 2014-06-30 16:05:26 +02:00
Dennis Luxen e67cf578ae remove explicit c'tor from Coordinate, use initializer list in PolylineCompressor 2014-06-30 15:16:35 +02:00
Dennis Luxen 186ad5d444 stream-line code in PolylineCompressor, apply range-based for loop again 2014-06-30 15:10:28 +02:00
Emil Tin 7eb810c34a fix shared mem warnings 2014-06-30 13:01:59 +02:00
Dennis Luxen 7817384e3c remove debug call 2014-06-30 11:53:36 +02:00
Dennis Luxen 34256ba358 properly compute sharing of nodes in search space with packed shortest path 2014-06-27 19:41:40 +02:00
Dennis Luxen 08eb5aa7d1 use shrink_to_fit() instead of swap trick 2014-06-27 19:40:47 +02:00
203 changed files with 8688 additions and 3984 deletions
+2
View File
@@ -38,6 +38,7 @@ Thumbs.db
/build/
/Util/FingerPrint.cpp
/Util/GitDescription.cpp
/cmake/postinst
# Eclipse related files #
#########################
@@ -79,6 +80,7 @@ stxxl.errlog
/osrm-prepare
/osrm-unlock-all
/osrm-cli
/osrm-check-hsgr
/nohup.out
# Sandbox folder #
+7 -4
View File
@@ -7,13 +7,15 @@ install:
- sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test
- sudo add-apt-repository -y ppa:boost-latest/ppa
- sudo apt-get update >/dev/null
- sudo apt-get -q install libprotoc-dev libprotobuf7 libprotobuf-dev libosmpbf-dev libbz2-dev libstxxl-dev libstxxl1 libxml2-dev libzip-dev lua5.1 liblua5.1-0-dev rubygems libtbb-dev
- sudo apt-get -q install g++-4.7
- sudo apt-get -q install protobuf-compiler libprotoc-dev libprotobuf7 libprotobuf-dev libosmpbf-dev libbz2-dev libstxxl-dev libstxxl1 libxml2-dev libzip-dev lua5.1 liblua5.1-0-dev rubygems libtbb-dev
- sudo apt-get -q install g++-4.8
- sudo apt-get install libboost1.54-all-dev
#luabind
- curl https://gist.githubusercontent.com/DennisOSRM/f2eb7b948e6fe1ae319e/raw/install-luabind.sh | sudo bash
#osmosis
- curl -s https://gist.githubusercontent.com/DennisOSRM/803a64a9178ec375069f/raw/ | sudo bash
#cmake
- curl -s https://gist.githubusercontent.com/DennisOSRM/5fad9bee5c7f09fd7fc9/raw/ | sudo bash
before_script:
- rvm use 1.9.3
- gem install bundler
@@ -23,6 +25,7 @@ before_script:
- cmake .. $CMAKEOPTIONS
script:
- make -j 2
- make -j 2 tests
- cd ..
- cucumber -p verify
after_script:
@@ -36,8 +39,8 @@ cache:
- bundler
- apt
env:
- CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=g++-4.7" OSRM_PORT=5000 OSRM_TIMEOUT=60
- CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER=g++-4.7" OSRM_PORT=5010 OSRM_TIMEOUT=60
- CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=g++-4.8" OSRM_PORT=5000 OSRM_TIMEOUT=60
- CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER=g++-4.8" OSRM_PORT=5010 OSRM_TIMEOUT=60
notifications:
irc:
channels:
+8 -9
View File
@@ -1,8 +1,7 @@
#ifndef __BFS_COMPONENT_EXPLORER_H__
#define __BFS_COMPONENT_EXPLORER_H__
#ifndef BFS_COMPONENT_EXPLORER_H_
#define BFS_COMPONENT_EXPLORER_H_
#include "../typedefs.h"
#include "../DataStructures/DynamicGraph.h"
#include "../DataStructures/RestrictionMap.h"
#include <queue>
@@ -13,10 +12,10 @@
template <typename GraphT> class BFSComponentExplorer
{
public:
BFSComponentExplorer(const GraphT &dynamicGraph,
BFSComponentExplorer(const GraphT &dynamic_graph,
const RestrictionMap &restrictions,
const std::unordered_set<NodeID> &barrier_nodes)
: m_graph(dynamicGraph), m_restriction_map(restrictions), m_barrier_nodes(barrier_nodes)
: m_graph(dynamic_graph), m_restriction_map(restrictions), m_barrier_nodes(barrier_nodes)
{
BOOST_ASSERT(m_graph.GetNumberOfNodes() > 0);
}
@@ -24,14 +23,14 @@ template <typename GraphT> class BFSComponentExplorer
/*!
* Returns the size of the component that the node belongs to.
*/
inline unsigned int GetComponentSize(NodeID node)
unsigned int GetComponentSize(const NodeID node) const
{
BOOST_ASSERT(node < m_component_index_list.size());
return m_component_index_size[m_component_index_list[node]];
}
inline unsigned int GetNumberOfComponents() { return m_component_index_size.size(); }
unsigned int GetNumberOfComponents() { return m_component_index_size.size(); }
/*!
* Computes the component sizes.
@@ -68,7 +67,7 @@ template <typename GraphT> class BFSComponentExplorer
/*!
* Explores the current component that starts at node using BFS.
*/
inline unsigned ExploreComponent(std::queue<std::pair<NodeID, NodeID>> &bfs_queue,
unsigned ExploreComponent(std::queue<std::pair<NodeID, NodeID>> &bfs_queue,
NodeID node,
unsigned current_component)
{
@@ -145,4 +144,4 @@ template <typename GraphT> class BFSComponentExplorer
const std::unordered_set<NodeID> &m_barrier_nodes;
};
#endif
#endif // BFS_COMPONENT_EXPLORER_H_
+10 -7
View File
@@ -25,11 +25,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <osrm/Coordinate.h>
#include "DouglasPeucker.h"
#include "../DataStructures/Range.h"
#include "../DataStructures/SegmentInformation.h"
#include "../Util/SimpleLogger.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
@@ -37,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <algorithm>
namespace {
struct CoordinatePairCalculator
{
CoordinatePairCalculator() = delete;
@@ -78,6 +80,7 @@ struct CoordinatePairCalculator
float second_lat;
float second_lon;
};
}
DouglasPeucker::DouglasPeucker()
: douglas_peucker_thresholds({512440, // z0
@@ -150,13 +153,13 @@ void DouglasPeucker::Run(std::vector<SegmentInformation> &input_geometry, const
int max_int_distance = 0;
unsigned farthest_entry_index = pair.second;
const CoordinatePairCalculator DistCalc(input_geometry[pair.first].location,
input_geometry[pair.second].location);
const CoordinatePairCalculator dist_calc(input_geometry[pair.first].location,
input_geometry[pair.second].location);
// sweep over range to find the maximum
for (unsigned i = pair.first + 1; i < pair.second; ++i)
for (const auto i : osrm::irange(pair.first + 1, pair.second))
{
const int distance = DistCalc(input_geometry[i].location);
const int distance = dist_calc(input_geometry[i].location);
// found new feasible maximum?
if (distance > max_int_distance && distance > douglas_peucker_thresholds[zoom_level])
{
+1 -1
View File
@@ -46,7 +46,7 @@ class DouglasPeucker
private:
std::vector<int> douglas_peucker_thresholds;
typedef std::pair<unsigned, unsigned> GeometryRange;
using GeometryRange = std::pair<unsigned, unsigned>;
// Stack to simulate the recursion
std::stack<GeometryRange> recursion_stack;
+3 -3
View File
@@ -54,7 +54,7 @@ template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
for (const SegmentT &segment : segment_list)
{
if (segment.name_id != blocked_name_id && segment.length > result_segment.length)
if (segment.name_id != blocked_name_id && segment.length > result_segment.length && segment.name_id != 0)
{
result_segment = segment;
}
@@ -111,7 +111,7 @@ template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
shortest_path_set_difference.end(),
length_comperator);
shortest_segment_2 =
PickNextLongestSegment(shortest_path_set_difference, shortest_path_segments[0].name_id);
PickNextLongestSegment(shortest_path_set_difference, shortest_segment_1.name_id);
// compute the set difference (for alternative path) depending on names between shortest and
// alternative
@@ -138,7 +138,7 @@ template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
if (!alternative_path_segments.empty())
{
alternative_segment_2 = PickNextLongestSegment(alternative_path_set_difference,
alternative_path_segments[0].name_id);
alternative_segment_1.name_id);
}
// move the segments into the order in which they occur.
+63 -61
View File
@@ -28,44 +28,59 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ITERATOR_BASED_CRC32_H
#define ITERATOR_BASED_CRC32_H
#include "../Util/SimpleLogger.h"
#include <iostream>
#if defined(__x86_64__) && !defined(__MINGW64__)
#include <cpuid.h>
#else
#endif
#include <boost/crc.hpp> // for boost::crc_32_type
inline void __get_cpuid(int param, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx)
#include <iterator>
class IteratorbasedCRC32
{
*ecx = 0;
}
#endif
public:
bool using_hardware() const { return use_hardware_implementation; }
template <class ContainerT> class IteratorbasedCRC32
{
private:
typedef typename ContainerT::iterator IteratorType;
unsigned crc;
IteratorbasedCRC32() : crc(0) { use_hardware_implementation = detect_hardware_support(); }
bool use_SSE42_CRC_function;
#if !defined(__x86_64__)
boost::crc_optimal<32, 0x1EDC6F41, 0x0, 0x0, true, true> CRC32_processor;
#endif
unsigned SoftwareBasedCRC32(char *str, unsigned len)
template <class Iterator> unsigned operator()(Iterator iter, const Iterator end)
{
#if !defined(__x86_64__)
CRC32_processor.process_bytes(str, len);
return CRC32_processor.checksum();
#else
return 0;
#endif
unsigned crc = 0;
while (iter != end)
{
using value_type = typename std::iterator_traits<Iterator>::value_type;
char *data = (char *)(&(*iter));
if (use_hardware_implementation)
{
crc = compute_in_hardware(data, sizeof(value_type));
}
else
{
crc = compute_in_software(data, sizeof(value_type));
}
++iter;
}
return crc;
}
private:
bool detect_hardware_support() const
{
static const int sse42_bit = 0x00100000;
const unsigned ecx = cpuid();
const bool sse42_found = (ecx & sse42_bit) != 0;
return sse42_found;
}
unsigned compute_in_software(char *str, unsigned len)
{
crc_processor.process_bytes(str, len);
return crc_processor.checksum();
}
// adapted from http://byteworm.com/2010/10/13/crc32/
unsigned SSE42BasedCRC32(char *str, unsigned len)
unsigned compute_in_hardware(char *str, unsigned len)
{
#if defined(__x86_64__)
unsigned q = len / sizeof(unsigned);
@@ -101,44 +116,31 @@ template <class ContainerT> class IteratorbasedCRC32
return ecx;
}
bool DetectNativeCRC32Support()
#if defined(__MINGW64__) || defined(_MSC_VER)
inline void
__get_cpuid(int param, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) const
{
static const int SSE42_BIT = 0x00100000;
const unsigned ecx = cpuid();
const bool has_SSE42 = (ecx & SSE42_BIT) != 0;
if (has_SSE42)
{
SimpleLogger().Write() << "using hardware based CRC32 computation";
}
else
{
SimpleLogger().Write() << "using software based CRC32 computation";
}
return has_SSE42;
*ecx = 0;
}
#endif
boost::crc_optimal<32, 0x1EDC6F41, 0x0, 0x0, true, true> crc_processor;
unsigned crc;
bool use_hardware_implementation;
};
struct RangebasedCRC32
{
template<typename Iteratable>
unsigned operator()(const Iteratable &iterable)
{
return crc32(std::begin(iterable), std::end(iterable));
}
public:
IteratorbasedCRC32() : crc(0) { use_SSE42_CRC_function = DetectNativeCRC32Support(); }
bool using_hardware() const { return crc32.using_hardware(); }
unsigned operator()(IteratorType iter, const IteratorType end)
{
unsigned crc = 0;
while (iter != end)
{
char *data = reinterpret_cast<char *>(&(*iter));
if (use_SSE42_CRC_function)
{
crc = SSE42BasedCRC32(data, sizeof(typename ContainerT::value_type));
}
else
{
crc = SoftwareBasedCRC32(data, sizeof(typename ContainerT::value_type));
}
++iter;
}
return crc;
}
private:
IteratorbasedCRC32 crc32;
};
#endif /* ITERATOR_BASED_CRC32_H */
+48 -53
View File
@@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OBJECTTOBASE64_H_
#define OBJECTTOBASE64_H_
#ifndef OBJECT_TO_BASE64_H_
#define OBJECT_TO_BASE64_H_
#include "../Util/StringUtil.h"
@@ -39,61 +39,56 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include <vector>
typedef
boost::archive::iterators::base64_from_binary<
boost::archive::iterators::transform_width<const char *, 6, 8>
> base64_t;
struct ObjectEncoder
{
using base64_t = boost::archive::iterators::base64_from_binary<
boost::archive::iterators::transform_width<const char *, 6, 8>>;
typedef
boost::archive::iterators::transform_width<
boost::archive::iterators::binary_from_base64<
std::string::const_iterator>, 8, 6
> binary_t;
using binary_t = boost::archive::iterators::transform_width<
boost::archive::iterators::binary_from_base64<std::string::const_iterator>,
8,
6>;
template<class ObjectT>
static void EncodeObjectToBase64(const ObjectT & object, std::string& encoded) {
const char * char_ptr_to_object = (const char *)&object;
std::vector<unsigned char> data(sizeof(object));
std::copy(
char_ptr_to_object,
char_ptr_to_object + sizeof(ObjectT),
data.begin()
);
template <class ObjectT>
static void EncodeToBase64(const ObjectT &object, std::string &encoded)
{
const char *char_ptr_to_object = (const char *)&object;
std::vector<unsigned char> data(sizeof(object));
std::copy(char_ptr_to_object, char_ptr_to_object + sizeof(ObjectT), data.begin());
unsigned char number_of_padded_chars = 0; // is in {0,1,2};
while(data.size() % 3 != 0) {
++number_of_padded_chars;
data.push_back(0x00);
unsigned char number_of_padded_chars = 0; // is in {0,1,2};
while (data.size() % 3 != 0)
{
++number_of_padded_chars;
data.push_back(0x00);
}
BOOST_ASSERT_MSG(0 == data.size() % 3, "base64 input data size is not a multiple of 3!");
encoded.resize(sizeof(ObjectT));
encoded.assign(base64_t(&data[0]),
base64_t(&data[0] + (data.size() - number_of_padded_chars)));
replaceAll(encoded, "+", "-");
replaceAll(encoded, "/", "_");
}
BOOST_ASSERT_MSG(
0 == data.size() % 3,
"base64 input data size is not a multiple of 3!"
);
encoded.resize(sizeof(ObjectT));
encoded.assign(
base64_t( &data[0] ),
base64_t( &data[0] + (data.size() - number_of_padded_chars) )
);
replaceAll(encoded, "+", "-");
replaceAll(encoded, "/", "_");
}
template <class ObjectT>
static void DecodeFromBase64(const std::string &input, ObjectT &object)
{
try
{
std::string encoded(input);
// replace "-" with "+" and "_" with "/"
replaceAll(encoded, "-", "+");
replaceAll(encoded, "_", "/");
template<class ObjectT>
static void DecodeObjectFromBase64(const std::string& input, ObjectT & object) {
try {
std::string encoded(input);
//replace "-" with "+" and "_" with "/"
replaceAll(encoded, "-", "+");
replaceAll(encoded, "_", "/");
std::copy(binary_t(encoded.begin()),
binary_t(encoded.begin() + encoded.length() - 1),
(char *)&object);
}
catch (...)
{
}
}
};
std::copy (
binary_t( encoded.begin() ),
binary_t( encoded.begin() + encoded.length() - 1),
(char *)&object
);
} catch(...) { }
}
#endif /* OBJECTTOBASE64_H_ */
#endif /* OBJECT_TO_BASE64_H_ */
+12 -18
View File
@@ -30,8 +30,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <osrm/Coordinate.h>
void PolylineCompressor::encodeVectorSignedNumber(std::vector<int> &numbers, std::string &output)
const
void PolylineCompressor::encodeVectorSignedNumber(std::vector<int> &numbers,
std::string &output) const
{
const unsigned end = static_cast<unsigned>(numbers.size());
for (unsigned i = 0; i < end; ++i)
@@ -69,24 +69,20 @@ void PolylineCompressor::encodeNumber(int number_to_encode, std::string &output)
}
}
JSON::String PolylineCompressor::printEncodedString(const std::vector<SegmentInformation> &polyline)
const
JSON::String
PolylineCompressor::printEncodedString(const std::vector<SegmentInformation> &polyline) const
{
std::string output;
std::vector<int> delta_numbers;
if (!polyline.empty())
{
FixedPointCoordinate last_coordinate = polyline[0].location;
delta_numbers.emplace_back(last_coordinate.lat);
delta_numbers.emplace_back(last_coordinate.lon);
// iterate after skipping the first, already handled, segment
for (auto it = ++polyline.cbegin(); it != polyline.cend(); ++it)
FixedPointCoordinate last_coordinate = {0, 0};
for (const auto &segment : polyline)
{
const auto &segment = *it;
if (segment.necessary)
{
int lat_diff = segment.location.lat - last_coordinate.lat;
int lon_diff = segment.location.lon - last_coordinate.lon;
const int lat_diff = segment.location.lat - last_coordinate.lat;
const int lon_diff = segment.location.lon - last_coordinate.lon;
delta_numbers.emplace_back(lat_diff);
delta_numbers.emplace_back(lon_diff);
last_coordinate = segment.location;
@@ -106,12 +102,10 @@ PolylineCompressor::printUnencodedString(const std::vector<SegmentInformation> &
{
if (segment.necessary)
{
std::string tmp, output;
FixedPointCoordinate::convertInternalLatLonToString(segment.location.lat, tmp);
output += (tmp + ",");
FixedPointCoordinate::convertInternalLatLonToString(segment.location.lon, tmp);
output += tmp;
json_geometry_array.values.push_back(output);
JSON::Array json_coordinate;
json_coordinate.values.push_back(segment.location.lat / COORDINATE_PRECISION);
json_coordinate.values.push_back(segment.location.lon / COORDINATE_PRECISION);
json_geometry_array.values.push_back(json_coordinate);
}
}
return json_geometry_array;
+116 -104
View File
@@ -34,18 +34,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../DataStructures/ImportEdge.h"
#include "../DataStructures/QueryNode.h"
#include "../DataStructures/Percent.h"
#include "../DataStructures/Range.h"
#include "../DataStructures/Restriction.h"
#include "../DataStructures/TurnInstructions.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../Util/simple_logger.hpp"
#include "../Util/StdHashExtensions.h"
#include "../Util/TimingUtil.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <tbb/parallel_sort.h>
#ifdef __APPLE__
#include <gdal.h>
#include <ogrsf_frmts.h>
@@ -67,7 +71,7 @@ class TarjanSCC
private:
struct TarjanNode
{
TarjanNode() : index(UINT_MAX), low_link(UINT_MAX), on_stack(false) {}
TarjanNode() : index(SPECIAL_NODEID), low_link(SPECIAL_NODEID), on_stack(false) {}
unsigned index;
unsigned low_link;
bool on_stack;
@@ -75,13 +79,10 @@ class TarjanSCC
struct TarjanEdgeData
{
TarjanEdgeData() : distance(INVALID_EDGE_WEIGHT), name_id(INVALID_NAMEID) {}
TarjanEdgeData(int distance, unsigned name_id) : distance(distance), name_id(name_id) {}
int distance;
unsigned name_id : 31;
bool shortcut : 1;
short type;
bool forward : 1;
bool backward : 1;
bool reversedEdge : 1;
unsigned name_id;
};
struct TarjanStackFrame
@@ -91,18 +92,18 @@ class TarjanSCC
NodeID parent;
};
typedef DynamicGraph<TarjanEdgeData> TarjanDynamicGraph;
typedef TarjanDynamicGraph::InputEdge TarjanEdge;
typedef std::pair<NodeID, NodeID> RestrictionSource;
typedef std::pair<NodeID, bool> restriction_target;
typedef std::vector<restriction_target> EmanatingRestrictionsVector;
typedef std::unordered_map<RestrictionSource, unsigned> RestrictionMap;
using TarjanDynamicGraph = DynamicGraph<TarjanEdgeData>;
using TarjanEdge = TarjanDynamicGraph::InputEdge;
using RestrictionSource = std::pair<NodeID, NodeID>;
using RestrictionTarget = std::pair<NodeID, bool>;
using EmanatingRestrictionsVector = std::vector<RestrictionTarget>;
using RestrictionMap = std::unordered_map<RestrictionSource, unsigned>;
std::vector<NodeInfo> m_coordinate_list;
std::vector<EmanatingRestrictionsVector> m_restriction_bucket_list;
std::shared_ptr<TarjanDynamicGraph> m_node_based_graph;
std::unordered_set<NodeID> m_barrier_node_list;
std::unordered_set<NodeID> m_traffic_light_list;
std::unordered_set<NodeID> barrier_node_list;
std::unordered_set<NodeID> traffic_light_list;
unsigned m_restriction_counter;
RestrictionMap m_restriction_map;
@@ -115,18 +116,18 @@ class TarjanSCC
std::vector<NodeInfo> &nI)
: m_coordinate_list(nI), m_restriction_counter(irs.size())
{
TIMER_START(SCC_LOAD);
for (const TurnRestriction &restriction : irs)
{
std::pair<NodeID, NodeID> restrictionSource = {restriction.fromNode,
restriction.viaNode};
unsigned index;
RestrictionMap::iterator restriction_iterator =
m_restriction_map.find(restrictionSource);
std::pair<NodeID, NodeID> restriction_source = {restriction.fromNode,
restriction.viaNode};
unsigned index = 0;
const auto restriction_iterator = m_restriction_map.find(restriction_source);
if (restriction_iterator == m_restriction_map.end())
{
index = m_restriction_bucket_list.size();
m_restriction_bucket_list.resize(index + 1);
m_restriction_map.emplace(restrictionSource, index);
m_restriction_map.emplace(restriction_source, index);
}
else
{
@@ -147,8 +148,8 @@ class TarjanSCC
.emplace_back(restriction.toNode, restriction.flags.isOnly);
}
m_barrier_node_list.insert(bn.begin(), bn.end());
m_traffic_light_list.insert(tl.begin(), tl.end());
barrier_node_list.insert(bn.begin(), bn.end());
traffic_light_list.insert(tl.begin(), tl.end());
DeallocatingVector<TarjanEdge> edge_list;
for (const NodeBasedEdge &input_edge : input_edges)
@@ -158,50 +159,37 @@ class TarjanSCC
continue;
}
TarjanEdge edge;
if (input_edge.forward)
{
edge.source = input_edge.source;
edge.target = input_edge.target;
edge.data.forward = input_edge.forward;
edge.data.backward = input_edge.backward;
edge_list.emplace_back(input_edge.source,
input_edge.target,
(std::max)((int)input_edge.weight, 1),
input_edge.name_id);
}
else
if (input_edge.backward)
{
edge.source = input_edge.target;
edge.target = input_edge.source;
edge.data.backward = input_edge.forward;
edge.data.forward = input_edge.backward;
}
edge.data.distance = (std::max)((int)input_edge.weight, 1);
BOOST_ASSERT(edge.data.distance > 0);
edge.data.shortcut = false;
edge.data.name_id = input_edge.name_id;
edge.data.type = input_edge.type;
edge.data.reversedEdge = false;
edge_list.push_back(edge);
if (edge.data.backward)
{
std::swap(edge.source, edge.target);
edge.data.forward = input_edge.backward;
edge.data.backward = input_edge.forward;
edge.data.reversedEdge = true;
edge_list.push_back(edge);
edge_list.emplace_back(input_edge.target,
input_edge.source,
(std::max)((int)input_edge.weight, 1),
input_edge.name_id);
}
}
input_edges.clear();
input_edges.shrink_to_fit();
BOOST_ASSERT_MSG(0 == input_edges.size() && 0 == input_edges.capacity(),
"input edge vector not properly deallocated");
std::sort(edge_list.begin(), edge_list.end());
tbb::parallel_sort(edge_list.begin(), edge_list.end());
m_node_based_graph = std::make_shared<TarjanDynamicGraph>(number_of_nodes, edge_list);
TIMER_STOP(SCC_LOAD);
SimpleLogger().Write() << "Loading data into SCC took " << TIMER_MSEC(SCC_LOAD)/1000. << "s";
}
~TarjanSCC() { m_node_based_graph.reset(); }
void Run()
{
TIMER_START(SCC_RUN_SETUP);
// remove files from previous run if exist
DeleteFileIfExists("component.dbf");
DeleteFileIfExists("component.shx");
@@ -225,42 +213,56 @@ class TarjanSCC
throw OSRMException("Creation of output file failed");
}
OGRLayer *poLayer = poDS->CreateLayer("component", nullptr, wkbLineString, nullptr);
OGRSpatialReference *poSRS = new OGRSpatialReference();
poSRS->importFromEPSG(4326);
OGRLayer *poLayer = poDS->CreateLayer("component", poSRS, wkbLineString, nullptr);
if (nullptr == poLayer)
{
throw OSRMException("Layer creation failed.");
}
TIMER_STOP(SCC_RUN_SETUP);
SimpleLogger().Write() << "shapefile setup took " << TIMER_MSEC(SCC_RUN_SETUP)/1000. << "s";
TIMER_START(SCC_RUN);
// The following is a hack to distinguish between stuff that happens
// before the recursive call and stuff that happens after
std::stack<std::pair<bool, TarjanStackFrame>> recursion_stack;
std::stack<TarjanStackFrame> recursion_stack;
// true = stuff before, false = stuff after call
std::stack<NodeID> tarjan_stack;
std::vector<unsigned> components_index(m_node_based_graph->GetNumberOfNodes(), UINT_MAX);
std::vector<unsigned> components_index(m_node_based_graph->GetNumberOfNodes(),
SPECIAL_NODEID);
std::vector<NodeID> component_size_vector;
std::vector<TarjanNode> tarjan_node_list(m_node_based_graph->GetNumberOfNodes());
unsigned component_index = 0, size_of_current_component = 0;
int index = 0;
NodeID last_node = m_node_based_graph->GetNumberOfNodes();
for (NodeID node = 0; node < last_node; ++node)
const NodeID last_node = m_node_based_graph->GetNumberOfNodes();
std::vector<bool> processing_node_before_recursion(m_node_based_graph->GetNumberOfNodes(), true);
for(const NodeID node : osrm::irange(0u, last_node))
{
if (UINT_MAX == components_index[node])
if (SPECIAL_NODEID == components_index[node])
{
recursion_stack.emplace(true, TarjanStackFrame(node, node));
recursion_stack.emplace(TarjanStackFrame(node, node));
}
while (!recursion_stack.empty())
{
const bool before_recursion = recursion_stack.top().first;
TarjanStackFrame currentFrame = recursion_stack.top().second;
NodeID v = currentFrame.v;
TarjanStackFrame currentFrame = recursion_stack.top();
const NodeID v = currentFrame.v;
recursion_stack.pop();
const bool before_recursion = processing_node_before_recursion[v];
if (before_recursion && tarjan_node_list[v].index != UINT_MAX)
{
continue;
}
if (before_recursion)
{
// Mark frame to handle tail of recursion
recursion_stack.emplace(false, currentFrame);
recursion_stack.emplace(currentFrame);
processing_node_before_recursion[v] = false;
// Mark essential information for SCC
tarjan_node_list[v].index = index;
@@ -270,13 +272,13 @@ class TarjanSCC
++index;
// Traverse outgoing edges
for (auto e2 : m_node_based_graph->GetAdjacentEdgeRange(v))
for (const auto current_edge : m_node_based_graph->GetAdjacentEdgeRange(v))
{
const TarjanDynamicGraph::NodeIterator vprime =
m_node_based_graph->GetTarget(e2);
if (UINT_MAX == tarjan_node_list[vprime].index)
m_node_based_graph->GetTarget(current_edge);
if (SPECIAL_NODEID == tarjan_node_list[vprime].index)
{
recursion_stack.emplace(true, TarjanStackFrame(vprime, v));
recursion_stack.emplace(TarjanStackFrame(vprime, v));
}
else
{
@@ -290,6 +292,7 @@ class TarjanSCC
}
else
{
processing_node_before_recursion[v] = true;
tarjan_node_list[currentFrame.parent].low_link =
std::min(tarjan_node_list[currentFrame.parent].low_link,
tarjan_node_list[v].low_link);
@@ -322,53 +325,60 @@ class TarjanSCC
}
}
TIMER_STOP(SCC_RUN);
SimpleLogger().Write() << "SCC run took: " << TIMER_MSEC(SCC_RUN)/1000. << "s";
SimpleLogger().Write() << "identified: " << component_size_vector.size()
<< " many components, marking small components";
unsigned size_one_counter = std::count_if(component_size_vector.begin(),
component_size_vector.end(),
[] (unsigned value) { return 1 == value;});
TIMER_START(SCC_OUTPUT);
const unsigned size_one_counter = std::count_if(component_size_vector.begin(),
component_size_vector.end(),
[](unsigned value)
{
return 1 == value;
});
SimpleLogger().Write() << "identified " << size_one_counter << " SCCs of size 1";
uint64_t total_network_distance = 0;
p.reinit(m_node_based_graph->GetNumberOfNodes());
NodeID last_u_node = m_node_based_graph->GetNumberOfNodes();
for (NodeID u = 0; u < last_u_node; ++u)
// const NodeID last_u_node = m_node_based_graph->GetNumberOfNodes();
for (const NodeID source : osrm::irange(0u, last_node))
{
p.printIncrement();
for (auto e1 : m_node_based_graph->GetAdjacentEdgeRange(u))
for (const auto current_edge : m_node_based_graph->GetAdjacentEdgeRange(source))
{
if (!m_node_based_graph->GetEdgeData(e1).reversedEdge)
{
continue;
}
const TarjanDynamicGraph::NodeIterator v = m_node_based_graph->GetTarget(e1);
const TarjanDynamicGraph::NodeIterator target =
m_node_based_graph->GetTarget(current_edge);
total_network_distance +=
100 * FixedPointCoordinate::ApproximateDistance(m_coordinate_list[u].lat,
m_coordinate_list[u].lon,
m_coordinate_list[v].lat,
m_coordinate_list[v].lon);
if (SHRT_MAX != m_node_based_graph->GetEdgeData(e1).type)
if (source < target ||
m_node_based_graph->EndEdges(target) ==
m_node_based_graph->FindEdge(target, source))
{
BOOST_ASSERT(e1 != UINT_MAX);
BOOST_ASSERT(u != UINT_MAX);
BOOST_ASSERT(v != UINT_MAX);
total_network_distance +=
100 * FixedPointCoordinate::ApproximateEuclideanDistance(
m_coordinate_list[source].lat,
m_coordinate_list[source].lon,
m_coordinate_list[target].lat,
m_coordinate_list[target].lon);
BOOST_ASSERT(current_edge != SPECIAL_EDGEID);
BOOST_ASSERT(source != SPECIAL_NODEID);
BOOST_ASSERT(target != SPECIAL_NODEID);
const unsigned size_of_containing_component =
std::min(component_size_vector[components_index[u]],
component_size_vector[components_index[v]]);
std::min(component_size_vector[components_index[source]],
component_size_vector[components_index[target]]);
// edges that end on bollard nodes may actually be in two distinct components
if (size_of_containing_component < 10)
{
OGRLineString lineString;
lineString.addPoint(m_coordinate_list[u].lon / COORDINATE_PRECISION,
m_coordinate_list[u].lat / COORDINATE_PRECISION);
lineString.addPoint(m_coordinate_list[v].lon / COORDINATE_PRECISION,
m_coordinate_list[v].lat / COORDINATE_PRECISION);
lineString.addPoint(m_coordinate_list[source].lon / COORDINATE_PRECISION,
m_coordinate_list[source].lat / COORDINATE_PRECISION);
lineString.addPoint(m_coordinate_list[target].lon / COORDINATE_PRECISION,
m_coordinate_list[target].lat / COORDINATE_PRECISION);
OGRFeature *poFeature = OGRFeature::CreateFeature(poLayer->GetLayerDefn());
@@ -383,24 +393,27 @@ class TarjanSCC
}
}
OGRDataSource::DestroyDataSource(poDS);
std::vector<NodeID>().swap(component_size_vector);
component_size_vector.clear();
component_size_vector.shrink_to_fit();
BOOST_ASSERT_MSG(0 == component_size_vector.size() && 0 == component_size_vector.capacity(),
"component_size_vector not properly deallocated");
std::vector<NodeID>().swap(components_index);
components_index.clear();
components_index.shrink_to_fit();
BOOST_ASSERT_MSG(0 == components_index.size() && 0 == components_index.capacity(),
"icomponents_index not properly deallocated");
"components_index not properly deallocated");
TIMER_STOP(SCC_OUTPUT);
SimpleLogger().Write() << "generating output took: " << TIMER_MSEC(SCC_OUTPUT)/1000. << "s";
SimpleLogger().Write() << "total network distance: " << (uint64_t)total_network_distance /
100 / 1000. << " km";
SimpleLogger().Write() << "total network distance: "
<< (uint64_t)total_network_distance / 100 / 1000. << " km";
}
private:
unsigned CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const
{
std::pair<NodeID, NodeID> restriction_source = {u, v};
RestrictionMap::const_iterator restriction_iterator =
m_restriction_map.find(restriction_source);
const auto restriction_iterator = m_restriction_map.find(restriction_source);
if (restriction_iterator != m_restriction_map.end())
{
const unsigned index = restriction_iterator->second;
@@ -412,19 +425,18 @@ class TarjanSCC
}
}
}
return UINT_MAX;
return SPECIAL_NODEID;
}
bool CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const
{
// only add an edge if turn is not a U-turn except it is the end of dead-end street.
std::pair<NodeID, NodeID> restriction_source = {u, v};
RestrictionMap::const_iterator restriction_iterator =
m_restriction_map.find(restriction_source);
const auto restriction_iterator = m_restriction_map.find(restriction_source);
if (restriction_iterator != m_restriction_map.end())
{
const unsigned index = restriction_iterator->second;
for (const restriction_target &restriction_target : m_restriction_bucket_list.at(index))
for (const RestrictionTarget &restriction_target : m_restriction_bucket_list.at(index))
{
if (w == restriction_target.first)
{
+130
View File
@@ -0,0 +1,130 @@
#include "../DataStructures/OriginalEdgeData.h"
#include "../DataStructures/QueryNode.h"
#include "../DataStructures/SharedMemoryVectorWrapper.h"
#include "../DataStructures/StaticRTree.h"
#include "../Util/BoostFileSystemFix.h"
#include "../DataStructures/EdgeBasedNode.h"
#include <osrm/Coordinate.h>
#include <random>
// Choosen by a fair W20 dice roll (this value is completely arbitrary)
constexpr unsigned RANDOM_SEED = 13;
constexpr int32_t WORLD_MIN_LAT = -90 * COORDINATE_PRECISION;
constexpr int32_t WORLD_MAX_LAT = 90 * COORDINATE_PRECISION;
constexpr int32_t WORLD_MIN_LON = -180 * COORDINATE_PRECISION;
constexpr int32_t WORLD_MAX_LON = 180 * COORDINATE_PRECISION;
using RTreeLeaf = EdgeBasedNode;
using FixedPointCoordinateListPtr = std::shared_ptr<std::vector<FixedPointCoordinate>>;
using BenchStaticRTree = StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, false>::vector, false>;
FixedPointCoordinateListPtr LoadCoordinates(const boost::filesystem::path &nodes_file)
{
boost::filesystem::ifstream nodes_input_stream(nodes_file, std::ios::binary);
NodeInfo current_node;
unsigned number_of_coordinates = 0;
nodes_input_stream.read((char *)&number_of_coordinates, sizeof(unsigned));
auto coords = std::make_shared<std::vector<FixedPointCoordinate>>(number_of_coordinates);
for (unsigned i = 0; i < number_of_coordinates; ++i)
{
nodes_input_stream.read((char *)&current_node, sizeof(NodeInfo));
coords->at(i) = FixedPointCoordinate(current_node.lat, current_node.lon);
BOOST_ASSERT((std::abs(coords->at(i).lat) >> 30) == 0);
BOOST_ASSERT((std::abs(coords->at(i).lon) >> 30) == 0);
}
nodes_input_stream.close();
return coords;
}
void Benchmark(BenchStaticRTree &rtree, unsigned num_queries)
{
std::mt19937 mt_rand(RANDOM_SEED);
std::uniform_int_distribution<> lat_udist(WORLD_MIN_LAT, WORLD_MAX_LAT);
std::uniform_int_distribution<> lon_udist(WORLD_MIN_LON, WORLD_MAX_LON);
std::vector<FixedPointCoordinate> queries;
for (unsigned i = 0; i < num_queries; i++)
{
queries.emplace_back(FixedPointCoordinate(lat_udist(mt_rand), lon_udist(mt_rand)));
}
const unsigned num_results = 5;
std::cout << "#### IncrementalFindPhantomNodeForCoordinate : " << num_results
<< " phantom nodes"
<< "\n";
TIMER_START(query_phantom);
std::vector<PhantomNode> resulting_phantom_node_vector;
for (const auto &q : queries)
{
resulting_phantom_node_vector.clear();
rtree.IncrementalFindPhantomNodeForCoordinate(
q, resulting_phantom_node_vector, 3, num_results);
resulting_phantom_node_vector.clear();
rtree.IncrementalFindPhantomNodeForCoordinate(
q, resulting_phantom_node_vector, 17, num_results);
}
TIMER_STOP(query_phantom);
std::cout << "Took " << TIMER_MSEC(query_phantom) << " msec for " << num_queries << " queries."
<< "\n";
std::cout << TIMER_MSEC(query_phantom) / ((double)num_queries) << " msec/query."
<< "\n";
std::cout << "#### LocateClosestEndPointForCoordinate"
<< "\n";
TIMER_START(query_endpoint);
FixedPointCoordinate result;
for (const auto &q : queries)
{
rtree.LocateClosestEndPointForCoordinate(q, result, 3);
}
TIMER_STOP(query_endpoint);
std::cout << "Took " << TIMER_MSEC(query_endpoint) << " msec for " << num_queries << " queries."
<< "\n";
std::cout << TIMER_MSEC(query_endpoint) / ((double)num_queries) << " msec/query."
<< "\n";
std::cout << "#### FindPhantomNodeForCoordinate"
<< "\n";
TIMER_START(query_phantomnode);
for (const auto &q : queries)
{
PhantomNode phantom;
rtree.FindPhantomNodeForCoordinate(q, phantom, 3);
}
TIMER_STOP(query_phantomnode);
std::cout << "Took " << TIMER_MSEC(query_phantomnode) << " msec for " << num_queries
<< " queries."
<< "\n";
std::cout << TIMER_MSEC(query_phantomnode) / ((double)num_queries) << " msec/query."
<< "\n";
}
int main(int argc, char **argv)
{
if (argc < 4)
{
std::cout << "./rtree-bench file.ramIndex file.fileIndx file.nodes"
<< "\n";
return 1;
}
const char *ramPath = argv[1];
const char *filePath = argv[2];
const char *nodesPath = argv[3];
auto coords = LoadCoordinates(nodesPath);
BenchStaticRTree rtree(ramPath, filePath, coords);
Benchmark(rtree, 10000);
return 0;
}
+80 -56
View File
@@ -1,4 +1,11 @@
cmake_minimum_required(VERSION 2.8)
cmake_minimum_required(VERSION 2.8.8)
if( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE )
message(FATAL_ERROR "In-source builds are not allowed.
Please create a directory and run cmake from there, passing the path to this source directory as the last argument.
This process created the file `CMakeCache.txt' and the directory `CMakeFiles'. Please delete them.")
endif()
project(OSRM)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include(CheckCXXCompilerFlag)
@@ -20,7 +27,8 @@ if (WIN32 AND MSVC_VERSION LESS 1800)
message(FATAL_ERROR "Building with Microsoft compiler needs Visual Studio 2013 or later (Express version works too)")
endif()
OPTION(WITH_TOOLS "Build ORSM tools" OFF)
OPTION(WITH_TOOLS "Build OSRM tools" OFF)
OPTION(BUILD_TOOLS "Build OSRM tools" OFF)
include_directories(${CMAKE_SOURCE_DIR}/Include/)
@@ -33,8 +41,10 @@ add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/Util/FingerPrint.cpp FingerPrint.c
VERBATIM)
add_custom_target(FingerPrintConfigure DEPENDS ${CMAKE_SOURCE_DIR}/Util/FingerPrint.cpp)
add_custom_target(tests DEPENDS datastructure-tests)
add_custom_target(benchmarks DEPENDS rtree-bench)
set(BOOST_COMPONENTS date_time filesystem iostreams program_options regex system thread)
set(BOOST_COMPONENTS date_time filesystem iostreams program_options regex system thread unit_test_framework)
configure_file(
${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp.in
@@ -42,21 +52,25 @@ configure_file(
)
file(GLOB ExtractorGlob Extractor/*.cpp)
file(GLOB ImporterGlob DataStructures/Import*.cpp)
add_library(IMPORT STATIC ${ImporterGlob})
set(ExtractorSources extractor.cpp ${ExtractorGlob})
add_executable(osrm-extract ${ExtractorSources})
add_library(IMPORT OBJECT ${ImporterGlob})
add_library(LOGGER OBJECT Util/simple_logger.cpp)
file(GLOB PrepareGlob Contractor/*.cpp DataStructures/HilbertValue.cpp DataStructures/RestrictionMap.cpp)
set(ExtractorSources extractor.cpp ${ExtractorGlob})
add_executable(osrm-extract ${ExtractorSources} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:LOGGER>)
file(GLOB PrepareGlob Contractor/*.cpp DataStructures/HilbertValue.cpp DataStructures/RestrictionMap.cpp Util/compute_angle.cpp)
set(PrepareSources prepare.cpp ${PrepareGlob})
add_executable(osrm-prepare ${PrepareSources})
add_executable(osrm-prepare ${PrepareSources} $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:LOGGER>)
file(GLOB ServerGlob Server/*.cpp)
file(GLOB DescriptorGlob Descriptors/*.cpp)
file(GLOB DatastructureGlob DataStructures/SearchEngineData.cpp DataStructures/RouteParameters.cpp)
list(REMOVE_ITEM DatastructureGlob DataStructures/Coordinate.cpp)
file(GLOB CoordinateGlob DataStructures/Coordinate.cpp)
file(GLOB AlgorithmGlob Algorithms/*.cpp)
file(GLOB HttpGlob Server/Http/*.cpp)
file(GLOB LibOSRMGlob Library/*.cpp)
file(GLOB DataStructureTestsGlob UnitTests/DataStructures/*.cpp DataStructures/HilbertValue.cpp)
set(
OSRMSources
@@ -67,14 +81,20 @@ set(
${AlgorithmGlob}
${HttpGlob}
)
add_library(COORDLIB STATIC ${CoordinateGlob})
add_library(FINGERPRINT STATIC Util/FingerPrint.cpp)
add_library(OSRM ${OSRMSources} Util/GitDescription.cpp Util/FingerPrint.cpp)
add_library(GITDESCRIPTION STATIC Util/GitDescription.cpp)
add_library(COORDINATE OBJECT ${CoordinateGlob})
add_library(FINGERPRINT OBJECT Util/FingerPrint.cpp)
add_library(GITDESCRIPTION OBJECT Util/GitDescription.cpp)
add_library(OSRM ${OSRMSources} $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER>)
add_dependencies(FINGERPRINT FingerPrintConfigure)
add_executable(osrm-routed routed.cpp ${ServerGlob})
add_executable(osrm-datastore datastore.cpp)
add_executable(osrm-datastore datastore.cpp $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:LOGGER>)
# Unit tests
add_executable(datastructure-tests EXCLUDE_FROM_ALL UnitTests/datastructure_tests.cpp ${DataStructureTestsGlob} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER>)
# Benchmarks
add_executable(rtree-bench EXCLUDE_FROM_ALL Benchmarks/StaticRTreeBench.cpp $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER>)
# Check the release mode
if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
@@ -98,7 +118,7 @@ if(CMAKE_BUILD_TYPE MATCHES Release)
# Since gcc 4.9 the LTO format is non-standart ('slim'), so we need to use the build-in tools
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND
NOT "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "4.9.0")
NOT "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "4.9.0" AND NOT MINGW)
message(STATUS "Using gcc specific binutils for LTO.")
set(CMAKE_AR "/usr/bin/gcc-ar")
set(CMAKE_RANLIB "/usr/bin/gcc-ranlib")
@@ -106,6 +126,10 @@ if(CMAKE_BUILD_TYPE MATCHES Release)
endif (HAS_LTO_FLAG)
endif()
if (NOT WIN32)
add_definitions(-DBOOST_TEST_DYN_LINK)
endif()
# Configuring compilers
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# using Clang
@@ -114,10 +138,9 @@ elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
# using GCC
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -fPIC")
if (WIN32) # using mingw
add_definitions(-DM_PI=3.141592653589793238462643383) # define M_PI
add_definitions(-D_USE_MATH_DEFINES) # define M_PI, M_1_PI etc.
add_definitions(-DWIN32)
SET(OPTIONAL_SOCKET_LIBS ws2_32 wsock32)
SET(OPTIONAL_OMP_LIB gomp)
endif()
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
# using Intel C++
@@ -131,18 +154,6 @@ elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
add_definitions(-D_WIN32_WINNT=0x0501)
endif()
# disable partitioning of LTO process when possible (fixes Debian issues)
set(LTO_PARTITION_FLAGS "")
CHECK_CXX_COMPILER_FLAG("-flto-partition=none" HAS_LTO_PARTITION_FLAG)
if (HAS_LTO_PARTITION_FLAG)
set(LTO_PARTITION_FLAGS "${LTO_PARTITION_FLAGS} -flto-partition=none")
endif (HAS_LTO_PARTITION_FLAG)
# Add Link-Time-Optimization flags, if supported (GCC >= 4.7) and enabled
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LTO_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LTO_FLAGS} ${LTO_PARTITION_FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${LTO_FLAGS} ${LTO_PARTITION_FLAGS}")
# Activate C++11
if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
ADD_DEFINITIONS(-std=c++11)
@@ -177,16 +188,21 @@ if(NOT Boost_FOUND)
endif()
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(OSRM ${Boost_LIBRARIES} COORDLIB)
target_link_libraries(osrm-extract ${Boost_LIBRARIES} FINGERPRINT GITDESCRIPTION COORDLIB IMPORT)
target_link_libraries(osrm-prepare ${Boost_LIBRARIES} FINGERPRINT GITDESCRIPTION COORDLIB IMPORT)
target_link_libraries(osrm-routed ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSRM FINGERPRINT GITDESCRIPTION)
target_link_libraries(osrm-datastore ${Boost_LIBRARIES} FINGERPRINT GITDESCRIPTION COORDLIB)
target_link_libraries(OSRM ${Boost_LIBRARIES})
target_link_libraries(osrm-extract ${Boost_LIBRARIES})
target_link_libraries(osrm-prepare ${Boost_LIBRARIES})
target_link_libraries(osrm-routed ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSRM)
target_link_libraries(osrm-datastore ${Boost_LIBRARIES})
target_link_libraries(datastructure-tests ${Boost_LIBRARIES})
target_link_libraries(rtree-bench ${Boost_LIBRARIES})
find_package(Threads REQUIRED)
target_link_libraries(osrm-extract ${CMAKE_THREAD_LIBS_INIT} ${OPTIONAL_OMP_LIB})
target_link_libraries(osrm-extract ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(osrm-datastore ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(osrm-prepare ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(OSRM ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(datastructure-tests ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(rtree-bench ${CMAKE_THREAD_LIBS_INIT})
find_package(TBB REQUIRED)
if(WIN32 AND CMAKE_BUILD_TYPE MATCHES Debug)
@@ -196,21 +212,13 @@ target_link_libraries(osrm-datastore ${TBB_LIBRARIES})
target_link_libraries(osrm-extract ${TBB_LIBRARIES})
target_link_libraries(osrm-prepare ${TBB_LIBRARIES})
target_link_libraries(osrm-routed ${TBB_LIBRARIES})
target_link_libraries(datastructure-tests ${TBB_LIBRARIES})
target_link_libraries(rtree-bench ${TBB_LIBRARIES})
include_directories(${TBB_INCLUDE_DIR})
find_package(Lua52)
if(NOT LUA52_FOUND)
find_package(Lua51 REQUIRED)
if(NOT APPLE)
find_package(LuaJIT 5.1)
endif()
else()
if(NOT APPLE)
find_package(LuaJIT 5.2)
endif()
endif()
find_package( Luabind REQUIRED )
include(check_luabind)
include_directories(${LUABIND_INCLUDE_DIR})
target_link_libraries(osrm-extract ${LUABIND_LIBRARY})
target_link_libraries(osrm-prepare ${LUABIND_LIBRARY})
@@ -253,29 +261,40 @@ include_directories(${ZLIB_INCLUDE_DIRS})
target_link_libraries(osrm-extract ${ZLIB_LIBRARY})
target_link_libraries(osrm-routed ${ZLIB_LIBRARY})
if(WITH_TOOLS)
if(WITH_TOOLS OR BUILD_TOOLS)
message(STATUS "Activating OSRM internal tools")
find_package(GDAL)
if(GDAL_FOUND)
add_executable(osrm-components Tools/components.cpp)
target_link_libraries(osrm-components ${TBB_LIBRARIES} IMPORT)
add_executable(osrm-components Tools/components.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER>)
target_link_libraries(osrm-components ${TBB_LIBRARIES})
include_directories(${GDAL_INCLUDE_DIR})
target_link_libraries(
osrm-components
${GDAL_LIBRARIES} ${Boost_LIBRARIES} FINGERPRINT GITDESCRIPTION COORDLIB)
${GDAL_LIBRARIES} ${Boost_LIBRARIES})
install(TARGETS osrm-components DESTINATION bin)
else()
message(FATAL_ERROR "libgdal and/or development headers not found")
endif()
add_executable(osrm-cli Tools/simpleclient.cpp)
target_link_libraries(osrm-cli ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSRM FINGERPRINT GITDESCRIPTION)
add_executable(osrm-cli Tools/simpleclient.cpp $<TARGET_OBJECTS:LOGGER>)
target_link_libraries(osrm-cli ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSRM)
target_link_libraries(osrm-cli ${TBB_LIBRARIES})
add_executable(osrm-io-benchmark Tools/io-benchmark.cpp)
target_link_libraries(osrm-io-benchmark ${Boost_LIBRARIES} GITDESCRIPTION)
add_executable(osrm-unlock-all Tools/unlock_all_mutexes.cpp)
target_link_libraries(osrm-unlock-all ${Boost_LIBRARIES} GITDESCRIPTION)
add_executable(osrm-io-benchmark Tools/io-benchmark.cpp $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:LOGGER>)
target_link_libraries(osrm-io-benchmark ${Boost_LIBRARIES})
add_executable(osrm-unlock-all Tools/unlock_all_mutexes.cpp $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:LOGGER>)
target_link_libraries(osrm-unlock-all ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
if(UNIX AND NOT APPLE)
target_link_libraries(osrm-unlock-all rt)
endif()
add_executable(osrm-check-hsgr Tools/check-hsgr.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:LOGGER>)
target_link_libraries(osrm-check-hsgr ${Boost_LIBRARIES})
add_executable(osrm-springclean Tools/springclean.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:GITDESCRIPTION>)
target_link_libraries(osrm-springclean ${Boost_LIBRARIES})
install(TARGETS osrm-cli DESTINATION bin)
install(TARGETS osrm-io-benchmark DESTINATION bin)
install(TARGETS osrm-unlock-all DESTINATION bin)
install(TARGETS osrm-check-hsgr DESTINATION bin)
install(TARGETS osrm-springclean DESTINATION bin)
endif()
file(GLOB InstallGlob Include/osrm/*.h Library/OSRM.h)
@@ -305,3 +324,8 @@ endforeach ()
configure_file(${CMAKE_SOURCE_DIR}/cmake/pkgconfig.in libosrm.pc @ONLY)
install(FILES ${PROJECT_BINARY_DIR}/libosrm.pc DESTINATION lib/pkgconfig)
if(BUILD_DEBIAN_PACKAGE)
include(CPackDebianConfig)
include(CPack)
endif()
+82 -115
View File
@@ -28,19 +28,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef CONTRACTOR_H
#define CONTRACTOR_H
#include "TemporaryStorage.h"
#include "../DataStructures/BinaryHeap.h"
#include "../DataStructures/DeallocatingVector.h"
#include "../DataStructures/DynamicGraph.h"
#include "../DataStructures/Percent.h"
#include "../DataStructures/QueryEdge.h"
#include "../DataStructures/Range.h"
#include "../DataStructures/XORFastHash.h"
#include "../DataStructures/XORFastHashStorage.h"
#include "../Util/SimpleLogger.h"
#include "../Util/simple_logger.hpp"
#include "../Util/StringUtil.h"
#include "../Util/TimingUtil.h"
#include "../typedefs.h"
#include <boost/assert.hpp>
#include <stxxl/vector>
#include <tbb/enumerable_thread_specific.h>
#include <tbb/parallel_for.h>
#include <tbb/parallel_sort.h>
@@ -60,15 +64,15 @@ class Contractor
is_original_via_node_ID(false)
{
}
ContractorEdgeData(unsigned _distance,
unsigned _originalEdges,
unsigned _id,
bool _shortcut,
bool _forward,
bool _backward)
: distance(_distance), id(_id),
originalEdges(std::min((unsigned)1 << 28, _originalEdges)), shortcut(_shortcut),
forward(_forward), backward(_backward), is_original_via_node_ID(false)
ContractorEdgeData(unsigned distance,
unsigned original_edges,
unsigned id,
bool shortcut,
bool forward,
bool backward)
: distance(distance), id(id),
originalEdges(std::min((unsigned)1 << 28, original_edges)), shortcut(shortcut),
forward(forward), backward(backward), is_original_via_node_ID(false)
{
}
unsigned distance;
@@ -88,19 +92,18 @@ class Contractor
ContractorHeapData(short h, bool t) : hop(h), target(t) {}
};
typedef DynamicGraph<ContractorEdgeData> ContractorGraph;
// typedef BinaryHeap< NodeID, NodeID, int, ContractorHeapData, ArrayStorage<NodeID, NodeID>
// > ContractorHeap;
typedef BinaryHeap<NodeID, NodeID, int, ContractorHeapData, XORFastHashStorage<NodeID, NodeID>>
ContractorHeap;
typedef ContractorGraph::InputEdge ContractorEdge;
using ContractorGraph = DynamicGraph<ContractorEdgeData>;
// using ContractorHeap = BinaryHeap<NodeID, NodeID, int, ContractorHeapData, ArrayStorage<NodeID, NodeID>
// >;
using ContractorHeap = BinaryHeap<NodeID, NodeID, int, ContractorHeapData, XORFastHashStorage<NodeID, NodeID>>;
using ContractorEdge = ContractorGraph::InputEdge;
struct ContractorThreadData
{
ContractorHeap heap;
std::vector<ContractorEdge> inserted_edges;
std::vector<NodeID> neighbours;
ContractorThreadData(NodeID nodes) : heap(nodes) {}
explicit ContractorThreadData(NodeID nodes) : heap(nodes) {}
};
struct NodePriorityData
@@ -132,7 +135,7 @@ class Contractor
struct ThreadDataContainer
{
ThreadDataContainer(int number_of_nodes) : number_of_nodes(number_of_nodes) {}
explicit ThreadDataContainer(int number_of_nodes) : number_of_nodes(number_of_nodes) {}
inline ContractorThreadData* getThreadData()
{
@@ -147,7 +150,7 @@ class Contractor
}
int number_of_nodes;
typedef tbb::enumerable_thread_specific<std::shared_ptr<ContractorThreadData>> EnumerableThreadData;
using EnumerableThreadData = tbb::enumerable_thread_specific<std::shared_ptr<ContractorThreadData>>;
EnumerableThreadData data;
};
@@ -156,41 +159,38 @@ class Contractor
{
std::vector<ContractorEdge> edges;
edges.reserve(input_edge_list.size() * 2);
temp_edge_counter = 0;
auto diter = input_edge_list.dbegin();
auto dend = input_edge_list.dend();
ContractorEdge new_edge;
while (diter != dend)
const auto dend = input_edge_list.dend();
for (auto diter = input_edge_list.dbegin(); diter != dend; ++diter)
{
new_edge.source = diter->source;
new_edge.target = diter->target;
new_edge.data = { static_cast<unsigned int>(std::max(diter->weight, 1)),
1,
diter->edge_id,
false,
diter->forward,
diter->backward};
BOOST_ASSERT_MSG(new_edge.data.distance > 0, "edge distance < 1");
BOOST_ASSERT_MSG(static_cast<unsigned int>(std::max(diter->weight, 1)) > 0, "edge distance < 1");
#ifndef NDEBUG
if (new_edge.data.distance > 24 * 60 * 60 * 10)
if (static_cast<unsigned int>(std::max(diter->weight, 1)) > 24 * 60 * 60 * 10)
{
SimpleLogger().Write(logWARNING) << "Edge weight large -> "
<< new_edge.data.distance;
<< static_cast<unsigned int>(std::max(diter->weight, 1));
}
#endif
edges.push_back(new_edge);
std::swap(new_edge.source, new_edge.target);
new_edge.data.forward = diter->backward;
new_edge.data.backward = diter->forward;
edges.push_back(new_edge);
++diter;
edges.emplace_back(diter->source, diter->target,
static_cast<unsigned int>(std::max(diter->weight, 1)),
1,
diter->edge_id,
false,
diter->forward ? true : false,
diter->backward ? true : false);
edges.emplace_back(diter->target, diter->source,
static_cast<unsigned int>(std::max(diter->weight, 1)),
1,
diter->edge_id,
false,
diter->backward ? true : false,
diter->forward ? true : false);
}
// clear input vector
edges.shrink_to_fit();
input_edge_list.clear();
edges.shrink_to_fit();
tbb::parallel_sort(edges.begin(), edges.end());
NodeID edge = 0;
for (NodeID i = 0; i < edges.size();)
@@ -201,7 +201,7 @@ class Contractor
// remove eigenloops
if (source == target)
{
i++;
++i;
continue;
}
ContractorEdge forward_edge;
@@ -280,13 +280,10 @@ class Contractor
// << "); via: " << contractor_graph->GetEdgeData(i).via;
// }
// Create temporary file
edge_storage_slot = TemporaryStorage::GetInstance().AllocateSlot();
std::cout << "contractor finished initalization" << std::endl;
}
~Contractor() { TemporaryStorage::GetInstance().DeallocateSlot(edge_storage_slot); }
~Contractor() { }
void Run()
{
@@ -362,7 +359,7 @@ class Contractor
// build forward and backward renumbering map and remap ids in remaining_nodes and
// Priorities.
for (unsigned new_node_id = 0; new_node_id < remaining_nodes.size(); ++new_node_id)
for (const auto new_node_id : osrm::irange<std::size_t>(0, remaining_nodes.size()))
{
// create renumbering maps in both directions
orig_node_id_to_new_id_map[new_node_id] = remaining_nodes[new_node_id].id;
@@ -371,9 +368,8 @@ class Contractor
node_priorities[remaining_nodes[new_node_id].id];
remaining_nodes[new_node_id].id = new_node_id;
}
TemporaryStorage &temporary_storage = TemporaryStorage::GetInstance();
// walk over all nodes
for (unsigned i = 0; i < contractor_graph->GetNumberOfNodes(); ++i)
for (const auto i : osrm::irange<std::size_t>(0, contractor_graph->GetNumberOfNodes()))
{
const NodeID source = i;
for (auto current_edge : contractor_graph->GetAdjacentEdgeRange(source))
@@ -381,26 +377,20 @@ class Contractor
ContractorGraph::EdgeData &data =
contractor_graph->GetEdgeData(current_edge);
const NodeID target = contractor_graph->GetTarget(current_edge);
if (UINT_MAX == new_node_id_from_orig_id_map[i])
if (SPECIAL_NODEID == new_node_id_from_orig_id_map[i])
{
// Save edges of this node w/o renumbering.
temporary_storage.WriteToSlot(
edge_storage_slot, (char *)&source, sizeof(NodeID));
temporary_storage.WriteToSlot(
edge_storage_slot, (char *)&target, sizeof(NodeID));
temporary_storage.WriteToSlot(edge_storage_slot,
(char *)&data,
sizeof(ContractorGraph::EdgeData));
++temp_edge_counter;
external_edge_list.push_back({source, target, data});
}
else
{
// node is not yet contracted.
// add (renumbered) outgoing edges to new DynamicGraph.
ContractorEdge new_edge;
new_edge.source = new_node_id_from_orig_id_map[source];
new_edge.target = new_node_id_from_orig_id_map[target];
new_edge.data = data;
ContractorEdge new_edge = {
new_node_id_from_orig_id_map[source],
new_node_id_from_orig_id_map[target],
data
};
new_edge.data.is_original_via_node_ID = true;
BOOST_ASSERT_MSG(UINT_MAX != new_node_id_from_orig_id_map[source],
"new source id not resolveable");
@@ -569,7 +559,7 @@ class Contractor
if (contractor_graph->GetNumberOfNodes())
{
Edge new_edge;
for (NodeID node = 0; node < number_of_nodes; ++node)
for (const auto node : osrm::irange(0u, number_of_nodes))
{
p.printStatus(node);
for (auto edge : contractor_graph->GetAdjacentEdgeRange(node))
@@ -611,29 +601,9 @@ class Contractor
orig_node_id_to_new_id_map.shrink_to_fit();
BOOST_ASSERT(0 == orig_node_id_to_new_id_map.capacity());
TemporaryStorage &temporary_storage = TemporaryStorage::GetInstance();
// loads edges of graph before renumbering, no need for further numbering action.
NodeID source;
NodeID target;
ContractorGraph::EdgeData data;
Edge restored_edge;
for (unsigned i = 0; i < temp_edge_counter; ++i)
{
temporary_storage.ReadFromSlot(edge_storage_slot, (char *)&source, sizeof(NodeID));
temporary_storage.ReadFromSlot(edge_storage_slot, (char *)&target, sizeof(NodeID));
temporary_storage.ReadFromSlot(
edge_storage_slot, (char *)&data, sizeof(ContractorGraph::EdgeData));
restored_edge.source = source;
restored_edge.target = target;
restored_edge.data.distance = data.distance;
restored_edge.data.shortcut = data.shortcut;
restored_edge.data.id = data.id;
restored_edge.data.forward = data.forward;
restored_edge.data.backward = data.backward;
edges.push_back(restored_edge);
}
temporary_storage.DeallocateSlot(edge_storage_slot);
edges.append(external_edge_list.begin(), external_edge_list.end());
external_edge_list.clear();
}
private:
@@ -648,7 +618,7 @@ class Contractor
int nodes = 0;
unsigned number_of_targets_found = 0;
while (heap.Size() > 0)
while (!heap.Empty())
{
const NodeID node = heap.DeleteMin();
const int distance = heap.GetKey(node);
@@ -658,12 +628,12 @@ class Contractor
{
return;
}
// Destination settled?
if (distance > max_distance)
{
return;
}
// Destination settled?
if (heap.GetData(node).target)
{
++number_of_targets_found;
@@ -731,7 +701,7 @@ class Contractor
template <bool RUNSIMULATION>
inline bool
ContractNode(ContractorThreadData *data, NodeID node, ContractionStats *stats = nullptr)
ContractNode(ContractorThreadData *data, const NodeID node, ContractionStats *stats = nullptr)
{
ContractorHeap &heap = data->heap;
int inserted_edges_size = data->inserted_edges.size();
@@ -803,21 +773,19 @@ class Contractor
}
else
{
ContractorEdge new_edge;
new_edge.source = source;
new_edge.target = target;
new_edge.data =
ContractorEdgeData(path_distance,
out_data.originalEdges + in_data.originalEdges,
node /*, 0, in_data.turnInstruction*/,
true,
true,
false);
inserted_edges.push_back(new_edge);
std::swap(new_edge.source, new_edge.target);
new_edge.data.forward = false;
new_edge.data.backward = true;
inserted_edges.push_back(new_edge);
inserted_edges.emplace_back(source, target, path_distance,
out_data.originalEdges + in_data.originalEdges,
node,
true,
true,
false);
inserted_edges.emplace_back(target, source, path_distance,
out_data.originalEdges + in_data.originalEdges,
node,
true,
false,
true);
}
}
}
@@ -879,7 +847,7 @@ class Contractor
std::sort(neighbours.begin(), neighbours.end());
neighbours.resize(std::unique(neighbours.begin(), neighbours.end()) - neighbours.begin());
for (int i = 0, e = (int)neighbours.size(); i < e; ++i)
for (const auto i : osrm::irange<std::size_t>(0, neighbours.size()))
{
contractor_graph->DeleteEdgesTo(neighbours[i], node);
}
@@ -917,7 +885,7 @@ class Contractor
}
inline bool IsNodeIndependent(
const std::vector<float> &priorities /*, const std::vector< NodePriorityData >& node_data*/,
const std::vector<float> &priorities,
ContractorThreadData *const data,
NodeID node) const
{
@@ -963,7 +931,7 @@ class Contractor
continue;
}
const float target_priority = priorities[target];
assert(target_priority >= 0);
BOOST_ASSERT(target_priority >= 0);
// found a neighbour with lower priority?
if (priority > target_priority)
{
@@ -983,8 +951,8 @@ class Contractor
// This bias function takes up 22 assembly instructions in total on X86
inline bool bias(const NodeID a, const NodeID b) const
{
unsigned short hasha = fast_hash(a);
unsigned short hashb = fast_hash(b);
const unsigned short hasha = fast_hash(a);
const unsigned short hashb = fast_hash(b);
// The compiler optimizes that to conditional register flags but without branching
// statements!
@@ -997,8 +965,7 @@ class Contractor
std::shared_ptr<ContractorGraph> contractor_graph;
std::vector<ContractorGraph::InputEdge> contracted_edge_list;
unsigned edge_storage_slot;
uint64_t temp_edge_counter;
stxxl::vector<QueryEdge> external_edge_list;
std::vector<NodeID> orig_node_id_to_new_id_map;
XORFastHash fast_hash;
};
+130 -127
View File
@@ -28,14 +28,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "EdgeBasedGraphFactory.h"
#include "../Algorithms/BFSComponentExplorer.h"
#include "../DataStructures/Percent.h"
#include "../Util/ComputeAngle.h"
#include "../DataStructures/Range.h"
#include "../Util/compute_angle.hpp"
#include "../Util/LuaUtil.h"
#include "../Util/SimpleLogger.h"
#include "../Util/simple_logger.hpp"
#include "../Util/TimingUtil.h"
#include <boost/assert.hpp>
#include <fstream>
#include <iomanip>
#include <limits>
EdgeBasedGraphFactory::EdgeBasedGraphFactory(
@@ -43,11 +45,11 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
std::unique_ptr<RestrictionMap> restriction_map,
std::vector<NodeID> &barrier_node_list,
std::vector<NodeID> &traffic_light_node_list,
std::vector<NodeInfo> &m_node_info_list,
std::vector<NodeInfo> &node_info_list,
SpeedProfileProperties &speed_profile)
: speed_profile(speed_profile),
m_number_of_edge_based_nodes(std::numeric_limits<unsigned>::max()),
m_node_info_list(m_node_info_list), m_node_based_graph(node_based_graph),
m_node_info_list(node_info_list), m_node_based_graph(node_based_graph),
m_restriction_map(std::move(restriction_map)), max_id(0)
{
@@ -77,33 +79,29 @@ void EdgeBasedGraphFactory::GetEdgeBasedNodes(std::vector<EdgeBasedNode> &nodes)
}
void
EdgeBasedGraphFactory::InsertEdgeBasedNode(NodeID u, NodeID v, EdgeID e1, bool belongs_to_tiny_cc)
EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeID node_v, const bool belongs_to_tiny_cc)
{
// merge edges together into one EdgeBasedNode
BOOST_ASSERT(u != SPECIAL_NODEID);
BOOST_ASSERT(v != SPECIAL_NODEID);
BOOST_ASSERT(e1 != SPECIAL_EDGEID);
BOOST_ASSERT(node_u != SPECIAL_NODEID);
BOOST_ASSERT(node_v != SPECIAL_NODEID);
#ifndef NDEBUG
// find forward edge id and
const EdgeID e1b = m_node_based_graph->FindEdge(u, v);
BOOST_ASSERT(e1 == e1b);
#endif
const EdgeID e1 = m_node_based_graph->FindEdge(node_u, node_v);
BOOST_ASSERT(e1 != SPECIAL_EDGEID);
const EdgeData &forward_data = m_node_based_graph->GetEdgeData(e1);
// find reverse edge id and
const EdgeID e2 = m_node_based_graph->FindEdge(v, u);
const EdgeID e2 = m_node_based_graph->FindEdge(node_v, node_u);
#ifndef NDEBUG
if (e2 == m_node_based_graph->EndEdges(v))
if (e2 == m_node_based_graph->EndEdges(node_v))
{
SimpleLogger().Write(logWARNING) << "Did not find edge (" << v << "," << u << ")";
SimpleLogger().Write(logWARNING) << "Did not find edge (" << node_v << "," << node_u << ")";
}
#endif
BOOST_ASSERT(e2 != SPECIAL_EDGEID);
BOOST_ASSERT(e2 < m_node_based_graph->EndEdges(v));
BOOST_ASSERT(e2 < m_node_based_graph->EndEdges(node_v));
const EdgeData &reverse_data = m_node_based_graph->GetEdgeData(e2);
if (forward_data.edgeBasedNodeID == SPECIAL_NODEID &&
@@ -125,6 +123,8 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(NodeID u, NodeID v, EdgeID e1, bool b
m_geometry_compressor.GetBucketReference(e2);
BOOST_ASSERT(forward_geometry.size() == reverse_geometry.size());
BOOST_ASSERT(0 != forward_geometry.size());
const unsigned geometry_size = forward_geometry.size();
BOOST_ASSERT(geometry_size > 1);
// reconstruct bidirectional edge with individual weights and put each into the NN index
@@ -135,7 +135,7 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(NodeID u, NodeID v, EdgeID e1, bool b
// TODO: move to lambda function with C++11
int temp_sum = 0;
for (unsigned i = 0; i < forward_geometry.size(); ++i)
for (const auto i : osrm::irange(0u, geometry_size))
{
forward_dist_prefix_sum[i] = temp_sum;
temp_sum += forward_geometry[i].second;
@@ -144,20 +144,16 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(NodeID u, NodeID v, EdgeID e1, bool b
}
temp_sum = 0;
for (unsigned i = 0; i < reverse_geometry.size(); ++i)
for (const auto i : osrm::irange(0u, geometry_size))
{
temp_sum += reverse_geometry[reverse_geometry.size() - 1 - i].second;
reverse_dist_prefix_sum[i] = reverse_data.distance - temp_sum;
BOOST_ASSERT(reverse_data.distance >= temp_sum);
// BOOST_ASSERT(reverse_data.distance >= temp_sum);
}
BOOST_ASSERT(forward_geometry.size() == reverse_geometry.size());
NodeID current_edge_source_coordinate_id = node_u;
const unsigned geometry_size = forward_geometry.size();
BOOST_ASSERT(geometry_size > 1);
NodeID current_edge_source_coordinate_id = u;
if (forward_data.edgeBasedNodeID != SPECIAL_NODEID)
if (SPECIAL_NODEID != forward_data.edgeBasedNodeID)
{
max_id = std::max(forward_data.edgeBasedNodeID, max_id);
}
@@ -167,7 +163,7 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(NodeID u, NodeID v, EdgeID e1, bool b
}
// traverse arrays from start and end respectively
for (unsigned i = 0; i < geometry_size; ++i)
for (const auto i : osrm::irange(0u, geometry_size))
{
BOOST_ASSERT(current_edge_source_coordinate_id ==
reverse_geometry[geometry_size - 1 - i].first);
@@ -181,24 +177,26 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(NodeID u, NodeID v, EdgeID e1, bool b
current_edge_target_coordinate_id,
forward_data.nameID,
forward_geometry[i].second,
reverse_geometry[i].second,
reverse_geometry[geometry_size - 1 - i].second,
forward_dist_prefix_sum[i],
reverse_dist_prefix_sum[i],
m_geometry_compressor.GetPositionForID(e1),
i,
belongs_to_tiny_cc);
belongs_to_tiny_cc,
forward_data.travel_mode,
reverse_data.travel_mode);
current_edge_source_coordinate_id = current_edge_target_coordinate_id;
BOOST_ASSERT(m_edge_based_node_list.back().IsCompressed());
BOOST_ASSERT(u != m_edge_based_node_list.back().u ||
v != m_edge_based_node_list.back().v);
BOOST_ASSERT(node_u != m_edge_based_node_list.back().u ||
node_v != m_edge_based_node_list.back().v);
BOOST_ASSERT(u != m_edge_based_node_list.back().v ||
v != m_edge_based_node_list.back().u);
BOOST_ASSERT(node_u != m_edge_based_node_list.back().v ||
node_v != m_edge_based_node_list.back().u);
}
BOOST_ASSERT(current_edge_source_coordinate_id == v);
BOOST_ASSERT(current_edge_source_coordinate_id == node_v);
BOOST_ASSERT(m_edge_based_node_list.back().IsCompressed());
}
else
@@ -225,18 +223,20 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(NodeID u, NodeID v, EdgeID e1, bool b
BOOST_ASSERT(forward_data.edgeBasedNodeID != SPECIAL_NODEID ||
reverse_data.edgeBasedNodeID != SPECIAL_NODEID);
m_edge_based_node_list.emplace_back(EdgeBasedNode(forward_data.edgeBasedNodeID,
reverse_data.edgeBasedNodeID,
u,
v,
forward_data.nameID,
forward_data.distance,
reverse_data.distance,
0,
0,
SPECIAL_EDGEID,
0,
belongs_to_tiny_cc));
m_edge_based_node_list.emplace_back(forward_data.edgeBasedNodeID,
reverse_data.edgeBasedNodeID,
node_u,
node_v,
forward_data.nameID,
forward_data.distance,
reverse_data.distance,
0,
0,
SPECIAL_EDGEID,
0,
belongs_to_tiny_cc,
forward_data.travel_mode,
reverse_data.travel_mode);
BOOST_ASSERT(!m_edge_based_node_list.back().IsCompressed());
}
}
@@ -289,61 +289,61 @@ void EdgeBasedGraphFactory::CompressGeometry()
const unsigned original_number_of_nodes = m_node_based_graph->GetNumberOfNodes();
const unsigned original_number_of_edges = m_node_based_graph->GetNumberOfEdges();
Percent p(original_number_of_nodes);
Percent progress(original_number_of_nodes);
unsigned removed_node_count = 0;
for (NodeID v = 0; v < original_number_of_nodes; ++v)
for (const NodeID node_v : osrm::irange(0u, original_number_of_nodes))
{
p.printStatus(v);
progress.printStatus(node_v);
// only contract degree 2 vertices
if (2 != m_node_based_graph->GetOutDegree(v))
if (2 != m_node_based_graph->GetOutDegree(node_v))
{
continue;
}
// don't contract barrier node
if (m_barrier_nodes.end() != m_barrier_nodes.find(v))
if (m_barrier_nodes.end() != m_barrier_nodes.find(node_v))
{
continue;
}
// check if v is a via node for a turn restriction, i.e. a 'directed' barrier node
if (m_restriction_map->IsViaNode(v))
if (m_restriction_map->IsViaNode(node_v))
{
continue;
}
const bool reverse_edge_order =
!(m_node_based_graph->GetEdgeData(m_node_based_graph->BeginEdges(v)).forward);
const EdgeID forward_e2 = m_node_based_graph->BeginEdges(v) + reverse_edge_order;
!(m_node_based_graph->GetEdgeData(m_node_based_graph->BeginEdges(node_v)).forward);
const EdgeID forward_e2 = m_node_based_graph->BeginEdges(node_v) + reverse_edge_order;
BOOST_ASSERT(SPECIAL_EDGEID != forward_e2);
const EdgeID reverse_e2 = m_node_based_graph->BeginEdges(v) + 1 - reverse_edge_order;
const EdgeID reverse_e2 = m_node_based_graph->BeginEdges(node_v) + 1 - reverse_edge_order;
BOOST_ASSERT(SPECIAL_EDGEID != reverse_e2);
const EdgeData &fwd_edge_data2 = m_node_based_graph->GetEdgeData(forward_e2);
const EdgeData &rev_edge_data2 = m_node_based_graph->GetEdgeData(reverse_e2);
const NodeID w = m_node_based_graph->GetTarget(forward_e2);
BOOST_ASSERT(SPECIAL_NODEID != w);
BOOST_ASSERT(v != w);
const NodeID u = m_node_based_graph->GetTarget(reverse_e2);
BOOST_ASSERT(SPECIAL_NODEID != u);
BOOST_ASSERT(u != v);
const NodeID node_w = m_node_based_graph->GetTarget(forward_e2);
BOOST_ASSERT(SPECIAL_NODEID != node_w);
BOOST_ASSERT(node_v != node_w);
const NodeID node_u = m_node_based_graph->GetTarget(reverse_e2);
BOOST_ASSERT(SPECIAL_NODEID != node_u);
BOOST_ASSERT(node_u != node_v);
const EdgeID forward_e1 = m_node_based_graph->FindEdge(u, v);
BOOST_ASSERT(m_node_based_graph->EndEdges(u) != forward_e1);
const EdgeID forward_e1 = m_node_based_graph->FindEdge(node_u, node_v);
BOOST_ASSERT(m_node_based_graph->EndEdges(node_u) != forward_e1);
BOOST_ASSERT(SPECIAL_EDGEID != forward_e1);
BOOST_ASSERT(v == m_node_based_graph->GetTarget(forward_e1));
const EdgeID reverse_e1 = m_node_based_graph->FindEdge(w, v);
BOOST_ASSERT(node_v == m_node_based_graph->GetTarget(forward_e1));
const EdgeID reverse_e1 = m_node_based_graph->FindEdge(node_w, node_v);
BOOST_ASSERT(SPECIAL_EDGEID != reverse_e1);
BOOST_ASSERT(v == m_node_based_graph->GetTarget(reverse_e1));
BOOST_ASSERT(node_v == m_node_based_graph->GetTarget(reverse_e1));
const EdgeData &fwd_edge_data1 = m_node_based_graph->GetEdgeData(forward_e1);
const EdgeData &rev_edge_data1 = m_node_based_graph->GetEdgeData(reverse_e1);
if ((m_node_based_graph->FindEdge(u, w) != m_node_based_graph->EndEdges(u)) ||
(m_node_based_graph->FindEdge(w, u) != m_node_based_graph->EndEdges(w)))
if ((m_node_based_graph->FindEdge(node_u, node_w) != m_node_based_graph->EndEdges(node_u)) ||
(m_node_based_graph->FindEdge(node_w, node_u) != m_node_based_graph->EndEdges(node_w)))
{
continue;
}
@@ -366,7 +366,7 @@ void EdgeBasedGraphFactory::CompressGeometry()
BOOST_ASSERT(0 != forward_weight2);
const bool add_traffic_signal_penalty =
(m_traffic_lights.find(v) != m_traffic_lights.end());
(m_traffic_lights.find(node_v) != m_traffic_lights.end());
// add weight of e2's to e1
m_node_based_graph->GetEdgeData(forward_e1).distance += fwd_edge_data2.distance;
@@ -374,43 +374,43 @@ void EdgeBasedGraphFactory::CompressGeometry()
if (add_traffic_signal_penalty)
{
m_node_based_graph->GetEdgeData(forward_e1).distance +=
speed_profile.trafficSignalPenalty;
speed_profile.traffic_signal_penalty;
m_node_based_graph->GetEdgeData(reverse_e1).distance +=
speed_profile.trafficSignalPenalty;
speed_profile.traffic_signal_penalty;
}
// extend e1's to targets of e2's
m_node_based_graph->SetTarget(forward_e1, w);
m_node_based_graph->SetTarget(reverse_e1, u);
m_node_based_graph->SetTarget(forward_e1, node_w);
m_node_based_graph->SetTarget(reverse_e1, node_u);
// remove e2's (if bidir, otherwise only one)
m_node_based_graph->DeleteEdge(v, forward_e2);
m_node_based_graph->DeleteEdge(v, reverse_e2);
m_node_based_graph->DeleteEdge(node_v, forward_e2);
m_node_based_graph->DeleteEdge(node_v, reverse_e2);
// update any involved turn restrictions
m_restriction_map->FixupStartingTurnRestriction(u, v, w);
m_restriction_map->FixupArrivingTurnRestriction(u, v, w);
m_restriction_map->FixupStartingTurnRestriction(node_u, node_v, node_w);
m_restriction_map->FixupArrivingTurnRestriction(node_u, node_v, node_w);
m_restriction_map->FixupStartingTurnRestriction(w, v, u);
m_restriction_map->FixupArrivingTurnRestriction(w, v, u);
m_restriction_map->FixupStartingTurnRestriction(node_w, node_v, node_u);
m_restriction_map->FixupArrivingTurnRestriction(node_w, node_v, node_u);
// store compressed geometry in container
m_geometry_compressor.CompressEdge(
forward_e1,
forward_e2,
v,
w,
node_v,
node_w,
forward_weight1 +
(add_traffic_signal_penalty ? speed_profile.trafficSignalPenalty : 0),
(add_traffic_signal_penalty ? speed_profile.traffic_signal_penalty : 0),
forward_weight2);
m_geometry_compressor.CompressEdge(
reverse_e1,
reverse_e2,
v,
u,
node_v,
node_u,
reverse_weight1,
reverse_weight2 +
(add_traffic_signal_penalty ? speed_profile.trafficSignalPenalty : 0));
(add_traffic_signal_penalty ? speed_profile.traffic_signal_penalty : 0));
++removed_node_count;
BOOST_ASSERT(m_node_based_graph->GetEdgeData(forward_e1).nameID ==
@@ -422,7 +422,8 @@ void EdgeBasedGraphFactory::CompressGeometry()
unsigned new_node_count = 0;
unsigned new_edge_count = 0;
for (unsigned i = 0; i < m_node_based_graph->GetNumberOfNodes(); ++i)
for(const auto i : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes()))
{
if (m_node_based_graph->GetOutDegree(i) > 0)
{
@@ -438,7 +439,7 @@ void EdgeBasedGraphFactory::CompressGeometry()
}
/**
* Writes the id of the edge in the edge expanded graph (into the egde in the node based graph)
* Writes the id of the edge in the edge expanded graph (into the edge in the node based graph)
*/
void EdgeBasedGraphFactory::RenumberEdges()
{
@@ -482,21 +483,17 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
<< " many components";
SimpleLogger().Write() << "generating edge-expanded nodes";
Percent p(m_node_based_graph->GetNumberOfNodes());
Percent progress(m_node_based_graph->GetNumberOfNodes());
// loop over all edges and generate new set of nodes
for (NodeID u = 0, end = m_node_based_graph->GetNumberOfNodes(); u < end; ++u)
{
BOOST_ASSERT(u != SPECIAL_NODEID);
BOOST_ASSERT(u < m_node_based_graph->GetNumberOfNodes());
p.printIncrement();
progress.printStatus(u);
for (EdgeID e1 : m_node_based_graph->GetAdjacentEdgeRange(u))
{
const EdgeData &edge_data = m_node_based_graph->GetEdgeData(e1);
if (edge_data.edgeBasedNodeID == SPECIAL_NODEID)
{
// continue;
}
BOOST_ASSERT(e1 != SPECIAL_EDGEID);
const NodeID v = m_node_based_graph->GetTarget(e1);
@@ -508,7 +505,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
}
BOOST_ASSERT(u < v);
BOOST_ASSERT(edge_data.type != SHRT_MAX);
// Note: edges that end on barrier nodes or on a turn restriction
// may actually be in two distinct components. We choose the smallest
@@ -516,7 +512,14 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
component_explorer.GetComponentSize(v));
const bool component_is_tiny = (size_of_component < 1000);
InsertEdgeBasedNode(u, v, e1, component_is_tiny);
if (edge_data.edgeBasedNodeID == SPECIAL_NODEID)
{
InsertEdgeBasedNode(v, u, component_is_tiny);
}
else
{
InsertEdgeBasedNode(u, v, component_is_tiny);
}
}
}
@@ -552,11 +555,12 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg
unsigned skipped_barrier_turns_counter = 0;
unsigned compressed = 0;
Percent p(m_node_based_graph->GetNumberOfNodes());
Percent progress(m_node_based_graph->GetNumberOfNodes());
for (NodeID u = 0, end = m_node_based_graph->GetNumberOfNodes(); u < end; ++u)
{
for (EdgeID e1 : m_node_based_graph->GetAdjacentEdgeRange(u))
progress.printStatus(u);
for (const EdgeID e1 : m_node_based_graph->GetAdjacentEdgeRange(u))
{
if (!m_node_based_graph->GetEdgeData(e1).forward)
{
@@ -625,15 +629,27 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg
unsigned distance = edge_data1.distance;
if (m_traffic_lights.find(v) != m_traffic_lights.end())
{
distance += speed_profile.trafficSignalPenalty;
distance += speed_profile.traffic_signal_penalty;
}
const double angle = GetAngleBetweenThreeFixedPointCoordinates(
m_node_info_list[u], m_node_info_list[v], m_node_info_list[w]);
const int turn_penalty = GetTurnPenalty(angle, lua_state);
TurnInstruction turn_instruction = AnalyzeTurn(u, v, w, angle);
// unpack last node of first segment if packed
const auto first_coordinate = m_node_info_list[(m_geometry_compressor.HasEntryForID(e1) ?
m_geometry_compressor.GetLastNodeIDOfBucket(e1) :
u)];
// unpack first node of second segment if packed
const auto third_coordinate = m_node_info_list[(m_geometry_compressor.HasEntryForID(e2) ?
m_geometry_compressor.GetFirstNodeIDOfBucket(e2) :
w)];
const double turn_angle = ComputeAngle::OfThreeFixedPointCoordinates(
first_coordinate, m_node_info_list[v], third_coordinate);
const int turn_penalty = GetTurnPenalty(turn_angle, lua_state);
TurnInstruction turn_instruction = AnalyzeTurn(u, v, w, turn_angle);
if (turn_instruction == TurnInstruction::UTurn)
{
distance += speed_profile.uTurnPenalty;
distance += speed_profile.u_turn_penalty;
}
distance += turn_penalty;
@@ -648,7 +664,8 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg
(edge_is_compressed ? m_geometry_compressor.GetPositionForID(e1) : v),
edge_data1.nameID,
turn_instruction,
edge_is_compressed);
edge_is_compressed,
edge_data2.travel_mode);
++original_edges_counter;
@@ -668,7 +685,6 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg
false));
}
}
p.printIncrement();
}
FlushVectorToStream(edge_data_file, original_edge_data_vector);
@@ -702,37 +718,28 @@ int EdgeBasedGraphFactory::GetTurnPenalty(double angle, lua_State *lua_state) co
return 0;
}
TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u,
const NodeID v,
const NodeID w,
double angle)
TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID node_u,
const NodeID node_v,
const NodeID node_w,
const double angle)
const
{
if (u == w)
if (node_u == node_w)
{
return TurnInstruction::UTurn;
}
const EdgeID edge1 = m_node_based_graph->FindEdge(u, v);
const EdgeID edge2 = m_node_based_graph->FindEdge(v, w);
const EdgeID edge1 = m_node_based_graph->FindEdge(node_u, node_v);
const EdgeID edge2 = m_node_based_graph->FindEdge(node_v, node_w);
const EdgeData &data1 = m_node_based_graph->GetEdgeData(edge1);
const EdgeData &data2 = m_node_based_graph->GetEdgeData(edge2);
if (!data1.contraFlow && data2.contraFlow)
{
return TurnInstruction::EnterAgainstAllowedDirection;
}
if (data1.contraFlow && !data2.contraFlow)
{
return TurnInstruction::LeaveAgainstAllowedDirection;
}
// roundabouts need to be handled explicitely
if (data1.roundabout && data2.roundabout)
{
// Is a turn possible? If yes, we stay on the roundabout!
if (1 == m_node_based_graph->GetDirectedOutDegree(v))
if (1 == m_node_based_graph->GetDirectedOutDegree(node_v))
{
// No turn possible.
return TurnInstruction::NoTurn;
@@ -760,11 +767,7 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u,
{
// TODO: Here we should also do a small graph exploration to check for
// more complex situations
if (0 != data1.nameID)
{
return TurnInstruction::NoTurn;
}
else if (m_node_based_graph->GetOutDegree(v) <= 2)
if (0 != data1.nameID || m_node_based_graph->GetOutDegree(node_v) <= 2)
{
return TurnInstruction::NoTurn;
}
+7 -7
View File
@@ -74,7 +74,7 @@ class EdgeBasedGraphFactory
void GetEdgeBasedNodes(std::vector<EdgeBasedNode> &nodes);
TurnInstruction AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w, double angle) const;
TurnInstruction AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w, const double angle) const;
int GetTurnPenalty(double angle, lua_State *lua_state) const;
@@ -83,17 +83,17 @@ class EdgeBasedGraphFactory
struct SpeedProfileProperties
{
SpeedProfileProperties()
: trafficSignalPenalty(0), uTurnPenalty(0), has_turn_penalty_function(false)
: traffic_signal_penalty(0), u_turn_penalty(0), has_turn_penalty_function(false)
{
}
int trafficSignalPenalty;
int uTurnPenalty;
int traffic_signal_penalty;
int u_turn_penalty;
bool has_turn_penalty_function;
} speed_profile;
private:
typedef NodeBasedDynamicGraph::EdgeData EdgeData;
using EdgeData = NodeBasedDynamicGraph::EdgeData;
unsigned m_number_of_edge_based_nodes;
@@ -115,12 +115,12 @@ class EdgeBasedGraphFactory
void GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename,
lua_State *lua_state);
void InsertEdgeBasedNode(NodeID u, NodeID v, EdgeID e1, bool belongsToTinyComponent);
void InsertEdgeBasedNode(const NodeID u, const NodeID v, const bool belongsToTinyComponent);
void FlushVectorToStream(std::ofstream &edge_data_file,
std::vector<OriginalEdgeData> &original_edge_data_vector) const;
unsigned max_id;
NodeID max_id;
};
#endif /* EDGEBASEDGRAPHFACTORY_H_ */
+15 -1
View File
@@ -26,7 +26,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "GeometryCompressor.h"
#include "../Util/SimpleLogger.h"
#include "../Util/simple_logger.hpp"
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
@@ -225,3 +225,17 @@ GeometryCompressor::GetBucketReference(const EdgeID edge_id) const
const unsigned index = m_edge_id_to_list_index_map.at(edge_id);
return m_compressed_geometries.at(index);
}
NodeID GeometryCompressor::GetFirstNodeIDOfBucket(const EdgeID edge_id) const
{
const auto &bucket = GetBucketReference(edge_id);
BOOST_ASSERT(bucket.size() >= 2);
return bucket[1].first;
}
NodeID GeometryCompressor::GetLastNodeIDOfBucket(const EdgeID edge_id) const
{
const auto &bucket = GetBucketReference(edge_id);
BOOST_ASSERT(bucket.size() >= 2);
return bucket[bucket.size()-2].first;
}
+6 -4
View File
@@ -25,6 +25,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GEOMETRY_COMPRESSOR_H
#define GEOMETRY_COMPRESSOR_H
#include "../typedefs.h"
#include <unordered_map>
@@ -32,13 +35,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include <vector>
#ifndef GEOMETRY_COMPRESSOR_H
#define GEOMETRY_COMPRESSOR_H
class GeometryCompressor
{
public:
typedef std::pair<NodeID, EdgeWeight> CompressedNode;
using CompressedNode = std::pair<NodeID, EdgeWeight>;
GeometryCompressor();
void CompressEdge(const EdgeID surviving_edge_id,
@@ -54,6 +54,8 @@ class GeometryCompressor
unsigned GetPositionForID(const EdgeID edge_id) const;
const std::vector<GeometryCompressor::CompressedNode> &
GetBucketReference(const EdgeID edge_id) const;
NodeID GetFirstNodeIDOfBucket(const EdgeID edge_id) const;
NodeID GetLastNodeIDOfBucket(const EdgeID edge_id) const;
private:
void IncreaseFreeList();
+575
View File
@@ -0,0 +1,575 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Prepare.h"
#include "Contractor.h"
#include "../Algorithms/IteratorBasedCRC32.h"
#include "../DataStructures/BinaryHeap.h"
#include "../DataStructures/DeallocatingVector.h"
#include "../DataStructures/Range.h"
#include "../DataStructures/StaticRTree.h"
#include "../DataStructures/RestrictionMap.h"
#include "../Util/GitDescription.h"
#include "../Util/LuaUtil.h"
#include "../Util/make_unique.hpp"
#include "../Util/OSRMException.h"
#include "../Util/simple_logger.hpp"
#include "../Util/StringUtil.h"
#include "../Util/TimingUtil.h"
#include "../typedefs.h"
#include <boost/filesystem/fstream.hpp>
#include <boost/program_options.hpp>
#include <tbb/task_scheduler_init.h>
#include <tbb/parallel_sort.h>
#include <chrono>
#include <memory>
#include <string>
#include <thread>
#include <vector>
Prepare::Prepare() : requested_num_threads(1) {}
Prepare::~Prepare() {}
int Prepare::Process(int argc, char *argv[])
{
LogPolicy::GetInstance().Unmute();
TIMER_START(preparing);
TIMER_START(expansion);
if (!ParseArguments(argc, argv))
{
return 0;
}
if (!boost::filesystem::is_regular_file(input_path))
{
SimpleLogger().Write(logWARNING) << "Input file " << input_path.string() << " not found!";
return 1;
}
if (!boost::filesystem::is_regular_file(profile_path))
{
SimpleLogger().Write(logWARNING) << "Profile " << profile_path.string() << " not found!";
return 1;
}
if (1 > requested_num_threads)
{
SimpleLogger().Write(logWARNING) << "Number of threads must be 1 or larger";
return 1;
}
const unsigned recommended_num_threads = tbb::task_scheduler_init::default_num_threads();
SimpleLogger().Write() << "Input file: " << input_path.filename().string();
SimpleLogger().Write() << "Restrictions file: " << restrictions_path.filename().string();
SimpleLogger().Write() << "Profile: " << profile_path.filename().string();
SimpleLogger().Write() << "Threads: " << requested_num_threads;
if (recommended_num_threads != requested_num_threads)
{
SimpleLogger().Write(logWARNING) << "The recommended number of threads is "
<< recommended_num_threads
<< "! This setting may have performance side-effects.";
}
tbb::task_scheduler_init init(requested_num_threads);
LogPolicy::GetInstance().Unmute();
FingerPrint fingerprint_orig;
CheckRestrictionsFile(fingerprint_orig);
boost::filesystem::ifstream input_stream(input_path, std::ios::in | std::ios::binary);
node_filename = input_path.string() + ".nodes";
edge_out = input_path.string() + ".edges";
geometry_filename = input_path.string() + ".geometry";
graph_out = input_path.string() + ".hsgr";
rtree_nodes_path = input_path.string() + ".ramIndex";
rtree_leafs_path = input_path.string() + ".fileIndex";
/*** Setup Scripting Environment ***/
// Create a new lua state
lua_State *lua_state = luaL_newstate();
// Connect LuaBind to this lua state
luabind::open(lua_state);
EdgeBasedGraphFactory::SpeedProfileProperties speed_profile;
if (!SetupScriptingEnvironment(lua_state, speed_profile))
{
return 1;
}
#ifdef WIN32
#pragma message("Memory consumption on Windows can be higher due to different bit packing")
#else
static_assert(sizeof(ImportEdge) == 20,
"changing ImportEdge type has influence on memory consumption!");
#endif
NodeID number_of_node_based_nodes =
readBinaryOSRMGraphFromStream(input_stream,
edge_list,
barrier_node_list,
traffic_light_list,
&internal_to_external_node_map,
restriction_list);
input_stream.close();
if (edge_list.empty())
{
SimpleLogger().Write(logWARNING) << "The input data is empty, exiting.";
return 1;
}
SimpleLogger().Write() << restriction_list.size() << " restrictions, "
<< barrier_node_list.size() << " bollard nodes, "
<< traffic_light_list.size() << " traffic lights";
std::vector<EdgeBasedNode> node_based_edge_list;
unsigned number_of_edge_based_nodes = 0;
DeallocatingVector<EdgeBasedEdge> edge_based_edge_list;
// init node_based_edge_list, edge_based_edge_list by edgeList
number_of_edge_based_nodes = BuildEdgeExpandedGraph(lua_state,
number_of_node_based_nodes,
node_based_edge_list,
edge_based_edge_list,
speed_profile);
lua_close(lua_state);
TIMER_STOP(expansion);
BuildRTree(node_based_edge_list);
RangebasedCRC32 crc32;
if (crc32.using_hardware())
{
SimpleLogger().Write() << "using hardware based CRC32 computation";
}
else
{
SimpleLogger().Write() << "using software based CRC32 computation";
}
const unsigned crc32_value = crc32(node_based_edge_list);
node_based_edge_list.clear();
node_based_edge_list.shrink_to_fit();
SimpleLogger().Write() << "CRC32: " << crc32_value;
WriteNodeMapping();
/***
* Contracting the edge-expanded graph
*/
SimpleLogger().Write() << "initializing contractor";
auto contractor =
osrm::make_unique<Contractor>(number_of_edge_based_nodes, edge_based_edge_list);
TIMER_START(contraction);
contractor->Run();
TIMER_STOP(contraction);
SimpleLogger().Write() << "Contraction took " << TIMER_SEC(contraction) << " sec";
DeallocatingVector<QueryEdge> contracted_edge_list;
contractor->GetEdges(contracted_edge_list);
contractor.reset();
/***
* Sorting contracted edges in a way that the static query graph can read some in in-place.
*/
tbb::parallel_sort(contracted_edge_list.begin(), contracted_edge_list.end());
const unsigned contracted_edge_count = contracted_edge_list.size();
SimpleLogger().Write() << "Serializing compacted graph of " << contracted_edge_count
<< " edges";
boost::filesystem::ofstream hsgr_output_stream(graph_out, std::ios::binary);
hsgr_output_stream.write((char *)&fingerprint_orig, sizeof(FingerPrint));
const unsigned max_used_node_id = 1 + [&contracted_edge_list]
{
unsigned tmp_max = 0;
for (const QueryEdge &edge : contracted_edge_list)
{
BOOST_ASSERT(SPECIAL_NODEID != edge.source);
BOOST_ASSERT(SPECIAL_NODEID != edge.target);
tmp_max = std::max(tmp_max, edge.source);
tmp_max = std::max(tmp_max, edge.target);
}
return tmp_max;
}();
SimpleLogger().Write(logDEBUG) << "input graph has " << number_of_edge_based_nodes << " nodes";
SimpleLogger().Write(logDEBUG) << "contracted graph has " << max_used_node_id << " nodes";
std::vector<StaticGraph<EdgeData>::NodeArrayEntry> node_array;
node_array.resize(number_of_edge_based_nodes + 1);
SimpleLogger().Write() << "Building node array";
StaticGraph<EdgeData>::EdgeIterator edge = 0;
StaticGraph<EdgeData>::EdgeIterator position = 0;
StaticGraph<EdgeData>::EdgeIterator last_edge = edge;
// initializing 'first_edge'-field of nodes:
for (const auto node : osrm::irange(0u, max_used_node_id))
{
last_edge = edge;
while ((edge < contracted_edge_count) && (contracted_edge_list[edge].source == node))
{
++edge;
}
node_array[node].first_edge = position; //=edge
position += edge - last_edge; // remove
}
for (const auto sentinel_counter : osrm::irange<unsigned>(max_used_node_id, node_array.size()))
{
// sentinel element, guarded against underflow
node_array[sentinel_counter].first_edge = contracted_edge_count;
}
SimpleLogger().Write() << "Serializing node array";
const unsigned node_array_size = node_array.size();
// serialize crc32, aka checksum
hsgr_output_stream.write((char *)&crc32_value, sizeof(unsigned));
// serialize number of nodes
hsgr_output_stream.write((char *)&node_array_size, sizeof(unsigned));
// serialize number of edges
hsgr_output_stream.write((char *)&contracted_edge_count, sizeof(unsigned));
// serialize all nodes
if (node_array_size > 0)
{
hsgr_output_stream.write((char *)&node_array[0],
sizeof(StaticGraph<EdgeData>::NodeArrayEntry) * node_array_size);
}
// serialize all edges
SimpleLogger().Write() << "Building edge array";
edge = 0;
int number_of_used_edges = 0;
StaticGraph<EdgeData>::EdgeArrayEntry current_edge;
for (const auto edge : osrm::irange<std::size_t>(0, contracted_edge_list.size()))
{
// no eigen loops
BOOST_ASSERT(contracted_edge_list[edge].source != contracted_edge_list[edge].target);
current_edge.target = contracted_edge_list[edge].target;
current_edge.data = contracted_edge_list[edge].data;
// every target needs to be valid
BOOST_ASSERT(current_edge.target < max_used_node_id);
#ifndef NDEBUG
if (current_edge.data.distance <= 0)
{
SimpleLogger().Write(logWARNING) << "Edge: " << edge
<< ",source: " << contracted_edge_list[edge].source
<< ", target: " << contracted_edge_list[edge].target
<< ", dist: " << current_edge.data.distance;
SimpleLogger().Write(logWARNING) << "Failed at adjacency list of node "
<< contracted_edge_list[edge].source << "/"
<< node_array.size() - 1;
return 1;
}
#endif
hsgr_output_stream.write((char *)&current_edge,
sizeof(StaticGraph<EdgeData>::EdgeArrayEntry));
++number_of_used_edges;
}
hsgr_output_stream.close();
TIMER_STOP(preparing);
SimpleLogger().Write() << "Preprocessing : " << TIMER_SEC(preparing) << " seconds";
SimpleLogger().Write() << "Expansion : " << (number_of_node_based_nodes / TIMER_SEC(expansion))
<< " nodes/sec and "
<< (number_of_edge_based_nodes / TIMER_SEC(expansion)) << " edges/sec";
SimpleLogger().Write() << "Contraction: "
<< (number_of_edge_based_nodes / TIMER_SEC(contraction))
<< " nodes/sec and " << number_of_used_edges / TIMER_SEC(contraction)
<< " edges/sec";
node_array.clear();
SimpleLogger().Write() << "finished preprocessing";
return 0;
}
/**
\brief Parses command line arguments
\param argc count of arguments
\param argv array of arguments
\param result [out] value for exit return value
\return true if everything is ok, false if need to terminate execution
*/
bool Prepare::ParseArguments(int argc, char *argv[])
{
// declare a group of options that will be allowed only on command line
boost::program_options::options_description generic_options("Options");
generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")(
"config,c",
boost::program_options::value<boost::filesystem::path>(&config_file_path)
->default_value("contractor.ini"),
"Path to a configuration file.");
// declare a group of options that will be allowed both on command line and in config file
boost::program_options::options_description config_options("Configuration");
config_options.add_options()(
"restrictions,r",
boost::program_options::value<boost::filesystem::path>(&restrictions_path),
"Restrictions file in .osrm.restrictions format")(
"profile,p",
boost::program_options::value<boost::filesystem::path>(&profile_path)
->default_value("profile.lua"),
"Path to LUA routing profile")(
"threads,t",
boost::program_options::value<unsigned int>(&requested_num_threads)
->default_value(tbb::task_scheduler_init::default_num_threads()),
"Number of threads to use");
// hidden options, will be allowed both on command line and in config file, but will not be
// shown to the user
boost::program_options::options_description hidden_options("Hidden options");
hidden_options.add_options()(
"input,i",
boost::program_options::value<boost::filesystem::path>(&input_path),
"Input file in .osm, .osm.bz2 or .osm.pbf format");
// positional option
boost::program_options::positional_options_description positional_options;
positional_options.add("input", 1);
// combine above options for parsing
boost::program_options::options_description cmdline_options;
cmdline_options.add(generic_options).add(config_options).add(hidden_options);
boost::program_options::options_description config_file_options;
config_file_options.add(config_options).add(hidden_options);
boost::program_options::options_description visible_options(
"Usage: " + boost::filesystem::basename(argv[0]) + " <input.osrm> [options]");
visible_options.add(generic_options).add(config_options);
// parse command line options
boost::program_options::variables_map option_variables;
boost::program_options::store(boost::program_options::command_line_parser(argc, argv)
.options(cmdline_options)
.positional(positional_options)
.run(),
option_variables);
if (option_variables.count("version"))
{
SimpleLogger().Write() << g_GIT_DESCRIPTION;
return false;
}
if (option_variables.count("help"))
{
SimpleLogger().Write() << "\n" << visible_options;
return false;
}
boost::program_options::notify(option_variables);
if (!option_variables.count("restrictions"))
{
restrictions_path = std::string(input_path.string() + ".restrictions");
}
if (!option_variables.count("input"))
{
SimpleLogger().Write() << "\n" << visible_options;
return false;
}
return true;
}
/**
\brief Loads and checks file UUIDs
*/
void Prepare::CheckRestrictionsFile(FingerPrint &fingerprint_orig)
{
boost::filesystem::ifstream restriction_stream(restrictions_path, std::ios::binary);
FingerPrint fingerprint_loaded;
unsigned number_of_usable_restrictions = 0;
restriction_stream.read((char *)&fingerprint_loaded, sizeof(FingerPrint));
if (!fingerprint_loaded.TestPrepare(fingerprint_orig))
{
SimpleLogger().Write(logWARNING) << ".restrictions was prepared with different build.\n"
"Reprocess to get rid of this warning.";
}
restriction_stream.read((char *)&number_of_usable_restrictions, sizeof(unsigned));
restriction_list.resize(number_of_usable_restrictions);
if (number_of_usable_restrictions > 0)
{
restriction_stream.read((char *)&(restriction_list[0]),
number_of_usable_restrictions * sizeof(TurnRestriction));
}
restriction_stream.close();
}
/**
\brief Setups scripting environment (lua-scripting)
Also initializes speed profile.
*/
bool
Prepare::SetupScriptingEnvironment(lua_State *lua_state,
EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile)
{
// open utility libraries string library;
luaL_openlibs(lua_state);
// adjust lua load path
luaAddScriptFolderToLoadPath(lua_state, profile_path.string().c_str());
// Now call our function in a lua script
if (0 != luaL_dofile(lua_state, profile_path.string().c_str()))
{
std::cerr << lua_tostring(lua_state, -1) << " occured in scripting block" << std::endl;
return false;
}
if (0 != luaL_dostring(lua_state, "return traffic_signal_penalty\n"))
{
std::cerr << lua_tostring(lua_state, -1) << " occured in scripting block" << std::endl;
return false;
}
speed_profile.traffic_signal_penalty = 10 * lua_tointeger(lua_state, -1);
SimpleLogger().Write(logDEBUG)
<< "traffic_signal_penalty: " << speed_profile.traffic_signal_penalty;
if (0 != luaL_dostring(lua_state, "return u_turn_penalty\n"))
{
std::cerr << lua_tostring(lua_state, -1) << " occured in scripting block" << std::endl;
return false;
}
speed_profile.u_turn_penalty = 10 * lua_tointeger(lua_state, -1);
speed_profile.has_turn_penalty_function = lua_function_exists(lua_state, "turn_function");
return true;
}
/**
\brief Building an edge-expanded graph from node-based input and turn restrictions
*/
std::size_t
Prepare::BuildEdgeExpandedGraph(lua_State *lua_state,
NodeID number_of_node_based_nodes,
std::vector<EdgeBasedNode> &node_based_edge_list,
DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile)
{
SimpleLogger().Write() << "Generating edge-expanded graph representation";
std::shared_ptr<NodeBasedDynamicGraph> node_based_graph =
NodeBasedDynamicGraphFromImportEdges(number_of_node_based_nodes, edge_list);
std::unique_ptr<RestrictionMap> restriction_map =
std::unique_ptr<RestrictionMap>(new RestrictionMap(node_based_graph, restriction_list));
std::shared_ptr<EdgeBasedGraphFactory> edge_based_graph_factory =
std::make_shared<EdgeBasedGraphFactory>(node_based_graph,
std::move(restriction_map),
barrier_node_list,
traffic_light_list,
internal_to_external_node_map,
speed_profile);
edge_list.clear();
edge_list.shrink_to_fit();
edge_based_graph_factory->Run(edge_out, geometry_filename, lua_state);
restriction_list.clear();
restriction_list.shrink_to_fit();
barrier_node_list.clear();
barrier_node_list.shrink_to_fit();
traffic_light_list.clear();
traffic_light_list.shrink_to_fit();
const std::size_t number_of_edge_based_nodes =
edge_based_graph_factory->GetNumberOfEdgeBasedNodes();
BOOST_ASSERT(number_of_edge_based_nodes != std::numeric_limits<unsigned>::max());
#ifndef WIN32
static_assert(sizeof(EdgeBasedEdge) == 16,
"changing ImportEdge type has influence on memory consumption!");
#endif
edge_based_graph_factory->GetEdgeBasedEdges(edge_based_edge_list);
edge_based_graph_factory->GetEdgeBasedNodes(node_based_edge_list);
edge_based_graph_factory.reset();
node_based_graph.reset();
return number_of_edge_based_nodes;
}
/**
\brief Writing info on original (node-based) nodes
*/
void Prepare::WriteNodeMapping()
{
SimpleLogger().Write() << "writing node map ...";
boost::filesystem::ofstream node_stream(node_filename, std::ios::binary);
const unsigned size_of_mapping = internal_to_external_node_map.size();
node_stream.write((char *)&size_of_mapping, sizeof(unsigned));
if (size_of_mapping > 0)
{
node_stream.write((char *)&(internal_to_external_node_map[0]),
size_of_mapping * sizeof(NodeInfo));
}
node_stream.close();
internal_to_external_node_map.clear();
internal_to_external_node_map.shrink_to_fit();
}
/**
\brief Building rtree-based nearest-neighbor data structure
Saves info to files: '.ramIndex' and '.fileIndex'.
*/
void Prepare::BuildRTree(std::vector<EdgeBasedNode> &node_based_edge_list)
{
SimpleLogger().Write() << "building r-tree ...";
StaticRTree<EdgeBasedNode>(node_based_edge_list,
rtree_nodes_path.c_str(),
rtree_leafs_path.c_str(),
internal_to_external_node_map);
}
+67
View File
@@ -0,0 +1,67 @@
#ifndef PREPARE_H
#define PREPARE_H
#include "EdgeBasedGraphFactory.h"
#include "../DataStructures/QueryEdge.h"
#include "../DataStructures/StaticGraph.h"
#include "../Util/GraphLoader.h"
#include <boost/filesystem.hpp>
#include <luabind/luabind.hpp>
#include <vector>
/**
\brief class of 'prepare' utility.
*/
class Prepare
{
public:
using EdgeData = QueryEdge::EdgeData;
using InputEdge = DynamicGraph<EdgeData>::InputEdge;
using StaticEdge = StaticGraph<EdgeData>::InputEdge;
explicit Prepare();
Prepare(const Prepare &) = delete;
~Prepare();
int Process(int argc, char *argv[]);
protected:
bool ParseArguments(int argc, char *argv[]);
void CheckRestrictionsFile(FingerPrint &fingerprint_orig);
bool SetupScriptingEnvironment(lua_State *myLuaState,
EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile);
std::size_t BuildEdgeExpandedGraph(lua_State *myLuaState,
NodeID nodeBasedNodeNumber,
std::vector<EdgeBasedNode> &nodeBasedEdgeList,
DeallocatingVector<EdgeBasedEdge> &edgeBasedEdgeList,
EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile);
void WriteNodeMapping();
void BuildRTree(std::vector<EdgeBasedNode> &node_based_edge_list);
private:
std::vector<NodeInfo> internal_to_external_node_map;
std::vector<TurnRestriction> restriction_list;
std::vector<NodeID> barrier_node_list;
std::vector<NodeID> traffic_light_list;
std::vector<ImportEdge> edge_list;
unsigned requested_num_threads;
boost::filesystem::path config_file_path;
boost::filesystem::path input_path;
boost::filesystem::path restrictions_path;
boost::filesystem::path preinfo_path;
boost::filesystem::path profile_path;
std::string node_filename;
std::string edge_out;
std::string info_out;
std::string geometry_filename;
std::string graph_out;
std::string rtree_nodes_path;
std::string rtree_leafs_path;
};
#endif // PREPARE_H
-172
View File
@@ -1,172 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "TemporaryStorage.h"
StreamData::StreamData()
: write_mode(true),
temp_path(boost::filesystem::unique_path(temp_directory / TemporaryFilePattern)),
temp_file(new boost::filesystem::fstream(
temp_path, std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary)),
readWriteMutex(std::make_shared<boost::mutex>())
{
if (temp_file->fail())
{
throw OSRMException("temporary file could not be created");
}
}
TemporaryStorage::TemporaryStorage() { temp_directory = boost::filesystem::temp_directory_path(); }
TemporaryStorage &TemporaryStorage::GetInstance()
{
static TemporaryStorage static_instance;
return static_instance;
}
TemporaryStorage::~TemporaryStorage() { RemoveAll(); }
void TemporaryStorage::RemoveAll()
{
boost::mutex::scoped_lock lock(mutex);
for (unsigned slot_id = 0; slot_id < stream_data_list.size(); ++slot_id)
{
DeallocateSlot(slot_id);
}
stream_data_list.clear();
}
int TemporaryStorage::AllocateSlot()
{
boost::mutex::scoped_lock lock(mutex);
try { stream_data_list.push_back(StreamData()); }
catch (boost::filesystem::filesystem_error &e) { Abort(e); }
CheckIfTemporaryDeviceFull();
return stream_data_list.size() - 1;
}
void TemporaryStorage::DeallocateSlot(const int slot_id)
{
try
{
StreamData &data = stream_data_list[slot_id];
boost::mutex::scoped_lock lock(*data.readWriteMutex);
if (!boost::filesystem::exists(data.temp_path))
{
return;
}
if (data.temp_file->is_open())
{
data.temp_file->close();
}
boost::filesystem::remove(data.temp_path);
}
catch (boost::filesystem::filesystem_error &e) { Abort(e); }
}
void TemporaryStorage::WriteToSlot(const int slot_id, char *pointer, const std::size_t size)
{
try
{
StreamData &data = stream_data_list[slot_id];
BOOST_ASSERT(data.write_mode);
boost::mutex::scoped_lock lock(*data.readWriteMutex);
BOOST_ASSERT_MSG(data.write_mode, "Writing after first read is not allowed");
if (1073741824 < data.buffer.size())
{
data.temp_file->write(&data.buffer[0], data.buffer.size());
// data.temp_file->write(pointer, size);
data.buffer.clear();
CheckIfTemporaryDeviceFull();
}
data.buffer.insert(data.buffer.end(), pointer, pointer + size);
}
catch (boost::filesystem::filesystem_error &e) { Abort(e); }
}
void TemporaryStorage::ReadFromSlot(const int slot_id, char *pointer, const std::size_t size)
{
try
{
StreamData &data = stream_data_list[slot_id];
boost::mutex::scoped_lock lock(*data.readWriteMutex);
if (data.write_mode)
{
data.write_mode = false;
data.temp_file->write(&data.buffer[0], data.buffer.size());
data.buffer.clear();
data.temp_file->seekg(data.temp_file->beg);
BOOST_ASSERT(data.temp_file->beg == data.temp_file->tellg());
}
BOOST_ASSERT(!data.write_mode);
data.temp_file->read(pointer, size);
}
catch (boost::filesystem::filesystem_error &error) { Abort(error); }
}
uint64_t TemporaryStorage::GetFreeBytesOnTemporaryDevice()
{
uint64_t value = -1;
try
{
boost::filesystem::path path = boost::filesystem::temp_directory_path();
boost::filesystem::space_info space_info = boost::filesystem::space(path);
value = space_info.free;
}
catch (boost::filesystem::filesystem_error &error) { Abort(error); }
return value;
}
void TemporaryStorage::CheckIfTemporaryDeviceFull()
{
boost::filesystem::path path = boost::filesystem::temp_directory_path();
boost::filesystem::space_info space_info = boost::filesystem::space(path);
if ((1024 * 1024) > space_info.free)
{
throw OSRMException("temporary device is full");
}
}
boost::filesystem::fstream::pos_type TemporaryStorage::Tell(const int slot_id)
{
boost::filesystem::fstream::pos_type position;
try
{
StreamData &data = stream_data_list[slot_id];
boost::mutex::scoped_lock lock(*data.readWriteMutex);
position = data.temp_file->tellp();
}
catch (boost::filesystem::filesystem_error &e) { Abort(e); }
return position;
}
void TemporaryStorage::Abort(const boost::filesystem::filesystem_error &error)
{
RemoveAll();
throw OSRMException(error.what());
}
-96
View File
@@ -1,96 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TEMPORARYSTORAGE_H_
#define TEMPORARYSTORAGE_H_
#include "../Util/BoostFileSystemFix.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/thread/mutex.hpp>
#include <cstdint>
#include <vector>
#include <fstream>
#include <memory>
struct StreamData
{
bool write_mode;
boost::filesystem::path temp_path;
std::shared_ptr<boost::filesystem::fstream> temp_file;
std::shared_ptr<boost::mutex> readWriteMutex;
std::vector<char> buffer;
StreamData();
};
// This class implements a singleton file storage for temporary data.
// temporary slots can be accessed by other objects through an int
// On deallocation every slot gets deallocated
//
// Access is sequential, which means, that there is no random access
// -> Data is written in first phase and reread in second.
static boost::filesystem::path temp_directory;
static std::string TemporaryFilePattern("OSRM-%%%%-%%%%-%%%%");
class TemporaryStorage
{
public:
static TemporaryStorage &GetInstance();
virtual ~TemporaryStorage();
int AllocateSlot();
void DeallocateSlot(const int slot_id);
void WriteToSlot(const int slot_id, char *pointer, const std::size_t size);
void ReadFromSlot(const int slot_id, char *pointer, const std::size_t size);
// returns the number of free bytes
uint64_t GetFreeBytesOnTemporaryDevice();
boost::filesystem::fstream::pos_type Tell(const int slot_id);
void RemoveAll();
private:
TemporaryStorage();
TemporaryStorage(TemporaryStorage const &) {};
TemporaryStorage &operator=(TemporaryStorage const &) { return *this; }
void Abort(const boost::filesystem::filesystem_error &e);
void CheckIfTemporaryDeviceFull();
// vector of file streams that is used to store temporary data
boost::mutex mutex;
std::vector<StreamData> stream_data_list;
};
#endif /* TEMPORARYSTORAGE_H_ */
+3 -2
View File
@@ -36,6 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <type_traits>
#include <unordered_map>
#include <vector>
#include <cstring>
template <typename NodeID, typename Key> class ArrayStorage
{
@@ -99,8 +100,8 @@ class BinaryHeap
void operator=(const BinaryHeap &right);
public:
typedef Weight WeightType;
typedef Data DataType;
using WeightType = Weight;
using DataType = Data;
explicit BinaryHeap(size_t maxID) : node_index(maxID) { Clear(); }
-2
View File
@@ -28,8 +28,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef CONCURRENT_QUEUE_H
#define CONCURRENT_QUEUE_H
#include "../typedefs.h"
#include <boost/circular_buffer.hpp>
#include <condition_variable>
#include <mutex>
+69 -32
View File
@@ -27,7 +27,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <osrm/Coordinate.h>
#include "../Util/MercatorUtil.h"
#include "../Util/SimpleLogger.h"
#ifndef NDEBUG
#include "../Util/simple_logger.hpp"
#endif
#include "../Util/StringUtil.h"
#include <boost/assert.hpp>
@@ -157,12 +159,12 @@ FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &s
const FixedPointCoordinate &point)
{
// initialize values
const float x_value = lat2y(point.lat / COORDINATE_PRECISION);
const float x_value = static_cast<float>(lat2y(point.lat / COORDINATE_PRECISION));
const float y_value = point.lon / COORDINATE_PRECISION;
const float a = lat2y(source_coordinate.lat / COORDINATE_PRECISION);
const float b = source_coordinate.lon / COORDINATE_PRECISION;
const float c = lat2y(target_coordinate.lat / COORDINATE_PRECISION);
const float d = target_coordinate.lon / COORDINATE_PRECISION;
float a = static_cast<float>(lat2y(source_coordinate.lat / COORDINATE_PRECISION));
float b = source_coordinate.lon / COORDINATE_PRECISION;
float c = static_cast<float>(lat2y(target_coordinate.lat / COORDINATE_PRECISION));
float d = target_coordinate.lon / COORDINATE_PRECISION;
float p, q;
if (std::abs(a - c) > std::numeric_limits<float>::epsilon())
{
@@ -178,15 +180,36 @@ FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &s
q = y_value;
}
float nY = (d * p - c * q) / (a * d - b * c);
// discretize the result to coordinate precision. it's a hack!
if (std::abs(nY) < (1.f / COORDINATE_PRECISION))
float ratio;
bool inverse_ratio = false;
// straight line segment on equator
if (std::abs(c) < std::numeric_limits<float>::epsilon() &&
std::abs(a) < std::numeric_limits<float>::epsilon())
{
nY = 0.f;
ratio = (q - b) / (d - b);
}
else
{
if (std::abs(c) < std::numeric_limits<float>::epsilon())
{
// swap start/end
std::swap(a, c);
std::swap(b, d);
inverse_ratio = true;
}
float nY = (d * p - c * q) / (a * d - b * c);
// discretize the result to coordinate precision. it's a hack!
if (std::abs(nY) < (1.f / COORDINATE_PRECISION))
{
nY = 0.f;
}
// compute ratio
ratio = (p - nY * a) / c;
}
// compute ratio
float ratio = (p - nY * a) / c;
if (std::isnan(ratio))
{
ratio = (target_coordinate == point ? 1.f : 0.f);
@@ -200,7 +223,13 @@ FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &s
ratio = 1.f;
}
//compute the nearest location
// we need to do this, if we switched start/end coordinates
if (inverse_ratio)
{
ratio = 1.0f - ratio;
}
// compute the nearest location
FixedPointCoordinate nearest_location;
BOOST_ASSERT(!std::isnan(ratio));
if (ratio <= 0.f)
@@ -216,6 +245,7 @@ FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &s
nearest_location.lat = static_cast<int>(y2lat(p) * COORDINATE_PRECISION);
nearest_location.lon = static_cast<int>(q * COORDINATE_PRECISION);
}
BOOST_ASSERT(nearest_location.isValid());
return FixedPointCoordinate::ApproximateEuclideanDistance(point, nearest_location);
}
@@ -229,16 +259,16 @@ float FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordin
BOOST_ASSERT(query_location.isValid());
// initialize values
const float x = lat2y(query_location.lat / COORDINATE_PRECISION);
const float y = query_location.lon / COORDINATE_PRECISION;
const float a = lat2y(segment_source.lat / COORDINATE_PRECISION);
const float b = segment_source.lon / COORDINATE_PRECISION;
const float c = lat2y(segment_target.lat / COORDINATE_PRECISION);
const float d = segment_target.lon / COORDINATE_PRECISION;
float p, q /*,mX*/, nY;
if (std::abs(a - c) > std::numeric_limits<float>::epsilon())
const double x = lat2y(query_location.lat / COORDINATE_PRECISION);
const double y = query_location.lon / COORDINATE_PRECISION;
const double a = lat2y(segment_source.lat / COORDINATE_PRECISION);
const double b = segment_source.lon / COORDINATE_PRECISION;
const double c = lat2y(segment_target.lat / COORDINATE_PRECISION);
const double d = segment_target.lon / COORDINATE_PRECISION;
double p, q /*,mX*/, nY;
if (std::abs(a - c) > std::numeric_limits<double>::epsilon())
{
const float m = (d - b) / (c - a); // slope
const double m = (d - b) / (c - a); // slope
// Projection of (x,y) on line joining (a,b) and (c,d)
p = ((x + (m * y)) + (m * m * a - m * b)) / (1.f + m * m);
q = b + m * (p - a);
@@ -264,11 +294,11 @@ float FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordin
{
ratio = (segment_target == query_location ? 1.f : 0.f);
}
else if (std::abs(ratio) <= std::numeric_limits<float>::epsilon())
else if (std::abs(ratio) <= std::numeric_limits<double>::epsilon())
{
ratio = 0.;
ratio = 0.f;
}
else if (std::abs(ratio - 1.f) <= std::numeric_limits<float>::epsilon())
else if (std::abs(ratio - 1.f) <= std::numeric_limits<double>::epsilon())
{
ratio = 1.f;
}
@@ -279,7 +309,7 @@ float FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordin
{
nearest_location = segment_source;
}
else if (ratio >= 1.)
else if (ratio >= 1.f)
{
nearest_location = segment_target;
}
@@ -337,7 +367,8 @@ void FixedPointCoordinate::Output(std::ostream &out) const
float FixedPointCoordinate::GetBearing(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate)
{
const float lon_diff = second_coordinate.lon / COORDINATE_PRECISION - first_coordinate.lon / COORDINATE_PRECISION;
const float lon_diff =
second_coordinate.lon / COORDINATE_PRECISION - first_coordinate.lon / COORDINATE_PRECISION;
const float lon_delta = DegreeToRadian(lon_diff);
const float lat1 = DegreeToRadian(first_coordinate.lat / COORDINATE_PRECISION);
const float lat2 = DegreeToRadian(second_coordinate.lat / COORDINATE_PRECISION);
@@ -379,9 +410,15 @@ float FixedPointCoordinate::GetBearing(const FixedPointCoordinate &other) const
return result;
}
float FixedPointCoordinate::DegreeToRadian(const float degree) { return degree * (static_cast<float>(M_PI) / 180.f); }
float FixedPointCoordinate::DegreeToRadian(const float degree)
{
return degree * (static_cast<float>(M_PI) / 180.f);
}
float FixedPointCoordinate::RadianToDegree(const float radian) { return radian * (180.f * static_cast<float>(M_1_PI)); }
float FixedPointCoordinate::RadianToDegree(const float radian)
{
return radian * (180.f * static_cast<float>(M_1_PI));
}
// This distance computation does integer arithmetic only and is a lot faster than
// the other distance function which are numerically correct('ish).
@@ -392,11 +429,11 @@ int FixedPointCoordinate::OrderedPerpendicularDistanceApproximation(
const FixedPointCoordinate &segment_target)
{
// initialize values
const float x = lat2y(input_point.lat / COORDINATE_PRECISION);
const float x = static_cast<float>(lat2y(input_point.lat / COORDINATE_PRECISION));
const float y = input_point.lon / COORDINATE_PRECISION;
const float a = lat2y(segment_source.lat / COORDINATE_PRECISION);
const float a = static_cast<float>(lat2y(segment_source.lat / COORDINATE_PRECISION));
const float b = segment_source.lon / COORDINATE_PRECISION;
const float c = lat2y(segment_target.lat / COORDINATE_PRECISION);
const float c = static_cast<float>(lat2y(segment_target.lat / COORDINATE_PRECISION));
const float d = segment_target.lon / COORDINATE_PRECISION;
float p, q;
+173 -261
View File
@@ -28,250 +28,154 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef DEALLOCATINGVECTOR_H_
#define DEALLOCATINGVECTOR_H_
#include <boost/assert.hpp>
#include <cstring>
#include "Range.h"
#include <boost/iterator/iterator_facade.hpp>
#include <utility>
#include <vector>
template <typename ElementT,
std::size_t bucketSizeC = 8388608 / sizeof(ElementT),
bool DeallocateC = false>
class DeallocatingVectorIterator : public std::iterator<std::random_access_iterator_tag, ElementT>
template <typename ElementT> struct DeallocatingVectorIteratorState
{
protected:
class DeallocatingVectorIteratorState
{
private:
// make constructors explicit, so we do not mix random access and deallocation iterators.
DeallocatingVectorIteratorState();
public:
explicit DeallocatingVectorIteratorState(const DeallocatingVectorIteratorState &r)
: index(r.index), bucket_list(r.bucket_list)
{
}
explicit DeallocatingVectorIteratorState(const std::size_t idx,
std::vector<ElementT *> &input_list)
: index(idx), bucket_list(input_list)
{
}
std::size_t index;
std::vector<ElementT *> &bucket_list;
inline bool operator!=(const DeallocatingVectorIteratorState &other)
{
return index != other.index;
}
inline bool operator==(const DeallocatingVectorIteratorState &other)
{
return index == other.index;
}
bool operator<(const DeallocatingVectorIteratorState &other) const
{
return index < other.index;
}
bool operator>(const DeallocatingVectorIteratorState &other) const
{
return index > other.index;
}
bool operator>=(const DeallocatingVectorIteratorState &other) const
{
return index >= other.index;
}
// This is a hack to make assignment operator possible with reference member
inline DeallocatingVectorIteratorState &operator=(const DeallocatingVectorIteratorState &a)
{
if (this != &a)
{
this->DeallocatingVectorIteratorState::
~DeallocatingVectorIteratorState(); // explicit non-virtual destructor
new (this) DeallocatingVectorIteratorState(a); // placement new
}
return *this;
}
};
DeallocatingVectorIteratorState current_state;
public:
typedef std::random_access_iterator_tag iterator_category;
typedef typename std::iterator<std::random_access_iterator_tag, ElementT>::value_type
value_type;
typedef typename std::iterator<std::random_access_iterator_tag, ElementT>::difference_type
difference_type;
typedef typename std::iterator<std::random_access_iterator_tag, ElementT>::reference reference;
typedef typename std::iterator<std::random_access_iterator_tag, ElementT>::pointer pointer;
DeallocatingVectorIterator() {}
template <typename T2>
explicit DeallocatingVectorIterator(const DeallocatingVectorIterator<T2> &r)
: current_state(r.current_state)
DeallocatingVectorIteratorState() : index(-1), bucket_list(nullptr) {}
explicit DeallocatingVectorIteratorState(const DeallocatingVectorIteratorState &r)
: index(r.index), bucket_list(r.bucket_list)
{
}
DeallocatingVectorIterator(std::size_t idx, std::vector<ElementT *> &input_list)
: current_state(idx, input_list)
explicit DeallocatingVectorIteratorState(const std::size_t idx,
std::vector<ElementT *> *input_list)
: index(idx), bucket_list(input_list)
{
}
explicit DeallocatingVectorIterator(const DeallocatingVectorIteratorState &r) : current_state(r) {}
std::size_t index;
std::vector<ElementT *> *bucket_list;
template <typename T2>
DeallocatingVectorIterator &operator=(const DeallocatingVectorIterator<T2> &r)
inline DeallocatingVectorIteratorState &operator=(const DeallocatingVectorIteratorState &other)
{
if (DeallocateC)
{
BOOST_ASSERT(false);
}
current_state = r.current_state;
index = other.index;
bucket_list = other.bucket_list;
return *this;
}
inline DeallocatingVectorIterator &operator++()
{ // prefix
++current_state.index;
return *this;
}
inline DeallocatingVectorIterator &operator--()
{ // prefix
if (DeallocateC)
{
BOOST_ASSERT(false);
}
--current_state.index;
return *this;
}
inline DeallocatingVectorIterator operator++(int)
{ // postfix
DeallocatingVectorIteratorState my_state(current_state);
current_state.index++;
return DeallocatingVectorIterator(my_state);
}
inline DeallocatingVectorIterator operator--(int)
{ // postfix
if (DeallocateC)
{
BOOST_ASSERT(false);
}
DeallocatingVectorIteratorState my_state(current_state);
current_state.index--;
return DeallocatingVectorIterator(my_state);
}
inline DeallocatingVectorIterator operator+(const difference_type &n) const
{
DeallocatingVectorIteratorState my_state(current_state);
my_state.index += n;
return DeallocatingVectorIterator(my_state);
}
inline DeallocatingVectorIterator &operator+=(const difference_type &n)
{
current_state.index += n;
return *this;
}
inline DeallocatingVectorIterator operator-(const difference_type &n) const
{
if (DeallocateC)
{
BOOST_ASSERT(false);
}
DeallocatingVectorIteratorState my_state(current_state);
my_state.index -= n;
return DeallocatingVectorIterator(my_state);
}
inline DeallocatingVectorIterator &operator-=(const difference_type &n) const
{
if (DeallocateC)
{
BOOST_ASSERT(false);
}
current_state.index -= n;
return *this;
}
inline reference operator*() const
{
std::size_t current_bucket = current_state.index / bucketSizeC;
std::size_t current_index = current_state.index % bucketSizeC;
return (current_state.bucket_list[current_bucket][current_index]);
}
inline pointer operator->() const
{
std::size_t current_bucket = current_state.index / bucketSizeC;
std::size_t current_index = current_state.index % bucketSizeC;
return &(current_state.bucket_list[current_bucket][current_index]);
}
inline bool operator!=(const DeallocatingVectorIterator &other)
{
return current_state != other.current_state;
}
inline bool operator==(const DeallocatingVectorIterator &other)
{
return current_state == other.current_state;
}
inline bool operator<(const DeallocatingVectorIterator &other) const
{
return current_state < other.current_state;
}
inline bool operator>(const DeallocatingVectorIterator &other) const
{
return current_state > other.current_state;
}
inline bool operator>=(const DeallocatingVectorIterator &other) const
{
return current_state >= other.current_state;
}
difference_type operator-(const DeallocatingVectorIterator &other)
{
if (DeallocateC)
{
BOOST_ASSERT(false);
}
return current_state.index - other.current_state.index;
}
};
template <typename ElementT, std::size_t bucketSizeC = 8388608 / sizeof(ElementT)>
template <typename ElementT, std::size_t ELEMENTS_PER_BLOCK>
class DeallocatingVectorIterator
: public boost::iterator_facade<DeallocatingVectorIterator<ElementT, ELEMENTS_PER_BLOCK>,
ElementT,
std::random_access_iterator_tag>
{
DeallocatingVectorIteratorState<ElementT> current_state;
public:
DeallocatingVectorIterator() {}
DeallocatingVectorIterator(std::size_t idx, std::vector<ElementT *> *input_list)
: current_state(idx, input_list)
{
}
friend class boost::iterator_core_access;
void advance(std::size_t n) { current_state.index += n; }
void increment() { advance(1); }
void decrement() { advance(-1); }
bool equal(DeallocatingVectorIterator const &other) const
{
return current_state.index == other.current_state.index;
}
std::ptrdiff_t distance_to(DeallocatingVectorIterator const &other) const
{
// it is important to implement it 'other minus this'. otherwise sorting breaks
return other.current_state.index - current_state.index;
}
ElementT &dereference() const
{
const std::size_t current_bucket = current_state.index / ELEMENTS_PER_BLOCK;
const std::size_t current_index = current_state.index % ELEMENTS_PER_BLOCK;
return (current_state.bucket_list->at(current_bucket)[current_index]);
}
ElementT &operator[](const std::size_t index) const
{
const std::size_t current_bucket = (index + current_state.index) / ELEMENTS_PER_BLOCK;
const std::size_t current_index = (index + current_state.index) % ELEMENTS_PER_BLOCK;
return (current_state.bucket_list->at(current_bucket)[current_index]);
}
};
template <typename ElementT, std::size_t ELEMENTS_PER_BLOCK>
class DeallocatingVectorRemoveIterator
: public boost::iterator_facade<DeallocatingVectorRemoveIterator<ElementT, ELEMENTS_PER_BLOCK>,
ElementT,
boost::forward_traversal_tag>
{
DeallocatingVectorIteratorState<ElementT> current_state;
public:
DeallocatingVectorRemoveIterator(std::size_t idx, std::vector<ElementT *> *input_list)
: current_state(idx, input_list)
{
}
friend class boost::iterator_core_access;
void increment()
{
const std::size_t old_bucket = current_state.index / ELEMENTS_PER_BLOCK;
++current_state.index;
const std::size_t new_bucket = current_state.index / ELEMENTS_PER_BLOCK;
if (old_bucket != new_bucket)
{
// delete old bucket entry
if (nullptr != current_state.bucket_list->at(old_bucket))
{
delete[] current_state.bucket_list->at(old_bucket);
current_state.bucket_list->at(old_bucket) = nullptr;
}
}
}
bool equal(DeallocatingVectorRemoveIterator const &other) const
{
return current_state.index == other.current_state.index;
}
std::ptrdiff_t distance_to(DeallocatingVectorRemoveIterator const &other) const
{
return other.current_state.index - current_state.index;
}
ElementT &dereference() const
{
const std::size_t current_bucket = current_state.index / ELEMENTS_PER_BLOCK;
const std::size_t current_index = current_state.index % ELEMENTS_PER_BLOCK;
return (current_state.bucket_list->at(current_bucket)[current_index]);
}
};
template <typename ElementT, std::size_t ELEMENTS_PER_BLOCK = 8388608 / sizeof(ElementT)>
class DeallocatingVector
{
private:
std::size_t current_size;
std::vector<ElementT *> bucket_list;
public:
typedef ElementT value_type;
typedef DeallocatingVectorIterator<ElementT, bucketSizeC, false> iterator;
typedef DeallocatingVectorIterator<ElementT, bucketSizeC, false> const_iterator;
using iterator = DeallocatingVectorIterator<ElementT, ELEMENTS_PER_BLOCK>;
using const_iterator = DeallocatingVectorIterator<ElementT, ELEMENTS_PER_BLOCK>;
// this iterator deallocates all buckets that have been visited. Iterators to visited objects
// become invalid.
typedef DeallocatingVectorIterator<ElementT, bucketSizeC, true> deallocation_iterator;
// this forward-only iterator deallocates all buckets that have been visited
using deallocation_iterator = DeallocatingVectorRemoveIterator<ElementT, ELEMENTS_PER_BLOCK>;
DeallocatingVector() : current_size(0)
{
// initial bucket
bucket_list.emplace_back(new ElementT[bucketSizeC]);
}
DeallocatingVector() : current_size(0) { bucket_list.emplace_back(new ElementT[ELEMENTS_PER_BLOCK]); }
~DeallocatingVector() { clear(); }
inline void swap(DeallocatingVector<ElementT, bucketSizeC> &other)
inline void swap(DeallocatingVector<ElementT, ELEMENTS_PER_BLOCK> &other)
{
std::swap(current_size, other.current_size);
bucket_list.swap(other.bucket_list);
@@ -280,16 +184,15 @@ class DeallocatingVector
inline void clear()
{
// Delete[]'ing ptr's to all Buckets
for (unsigned i = 0; i < bucket_list.size(); ++i)
for (auto bucket : bucket_list)
{
if (nullptr != bucket_list[i])
if (nullptr != bucket)
{
delete[] bucket_list[i];
bucket_list[i] = nullptr;
delete[] bucket;
bucket = nullptr;
}
}
// Removing all ptrs from vector
std::vector<ElementT *>().swap(bucket_list);
bucket_list.clear(); bucket_list.shrink_to_fit();
current_size = 0;
}
@@ -298,104 +201,113 @@ class DeallocatingVector
const std::size_t current_capacity = capacity();
if (current_size == current_capacity)
{
bucket_list.push_back(new ElementT[bucketSizeC]);
bucket_list.push_back(new ElementT[ELEMENTS_PER_BLOCK]);
}
std::size_t current_index = size() % bucketSizeC;
std::size_t current_index = size() % ELEMENTS_PER_BLOCK;
bucket_list.back()[current_index] = element;
++current_size;
}
inline void emplace_back(const ElementT &&element)
template <typename... Ts> inline void emplace_back(Ts &&... element)
{
const std::size_t current_capacity = capacity();
if (current_size == current_capacity)
{
bucket_list.push_back(new ElementT[bucketSizeC]);
bucket_list.push_back(new ElementT[ELEMENTS_PER_BLOCK]);
}
const std::size_t current_index = size() % bucketSizeC;
bucket_list.back()[current_index] = element;
const std::size_t current_index = size() % ELEMENTS_PER_BLOCK;
bucket_list.back()[current_index] = ElementT(std::forward<Ts>(element)...);
++current_size;
}
inline void reserve(const std::size_t) const
{
// don't do anything
}
inline void reserve(const std::size_t) const { /* don't do anything */ }
inline void resize(const std::size_t new_size)
{
if (new_size > current_size)
if (new_size >= current_size)
{
while (capacity() < new_size)
{
bucket_list.push_back(new ElementT[bucketSizeC]);
bucket_list.push_back(new ElementT[ELEMENTS_PER_BLOCK]);
}
current_size = new_size;
}
if (new_size < current_size)
{
const std::size_t number_of_necessary_buckets = 1 + (new_size / bucketSizeC);
for (std::size_t i = number_of_necessary_buckets; i < bucket_list.size(); ++i)
else
{ // down-size
const std::size_t number_of_necessary_buckets = 1 + (new_size / ELEMENTS_PER_BLOCK);
for (const auto bucket_index : osrm::irange(number_of_necessary_buckets, bucket_list.size()))
{
delete[] bucket_list[i];
if (nullptr != bucket_list[bucket_index])
{
delete[] bucket_list[bucket_index];
}
}
bucket_list.resize(number_of_necessary_buckets);
current_size = new_size;
}
current_size = new_size;
}
inline std::size_t size() const { return current_size; }
inline std::size_t capacity() const { return bucket_list.size() * bucketSizeC; }
inline std::size_t capacity() const { return bucket_list.size() * ELEMENTS_PER_BLOCK; }
inline iterator begin() { return iterator(static_cast<std::size_t>(0), bucket_list); }
inline iterator begin() { return iterator(static_cast<std::size_t>(0), &bucket_list); }
inline iterator end() { return iterator(size(), bucket_list); }
inline iterator end() { return iterator(size(), &bucket_list); }
inline deallocation_iterator dbegin()
{
return deallocation_iterator(static_cast<std::size_t>(0), bucket_list);
return deallocation_iterator(static_cast<std::size_t>(0), &bucket_list);
}
inline deallocation_iterator dend() { return deallocation_iterator(size(), bucket_list); }
inline deallocation_iterator dend() { return deallocation_iterator(size(), &bucket_list); }
inline const_iterator begin() const
{
return const_iterator(static_cast<std::size_t>(0), bucket_list);
return const_iterator(static_cast<std::size_t>(0), &bucket_list);
}
inline const_iterator end() const { return const_iterator(size(), bucket_list); }
inline const_iterator end() const { return const_iterator(size(), &bucket_list); }
inline ElementT &operator[](const std::size_t index)
{
std::size_t _bucket = index / bucketSizeC;
std::size_t _index = index % bucketSizeC;
const std::size_t _bucket = index / ELEMENTS_PER_BLOCK;
const std::size_t _index = index % ELEMENTS_PER_BLOCK;
return (bucket_list[_bucket][_index]);
}
const inline ElementT &operator[](const std::size_t index) const
{
std::size_t _bucket = index / bucketSizeC;
std::size_t _index = index % bucketSizeC;
const std::size_t _bucket = index / ELEMENTS_PER_BLOCK;
const std::size_t _index = index % ELEMENTS_PER_BLOCK;
return (bucket_list[_bucket][_index]);
}
inline ElementT &back()
{
std::size_t _bucket = current_size / bucketSizeC;
std::size_t _index = current_size % bucketSizeC;
const std::size_t _bucket = current_size / ELEMENTS_PER_BLOCK;
const std::size_t _index = current_size % ELEMENTS_PER_BLOCK;
return (bucket_list[_bucket][_index]);
}
const inline ElementT &back() const
{
std::size_t _bucket = current_size / bucketSizeC;
std::size_t _index = current_size % bucketSizeC;
const std::size_t _bucket = current_size / ELEMENTS_PER_BLOCK;
const std::size_t _index = current_size % ELEMENTS_PER_BLOCK;
return (bucket_list[_bucket][_index]);
}
template<class InputIterator>
const inline void append(InputIterator first, const InputIterator last)
{
InputIterator position = first;
while (position != last)
{
push_back(*position);
++position;
}
}
};
#endif /* DEALLOCATINGVECTOR_H_ */
+87 -72
View File
@@ -28,10 +28,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef DYNAMICGRAPH_H
#define DYNAMICGRAPH_H
#include "../DataStructures/DeallocatingVector.h"
#include "DeallocatingVector.h"
#include "Range.h"
#include <boost/assert.hpp>
#include <boost/range/irange.hpp>
#include <cstdint>
@@ -43,10 +43,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
template <typename EdgeDataT> class DynamicGraph
{
public:
typedef decltype(boost::irange(0u,0u)) EdgeRange;
typedef EdgeDataT EdgeData;
typedef unsigned NodeIterator;
typedef unsigned EdgeIterator;
using EdgeData = EdgeDataT;
using NodeIterator = unsigned;
using EdgeIterator = unsigned;
using EdgeRange = osrm::range<EdgeIterator>;
class InputEdge
{
@@ -54,57 +54,62 @@ template <typename EdgeDataT> class DynamicGraph
NodeIterator source;
NodeIterator target;
EdgeDataT data;
InputEdge() : source(std::numeric_limits<NodeIterator>::max()), target(std::numeric_limits<NodeIterator>::max()) { }
template<typename... Ts>
InputEdge(NodeIterator source, NodeIterator target, Ts &&...data) : source(source), target(target), data(std::forward<Ts>(data)...) { }
bool operator<(const InputEdge &right) const
{
if (source != right.source)
{
return source < right.source;
}
return target < right.target;
}
};
// Constructs an empty graph with a given number of nodes.
explicit DynamicGraph(int32_t nodes) : m_numNodes(nodes), m_numEdges(0)
explicit DynamicGraph(NodeIterator nodes) : number_of_nodes(nodes), number_of_edges(0)
{
m_nodes.reserve(m_numNodes);
m_nodes.resize(m_numNodes);
node_list.reserve(number_of_nodes);
node_list.resize(number_of_nodes);
m_edges.reserve(m_numNodes * 1.1);
m_edges.resize(m_numNodes);
edge_list.reserve(number_of_nodes * 1.1);
edge_list.resize(number_of_nodes);
}
template <class ContainerT> DynamicGraph(const int32_t nodes, const ContainerT &graph)
template <class ContainerT> DynamicGraph(const NodeIterator nodes, const ContainerT &graph)
{
m_numNodes = nodes;
m_numEdges = (EdgeIterator)graph.size();
m_nodes.reserve(m_numNodes + 1);
m_nodes.resize(m_numNodes + 1);
number_of_nodes = nodes;
number_of_edges = (EdgeIterator)graph.size();
node_list.reserve(number_of_nodes + 1);
node_list.resize(number_of_nodes + 1);
EdgeIterator edge = 0;
EdgeIterator position = 0;
for (NodeIterator node = 0; node < m_numNodes; ++node)
for (const auto node : osrm::irange(0u, number_of_nodes))
{
EdgeIterator lastEdge = edge;
while (edge < m_numEdges && graph[edge].source == node)
while (edge < number_of_edges && graph[edge].source == node)
{
++edge;
}
m_nodes[node].firstEdge = position;
m_nodes[node].edges = edge - lastEdge;
position += m_nodes[node].edges;
node_list[node].firstEdge = position;
node_list[node].edges = edge - lastEdge;
position += node_list[node].edges;
}
m_nodes.back().firstEdge = position;
m_edges.reserve(static_cast<std::size_t>(position * 1.1));
m_edges.resize(position);
node_list.back().firstEdge = position;
edge_list.reserve((std::size_t)edge_list.size() * 1.1);
edge_list.resize(position);
edge = 0;
for (NodeIterator node = 0; node < m_numNodes; ++node)
for (const auto node : osrm::irange(0u, number_of_nodes))
{
for (EdgeIterator i = m_nodes[node].firstEdge,
e = m_nodes[node].firstEdge + m_nodes[node].edges;
i != e;
++i)
for (const auto i : osrm::irange(node_list[node].firstEdge,
node_list[node].firstEdge + node_list[node].edges))
{
m_edges[i].target = graph[edge].target;
m_edges[i].data = graph[edge].data;
BOOST_ASSERT_MSG(graph[edge].data.distance > 0, "edge distance invalid");
edge_list[i].target = graph[edge].target;
edge_list[i].data = graph[edge].data;
++edge;
}
}
@@ -112,16 +117,16 @@ template <typename EdgeDataT> class DynamicGraph
~DynamicGraph() {}
unsigned GetNumberOfNodes() const { return m_numNodes; }
unsigned GetNumberOfNodes() const { return number_of_nodes; }
unsigned GetNumberOfEdges() const { return m_numEdges; }
unsigned GetNumberOfEdges() const { return number_of_edges; }
unsigned GetOutDegree(const NodeIterator n) const { return m_nodes[n].edges; }
unsigned GetOutDegree(const NodeIterator n) const { return node_list[n].edges; }
unsigned GetDirectedOutDegree(const NodeIterator n) const
{
unsigned degree = 0;
for(EdgeIterator edge = BeginEdges(n); edge < EndEdges(n); ++edge)
for (const auto edge : osrm::irange(BeginEdges(n), EndEdges(n)))
{
if (GetEdgeData(edge).forward)
{
@@ -131,66 +136,76 @@ template <typename EdgeDataT> class DynamicGraph
return degree;
}
NodeIterator GetTarget(const EdgeIterator e) const { return NodeIterator(m_edges[e].target); }
NodeIterator GetTarget(const EdgeIterator e) const { return NodeIterator(edge_list[e].target); }
void SetTarget(const EdgeIterator e, const NodeIterator n) { m_edges[e].target = n; }
void SetTarget(const EdgeIterator e, const NodeIterator n) { edge_list[e].target = n; }
EdgeDataT &GetEdgeData(const EdgeIterator e) { return m_edges[e].data; }
EdgeDataT &GetEdgeData(const EdgeIterator e) { return edge_list[e].data; }
const EdgeDataT &GetEdgeData(const EdgeIterator e) const { return m_edges[e].data; }
const EdgeDataT &GetEdgeData(const EdgeIterator e) const { return edge_list[e].data; }
EdgeIterator BeginEdges(const NodeIterator n) const
{
return EdgeIterator(m_nodes[n].firstEdge);
return EdgeIterator(node_list[n].firstEdge);
}
EdgeIterator EndEdges(const NodeIterator n) const
{
return EdgeIterator(m_nodes[n].firstEdge + m_nodes[n].edges);
return EdgeIterator(node_list[n].firstEdge + node_list[n].edges);
}
EdgeRange GetAdjacentEdgeRange(const NodeIterator node) const
{
return boost::irange(BeginEdges(node), EndEdges(node));
return osrm::irange(BeginEdges(node), EndEdges(node));
}
NodeIterator InsertNode()
{
node_list.emplace_back(node_list.back());
number_of_nodes += 1;
return number_of_nodes;
}
// adds an edge. Invalidates edge iterators for the source node
EdgeIterator InsertEdge(const NodeIterator from, const NodeIterator to, const EdgeDataT &data)
{
Node &node = m_nodes[from];
Node &node = node_list[from];
EdgeIterator newFirstEdge = node.edges + node.firstEdge;
if (newFirstEdge >= m_edges.size() || !isDummy(newFirstEdge))
if (newFirstEdge >= edge_list.size() || !isDummy(newFirstEdge))
{
if (node.firstEdge != 0 && isDummy(node.firstEdge - 1))
{
node.firstEdge--;
m_edges[node.firstEdge] = m_edges[node.firstEdge + node.edges];
edge_list[node.firstEdge] = edge_list[node.firstEdge + node.edges];
}
else
{
EdgeIterator newFirstEdge = (EdgeIterator)m_edges.size();
EdgeIterator newFirstEdge = (EdgeIterator)edge_list.size();
unsigned newSize = node.edges * 1.1 + 2;
EdgeIterator requiredCapacity = newSize + m_edges.size();
EdgeIterator oldCapacity = m_edges.capacity();
EdgeIterator requiredCapacity = newSize + edge_list.size();
EdgeIterator oldCapacity = edge_list.capacity();
if (requiredCapacity >= oldCapacity)
{
m_edges.reserve(requiredCapacity * 1.1);
edge_list.reserve(requiredCapacity * 1.1);
}
m_edges.resize(m_edges.size() + newSize);
for (EdgeIterator i = 0; i < node.edges; ++i)
edge_list.resize(edge_list.size() + newSize);
for (const auto i : osrm::irange(0u, node.edges))
{
m_edges[newFirstEdge + i] = m_edges[node.firstEdge + i];
edge_list[newFirstEdge + i] = edge_list[node.firstEdge + i];
makeDummy(node.firstEdge + i);
}
for (EdgeIterator i = node.edges + 1; i < newSize; ++i)
for (const auto i : osrm::irange(node.edges + 1, newSize))
{
makeDummy(newFirstEdge + i);
}
node.firstEdge = newFirstEdge;
}
}
Edge &edge = m_edges[node.firstEdge + node.edges];
Edge &edge = edge_list[node.firstEdge + node.edges];
edge.target = to;
edge.data = data;
++m_numEdges;
++number_of_edges;
++node.edges;
return EdgeIterator(node.firstEdge + node.edges);
}
@@ -198,14 +213,14 @@ template <typename EdgeDataT> class DynamicGraph
// removes an edge. Invalidates edge iterators for the source node
void DeleteEdge(const NodeIterator source, const EdgeIterator e)
{
Node &node = m_nodes[source];
--m_numEdges;
Node &node = node_list[source];
--number_of_edges;
--node.edges;
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != node.edges);
const unsigned last = node.firstEdge + node.edges;
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != last);
// swap with last edge
m_edges[e] = m_edges[last];
edge_list[e] = edge_list[last];
makeDummy(last);
}
@@ -215,19 +230,19 @@ template <typename EdgeDataT> class DynamicGraph
int32_t deleted = 0;
for (EdgeIterator i = BeginEdges(source), iend = EndEdges(source); i < iend - deleted; ++i)
{
if (m_edges[i].target == target)
if (edge_list[i].target == target)
{
do
{
deleted++;
m_edges[i] = m_edges[iend - deleted];
edge_list[i] = edge_list[iend - deleted];
makeDummy(iend - deleted);
} while (i < iend - deleted && m_edges[i].target == target);
} while (i < iend - deleted && edge_list[i].target == target);
}
}
m_numEdges -= deleted;
m_nodes[source].edges -= deleted;
number_of_edges -= deleted;
node_list[source].edges -= deleted;
return deleted;
}
@@ -235,9 +250,9 @@ template <typename EdgeDataT> class DynamicGraph
// searches for a specific edge
EdgeIterator FindEdge(const NodeIterator from, const NodeIterator to) const
{
for (EdgeIterator i = BeginEdges(from), iend = EndEdges(from); i != iend; ++i)
for (const auto i : osrm::irange(BeginEdges(from), EndEdges(from)))
{
if (to == m_edges[i].target)
if (to == edge_list[i].target)
{
return i;
}
@@ -248,12 +263,12 @@ template <typename EdgeDataT> class DynamicGraph
protected:
bool isDummy(const EdgeIterator edge) const
{
return m_edges[edge].target == (std::numeric_limits<NodeIterator>::max)();
return edge_list[edge].target == (std::numeric_limits<NodeIterator>::max)();
}
void makeDummy(const EdgeIterator edge)
{
m_edges[edge].target = (std::numeric_limits<NodeIterator>::max)();
edge_list[edge].target = (std::numeric_limits<NodeIterator>::max)();
}
struct Node
@@ -270,11 +285,11 @@ template <typename EdgeDataT> class DynamicGraph
EdgeDataT data;
};
NodeIterator m_numNodes;
std::atomic_uint m_numEdges;
NodeIterator number_of_nodes;
std::atomic_uint number_of_edges;
std::vector<Node> m_nodes;
DeallocatingVector<Edge> m_edges;
std::vector<Node> node_list;
DeallocatingVector<Edge> edge_list;
};
#endif // DYNAMICGRAPH_H
+12 -4
View File
@@ -1,7 +1,7 @@
#ifndef EDGE_BASED_NODE_H
#define EDGE_BASED_NODE_H
#include "../Util/SimpleLogger.h"
#include "../DataStructures/TravelMode.h"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
@@ -25,7 +25,9 @@ struct EdgeBasedNode
reverse_offset(0),
packed_geometry_id(SPECIAL_EDGEID),
fwd_segment_position( std::numeric_limits<unsigned short>::max() ),
is_in_tiny_cc(false)
is_in_tiny_cc(false),
forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
{ }
explicit EdgeBasedNode(
@@ -40,7 +42,9 @@ struct EdgeBasedNode
int reverse_offset,
unsigned packed_geometry_id,
unsigned short fwd_segment_position,
bool belongs_to_tiny_component
bool belongs_to_tiny_component,
TravelMode forward_travel_mode,
TravelMode backward_travel_mode
) :
forward_edge_based_node_id(forward_edge_based_node_id),
reverse_edge_based_node_id(reverse_edge_based_node_id),
@@ -53,7 +57,9 @@ struct EdgeBasedNode
reverse_offset(reverse_offset),
packed_geometry_id(packed_geometry_id),
fwd_segment_position(fwd_segment_position),
is_in_tiny_cc(belongs_to_tiny_component)
is_in_tiny_cc(belongs_to_tiny_component),
forward_travel_mode(forward_travel_mode),
backward_travel_mode(backward_travel_mode)
{
BOOST_ASSERT((forward_edge_based_node_id != SPECIAL_NODEID) ||
(reverse_edge_based_node_id != SPECIAL_NODEID));
@@ -85,6 +91,8 @@ struct EdgeBasedNode
unsigned packed_geometry_id; // if set, then the edge represents a packed geometry
unsigned short fwd_segment_position; // segment id in a compressed geometry
bool is_in_tiny_cc;
TravelMode forward_travel_mode : 4;
TravelMode backward_travel_mode : 4;
};
#endif //EDGE_BASED_NODE_H
+216
View File
@@ -0,0 +1,216 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OSRM_FIXED_POINT_NUMBER_H
#define OSRM_FIXED_POINT_NUMBER_H
#include <cmath>
#include <cstdint>
#include <iostream>
#include <limits>
#include <type_traits>
#include <utility>
namespace osrm
{
// implements an binary based fixed point number type
template <unsigned FractionalBitSize,
bool use_64_bits = false,
bool is_unsigned = false,
bool truncate_results = false>
class FixedPointNumber
{
static_assert(FractionalBitSize > 0, "FractionalBitSize must be greater than 0");
static_assert(FractionalBitSize <= 32, "FractionalBitSize must at most 32");
typename std::conditional<use_64_bits, int64_t, int32_t>::type m_fixed_point_state;
constexpr static const decltype(m_fixed_point_state) PRECISION = 1 << FractionalBitSize;
// state signage encapsulates whether the state should either represent a
// signed or an unsigned floating point number
using state_signage =
typename std::conditional<is_unsigned,
typename std::make_unsigned<decltype(m_fixed_point_state)>::type,
decltype(m_fixed_point_state)>::type;
public:
FixedPointNumber() : m_fixed_point_state(0) {}
// the type is either initialized with a floating point value or an
// integral state. Anything else will throw at compile-time.
template <class T>
constexpr FixedPointNumber(const T &&input) noexcept
: m_fixed_point_state(static_cast<decltype(m_fixed_point_state)>(
std::round(std::forward<const T>(input) * PRECISION)))
{
static_assert(
std::is_floating_point<T>::value || std::is_integral<T>::value,
"FixedPointNumber needs to be initialized with floating point or integral value");
}
// get max value
template <typename T,
typename std::enable_if<std::is_floating_point<T>::value>::type * = nullptr>
constexpr static auto max() noexcept -> T
{
return static_cast<T>(std::numeric_limits<state_signage>::max()) / PRECISION;
}
// get min value
template <typename T,
typename std::enable_if<std::is_floating_point<T>::value>::type * = nullptr>
constexpr static auto min() noexcept -> T
{
return static_cast<T>(1) / PRECISION;
}
// get lowest value
template <typename T,
typename std::enable_if<std::is_floating_point<T>::value>::type * = nullptr>
constexpr static auto lowest() noexcept -> T
{
return static_cast<T>(std::numeric_limits<state_signage>::min()) / PRECISION;
}
// cast to floating point type T, return value
template <typename T,
typename std::enable_if<std::is_floating_point<T>::value>::type * = nullptr>
explicit operator const T() const noexcept
{
// casts to external type (signed or unsigned) and then to float
return static_cast<T>(static_cast<state_signage>(m_fixed_point_state)) / PRECISION;
}
// warn about cast to integral type T, its disabled for good reason
template <typename T, typename std::enable_if<std::is_integral<T>::value>::type * = nullptr>
explicit operator T() const
{
static_assert(std::is_integral<T>::value,
"casts to integral types have been disabled on purpose");
}
// compare, ie. sort fixed-point numbers
bool operator<(const FixedPointNumber &other) const noexcept
{
return m_fixed_point_state < other.m_fixed_point_state;
}
// equality, ie. sort fixed-point numbers
bool operator==(const FixedPointNumber &other) const noexcept
{
return m_fixed_point_state == other.m_fixed_point_state;
}
bool operator!=(const FixedPointNumber &other) const { return !(*this == other); }
bool operator>(const FixedPointNumber &other) const { return other < *this; }
bool operator<=(const FixedPointNumber &other) const { return !(other < *this); }
bool operator>=(const FixedPointNumber &other) const { return !(*this < other); }
// arithmetic operators
FixedPointNumber operator+(const FixedPointNumber &other) const noexcept
{
FixedPointNumber tmp = *this;
tmp.m_fixed_point_state += other.m_fixed_point_state;
return tmp;
}
FixedPointNumber &operator+=(const FixedPointNumber &other) noexcept
{
this->m_fixed_point_state += other.m_fixed_point_state;
return *this;
}
FixedPointNumber operator-(const FixedPointNumber &other) const noexcept
{
FixedPointNumber tmp = *this;
tmp.m_fixed_point_state -= other.m_fixed_point_state;
return tmp;
}
FixedPointNumber &operator-=(const FixedPointNumber &other) noexcept
{
this->m_fixed_point_state -= other.m_fixed_point_state;
return *this;
}
FixedPointNumber operator*(const FixedPointNumber &other) const noexcept
{
int64_t temp = this->m_fixed_point_state;
temp *= other.m_fixed_point_state;
// rounding!
if (!truncate_results)
{
temp = temp + ((temp & 1 << (FractionalBitSize - 1)) << 1);
}
temp >>= FractionalBitSize;
FixedPointNumber tmp;
tmp.m_fixed_point_state = static_cast<decltype(m_fixed_point_state)>(temp);
return tmp;
}
FixedPointNumber &operator*=(const FixedPointNumber &other) noexcept
{
int64_t temp = this->m_fixed_point_state;
temp *= other.m_fixed_point_state;
// rounding!
if (!truncate_results)
{
temp = temp + ((temp & 1 << (FractionalBitSize - 1)) << 1);
}
temp >>= FractionalBitSize;
this->m_fixed_point_state = static_cast<decltype(m_fixed_point_state)>(temp);
return *this;
}
FixedPointNumber operator/(const FixedPointNumber &other) const noexcept
{
int64_t temp = this->m_fixed_point_state;
temp <<= FractionalBitSize;
temp /= static_cast<int64_t>(other.m_fixed_point_state);
FixedPointNumber tmp;
tmp.m_fixed_point_state = static_cast<decltype(m_fixed_point_state)>(temp);
return tmp;
}
FixedPointNumber &operator/=(const FixedPointNumber &other) noexcept
{
int64_t temp = this->m_fixed_point_state;
temp <<= FractionalBitSize;
temp /= static_cast<int64_t>(other.m_fixed_point_state);
FixedPointNumber tmp;
this->m_fixed_point_state = static_cast<decltype(m_fixed_point_state)>(temp);
return *this;
}
};
static_assert(4 == sizeof(FixedPointNumber<1>), "FP19 has wrong size != 4");
}
#endif // OSRM_FIXED_POINT_NUMBER_H
+1 -1
View File
@@ -34,7 +34,7 @@ template <typename Key, typename Value>
class HashTable
{
private:
typedef std::pair<Key, Value> KeyValPair;
using KeyValPair = std::pair<Key, Value>;
std::vector<KeyValPair> table;
public:
+3 -5
View File
@@ -52,17 +52,15 @@ NodeBasedEdge::NodeBasedEdge(NodeID source,
EdgeWeight weight,
bool forward,
bool backward,
short type,
bool roundabout,
bool in_tiny_cc,
bool access_restricted,
bool contra_flow,
TravelMode travel_mode,
bool is_split)
: source(source), target(target), name_id(name_id), weight(weight), type(type),
: source(source), target(target), name_id(name_id), weight(weight),
forward(forward), backward(backward), roundabout(roundabout), in_tiny_cc(in_tiny_cc),
access_restricted(access_restricted), contra_flow(contra_flow), is_split(is_split)
access_restricted(access_restricted), is_split(is_split), travel_mode(travel_mode)
{
BOOST_ASSERT_MSG(type > 0, "negative edge type");
}
bool EdgeBasedEdge::operator<(const EdgeBasedEdge &other) const
+4 -5
View File
@@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef IMPORT_EDGE_H
#define IMPORT_EDGE_H
#include "../DataStructures/TravelMode.h"
#include "../typedefs.h"
struct NodeBasedEdge
@@ -40,25 +41,23 @@ struct NodeBasedEdge
EdgeWeight weight,
bool forward,
bool backward,
short type,
bool roundabout,
bool in_tiny_cc,
bool access_restricted,
bool contra_flow,
TravelMode travel_mode,
bool is_split);
NodeID source;
NodeID target;
NodeID name_id;
EdgeWeight weight;
short type;
bool forward : 1;
bool backward : 1;
bool roundabout : 1;
bool in_tiny_cc : 1;
bool access_restricted : 1;
bool contra_flow : 1;
bool is_split : 1;
TravelMode travel_mode : 4;
NodeBasedEdge() = delete;
};
@@ -87,6 +86,6 @@ struct EdgeBasedEdge
bool backward : 1;
};
typedef NodeBasedEdge ImportEdge;
using ImportEdge = NodeBasedEdge;
#endif /* IMPORT_EDGE_H */
+41 -42
View File
@@ -25,14 +25,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// based on https://svn.apache.org/repos/asf/mesos/tags/release-0.9.0-incubating-RC0/src/common/json.hpp
// based on
// https://svn.apache.org/repos/asf/mesos/tags/release-0.9.0-incubating-RC0/src/common/json.hpp
#ifndef JSON_CONTAINER_H
#define JSON_CONTAINER_H
#include "../Util/StringUtil.h"
#include <boost/variant.hpp>
#include "../ThirdParty/variant/variant.hpp"
#include "../Util/cast.hpp"
#include <iostream>
#include <vector>
@@ -42,21 +42,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace JSON
{
struct String;
struct Number;
struct Object;
struct Array;
struct True;
struct False;
struct Null;
typedef boost::variant<boost::recursive_wrapper<String>,
boost::recursive_wrapper<Number>,
boost::recursive_wrapper<Object>,
boost::recursive_wrapper<Array>,
boost::recursive_wrapper<True>,
boost::recursive_wrapper<False>,
boost::recursive_wrapper<Null> > Value;
struct String
{
@@ -73,16 +60,6 @@ struct Number
double value;
};
struct Object
{
std::unordered_map<std::string, Value> values;
};
struct Array
{
std::vector<Value> values;
};
struct True
{
};
@@ -95,9 +72,27 @@ struct Null
{
};
struct Renderer : boost::static_visitor<>
using Value = mapbox::util::variant<String,
Number,
mapbox::util::recursive_wrapper<Object>,
mapbox::util::recursive_wrapper<Array>,
True,
False,
Null>;
struct Object
{
Renderer(std::ostream &_out) : out(_out) {}
std::unordered_map<std::string, Value> values;
};
struct Array
{
std::vector<Value> values;
};
struct Renderer : mapbox::util::static_visitor<>
{
explicit Renderer(std::ostream &_out) : out(_out) {}
void operator()(const String &string) const { out << "\"" << string.value << "\""; }
@@ -114,7 +109,7 @@ struct Renderer : boost::static_visitor<>
while (iterator != object.values.end())
{
out << "\"" << (*iterator).first << "\":";
boost::apply_visitor(Renderer(out), (*iterator).second);
mapbox::util::apply_visitor(Renderer(out), (*iterator).second);
if (++iterator != object.values.end())
{
out << ",";
@@ -130,7 +125,7 @@ struct Renderer : boost::static_visitor<>
iterator = array.values.begin();
while (iterator != array.values.end())
{
boost::apply_visitor(Renderer(out), *iterator);
mapbox::util::apply_visitor(Renderer(out), *iterator);
if (++iterator != array.values.end())
{
out << ",";
@@ -149,11 +144,12 @@ struct Renderer : boost::static_visitor<>
std::ostream &out;
};
struct ArrayRenderer : boost::static_visitor<>
struct ArrayRenderer : mapbox::util::static_visitor<>
{
ArrayRenderer(std::vector<char> &_out) : out(_out) {}
explicit ArrayRenderer(std::vector<char> &_out) : out(_out) {}
void operator()(const String &string) const {
void operator()(const String &string) const
{
out.push_back('\"');
out.insert(out.end(), string.value.begin(), string.value.end());
out.push_back('\"');
@@ -161,7 +157,7 @@ struct ArrayRenderer : boost::static_visitor<>
void operator()(const Number &number) const
{
const std::string number_string = FixedDoubleToString(number.value);
const std::string number_string = cast::double_fixed_to_string(number.value);
out.insert(out.end(), number_string.begin(), number_string.end());
}
@@ -176,7 +172,7 @@ struct ArrayRenderer : boost::static_visitor<>
out.push_back('\"');
out.push_back(':');
boost::apply_visitor(ArrayRenderer(out), (*iterator).second);
mapbox::util::apply_visitor(ArrayRenderer(out), (*iterator).second);
if (++iterator != object.values.end())
{
out.push_back(',');
@@ -192,7 +188,7 @@ struct ArrayRenderer : boost::static_visitor<>
iterator = array.values.begin();
while (iterator != array.values.end())
{
boost::apply_visitor(ArrayRenderer(out), *iterator);
mapbox::util::apply_visitor(ArrayRenderer(out), *iterator);
if (++iterator != array.values.end())
{
out.push_back(',');
@@ -201,17 +197,20 @@ struct ArrayRenderer : boost::static_visitor<>
out.push_back(']');
}
void operator()(const True &) const {
void operator()(const True &) const
{
const std::string temp("true");
out.insert(out.end(), temp.begin(), temp.end());
}
void operator()(const False &) const {
void operator()(const False &) const
{
const std::string temp("false");
out.insert(out.end(), temp.begin(), temp.end());
}
void operator()(const Null &) const {
void operator()(const Null &) const
{
const std::string temp("null");
out.insert(out.end(), temp.begin(), temp.end());
}
@@ -223,13 +222,13 @@ struct ArrayRenderer : boost::static_visitor<>
inline void render(std::ostream &out, const Object &object)
{
Value value = object;
boost::apply_visitor(Renderer(out), value);
mapbox::util::apply_visitor(Renderer(out), value);
}
inline void render(std::vector<char> &out, const Object &object)
{
Value value = object;
boost::apply_visitor(ArrayRenderer(out), value);
mapbox::util::apply_visitor(ArrayRenderer(out), value);
}
} // namespace JSON
+93 -15
View File
@@ -1,9 +1,9 @@
#ifndef __NODE_BASED_GRAPH_H__
#define __NODE_BASED_GRAPH_H__
#ifndef NODE_BASED_GRAPH_H_
#define NODE_BASED_GRAPH_H_
#include "DynamicGraph.h"
#include "ImportEdge.h"
#include "../Util/SimpleLogger.h"
#include "../Util/simple_logger.hpp"
#include <tbb/parallel_sort.h>
@@ -13,23 +13,22 @@ struct NodeBasedEdgeData
{
NodeBasedEdgeData()
: distance(INVALID_EDGE_WEIGHT), edgeBasedNodeID(SPECIAL_NODEID),
nameID(std::numeric_limits<unsigned>::max()), type(std::numeric_limits<short>::max()),
nameID(std::numeric_limits<unsigned>::max()),
isAccessRestricted(false), shortcut(false), forward(false), backward(false),
roundabout(false), ignore_in_grid(false), contraFlow(false)
roundabout(false), ignore_in_grid(false), travel_mode(TRAVEL_MODE_INACCESSIBLE)
{
}
int distance;
unsigned edgeBasedNodeID;
unsigned nameID;
short type;
bool isAccessRestricted : 1;
bool shortcut : 1;
bool forward : 1;
bool backward : 1;
bool roundabout : 1;
bool ignore_in_grid : 1;
bool contraFlow : 1;
TravelMode travel_mode : 4;
void SwapDirectionFlags()
{
@@ -42,18 +41,24 @@ struct NodeBasedEdgeData
{
return (forward == other.forward) && (backward == other.backward) &&
(nameID == other.nameID) && (ignore_in_grid == other.ignore_in_grid) &&
(contraFlow == other.contraFlow);
(travel_mode == other.travel_mode);
}
};
typedef DynamicGraph<NodeBasedEdgeData> NodeBasedDynamicGraph;
struct SimpleEdgeData
{
SimpleEdgeData() : capacity(0) {}
EdgeWeight capacity;
};
using NodeBasedDynamicGraph = DynamicGraph<NodeBasedEdgeData>;
using SimpleNodeBasedDynamicGraph = DynamicGraph<SimpleEdgeData>;
// Factory method to create NodeBasedDynamicGraph from ImportEdges
inline std::shared_ptr<NodeBasedDynamicGraph>
NodeBasedDynamicGraphFromImportEdges(int number_of_nodes, std::vector<ImportEdge> &input_edge_list)
{
static_assert(sizeof(NodeBasedEdgeData) == 16, "changing node based edge data size changes memory consumption");
// tbb::parallel_sort(input_edge_list.begin(), input_edge_list.end());
DeallocatingVector<NodeBasedDynamicGraph::InputEdge> edges_list;
NodeBasedDynamicGraph::InputEdge edge;
@@ -85,9 +90,9 @@ NodeBasedDynamicGraphFromImportEdges(int number_of_nodes, std::vector<ImportEdge
edge.data.roundabout = import_edge.roundabout;
edge.data.ignore_in_grid = import_edge.in_tiny_cc;
edge.data.nameID = import_edge.name_id;
edge.data.type = import_edge.type;
edge.data.isAccessRestricted = import_edge.access_restricted;
edge.data.contraFlow = import_edge.contra_flow;
edge.data.travel_mode = import_edge.travel_mode;
edges_list.push_back(edge);
if (!import_edge.is_split)
@@ -100,7 +105,7 @@ NodeBasedDynamicGraphFromImportEdges(int number_of_nodes, std::vector<ImportEdge
}
// remove duplicate edges
std::sort(edges_list.begin(), edges_list.end());
tbb::parallel_sort(edges_list.begin(), edges_list.end());
NodeID edge_count = 0;
for (NodeID i = 0; i < edges_list.size(); )
{
@@ -159,8 +164,81 @@ NodeBasedDynamicGraphFromImportEdges(int number_of_nodes, std::vector<ImportEdge
edges_list.resize(edge_count);
SimpleLogger().Write() << "merged " << edges_list.size() - edge_count << " edges out of " << edges_list.size();
auto graph = std::make_shared<NodeBasedDynamicGraph>(number_of_nodes, edges_list);
auto graph = std::make_shared<NodeBasedDynamicGraph>(static_cast<NodeBasedDynamicGraph::NodeIterator>(number_of_nodes), edges_list);
return graph;
}
#endif // __NODE_BASED_GRAPH_H__
template<class SimpleEdgeT>
inline std::shared_ptr<SimpleNodeBasedDynamicGraph>
SimpleNodeBasedDynamicGraphFromEdges(int number_of_nodes, std::vector<SimpleEdgeT> &input_edge_list)
{
static_assert(sizeof(NodeBasedEdgeData) == 16, "changing node based edge data size changes memory consumption");
tbb::parallel_sort(input_edge_list.begin(), input_edge_list.end());
DeallocatingVector<SimpleNodeBasedDynamicGraph::InputEdge> edges_list;
SimpleNodeBasedDynamicGraph::InputEdge edge;
edge.data.capacity = 1;
for (const SimpleEdgeT &import_edge : input_edge_list)
{
if (import_edge.source == import_edge.target)
{
continue;
}
edge.source = import_edge.source;
edge.target = import_edge.target;
edges_list.push_back(edge);
std::swap(edge.source, edge.target);
edges_list.push_back(edge);
}
// remove duplicate edges
tbb::parallel_sort(edges_list.begin(), edges_list.end());
NodeID edge_count = 0;
for (NodeID i = 0; i < edges_list.size(); )
{
const NodeID source = edges_list[i].source;
const NodeID target = edges_list[i].target;
// remove eigenloops
if (source == target)
{
i++;
continue;
}
SimpleNodeBasedDynamicGraph::InputEdge forward_edge;
SimpleNodeBasedDynamicGraph::InputEdge reverse_edge;
forward_edge = reverse_edge = edges_list[i];
forward_edge.data.capacity = reverse_edge.data.capacity = INVALID_EDGE_WEIGHT;
// remove parallel edges
while (i < edges_list.size() && edges_list[i].source == source && edges_list[i].target == target)
{
forward_edge.data.capacity = std::min(edges_list[i].data.capacity, forward_edge.data.capacity);
reverse_edge.data.capacity = std::min(edges_list[i].data.capacity, reverse_edge.data.capacity);
++i;
}
// merge edges (s,t) and (t,s) into bidirectional edge
if (forward_edge.data.capacity == reverse_edge.data.capacity)
{
if ((int)forward_edge.data.capacity != INVALID_EDGE_WEIGHT)
{
edges_list[edge_count++] = forward_edge;
}
}
else
{ // insert seperate edges
if (((int)forward_edge.data.capacity) != INVALID_EDGE_WEIGHT)
{
edges_list[edge_count++] = forward_edge;
}
if ((int)reverse_edge.data.capacity != INVALID_EDGE_WEIGHT)
{
edges_list[edge_count++] = reverse_edge;
}
}
}
SimpleLogger().Write() << "merged " << edges_list.size() - edge_count << " edges out of " << edges_list.size();
auto graph = std::make_shared<SimpleNodeBasedDynamicGraph>(number_of_nodes, edges_list);
return graph;
}
#endif // NODE_BASED_GRAPH_H_
+7 -3
View File
@@ -29,6 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define ORIGINAL_EDGE_DATA_H
#include "TurnInstructions.h"
#include "../DataStructures/TravelMode.h"
#include "../typedefs.h"
#include <limits>
@@ -38,16 +39,18 @@ struct OriginalEdgeData
explicit OriginalEdgeData(NodeID via_node,
unsigned name_id,
TurnInstruction turn_instruction,
bool compressed_geometry)
bool compressed_geometry,
TravelMode travel_mode)
: via_node(via_node), name_id(name_id), turn_instruction(turn_instruction),
compressed_geometry(compressed_geometry)
compressed_geometry(compressed_geometry), travel_mode(travel_mode)
{
}
OriginalEdgeData()
: via_node(std::numeric_limits<unsigned>::max()),
name_id(std::numeric_limits<unsigned>::max()),
turn_instruction(TurnInstruction::NoTurn), compressed_geometry(false)
turn_instruction(TurnInstruction::NoTurn), compressed_geometry(false),
travel_mode(TRAVEL_MODE_INACCESSIBLE)
{
}
@@ -55,6 +58,7 @@ struct OriginalEdgeData
unsigned name_id;
TurnInstruction turn_instruction;
bool compressed_geometry;
TravelMode travel_mode;
};
#endif // ORIGINAL_EDGE_DATA_H
+13 -5
View File
@@ -29,7 +29,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define PHANTOM_NODES_H
#include <osrm/Coordinate.h>
#include "../Util/SimpleLogger.h"
#include "../DataStructures/TravelMode.h"
#include "../Util/simple_logger.hpp"
#include "../typedefs.h"
#include <vector>
@@ -39,7 +40,8 @@ struct PhantomNode
PhantomNode(NodeID forward_node_id, NodeID reverse_node_id, unsigned name_id,
int forward_weight, int reverse_weight, int forward_offset, int reverse_offset,
unsigned packed_geometry_id, FixedPointCoordinate &location,
unsigned short fwd_segment_position) :
unsigned short fwd_segment_position,
TravelMode forward_travel_mode, TravelMode backward_travel_mode) :
forward_node_id(forward_node_id),
reverse_node_id(reverse_node_id),
name_id(name_id),
@@ -49,7 +51,9 @@ struct PhantomNode
reverse_offset(reverse_offset),
packed_geometry_id(packed_geometry_id),
location(location),
fwd_segment_position(fwd_segment_position)
fwd_segment_position(fwd_segment_position),
forward_travel_mode(forward_travel_mode),
backward_travel_mode(backward_travel_mode)
{ }
PhantomNode() :
@@ -61,7 +65,9 @@ struct PhantomNode
forward_offset(0),
reverse_offset(0),
packed_geometry_id(SPECIAL_EDGEID),
fwd_segment_position(0)
fwd_segment_position(0),
forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
{ }
NodeID forward_node_id;
@@ -74,6 +80,8 @@ struct PhantomNode
unsigned packed_geometry_id;
FixedPointCoordinate location;
unsigned short fwd_segment_position;
TravelMode forward_travel_mode : 4;
TravelMode backward_travel_mode : 4;
int GetForwardWeightPlusOffset() const
{
@@ -134,7 +142,7 @@ struct PhantomNode
}
};
typedef std::vector<std::vector<PhantomNode>> PhantomNodeArray;
using PhantomNodeArray = std::vector<std::vector<PhantomNode>>;
struct PhantomNodeLists
{
+17
View File
@@ -36,6 +36,16 @@ struct QueryEdge
NodeID target;
struct EdgeData
{
EdgeData() : id(0), shortcut(false), distance(0), forward(false), backward(false) {}
template <class OtherT> EdgeData(const OtherT &other)
{
distance = other.distance;
shortcut = other.shortcut;
id = other.id;
forward = other.forward;
backward = other.backward;
}
NodeID id : 31;
bool shortcut : 1;
int distance : 30;
@@ -43,6 +53,13 @@ struct QueryEdge
bool backward : 1;
} data;
QueryEdge() : source(SPECIAL_NODEID), target(SPECIAL_NODEID) {}
QueryEdge(NodeID source, NodeID target, EdgeData data)
: source(source), target(target), data(data)
{
}
bool operator<(const QueryEdge &right) const
{
if (source != right.source)
+2 -2
View File
@@ -38,8 +38,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct NodeInfo
{
typedef NodeID key_type; // type of NodeID
typedef int value_type; // type of lat,lons
using key_type = NodeID; // type of NodeID
using value_type = int; // type of lat,lons
explicit NodeInfo(int lat, int lon, NodeID node_id) : lat(lat), lon(lon), node_id(node_id) {}
NodeInfo()
+67
View File
@@ -0,0 +1,67 @@
/*
Copyright (c) 2013,2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef RANGE_H
#define RANGE_H
#include <type_traits>
namespace osrm
{
template <typename Integer> class range
{
private:
Integer last;
Integer iter;
public:
range(Integer start, Integer end) : last(end), iter(start)
{
static_assert(std::is_integral<Integer>::value, "range type must be integral");
}
// Iterable functions
const range &begin() const { return *this; }
const range &end() const { return *this; }
Integer front() const { return iter; }
Integer back() const { return last - 1; }
// Iterator functions
bool operator!=(const range &) const { return iter < last; }
void operator++() { ++iter; }
Integer operator*() const { return iter; }
};
// convenience function to construct an integer range with type deduction
template <typename Integer> range<Integer> irange(Integer first, Integer last)
{
return range<Integer>(first, last);
}
}
#endif // RANGE_H
+11 -11
View File
@@ -1,11 +1,10 @@
#ifndef __RANGE_TABLE_H__
#define __RANGE_TABLE_H__
#ifndef RANGE_TABLE_H_
#define RANGE_TABLE_H_
#include "Range.h"
#include "SharedMemoryFactory.h"
#include "SharedMemoryVectorWrapper.h"
#include <boost/range/irange.hpp>
#include <fstream>
#include <vector>
#include <array>
@@ -37,10 +36,10 @@ class RangeTable
{
public:
typedef std::array<unsigned char, BLOCK_SIZE> BlockT;
typedef typename ShM<BlockT, USE_SHARED_MEMORY>::vector BlockContainerT;
typedef typename ShM<unsigned, USE_SHARED_MEMORY>::vector OffsetContainerT;
typedef decltype(boost::irange(0u,0u)) RangeT;
using BlockT = std::array<unsigned char, BLOCK_SIZE>;
using BlockContainerT = typename ShM<BlockT, USE_SHARED_MEMORY>::vector;
using OffsetContainerT = typename ShM<unsigned, USE_SHARED_MEMORY>::vector;
using RangeT = osrm::range<unsigned>;
friend std::ostream& operator<< <>(std::ostream &out, const RangeTable &table);
friend std::istream& operator>> <>(std::istream &in, RangeTable &table);
@@ -117,7 +116,8 @@ public:
{
// the last value is used as sentinel
block_offsets.push_back(lengths_prefix_sum);
block_idx = (block_idx + 1) % BLOCK_SIZE;
block_idx = 1;
last_length = 0;
}
while (0 != block_idx)
@@ -166,7 +166,7 @@ public:
BOOST_ASSERT(begin_idx < sum_lengths && end_idx <= sum_lengths);
BOOST_ASSERT(begin_idx <= end_idx);
return boost::irange(begin_idx, end_idx);
return osrm::irange(begin_idx, end_idx);
}
private:
@@ -228,4 +228,4 @@ std::istream& operator>>(std::istream &in, RangeTable<BLOCK_SIZE, USE_SHARED_MEM
return in;
}
#endif
#endif //RANGE_TABLE_H_
+16 -3
View File
@@ -29,6 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define RAW_ROUTE_DATA_H
#include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/TravelMode.h"
#include "../DataStructures/TurnInstructions.h"
#include "../typedefs.h"
@@ -41,18 +42,25 @@ struct PathData
PathData()
: node(SPECIAL_NODEID), name_id(INVALID_EDGE_WEIGHT),
segment_duration(INVALID_EDGE_WEIGHT),
turn_instruction(TurnInstruction::NoTurn)
turn_instruction(TurnInstruction::NoTurn),
travel_mode(TRAVEL_MODE_INACCESSIBLE)
{
}
PathData(NodeID node, unsigned name_id, TurnInstruction turn_instruction, EdgeWeight segment_duration)
: node(node), name_id(name_id), segment_duration(segment_duration), turn_instruction(turn_instruction)
PathData(NodeID node,
unsigned name_id,
TurnInstruction turn_instruction,
EdgeWeight segment_duration,
TravelMode travel_mode)
: node(node), name_id(name_id), segment_duration(segment_duration), turn_instruction(turn_instruction),
travel_mode(travel_mode)
{
}
NodeID node;
unsigned name_id;
EdgeWeight segment_duration;
TurnInstruction turn_instruction;
TravelMode travel_mode : 4;
};
struct RawRouteData
@@ -69,6 +77,11 @@ struct RawRouteData
int shortest_path_length;
int alternative_path_length;
bool is_via_leg(const std::size_t leg) const
{
return (leg != unpacked_path_segments.size() - 1);
}
RawRouteData()
: check_sum(SPECIAL_NODEID),
shortest_path_length(INVALID_EDGE_WEIGHT),
+2 -2
View File
@@ -101,7 +101,7 @@ struct InputRestrictionContainer
struct CmpRestrictionContainerByFrom
{
typedef InputRestrictionContainer value_type;
using value_type = InputRestrictionContainer;
inline bool operator()(const InputRestrictionContainer &a, const InputRestrictionContainer &b)
const
{
@@ -113,7 +113,7 @@ struct CmpRestrictionContainerByFrom
struct CmpRestrictionContainerByTo
{
typedef InputRestrictionContainer value_type;
using value_type = InputRestrictionContainer;
inline bool operator()(const InputRestrictionContainer &a, const InputRestrictionContainer &b)
const
{
+4 -9
View File
@@ -28,8 +28,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "RestrictionMap.h"
#include "NodeBasedGraph.h"
#include "../Util/SimpleLogger.h"
bool RestrictionMap::IsViaNode(const NodeID node) const
{
return m_no_turn_via_node_set.find(node) != m_no_turn_via_node_set.end();
@@ -96,9 +94,8 @@ void RestrictionMap::FixupArrivingTurnRestriction(const NodeID node_u,
std::vector<NodeID> predecessors;
for (const EdgeID current_edge_id : m_graph->GetAdjacentEdgeRange(node_u))
{
const EdgeData &edge_data = m_graph->GetEdgeData(current_edge_id);
const NodeID target = m_graph->GetTarget(current_edge_id);
if (edge_data.backward && (node_v != target))
if (node_v != target)
{
predecessors.push_back(target);
}
@@ -163,11 +160,11 @@ NodeID RestrictionMap::CheckForEmanatingIsOnlyTurn(const NodeID node_u, const No
return SPECIAL_NODEID;
}
auto restriction_iter = m_restriction_map.find({node_u, node_v});
const auto restriction_iter = m_restriction_map.find({node_u, node_v});
if (restriction_iter != m_restriction_map.end())
{
const unsigned index = restriction_iter->second;
auto &bucket = m_restriction_bucket_list.at(index);
const auto &bucket = m_restriction_bucket_list.at(index);
for (const RestrictionTarget &restriction_target : bucket)
{
if (restriction_target.is_only)
@@ -184,8 +181,6 @@ bool RestrictionMap::CheckIfTurnIsRestricted(const NodeID node_u,
const NodeID node_v,
const NodeID node_w) const
{
// return false;
BOOST_ASSERT(node_u != SPECIAL_NODEID);
BOOST_ASSERT(node_v != SPECIAL_NODEID);
BOOST_ASSERT(node_w != SPECIAL_NODEID);
@@ -195,7 +190,7 @@ bool RestrictionMap::CheckIfTurnIsRestricted(const NodeID node_u,
return false;
}
auto restriction_iter = m_restriction_map.find({node_u, node_v});
const auto restriction_iter = m_restriction_map.find({node_u, node_v});
if (restriction_iter != m_restriction_map.end())
{
const unsigned index = restriction_iter->second;
+7 -7
View File
@@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __RESTRICTION_MAP_H__
#define __RESTRICTION_MAP_H__
#ifndef RESTRICTION_MAP_H_
#define RESTRICTION_MAP_H_
#include <memory>
@@ -103,17 +103,17 @@ class RestrictionMap
NodeID CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const;
bool CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const;
bool IsViaNode(const NodeID node) const;
unsigned size()
std::size_t size()
{
return m_count;
}
private:
bool IsSourceNode(const NodeID node) const;
typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector;
typedef NodeBasedDynamicGraph::EdgeData EdgeData;
using EmanatingRestrictionsVector = std::vector<RestrictionTarget>;
using EdgeData = NodeBasedDynamicGraph::EdgeData;
unsigned m_count;
std::size_t m_count;
std::shared_ptr<NodeBasedDynamicGraph> m_graph;
//! index -> list of (target, isOnly)
std::vector<EmanatingRestrictionsVector> m_restriction_bucket_list;
@@ -123,4 +123,4 @@ class RestrictionMap
std::unordered_set<NodeID> m_no_turn_via_node_set;
};
#endif
#endif //RESTRICTION_MAP_H_
+29 -1
View File
@@ -33,7 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
RouteParameters::RouteParameters()
: zoom_level(18), print_instructions(false), alternate_route(true), geometry(true),
compression(true), deprecatedAPI(false), check_sum(-1)
compression(true), deprecatedAPI(false), uturn_default(false), check_sum(-1), num_results(1)
{
}
@@ -45,8 +45,36 @@ void RouteParameters::setZoomLevel(const short level)
}
}
void RouteParameters::setNumberOfResults(const short number)
{
if (number > 0 && number <= 100)
{
num_results = number;
}
}
void RouteParameters::setAlternateRouteFlag(const bool flag) { alternate_route = flag; }
void RouteParameters::setUTurn(const bool flag)
{
uturns.resize(coordinates.size(), uturn_default);
if (!uturns.empty())
{
uturns.back() = flag;
}
}
void RouteParameters::setAllUTurns(const bool flag)
{
// if the flag flips the default, then we erase everything.
if (flag)
{
uturn_default = flag;
uturns.clear();
uturns.resize(coordinates.size(), uturn_default);
}
}
void RouteParameters::setDeprecatedAPIFlag(const std::string &) { deprecatedAPI = true; }
void RouteParameters::setChecksum(const unsigned sum) { check_sum = sum; }
+2 -2
View File
@@ -41,8 +41,8 @@ struct HeapData
struct SearchEngineData
{
typedef BinaryHeap<NodeID, NodeID, int, HeapData, UnorderedMapStorage<NodeID, int>> QueryHeap;
typedef boost::thread_specific_ptr<QueryHeap> SearchEngineHeapPtr;
using QueryHeap = BinaryHeap<NodeID, NodeID, int, HeapData, UnorderedMapStorage<NodeID, int>>;
using SearchEngineHeapPtr = boost::thread_specific_ptr<QueryHeap>;
static SearchEngineHeapPtr forwardHeap;
static SearchEngineHeapPtr backwardHeap;
+12 -6
View File
@@ -30,6 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "TurnInstructions.h"
#include "../DataStructures/TravelMode.h"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
@@ -43,8 +44,9 @@ struct SegmentInformation
float length;
short bearing; // more than enough [0..3600] fits into 12 bits
TurnInstruction turn_instruction;
bool necessary:1;
bool is_via_location:1;
TravelMode travel_mode;
bool necessary;
bool is_via_location;
explicit SegmentInformation(const FixedPointCoordinate &location,
const NodeID name_id,
@@ -52,9 +54,11 @@ struct SegmentInformation
const float length,
const TurnInstruction turn_instruction,
const bool necessary,
const bool is_via_location)
const bool is_via_location,
const TravelMode travel_mode)
: location(location), name_id(name_id), duration(duration), length(length), bearing(0),
turn_instruction(turn_instruction), necessary(necessary), is_via_location(is_via_location)
turn_instruction(turn_instruction), travel_mode(travel_mode), necessary(necessary),
is_via_location(is_via_location)
{
}
@@ -62,9 +66,11 @@ struct SegmentInformation
const NodeID name_id,
const EdgeWeight duration,
const float length,
const TurnInstruction turn_instruction)
const TurnInstruction turn_instruction,
const TravelMode travel_mode)
: location(location), name_id(name_id), duration(duration), length(length), bearing(0),
turn_instruction(turn_instruction), necessary(turn_instruction != TurnInstruction::NoTurn), is_via_location(false)
turn_instruction(turn_instruction), travel_mode(travel_mode),
necessary(turn_instruction != TurnInstruction::NoTurn), is_via_location(false)
{
}
};
+6 -5
View File
@@ -29,7 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define SHARED_MEMORY_FACTORY_H
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../Util/simple_logger.hpp"
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
@@ -196,12 +196,14 @@ class SharedMemory
};
#else
// Windows - specific code
class SharedMemory : boost::noncopyable
class SharedMemory
{
SharedMemory(const SharedMemory&) = delete;
// Remove shared memory on destruction
class shm_remove : boost::noncopyable
class shm_remove
{
private:
shm_remove(const shm_remove&) = delete;
char *m_shmid;
bool m_initialized;
@@ -286,7 +288,6 @@ class SharedMemory : boost::noncopyable
private:
static void build_key(int id, char *key)
{
OSRMLockFile lock_file;
sprintf(key, "%s.%d", "osrm.lock", id);
}
@@ -365,6 +366,6 @@ template <class LockFileT = OSRMLockFile> class SharedMemoryFactory_tmpl
SharedMemoryFactory_tmpl(const SharedMemoryFactory_tmpl &) = delete;
};
typedef SharedMemoryFactory_tmpl<> SharedMemoryFactory;
using SharedMemoryFactory = SharedMemoryFactory_tmpl<>;
#endif /* SHARED_MEMORY_POINTER_FACTORY_H */
+4 -6
View File
@@ -28,8 +28,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef SHARED_MEMORY_VECTOR_WRAPPER_H
#define SHARED_MEMORY_VECTOR_WRAPPER_H
#include "../Util/SimpleLogger.h"
#include <boost/assert.hpp>
#include <algorithm>
@@ -78,7 +76,7 @@ template <typename DataT> class SharedMemoryWrapper
void swap(SharedMemoryWrapper<DataT> &other)
{
BOOST_ASSERT_MSG(m_size != 0 || other.size() != 0, "size invalid");
// BOOST_ASSERT_MSG(m_size != 0 || other.size() != 0, "size invalid");
std::swap(m_size, other.m_size);
std::swap(m_ptr, other.m_ptr);
}
@@ -121,7 +119,7 @@ template <> class SharedMemoryWrapper<bool>
void swap(SharedMemoryWrapper<bool> &other)
{
BOOST_ASSERT_MSG(m_size != 0 || other.size() != 0, "size invalid");
// BOOST_ASSERT_MSG(m_size != 0 || other.size() != 0, "size invalid");
std::swap(m_size, other.m_size);
std::swap(m_ptr, other.m_ptr);
}
@@ -148,9 +146,9 @@ template <> class SharedMemoryWrapper<bool>
template <typename DataT, bool UseSharedMemory> struct ShM
{
typedef typename std::conditional<UseSharedMemory,
using vector = typename std::conditional<UseSharedMemory,
SharedMemoryWrapper<DataT>,
std::vector<DataT>>::type vector;
std::vector<DataT>>::type;
};
#endif // SHARED_MEMORY_VECTOR_WRAPPER_H
+20 -49
View File
@@ -28,33 +28,37 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef STATIC_GRAPH_H
#define STATIC_GRAPH_H
#include "../DataStructures/Percent.h"
#include "../DataStructures/SharedMemoryVectorWrapper.h"
#include "../Util/SimpleLogger.h"
#include "Percent.h"
#include "Range.h"
#include "SharedMemoryVectorWrapper.h"
#include "../typedefs.h"
#include <boost/assert.hpp>
#include <boost/range/irange.hpp>
#include <tbb/parallel_sort.h>
#include <algorithm>
#include <limits>
#include <utility>
#include <vector>
template <typename EdgeDataT, bool UseSharedMemory = false> class StaticGraph
{
public:
typedef decltype(boost::irange(0u,0u)) EdgeRange;
typedef NodeID NodeIterator;
typedef NodeID EdgeIterator;
typedef EdgeDataT EdgeData;
using NodeIterator = NodeID;
using EdgeIterator = NodeID;
using EdgeData = EdgeDataT;
using EdgeRange = osrm::range<EdgeIterator>;
class InputEdge
{
public:
EdgeDataT data;
NodeIterator source;
NodeIterator target;
EdgeDataT data;
template<typename... Ts>
InputEdge(NodeIterator source, NodeIterator target, Ts &&...data) : source(source), target(target), data(std::forward<Ts>(data)...) { }
bool operator<(const InputEdge &right) const
{
if (source != right.source)
@@ -79,7 +83,7 @@ template <typename EdgeDataT, bool UseSharedMemory = false> class StaticGraph
EdgeRange GetAdjacentEdgeRange(const NodeID node) const
{
return boost::irange(BeginEdges(node), EndEdges(node));
return osrm::irange(BeginEdges(node), EndEdges(node));
}
StaticGraph(const int nodes, std::vector<InputEdge> &graph)
@@ -90,7 +94,7 @@ template <typename EdgeDataT, bool UseSharedMemory = false> class StaticGraph
node_array.resize(number_of_nodes + 1);
EdgeIterator edge = 0;
EdgeIterator position = 0;
for (NodeIterator node = 0; node <= number_of_nodes; ++node)
for (const auto node : osrm::irange(0u, number_of_nodes+1))
{
EdgeIterator last_edge = edge;
while (edge < number_of_edges && graph[edge].source == node)
@@ -102,7 +106,7 @@ template <typename EdgeDataT, bool UseSharedMemory = false> class StaticGraph
}
edge_array.resize(position); //(edge)
edge = 0;
for (NodeIterator node = 0; node < number_of_nodes; ++node)
for (const auto node : osrm::irange(0u, number_of_nodes))
{
EdgeIterator e = node_array[node + 1].first_edge;
for (EdgeIterator i = node_array[node].first_edge; i != e; ++i)
@@ -118,51 +122,18 @@ template <typename EdgeDataT, bool UseSharedMemory = false> class StaticGraph
StaticGraph(typename ShM<NodeArrayEntry, UseSharedMemory>::vector &nodes,
typename ShM<EdgeArrayEntry, UseSharedMemory>::vector &edges)
{
number_of_nodes = nodes.size() - 1;
number_of_edges = edges.size();
number_of_nodes = static_cast<decltype(number_of_nodes)>(nodes.size() - 1);
number_of_edges = static_cast<decltype(number_of_edges)>(edges.size());
node_array.swap(nodes);
edge_array.swap(edges);
#ifndef NDEBUG
Percent p(GetNumberOfNodes());
for (unsigned u = 0; u < GetNumberOfNodes(); ++u)
{
for (auto eid : GetAdjacentEdgeRange(u))
{
const EdgeData &data = GetEdgeData(eid);
if (!data.shortcut)
{
continue;
}
const unsigned v = GetTarget(eid);
const EdgeID first_edge_id = FindEdgeInEitherDirection(u, data.id);
if (SPECIAL_EDGEID == first_edge_id)
{
SimpleLogger().Write(logWARNING) << "cannot find first segment of edge ("
<< u << "," << data.id << "," << v
<< "), eid: " << eid;
BOOST_ASSERT(false);
}
const EdgeID second_edge_id = FindEdgeInEitherDirection(data.id, v);
if (SPECIAL_EDGEID == second_edge_id)
{
SimpleLogger().Write(logWARNING) << "cannot find second segment of edge ("
<< u << "," << data.id << "," << v
<< "), eid: " << eid;
BOOST_ASSERT(false);
}
}
p.printIncrement();
}
#endif
}
unsigned GetNumberOfNodes() const { return number_of_nodes -1; }
unsigned GetNumberOfNodes() const { return number_of_nodes; }
unsigned GetNumberOfEdges() const { return number_of_edges; }
unsigned GetOutDegree(const NodeIterator n) const { return BeginEdges(n) - EndEdges(n) - 1; }
unsigned GetOutDegree(const NodeIterator n) const { return EndEdges(n) - BeginEdges(n); }
inline NodeIterator GetTarget(const EdgeIterator e) const
{
+1 -1
View File
@@ -211,7 +211,7 @@ class StaticKDTree
}
private:
typedef unsigned Iterator;
using Iterator = unsigned;
struct Tree
{
Iterator left;
+266 -94
View File
@@ -35,9 +35,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "SharedMemoryFactory.h"
#include "SharedMemoryVectorWrapper.h"
#include "../ThirdParty/variant/variant.hpp"
#include "../Util/floating_point.hpp"
#include "../Util/MercatorUtil.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../Util/simple_logger.hpp"
#include "../Util/TimingUtil.h"
#include "../typedefs.h"
@@ -47,7 +49,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/thread.hpp>
#include <boost/variant.hpp>
#include <tbb/parallel_for.h>
#include <tbb/parallel_sort.h>
@@ -60,16 +61,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include <vector>
// tuning parameters
const static uint32_t RTREE_BRANCHING_FACTOR = 64;
const static uint32_t RTREE_LEAF_NODE_SIZE = 1024;
static boost::thread_specific_ptr<boost::filesystem::ifstream> thread_local_rtree_stream;
// Implements a static, i.e. packed, R-tree
template <class EdgeDataT,
class CoordinateListT = std::vector<FixedPointCoordinate>,
bool UseSharedMemory = false>
bool UseSharedMemory = false,
uint32_t BRANCHING_FACTOR=64,
uint32_t LEAF_NODE_SIZE=1024>
class StaticRTree
{
public:
@@ -80,7 +77,7 @@ class StaticRTree
int32_t min_lon, max_lon;
int32_t min_lat, max_lat;
inline void InitializeMBRectangle(const std::array<EdgeDataT, RTREE_LEAF_NODE_SIZE> &objects,
inline void InitializeMBRectangle(const std::array<EdgeDataT, LEAF_NODE_SIZE> &objects,
const uint32_t element_count,
const std::vector<NodeInfo> &coordinate_list)
{
@@ -147,19 +144,64 @@ class StaticRTree
return 0.;
}
enum Direction
{
INVALID = 0,
NORTH = 1,
SOUTH = 2,
EAST = 4,
NORTH_EAST = 5,
SOUTH_EAST = 6,
WEST = 8,
NORTH_WEST = 9,
SOUTH_WEST = 10
};
Direction d = INVALID;
if (location.lat > max_lat)
d = (Direction) (d | NORTH);
else if (location.lat < min_lat)
d = (Direction) (d | SOUTH);
if (location.lon > max_lon)
d = (Direction) (d | EAST);
else if (location.lon < min_lon)
d = (Direction) (d | WEST);
BOOST_ASSERT(d != INVALID);
float min_dist = std::numeric_limits<float>::max();
min_dist = std::min(min_dist,
FixedPointCoordinate::ApproximateEuclideanDistance(
location.lat, location.lon, max_lat, min_lon));
min_dist = std::min(min_dist,
FixedPointCoordinate::ApproximateEuclideanDistance(
location.lat, location.lon, max_lat, max_lon));
min_dist = std::min(min_dist,
FixedPointCoordinate::ApproximateEuclideanDistance(
location.lat, location.lon, min_lat, max_lon));
min_dist = std::min(min_dist,
FixedPointCoordinate::ApproximateEuclideanDistance(
location.lat, location.lon, min_lat, min_lon));
switch (d)
{
case NORTH:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(max_lat, location.lon));
break;
case SOUTH:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(min_lat, location.lon));
break;
case WEST:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(location.lat, min_lon));
break;
case EAST:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(location.lat, max_lon));
break;
case NORTH_EAST:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(max_lat, max_lon));
break;
case NORTH_WEST:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(max_lat, min_lon));
break;
case SOUTH_EAST:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(min_lat, max_lon));
break;
case SOUTH_WEST:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(min_lat, min_lon));
break;
default:
break;
}
BOOST_ASSERT(min_dist != std::numeric_limits<float>::max());
return min_dist;
}
@@ -167,10 +209,10 @@ class StaticRTree
{
float min_max_dist = std::numeric_limits<float>::max();
// Get minmax distance to each of the four sides
FixedPointCoordinate upper_left(max_lat, min_lon);
FixedPointCoordinate upper_right(max_lat, max_lon);
FixedPointCoordinate lower_right(min_lat, max_lon);
FixedPointCoordinate lower_left(min_lat, min_lon);
const FixedPointCoordinate upper_left(max_lat, min_lon);
const FixedPointCoordinate upper_right(max_lat, max_lon);
const FixedPointCoordinate lower_right(min_lat, max_lon);
const FixedPointCoordinate lower_left(min_lat, min_lon);
min_max_dist = std::min(
min_max_dist,
@@ -198,8 +240,8 @@ class StaticRTree
inline bool Contains(const FixedPointCoordinate &location) const
{
const bool lats_contained = (location.lat > min_lat) && (location.lat < max_lat);
const bool lons_contained = (location.lon > min_lon) && (location.lon < max_lon);
const bool lats_contained = (location.lat >= min_lat) && (location.lat <= max_lat);
const bool lons_contained = (location.lon >= min_lon) && (location.lon <= max_lon);
return lats_contained && lons_contained;
}
@@ -212,7 +254,7 @@ class StaticRTree
}
};
typedef RectangleInt2D RectangleT;
using RectangleT = RectangleInt2D;
struct TreeNode
{
@@ -220,7 +262,7 @@ class StaticRTree
RectangleT minimum_bounding_rectangle;
uint32_t child_count : 31;
bool child_is_on_disk : 1;
uint32_t children[RTREE_BRANCHING_FACTOR];
uint32_t children[BRANCHING_FACTOR];
};
private:
@@ -244,9 +286,9 @@ class StaticRTree
struct LeafNode
{
LeafNode() : object_count(0) {}
LeafNode() : object_count(0), objects() {}
uint32_t object_count;
std::array<EdgeDataT, RTREE_LEAF_NODE_SIZE> objects;
std::array<EdgeDataT, LEAF_NODE_SIZE> objects;
};
struct QueryCandidate
@@ -265,7 +307,7 @@ class StaticRTree
}
};
typedef boost::variant<TreeNode, EdgeDataT> IncrementalQueryNodeType;
using IncrementalQueryNodeType = mapbox::util::variant<TreeNode, EdgeDataT>;
struct IncrementalQueryCandidate
{
explicit IncrementalQueryCandidate(const float dist, const IncrementalQueryNodeType &node)
@@ -281,29 +323,15 @@ class StaticRTree
return other.min_dist < min_dist;
}
inline bool RepresentsTreeNode() const
{
return boost::apply_visitor(decide_type_visitor(), node);
}
float min_dist;
IncrementalQueryNodeType node;
private:
class decide_type_visitor : public boost::static_visitor<bool>
{
public:
bool operator()(const TreeNode &) const { return true; }
template<typename AnotherType>
bool operator()(const AnotherType &) const { return false; }
};
};
typename ShM<TreeNode, UseSharedMemory>::vector m_search_tree;
uint64_t m_element_count;
const std::string m_leaf_node_filename;
std::shared_ptr<CoordinateListT> m_coordinate_list;
boost::filesystem::ifstream leaves_stream;
public:
StaticRTree() = delete;
@@ -369,7 +397,7 @@ class StaticRTree
TreeNode current_node;
// SimpleLogger().Write() << "reading " << tree_size << " tree nodes in " <<
// (sizeof(TreeNode)*tree_size) << " bytes";
for (uint32_t current_element_index = 0; RTREE_LEAF_NODE_SIZE > current_element_index;
for (uint32_t current_element_index = 0; LEAF_NODE_SIZE > current_element_index;
++current_element_index)
{
if (m_element_count > (processed_objects_count + current_element_index))
@@ -406,9 +434,9 @@ class StaticRTree
while (processed_tree_nodes_in_level < tree_nodes_in_level.size())
{
TreeNode parent_node;
// pack RTREE_BRANCHING_FACTOR elements into tree_nodes each
// pack BRANCHING_FACTOR elements into tree_nodes each
for (uint32_t current_child_node_index = 0;
RTREE_BRANCHING_FACTOR > current_child_node_index;
BRANCHING_FACTOR > current_child_node_index;
++current_child_node_index)
{
if (processed_tree_nodes_in_level < tree_nodes_in_level.size())
@@ -507,16 +535,15 @@ class StaticRTree
throw OSRMException("mem index file is empty");
}
boost::filesystem::ifstream leaf_node_file(leaf_file, std::ios::binary);
leaf_node_file.read((char *)&m_element_count, sizeof(uint64_t));
leaf_node_file.close();
leaves_stream.open(leaf_file, std::ios::binary);
leaves_stream.read((char *)&m_element_count, sizeof(uint64_t));
// SimpleLogger().Write() << tree_size << " nodes in search tree";
// SimpleLogger().Write() << m_element_count << " elements in leafs";
}
explicit StaticRTree(TreeNode *tree_node_ptr,
const uint32_t number_of_nodes,
const uint64_t number_of_nodes,
const boost::filesystem::path &leaf_file,
std::shared_ptr<CoordinateListT> coordinate_list)
: m_search_tree(tree_node_ptr, number_of_nodes), m_leaf_node_filename(leaf_file.string()),
@@ -532,14 +559,8 @@ class StaticRTree
throw OSRMException("mem index file is empty");
}
boost::filesystem::ifstream leaf_node_file(leaf_file, std::ios::binary);
leaf_node_file.read((char *)&m_element_count, sizeof(uint64_t));
leaf_node_file.close();
if (thread_local_rtree_stream.get())
{
thread_local_rtree_stream->close();
}
leaves_stream.open(leaf_file, std::ios::binary);
leaves_stream.read((char *)&m_element_count, sizeof(uint64_t));
// SimpleLogger().Write() << tree_size << " nodes in search tree";
// SimpleLogger().Write() << m_element_count << " elements in leafs";
@@ -628,7 +649,7 @@ class StaticRTree
std::vector<PhantomNode> &result_phantom_node_vector,
const unsigned zoom_level,
const unsigned number_of_results,
const unsigned max_checked_segments = 4*RTREE_LEAF_NODE_SIZE)
const unsigned max_checked_segments = 4*LEAF_NODE_SIZE)
{
// TIMER_START(samet);
// SimpleLogger().Write(logDEBUG) << "searching for " << number_of_results << " results";
@@ -664,9 +685,9 @@ class StaticRTree
continue;
}
if (current_query_node.RepresentsTreeNode())
if (current_query_node.node.template is<TreeNode>())
{
const TreeNode & current_tree_node = boost::get<TreeNode>(current_query_node.node);
const TreeNode & current_tree_node = current_query_node.node.template get<TreeNode>();
if (current_tree_node.child_is_on_disk)
{
++loaded_leafs;
@@ -739,7 +760,7 @@ class StaticRTree
{
++inspected_segments;
// inspecting an actual road segment
const EdgeDataT & current_segment = boost::get<EdgeDataT>(current_query_node.node);
const EdgeDataT & current_segment = current_query_node.node.template get<EdgeDataT>();
// don't collect too many results from small components
if (number_of_results_found_in_big_cc == number_of_results && !current_segment.is_in_tiny_cc)
@@ -767,7 +788,7 @@ class StaticRTree
BOOST_ASSERT(0. <= current_perpendicular_distance);
if ((current_perpendicular_distance < current_min_dist) &&
!EpsilonCompare(current_perpendicular_distance, current_min_dist))
!osrm::epsilon_compare(current_perpendicular_distance, current_min_dist))
{
// store phantom node in result vector
result_phantom_node_vector.emplace_back(
@@ -780,7 +801,9 @@ class StaticRTree
current_segment.reverse_offset,
current_segment.packed_geometry_id,
foot_point_coordinate_on_segment,
current_segment.fwd_segment_position);
current_segment.fwd_segment_position,
current_segment.forward_travel_mode,
current_segment.backward_travel_mode);
// Hack to fix rounding errors and wandering via nodes.
FixUpRoundingIssue(input_coordinate, result_phantom_node_vector.back());
@@ -834,19 +857,172 @@ class StaticRTree
return !result_phantom_node_vector.empty();
}
// implementation of the Hjaltason/Samet query [3], a BFS traversal of the tree
bool
IncrementalFindPhantomNodeForCoordinateWithDistance(const FixedPointCoordinate &input_coordinate,
std::vector<std::pair<PhantomNode, double>> &result_phantom_node_vector,
const unsigned zoom_level,
const unsigned number_of_results,
const unsigned max_checked_segments = 4*LEAF_NODE_SIZE)
{
std::vector<float> min_found_distances(number_of_results, std::numeric_limits<float>::max());
unsigned number_of_results_found_in_big_cc = 0;
unsigned number_of_results_found_in_tiny_cc = 0;
unsigned inspected_segments = 0;
// initialize queue with root element
std::priority_queue<IncrementalQueryCandidate> traversal_queue;
traversal_queue.emplace(0.f, m_search_tree[0]);
while (!traversal_queue.empty())
{
const IncrementalQueryCandidate current_query_node = traversal_queue.top();
traversal_queue.pop();
const float current_min_dist = min_found_distances[number_of_results-1];
if (current_query_node.min_dist > current_min_dist)
{
continue;
}
if (current_query_node.RepresentsTreeNode())
{
const TreeNode & current_tree_node = current_query_node.node.template get<TreeNode>();
if (current_tree_node.child_is_on_disk)
{
LeafNode current_leaf_node;
LoadLeafFromDisk(current_tree_node.children[0], current_leaf_node);
// Add all objects from leaf into queue
for (uint32_t i = 0; i < current_leaf_node.object_count; ++i)
{
const auto &current_edge = current_leaf_node.objects[i];
const float current_perpendicular_distance =
FixedPointCoordinate::ComputePerpendicularDistance(
m_coordinate_list->at(current_edge.u),
m_coordinate_list->at(current_edge.v),
input_coordinate);
// distance must be non-negative
BOOST_ASSERT(0. <= current_perpendicular_distance);
if (current_perpendicular_distance < current_min_dist)
{
traversal_queue.emplace(current_perpendicular_distance, current_edge);
}
}
}
else
{
// for each child mbr
for (uint32_t i = 0; i < current_tree_node.child_count; ++i)
{
const int32_t child_id = current_tree_node.children[i];
const TreeNode &child_tree_node = m_search_tree[child_id];
const RectangleT &child_rectangle = child_tree_node.minimum_bounding_rectangle;
const float lower_bound_to_element = child_rectangle.GetMinDist(input_coordinate);
// TODO - enough elements found, i.e. nearest distance > maximum distance?
// ie. some measure of 'confidence of accuracy'
// check if it needs to be explored by mindist
if (lower_bound_to_element < current_min_dist)
{
traversal_queue.emplace(lower_bound_to_element, child_tree_node);
}
}
// SimpleLogger().Write(logDEBUG) << "added " << current_tree_node.child_count << " mbrs into queue of " << traversal_queue.size();
}
}
else
{
++inspected_segments;
// inspecting an actual road segment
const EdgeDataT & current_segment = current_query_node.node.template get<EdgeDataT>();
// don't collect too many results from small components
if (number_of_results_found_in_big_cc == number_of_results && !current_segment.is_in_tiny_cc)
{
continue;
}
// don't collect too many results from big components
if (number_of_results_found_in_tiny_cc == number_of_results && current_segment.is_in_tiny_cc)
{
continue;
}
// check if it is smaller than what we had before
float current_ratio = 0.;
FixedPointCoordinate foot_point_coordinate_on_segment;
const float current_perpendicular_distance =
FixedPointCoordinate::ComputePerpendicularDistance(
m_coordinate_list->at(current_segment.u),
m_coordinate_list->at(current_segment.v),
input_coordinate,
foot_point_coordinate_on_segment,
current_ratio);
BOOST_ASSERT(0. <= current_perpendicular_distance);
if ((current_perpendicular_distance < current_min_dist) &&
!osrm::epsilon_compare(current_perpendicular_distance, current_min_dist))
{
// store phantom node in result vector
result_phantom_node_vector.emplace_back(
current_segment.forward_edge_based_node_id,
current_segment.reverse_edge_based_node_id,
current_segment.name_id,
current_segment.forward_weight,
current_segment.reverse_weight,
current_segment.forward_offset,
current_segment.reverse_offset,
current_segment.packed_geometry_id,
foot_point_coordinate_on_segment,
current_segment.fwd_segment_position,
current_perpendicular_distance);
// Hack to fix rounding errors and wandering via nodes.
FixUpRoundingIssue(input_coordinate, result_phantom_node_vector.back());
// set forward and reverse weights on the phantom node
SetForwardAndReverseWeightsOnPhantomNode(current_segment,
result_phantom_node_vector.back());
// do we have results only in a small scc
if (current_segment.is_in_tiny_cc)
{
++number_of_results_found_in_tiny_cc;
}
else
{
// found an element in a large component
min_found_distances[number_of_results_found_in_big_cc] = current_perpendicular_distance;
++number_of_results_found_in_big_cc;
// SimpleLogger().Write(logDEBUG) << std::setprecision(8) << foot_point_coordinate_on_segment << " at " << current_perpendicular_distance;
}
}
}
// TODO add indicator to prune if maxdist > threshold
if (number_of_results == number_of_results_found_in_big_cc || inspected_segments >= max_checked_segments)
{
// SimpleLogger().Write(logDEBUG) << "flushing queue of " << traversal_queue.size() << " elements";
// work-around for traversal_queue.clear();
traversal_queue = std::priority_queue<IncrementalQueryCandidate>{};
}
}
return !result_phantom_node_vector.empty();
}
bool FindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
PhantomNode &result_phantom_node,
const unsigned zoom_level)
{
std::vector<PhantomNode> result_phantom_node_vector;
IncrementalFindPhantomNodeForCoordinate(input_coordinate, result_phantom_node_vector, zoom_level, 2);
// if (!result_phantom_node_vector.empty())
// {
// result_phantom_node = result_phantom_node_vector.front();
// }
// return !result_phantom_node_vector.empty();
const bool ignore_tiny_components = (zoom_level <= 14);
EdgeDataT nearest_edge;
@@ -891,7 +1067,7 @@ class StaticRTree
BOOST_ASSERT(0. <= current_perpendicular_distance);
if ((current_perpendicular_distance < min_dist) &&
!EpsilonCompare(current_perpendicular_distance, min_dist))
!osrm::epsilon_compare(current_perpendicular_distance, min_dist))
{ // found a new minimum
min_dist = current_perpendicular_distance;
result_phantom_node = {current_edge.forward_edge_based_node_id,
@@ -903,7 +1079,9 @@ class StaticRTree
current_edge.reverse_offset,
current_edge.packed_geometry_id,
nearest,
current_edge.fwd_segment_position};
current_edge.fwd_segment_position,
current_edge.forward_travel_mode,
current_edge.backward_travel_mode};
nearest_edge = current_edge;
}
}
@@ -997,22 +1175,21 @@ class StaticRTree
inline void LoadLeafFromDisk(const uint32_t leaf_id, LeafNode &result_node)
{
if (!thread_local_rtree_stream.get() || !thread_local_rtree_stream->is_open())
if (!leaves_stream.is_open())
{
thread_local_rtree_stream.reset(new boost::filesystem::ifstream(
m_leaf_node_filename, std::ios::in | std::ios::binary));
leaves_stream.open(m_leaf_node_filename, std::ios::in | std::ios::binary);
}
if (!thread_local_rtree_stream->good())
if (!leaves_stream.good())
{
thread_local_rtree_stream->clear(std::ios::goodbit);
leaves_stream.clear(std::ios::goodbit);
SimpleLogger().Write(logDEBUG) << "Resetting stale filestream";
}
const uint64_t seek_pos = sizeof(uint64_t) + leaf_id * sizeof(LeafNode);
thread_local_rtree_stream->seekg(seek_pos);
BOOST_ASSERT_MSG(thread_local_rtree_stream->good(),
leaves_stream.seekg(seek_pos);
BOOST_ASSERT_MSG(leaves_stream.good(),
"Seeking to position in leaf file failed.");
thread_local_rtree_stream->read((char *)&result_node, sizeof(LeafNode));
BOOST_ASSERT_MSG(thread_local_rtree_stream->good(), "Reading from leaf file failed.");
leaves_stream.read((char *)&result_node, sizeof(LeafNode));
BOOST_ASSERT_MSG(leaves_stream.good(), "Reading from leaf file failed.");
}
inline bool EdgesAreEquivalent(const FixedPointCoordinate &a,
@@ -1022,11 +1199,6 @@ class StaticRTree
{
return (a == b && c == d) || (a == c && b == d) || (a == d && b == c);
}
template <typename FloatT> inline bool EpsilonCompare(const FloatT d1, const FloatT d2) const
{
return (std::abs(d1 - d2) < std::numeric_limits<FloatT>::epsilon());
}
};
//[1] "On Packing R-Trees"; I. Kamel, C. Faloutsos; 1993; DOI: 10.1145/170088.170403
+35
View File
@@ -0,0 +1,35 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TRAVEL_MODE_H
#define TRAVEL_MODE_H
using TravelMode = unsigned char;
static const TravelMode TRAVEL_MODE_INACCESSIBLE = 0;
static const TravelMode TRAVEL_MODE_DEFAULT = 1;
#endif /* TRAVEL_MODE_H */
+1 -1
View File
@@ -31,7 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
enum class TurnInstruction : unsigned char
{
NoTurn = 0, GoStraight, TurnSlightRight, TurnRight, TurnSharpRight, UTurn,
TurnSharpLeft, TurnLeft, TurnSlightLeft, ReachViaPoint, HeadOn, EnterRoundAbout,
TurnSharpLeft, TurnLeft, TurnSlightLeft, ReachViaLocation, HeadOn, EnterRoundAbout,
LeaveRoundAbout, StayOnRoundAbout, StartAtEndOfStreet, ReachedYourDestination,
EnterAgainstAllowedDirection, LeaveAgainstAllowedDirection,
InverseAccessRestrictionFlag = 127,
+2 -2
View File
@@ -70,7 +70,7 @@ class XORFastHash
inline unsigned short operator()(const unsigned originalValue) const
{
unsigned short lsb = ((originalValue) & 0xffff);
unsigned short lsb = ((originalValue)&0xffff);
unsigned short msb = (((originalValue) >> 16) & 0xffff);
return table1[lsb] ^ table2[msb];
}
@@ -104,7 +104,7 @@ class XORMiniHash
}
unsigned char operator()(const unsigned originalValue) const
{
unsigned char byte1 = ((originalValue) & 0xff);
unsigned char byte1 = ((originalValue)&0xff);
unsigned char byte2 = ((originalValue >> 8) & 0xff);
unsigned char byte3 = ((originalValue >> 16) & 0xff);
unsigned char byte4 = ((originalValue >> 24) & 0xff);
+4 -4
View File
@@ -49,14 +49,14 @@ template <typename NodeID, typename Key> class XORFastHashStorage
HashCell(const HashCell &other) : key(other.key), id(other.id), time(other.time) {}
inline operator Key() const { return key; }
operator Key() const { return key; }
inline void operator=(const Key &key_to_insert) { key = key_to_insert; }
void operator=(const Key &key_to_insert) { key = key_to_insert; }
};
explicit XORFastHashStorage(size_t) : positions(2 << 16), current_timestamp(0) {}
inline HashCell &operator[](const NodeID node)
HashCell &operator[](const NodeID node)
{
unsigned short position = fast_hasher(node);
while ((positions[position].time == current_timestamp) && (positions[position].id != node))
@@ -69,7 +69,7 @@ template <typename NodeID, typename Key> class XORFastHashStorage
return positions[position];
}
inline void Clear()
void Clear()
{
++current_timestamp;
if (std::numeric_limits<unsigned>::max() == current_timestamp)
+43 -10
View File
@@ -45,38 +45,71 @@ void DescriptionFactory::SetStartSegment(const PhantomNode &source, const bool t
start_phantom = source;
const EdgeWeight segment_duration =
(traversed_in_reverse ? source.reverse_weight : source.forward_weight);
AppendSegment(source.location,
PathData(0, source.name_id, TurnInstruction::HeadOn, segment_duration));
const TravelMode travel_mode =
(traversed_in_reverse ? source.backward_travel_mode : source.forward_travel_mode);
AppendSegment(
source.location,
PathData(0, source.name_id, TurnInstruction::HeadOn, segment_duration, travel_mode));
BOOST_ASSERT(path_description.back().duration == segment_duration);
}
void DescriptionFactory::SetEndSegment(const PhantomNode &target, const bool traversed_in_reverse)
void DescriptionFactory::SetEndSegment(const PhantomNode &target,
const bool traversed_in_reverse,
const bool is_via_location)
{
target_phantom = target;
const EdgeWeight segment_duration =
(traversed_in_reverse ? target.reverse_weight : target.forward_weight);
path_description.emplace_back(
target.location, target.name_id, segment_duration, 0.f, TurnInstruction::NoTurn, true, true);
const TravelMode travel_mode =
(traversed_in_reverse ? target.backward_travel_mode : target.forward_travel_mode);
path_description.emplace_back(target.location,
target.name_id,
segment_duration,
0.f,
is_via_location ? TurnInstruction::ReachViaLocation
: TurnInstruction::NoTurn,
true,
true,
travel_mode);
BOOST_ASSERT(path_description.back().duration == segment_duration);
}
void DescriptionFactory::AppendSegment(const FixedPointCoordinate &coordinate,
const PathData &path_point)
{
if ((1 == path_description.size()) && (path_description.back().location == coordinate))
// if the start location is on top of a node, the first movement might be zero-length,
// in which case we dont' add a new description, but instead update the existing one
if ((1 == path_description.size()) && (path_description.front().location == coordinate))
{
path_description.back().name_id = path_point.name_id;
if (path_point.segment_duration > 0)
{
path_description.front().name_id = path_point.name_id;
path_description.front().travel_mode = path_point.travel_mode;
}
return;
}
// make sure mode changes are announced, even when there otherwise is no turn
const TurnInstruction turn = [&]() -> TurnInstruction
{
if (TurnInstruction::NoTurn == path_point.turn_instruction &&
path_description.front().travel_mode != path_point.travel_mode &&
path_point.segment_duration > 0)
{
return TurnInstruction::GoStraight;
}
return path_point.turn_instruction;
}();
path_description.emplace_back(coordinate,
path_point.name_id,
path_point.segment_duration,
0,
path_point.turn_instruction);
0.f,
turn,
path_point.travel_mode);
}
JSON::Value DescriptionFactory::AppendEncodedPolylineString(const bool return_encoded)
JSON::Value DescriptionFactory::AppendGeometryString(const bool return_encoded)
{
if (return_encoded)
{
+9 -6
View File
@@ -80,9 +80,11 @@ class DescriptionFactory
void AppendSegment(const FixedPointCoordinate &coordinate, const PathData &data);
void BuildRouteSummary(const double distance, const unsigned time);
void SetStartSegment(const PhantomNode &start_phantom, const bool traversed_in_reverse);
void SetEndSegment(const PhantomNode &start_phantom, const bool traversed_in_reverse);
JSON::Value AppendEncodedPolylineString(const bool return_encoded);
std::vector<unsigned> const & GetViaIndices() const;
void SetEndSegment(const PhantomNode &start_phantom,
const bool traversed_in_reverse,
const bool is_via_location = false);
JSON::Value AppendGeometryString(const bool return_encoded);
std::vector<unsigned> const &GetViaIndices() const;
template <class DataFacadeT> void Run(const DataFacadeT *facade, const unsigned zoomLevel)
{
@@ -198,14 +200,15 @@ class DescriptionFactory
{
++necessary_pieces;
if (path_description[i].is_via_location)
{ //mark the end of a leg
{ // mark the end of a leg
via_indices.push_back(necessary_pieces);
}
const double angle = path_description[i+1].location.GetBearing(path_description[i].location);
const double angle =
path_description[i + 1].location.GetBearing(path_description[i].location);
path_description[i].bearing = static_cast<unsigned>(angle * 10);
}
}
via_indices.push_back(necessary_pieces+1);
via_indices.push_back(necessary_pieces + 1);
BOOST_ASSERT(via_indices.size() >= 2);
// BOOST_ASSERT(0 != necessary_pieces || path_description.empty());
return;
+10 -9
View File
@@ -30,14 +30,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "BaseDescriptor.h"
template <class DataFacadeT> class GPXDescriptor : public BaseDescriptor<DataFacadeT>
template <class DataFacadeT> class GPXDescriptor final : public BaseDescriptor<DataFacadeT>
{
private:
DescriptorConfig config;
FixedPointCoordinate current;
DataFacadeT * facade;
DataFacadeT *facade;
void AddRoutePoint(const FixedPointCoordinate & coordinate, std::vector<char> & output)
void AddRoutePoint(const FixedPointCoordinate &coordinate, std::vector<char> &output)
{
const std::string route_point_head = "<rtept lat=\"";
const std::string route_point_middle = " lon=\"";
@@ -57,12 +57,12 @@ template <class DataFacadeT> class GPXDescriptor : public BaseDescriptor<DataFac
}
public:
GPXDescriptor(DataFacadeT *facade) : facade(facade) {}
explicit GPXDescriptor(DataFacadeT *facade) : facade(facade) {}
void SetConfig(const DescriptorConfig &c) { config = c; }
void SetConfig(const DescriptorConfig &c) final { config = c; }
// TODO: reorder parameters
void Run(const RawRouteData &raw_route, http::Reply &reply)
void Run(const RawRouteData &raw_route, http::Reply &reply) final
{
std::string header("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<gpx creator=\"OSRM Routing Engine\" version=\"1.1\" "
@@ -79,7 +79,8 @@ template <class DataFacadeT> class GPXDescriptor : public BaseDescriptor<DataFac
(!raw_route.unpacked_path_segments.front().empty());
if (found_route)
{
AddRoutePoint(raw_route.segment_end_coordinates.front().source_phantom.location, reply.content);
AddRoutePoint(raw_route.segment_end_coordinates.front().source_phantom.location,
reply.content);
for (const std::vector<PathData> &path_data_vector : raw_route.unpacked_path_segments)
{
@@ -90,8 +91,8 @@ template <class DataFacadeT> class GPXDescriptor : public BaseDescriptor<DataFac
AddRoutePoint(current_coordinate, reply.content);
}
}
AddRoutePoint(raw_route.segment_end_coordinates.back().target_phantom.location, reply.content);
AddRoutePoint(raw_route.segment_end_coordinates.back().target_phantom.location,
reply.content);
}
std::string footer("</rte></gpx>");
reply.content.insert(reply.content.end(), footer.begin(), footer.end());
+42 -36
View File
@@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../Algorithms/ObjectToBase64.h"
#include "../Algorithms/ExtractRouteNames.h"
#include "../DataStructures/JSONContainer.h"
#include "../DataStructures/Range.h"
#include "../DataStructures/SegmentInformation.h"
#include "../DataStructures/TurnInstructions.h"
#include "../Util/Azimuth.h"
@@ -41,7 +42,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <algorithm>
template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFacadeT>
template <class DataFacadeT> class JSONDescriptor final : public BaseDescriptor<DataFacadeT>
{
private:
DataFacadeT *facade;
@@ -69,13 +70,14 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
ExtractRouteNames<DataFacadeT, Segment> GenerateRouteNames;
public:
JSONDescriptor(DataFacadeT *facade) : facade(facade), entered_restricted_area_count(0) {}
explicit JSONDescriptor(DataFacadeT *facade) : facade(facade), entered_restricted_area_count(0) {}
void SetConfig(const DescriptorConfig &c) { config = c; }
void SetConfig(const DescriptorConfig &c) final { config = c; }
unsigned DescribeLeg(const std::vector<PathData> route_leg,
const PhantomNodes &leg_phantoms,
const bool target_traversed_in_reverse)
const bool target_traversed_in_reverse,
const bool is_via_leg)
{
unsigned added_element_count = 0;
// Get all the coordinates for the computed route
@@ -86,13 +88,14 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
description_factory.AppendSegment(current_coordinate, path_data);
++added_element_count;
}
description_factory.SetEndSegment(leg_phantoms.target_phantom, target_traversed_in_reverse);
description_factory.SetEndSegment(
leg_phantoms.target_phantom, target_traversed_in_reverse, is_via_leg);
++added_element_count;
BOOST_ASSERT((route_leg.size() + 1) == added_element_count);
return added_element_count;
}
void Run(const RawRouteData &raw_route, http::Reply &reply)
void Run(const RawRouteData &raw_route, http::Reply &reply) final
{
JSON::Object json_result;
if (INVALID_EDGE_WEIGHT == raw_route.shortest_path_length)
@@ -118,14 +121,15 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
json_result.values["status_message"] = "Found route between points";
// for each unpacked segment add the leg to the description
for (unsigned i = 0; i < raw_route.unpacked_path_segments.size(); ++i)
for (const auto i : osrm::irange<std::size_t>(0, raw_route.unpacked_path_segments.size()))
{
#ifndef NDEBUG
const int added_segments =
#endif
DescribeLeg(raw_route.unpacked_path_segments[i],
raw_route.segment_end_coordinates[i],
raw_route.target_traversed_in_reverse[i]);
raw_route.target_traversed_in_reverse[i],
raw_route.is_via_leg(i));
BOOST_ASSERT(0 < added_segments);
}
description_factory.Run(facade, config.zoom_level);
@@ -133,7 +137,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
if (config.geometry)
{
JSON::Value route_geometry =
description_factory.AppendEncodedPolylineString(config.encode_geometry);
description_factory.AppendGeometryString(config.encode_geometry);
json_result.values["route_geometry"] = route_geometry;
}
if (config.instructions)
@@ -201,13 +205,15 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
current = facade->GetCoordinateOfNode(path_data.node);
alternate_description_factory.AppendSegment(current, path_data);
}
alternate_description_factory.SetEndSegment(
raw_route.segment_end_coordinates.back().target_phantom,
raw_route.alt_source_traversed_in_reverse.back());
alternate_description_factory.Run(facade, config.zoom_level);
if (config.geometry)
{
JSON::Value alternate_geometry_string =
alternate_description_factory.AppendEncodedPolylineString(
config.encode_geometry);
alternate_description_factory.AppendGeometryString(config.encode_geometry);
JSON::Array json_alternate_geometries_array;
json_alternate_geometries_array.values.push_back(alternate_geometry_string);
json_result.values["alternative_geometries"] = json_alternate_geometries_array;
@@ -275,12 +281,12 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
json_hint_object.values["checksum"] = raw_route.check_sum;
JSON::Array json_location_hint_array;
std::string hint;
for (unsigned i = 0; i < raw_route.segment_end_coordinates.size(); ++i)
for (const auto i : osrm::irange<std::size_t>(0, raw_route.segment_end_coordinates.size()))
{
EncodeObjectToBase64(raw_route.segment_end_coordinates[i].source_phantom, hint);
ObjectEncoder::EncodeToBase64(raw_route.segment_end_coordinates[i].source_phantom, hint);
json_location_hint_array.values.push_back(hint);
}
EncodeObjectToBase64(raw_route.segment_end_coordinates.back().target_phantom, hint);
ObjectEncoder::EncodeToBase64(raw_route.segment_end_coordinates.back().target_phantom, hint);
json_location_hint_array.values.push_back(hint);
json_hint_object.values["locations"] = json_location_hint_array;
json_result.values["hint_data"] = json_hint_object;
@@ -324,16 +330,16 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
if (TurnInstruction::LeaveRoundAbout == current_instruction)
{
temp_instruction =
IntToString(as_integer(TurnInstruction::EnterRoundAbout));
cast::integral_to_string(cast::enum_to_underlying(TurnInstruction::EnterRoundAbout));
current_turn_instruction += temp_instruction;
current_turn_instruction += "-";
temp_instruction = IntToString(round_about.leave_at_exit + 1);
temp_instruction = cast::integral_to_string(round_about.leave_at_exit + 1);
current_turn_instruction += temp_instruction;
round_about.leave_at_exit = 0;
}
else
{
temp_instruction = IntToString(as_integer(current_instruction));
temp_instruction = cast::integral_to_string(cast::enum_to_underlying(current_instruction));
current_turn_instruction += temp_instruction;
}
json_instruction_row.values.push_back(current_turn_instruction);
@@ -344,13 +350,17 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
json_instruction_row.values.push_back(necessary_segments_running_index);
json_instruction_row.values.push_back(round(segment.duration / 10));
json_instruction_row.values.push_back(
UintToString(static_cast<unsigned>(segment.length)) + "m");
const double bearing_value = (segment.bearing / 10.) ;
cast::integral_to_string(static_cast<unsigned>(segment.length)) + "m");
const double bearing_value = (segment.bearing / 10.);
json_instruction_row.values.push_back(Azimuth::Get(bearing_value));
json_instruction_row.values.push_back(static_cast<unsigned>(round(bearing_value)));
json_instruction_row.values.push_back(
static_cast<unsigned>(round(bearing_value)));
json_instruction_row.values.push_back(segment.travel_mode);
route_segments_list.emplace_back(
segment.name_id, segment.length, route_segments_list.size());
segment.name_id,
static_cast<int>(segment.length),
static_cast<unsigned>(route_segments_list.size()));
json_instruction_array.values.push_back(json_instruction_row);
}
}
@@ -364,21 +374,17 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
}
}
// TODO: check if this in an invariant
if (INVALID_EDGE_WEIGHT != route_length)
{
JSON::Array json_last_instruction_row;
temp_instruction = IntToString(as_integer(TurnInstruction::ReachedYourDestination));
json_last_instruction_row.values.push_back(temp_instruction);
json_last_instruction_row.values.push_back("");
json_last_instruction_row.values.push_back(0);
json_last_instruction_row.values.push_back(necessary_segments_running_index - 1);
json_last_instruction_row.values.push_back(0);
json_last_instruction_row.values.push_back("0m");
json_last_instruction_row.values.push_back(Azimuth::Get(0.0));
json_last_instruction_row.values.push_back(0.);
json_instruction_array.values.push_back(json_last_instruction_row);
}
JSON::Array json_last_instruction_row;
temp_instruction = cast::integral_to_string(cast::enum_to_underlying(TurnInstruction::ReachedYourDestination));
json_last_instruction_row.values.push_back(temp_instruction);
json_last_instruction_row.values.push_back("");
json_last_instruction_row.values.push_back(0);
json_last_instruction_row.values.push_back(necessary_segments_running_index - 1);
json_last_instruction_row.values.push_back(0);
json_last_instruction_row.values.push_back("0m");
json_last_instruction_row.values.push_back(Azimuth::Get(0.0));
json_last_instruction_row.values.push_back(0.);
json_instruction_array.values.push_back(json_last_instruction_row);
}
};
+4 -3
View File
@@ -32,7 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../DataStructures/ImportNode.h"
#include "../Util/LuaUtil.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../Util/simple_logger.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/regex.hpp>
@@ -53,12 +53,13 @@ void BaseParser::ReadUseRestrictionsSetting()
{
if (0 != luaL_dostring(lua_state, "return use_turn_restrictions\n"))
{
throw OSRMException("ERROR occured in scripting block");
use_turn_restrictions = false;
}
if (lua_isboolean(lua_state, -1))
else if (lua_isboolean(lua_state, -1))
{
use_turn_restrictions = lua_toboolean(lua_state, -1);
}
if (use_turn_restrictions)
{
SimpleLogger().Write() << "Using turn restrictions";
+6 -4
View File
@@ -28,7 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ExtractionContainers.h"
#include "ExtractionWay.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../Util/simple_logger.hpp"
#include "../Util/TimingUtil.h"
#include "../DataStructures/RangeTable.h"
@@ -330,7 +330,6 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name,
edge_iterator->source_coordinate.lon != std::numeric_limits<int>::min())
{
BOOST_ASSERT(edge_iterator->speed != -1);
BOOST_ASSERT(edge_iterator->type >= 0);
edge_iterator->target_coordinate.lat = node_iterator->lat;
edge_iterator->target_coordinate.lon = node_iterator->lon;
@@ -371,12 +370,15 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name,
}
file_out_stream.write((char *)&integer_weight, sizeof(int));
file_out_stream.write((char *)&edge_iterator->type, sizeof(short));
file_out_stream.write((char *)&edge_iterator->name_id, sizeof(unsigned));
file_out_stream.write((char *)&edge_iterator->is_roundabout, sizeof(bool));
file_out_stream.write((char *)&edge_iterator->is_in_tiny_cc, sizeof(bool));
file_out_stream.write((char *)&edge_iterator->is_access_restricted, sizeof(bool));
file_out_stream.write((char *)&edge_iterator->is_contra_flow, sizeof(bool));
// cannot take adress of bit field, so use local
const TravelMode travel_mode = edge_iterator->travel_mode;
file_out_stream.write((char *)&travel_mode, sizeof(TravelMode));
file_out_stream.write((char *)&edge_iterator->is_split, sizeof(bool));
++number_of_used_edges;
}
+7 -7
View File
@@ -43,12 +43,12 @@ class ExtractionContainers
const static unsigned stxxl_memory = ((sizeof(std::size_t) == 4) ? INT_MAX : UINT_MAX);
#endif
public:
typedef stxxl::vector<NodeID> STXXLNodeIDVector;
typedef stxxl::vector<ExternalMemoryNode> STXXLNodeVector;
typedef stxxl::vector<InternalExtractorEdge> STXXLEdgeVector;
typedef stxxl::vector<std::string> STXXLStringVector;
typedef stxxl::vector<InputRestrictionContainer> STXXLRestrictionsVector;
typedef stxxl::vector<WayIDStartAndEndEdge> STXXLWayIDStartEndVector;
using STXXLNodeIDVector = stxxl::vector<NodeID>;
using STXXLNodeVector = stxxl::vector<ExternalMemoryNode>;
using STXXLEdgeVector = stxxl::vector<InternalExtractorEdge>;
using STXXLStringVector = stxxl::vector<std::string>;
using STXXLRestrictionsVector = stxxl::vector<InputRestrictionContainer>;
using STXXLWayIDStartEndVector = stxxl::vector<WayIDStartAndEndEdge>;
STXXLNodeIDVector used_node_id_list;
STXXLNodeVector all_nodes_list;
@@ -60,7 +60,7 @@ class ExtractionContainers
ExtractionContainers();
virtual ~ExtractionContainers();
~ExtractionContainers();
void PrepareData(const std::string &output_file_name,
const std::string &restrictions_file_name);
+8 -7
View File
@@ -28,10 +28,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef EXTRACTION_HELPER_FUNCTIONS_H
#define EXTRACTION_HELPER_FUNCTIONS_H
#include "../Util/StringUtil.h"
#include "../Util/cast.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string_regex.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/regex.hpp>
#include <limits>
@@ -68,18 +69,18 @@ inline unsigned parseDuration(const std::string &s)
{
if (1 == result.size())
{
minutes = StringToUint(result[0]);
minutes = cast::string_to_int(result[0]);
}
if (2 == result.size())
{
minutes = StringToUint(result[1]);
hours = StringToUint(result[0]);
minutes = cast::string_to_int(result[1]);
hours = cast::string_to_int(result[0]);
}
if (3 == result.size())
{
seconds = StringToUint(result[2]);
minutes = StringToUint(result[1]);
hours = StringToUint(result[0]);
seconds = cast::string_to_int(result[2]);
minutes = cast::string_to_int(result[1]);
hours = cast::string_to_int(result[0]);
}
return 10 * (3600 * hours + 60 * minutes + seconds);
}
+57 -6
View File
@@ -29,6 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define EXTRACTION_WAY_H
#include "../DataStructures/HashTable.h"
#include "../DataStructures/TravelMode.h"
#include "../typedefs.h"
#include <string>
@@ -44,15 +45,15 @@ struct ExtractionWay
nameID = INVALID_NAMEID;
path.clear();
keyVals.Clear();
direction = ExtractionWay::notSure;
speed = -1;
forward_speed = -1;
backward_speed = -1;
duration = -1;
type = -1;
access = true;
roundabout = false;
isAccessRestricted = false;
ignoreInGrid = false;
forward_travel_mode = TRAVEL_MODE_DEFAULT;
backward_travel_mode = TRAVEL_MODE_DEFAULT;
}
enum Directions
@@ -60,20 +61,70 @@ struct ExtractionWay
oneway,
bidirectional,
opposite };
// These accessor methods exists to support the depreciated "way.direction" access
// in LUA. Since the direction attribute was removed from ExtractionWay, the
// accessors translate to/from the mode attributes.
inline void set_direction(const Directions m)
{
if (Directions::oneway == m)
{
forward_travel_mode = TRAVEL_MODE_DEFAULT;
backward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
}
else if (Directions::opposite == m)
{
forward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
backward_travel_mode = TRAVEL_MODE_DEFAULT;
}
else if (Directions::bidirectional == m)
{
forward_travel_mode = TRAVEL_MODE_DEFAULT;
backward_travel_mode = TRAVEL_MODE_DEFAULT;
}
}
inline const Directions get_direction() const
{
if (TRAVEL_MODE_INACCESSIBLE != forward_travel_mode && TRAVEL_MODE_INACCESSIBLE != backward_travel_mode)
{
return Directions::bidirectional;
}
else if (TRAVEL_MODE_INACCESSIBLE != forward_travel_mode)
{
return Directions::oneway;
}
else if (TRAVEL_MODE_INACCESSIBLE != backward_travel_mode)
{
return Directions::opposite;
}
else
{
return Directions::notSure;
}
}
// These accessors exists because it's not possible to take the address of a bitfield,
// and LUA therefore cannot read/write the mode attributes directly.
inline void set_forward_mode(const TravelMode m) { forward_travel_mode = m; }
inline const TravelMode get_forward_mode() const { return forward_travel_mode; }
inline void set_backward_mode(const TravelMode m) { backward_travel_mode = m; }
inline const TravelMode get_backward_mode() const { return backward_travel_mode; }
unsigned id;
unsigned nameID;
double speed;
double forward_speed;
double backward_speed;
double duration;
Directions direction;
std::string name;
short type;
bool access;
bool roundabout;
bool isAccessRestricted;
bool ignoreInGrid;
std::vector<NodeID> path;
HashTable<std::string, std::string> keyVals;
TravelMode forward_travel_mode : 4;
TravelMode backward_travel_mode : 4;
};
#endif // EXTRACTION_WAY_H
+302
View File
@@ -0,0 +1,302 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Extractor.h"
#include "ExtractorCallbacks.h"
#include "ExtractionContainers.h"
#include "PBFParser.h"
#include "ScriptingEnvironment.h"
#include "XMLParser.h"
#include "../Util/GitDescription.h"
#include "../Util/IniFileUtil.h"
#include "../Util/OSRMException.h"
#include "../Util/simple_logger.hpp"
#include "../Util/TimingUtil.h"
#include "../typedefs.h"
#include <boost/program_options.hpp>
#include <tbb/task_scheduler_init.h>
#include <cstdlib>
#include <chrono>
#include <fstream>
#include <iostream>
#include <thread>
#include <unordered_map>
Extractor::Extractor() : requested_num_threads(0), file_has_pbf_format(false)
{
}
Extractor::~Extractor() {}
bool Extractor::ParseArguments(int argc, char *argv[])
{
// declare a group of options that will be allowed only on command line
boost::program_options::options_description generic_options("Options");
generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")(
"config,c",
boost::program_options::value<boost::filesystem::path>(&config_file_path)
->default_value("extractor.ini"),
"Path to a configuration file.");
// declare a group of options that will be allowed both on command line and in config file
boost::program_options::options_description config_options("Configuration");
config_options.add_options()("profile,p",
boost::program_options::value<boost::filesystem::path>(
&profile_path)->default_value("profile.lua"),
"Path to LUA routing profile")(
"threads,t",
boost::program_options::value<unsigned int>(&requested_num_threads)
->default_value(tbb::task_scheduler_init::default_num_threads()),
"Number of threads to use");
// hidden options, will be allowed both on command line and in config file, but will not be
// shown to the user
boost::program_options::options_description hidden_options("Hidden options");
hidden_options.add_options()(
"input,i",
boost::program_options::value<boost::filesystem::path>(&input_path),
"Input file in .osm, .osm.bz2 or .osm.pbf format");
// positional option
boost::program_options::positional_options_description positional_options;
positional_options.add("input", 1);
// combine above options for parsing
boost::program_options::options_description cmdline_options;
cmdline_options.add(generic_options).add(config_options).add(hidden_options);
boost::program_options::options_description config_file_options;
config_file_options.add(config_options).add(hidden_options);
boost::program_options::options_description visible_options(
boost::filesystem::basename(argv[0]) + " <input.osm/.osm.bz2/.osm.pbf> [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() << g_GIT_DESCRIPTION;
return false;
}
if (option_variables.count("help"))
{
SimpleLogger().Write() << visible_options;
return false;
}
boost::program_options::notify(option_variables);
// parse config file
if (boost::filesystem::is_regular_file(config_file_path))
{
SimpleLogger().Write() << "Reading options from: " << config_file_path.string();
std::string ini_file_contents = ReadIniFileAndLowerContents(config_file_path);
std::stringstream config_stream(ini_file_contents);
boost::program_options::store(parse_config_file(config_stream, config_file_options),
option_variables);
boost::program_options::notify(option_variables);
}
if (!option_variables.count("input"))
{
SimpleLogger().Write() << visible_options;
return false;
}
return true;
}
void Extractor::GenerateOutputFilesNames()
{
output_file_name = input_path.string();
restriction_file_name = input_path.string();
std::string::size_type pos = output_file_name.find(".osm.bz2");
if (pos == std::string::npos)
{
pos = output_file_name.find(".osm.pbf");
if (pos != std::string::npos)
{
file_has_pbf_format = true;
}
else
{
pos = output_file_name.find(".osm.xml");
}
}
if (pos == std::string::npos)
{
pos = output_file_name.find(".pbf");
if (pos != std::string::npos)
{
file_has_pbf_format = true;
}
}
if (pos == std::string::npos)
{
pos = output_file_name.find(".osm");
if (pos == std::string::npos)
{
output_file_name.append(".osrm");
restriction_file_name.append(".osrm.restrictions");
}
else
{
output_file_name.replace(pos, 5, ".osrm");
restriction_file_name.replace(pos, 5, ".osrm.restrictions");
}
}
else
{
output_file_name.replace(pos, 8, ".osrm");
restriction_file_name.replace(pos, 8, ".osrm.restrictions");
}
}
int Extractor::Run(int argc, char *argv[])
{
try
{
LogPolicy::GetInstance().Unmute();
TIMER_START(extracting);
if (!ParseArguments(argc, argv))
return 0;
if (1 > requested_num_threads)
{
SimpleLogger().Write(logWARNING) << "Number of threads must be 1 or larger";
return 1;
}
if (!boost::filesystem::is_regular_file(input_path))
{
SimpleLogger().Write(logWARNING) << "Input file " << input_path.string()
<< " not found!";
return 1;
}
if (!boost::filesystem::is_regular_file(profile_path))
{
SimpleLogger().Write(logWARNING) << "Profile " << profile_path.string()
<< " not found!";
return 1;
}
const unsigned recommended_num_threads = tbb::task_scheduler_init::default_num_threads();
SimpleLogger().Write() << "Input file: " << input_path.filename().string();
SimpleLogger().Write() << "Profile: " << profile_path.filename().string();
SimpleLogger().Write() << "Threads: " << requested_num_threads;
if (recommended_num_threads != requested_num_threads)
{
SimpleLogger().Write(logWARNING) << "The recommended number of threads is "
<< recommended_num_threads
<< "! This setting may have performance side-effects.";
}
tbb::task_scheduler_init init(requested_num_threads);
/*** Setup Scripting Environment ***/
ScriptingEnvironment scripting_environment(profile_path.string().c_str());
GenerateOutputFilesNames();
std::unordered_map<std::string, NodeID> string_map;
ExtractionContainers extraction_containers;
string_map[""] = 0;
auto extractor_callbacks = new ExtractorCallbacks(extraction_containers, string_map);
BaseParser *parser;
if (file_has_pbf_format)
{
parser = new PBFParser(input_path.string().c_str(),
extractor_callbacks,
scripting_environment,
requested_num_threads);
}
else
{
parser = new XMLParser(input_path.string().c_str(),
extractor_callbacks,
scripting_environment);
}
if (!parser->ReadHeader())
{
throw OSRMException("Parser not initialized!");
}
SimpleLogger().Write() << "Parsing in progress..";
TIMER_START(parsing);
parser->Parse();
delete parser;
delete extractor_callbacks;
TIMER_STOP(parsing);
SimpleLogger().Write() << "Parsing finished after " << TIMER_SEC(parsing) << " seconds";
if (extraction_containers.all_edges_list.empty())
{
SimpleLogger().Write(logWARNING) << "The input data is empty, exiting.";
return 1;
}
extraction_containers.PrepareData(output_file_name, restriction_file_name);
TIMER_STOP(extracting);
SimpleLogger().Write() << "extraction finished after " << TIMER_SEC(extracting) << "s";
SimpleLogger().Write() << "To prepare the data for routing, run: "
<< "./osrm-prepare " << output_file_name << std::endl;
}
catch (boost::program_options::too_many_positional_options_error &)
{
SimpleLogger().Write(logWARNING) << "Only one input file can be specified";
return 1;
}
catch (std::exception &e)
{
SimpleLogger().Write(logWARNING) << e.what();
return 1;
}
return 0;
}
+36
View File
@@ -0,0 +1,36 @@
#ifndef EXTRACTOR_H_
#define EXTRACTOR_H_
#include <boost/filesystem.hpp>
#include <string>
class ExtractorCallbacks;
/** \brief Class of 'extract' utility. */
class Extractor
{
protected:
unsigned requested_num_threads;
boost::filesystem::path config_file_path;
boost::filesystem::path input_path;
boost::filesystem::path profile_path;
std::string output_file_name;
std::string restriction_file_name;
bool file_has_pbf_format;
/** \brief Parses "extractor's" command line arguments */
bool ParseArguments(int argc, char *argv[]);
/** \brief Parses config file, if present in options */
void GenerateOutputFilesNames();
public:
explicit Extractor();
Extractor(const Extractor &) = delete;
virtual ~Extractor();
int Run(int argc, char *argv[]);
};
#endif /* EXTRACTOR_H_ */
+24 -13
View File
@@ -31,7 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../DataStructures/Restriction.h"
#include "../DataStructures/ImportNode.h"
#include "../Util/SimpleLogger.h"
#include "../Util/simple_logger.hpp"
#include <osrm/Coordinate.h>
@@ -63,7 +63,11 @@ bool ExtractorCallbacks::ProcessRestriction(const InputRestrictionContainer &res
/** warning: caller needs to take care of synchronization! */
void ExtractorCallbacks::ProcessWay(ExtractionWay &parsed_way)
{
if ((0 >= parsed_way.speed) && (0 >= parsed_way.duration))
if (((0 >= parsed_way.forward_speed) ||
(TRAVEL_MODE_INACCESSIBLE == parsed_way.forward_travel_mode)) &&
((0 >= parsed_way.backward_speed) ||
(TRAVEL_MODE_INACCESSIBLE == parsed_way.backward_travel_mode)) &&
(0 >= parsed_way.duration))
{ // Only true if the way is specified by the speed profile
return;
}
@@ -84,10 +88,11 @@ void ExtractorCallbacks::ProcessWay(ExtractionWay &parsed_way)
{
// TODO: iterate all way segments and set duration corresponding to the length of each
// segment
parsed_way.speed = parsed_way.duration / (parsed_way.path.size() - 1);
parsed_way.forward_speed = parsed_way.duration / (parsed_way.path.size() - 1);
parsed_way.backward_speed = parsed_way.duration / (parsed_way.path.size() - 1);
}
if (std::numeric_limits<double>::epsilon() >= std::abs(-1. - parsed_way.speed))
if (std::numeric_limits<double>::epsilon() >= std::abs(-1. - parsed_way.forward_speed))
{
SimpleLogger().Write(logDEBUG) << "found way with bogus speed, id: " << parsed_way.id;
return;
@@ -106,29 +111,34 @@ void ExtractorCallbacks::ProcessWay(ExtractionWay &parsed_way)
parsed_way.nameID = string_map_iterator->second;
}
if (ExtractionWay::opposite == parsed_way.direction)
if (TRAVEL_MODE_INACCESSIBLE == parsed_way.forward_travel_mode)
{
std::reverse(parsed_way.path.begin(), parsed_way.path.end());
parsed_way.direction = ExtractionWay::oneway;
parsed_way.forward_travel_mode = parsed_way.backward_travel_mode;
parsed_way.backward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
}
const bool split_edge =
(parsed_way.backward_speed > 0) && (parsed_way.speed != parsed_way.backward_speed);
(parsed_way.forward_speed>0) && (TRAVEL_MODE_INACCESSIBLE != parsed_way.forward_travel_mode) &&
(parsed_way.backward_speed>0) && (TRAVEL_MODE_INACCESSIBLE != parsed_way.backward_travel_mode) &&
((parsed_way.forward_speed != parsed_way.backward_speed) ||
(parsed_way.forward_travel_mode != parsed_way.backward_travel_mode));
BOOST_ASSERT(parsed_way.forward_travel_mode>0);
for (unsigned n = 0; n < (parsed_way.path.size() - 1); ++n)
{
external_memory.all_edges_list.push_back(InternalExtractorEdge(
parsed_way.path[n],
parsed_way.path[n + 1],
parsed_way.type,
(split_edge ? ExtractionWay::oneway : parsed_way.direction),
parsed_way.speed,
((split_edge || TRAVEL_MODE_INACCESSIBLE == parsed_way.backward_travel_mode) ? ExtractionWay::oneway
: ExtractionWay::bidirectional),
parsed_way.forward_speed,
parsed_way.nameID,
parsed_way.roundabout,
parsed_way.ignoreInGrid,
(0 < parsed_way.duration),
parsed_way.isAccessRestricted,
false,
parsed_way.forward_travel_mode,
split_edge));
external_memory.used_node_id_list.push_back(parsed_way.path[n]);
}
@@ -144,13 +154,14 @@ void ExtractorCallbacks::ProcessWay(ExtractionWay &parsed_way)
if (split_edge)
{ // Only true if the way should be split
BOOST_ASSERT(parsed_way.backward_travel_mode>0);
std::reverse(parsed_way.path.begin(), parsed_way.path.end());
for (std::vector<NodeID>::size_type n = 0; n < parsed_way.path.size() - 1; ++n)
{
external_memory.all_edges_list.push_back(
InternalExtractorEdge(parsed_way.path[n],
parsed_way.path[n + 1],
parsed_way.type,
ExtractionWay::oneway,
parsed_way.backward_speed,
parsed_way.nameID,
@@ -158,7 +169,7 @@ void ExtractorCallbacks::ProcessWay(ExtractionWay &parsed_way)
parsed_way.ignoreInGrid,
(0 < parsed_way.duration),
parsed_way.isAccessRestricted,
(ExtractionWay::oneway == parsed_way.direction),
parsed_way.backward_travel_mode,
split_edge));
}
external_memory.way_start_end_id_list.push_back(
+3 -3
View File
@@ -83,7 +83,7 @@ struct WayIDStartAndEndEdge
struct CmpWayByID
{
typedef WayIDStartAndEndEdge value_type;
using value_type = WayIDStartAndEndEdge;
bool operator()(const WayIDStartAndEndEdge &a, const WayIDStartAndEndEdge &b) const
{
return a.wayID < b.wayID;
@@ -94,7 +94,7 @@ struct CmpWayByID
struct Cmp
{
typedef NodeID value_type;
using value_type = NodeID;
bool operator()(const NodeID left, const NodeID right) const { return left < right; }
value_type max_value() { return 0xffffffff; }
value_type min_value() { return 0x0; }
@@ -102,7 +102,7 @@ struct Cmp
struct CmpNodeByID
{
typedef ExternalMemoryNode value_type;
using value_type = ExternalMemoryNode;
bool operator()(const ExternalMemoryNode &left, const ExternalMemoryNode &right) const
{
return left.node_id < right.node_id;
+11 -13
View File
@@ -29,6 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define INTERNAL_EXTRACTOR_EDGE_H
#include "../typedefs.h"
#include "../DataStructures/TravelMode.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
@@ -36,15 +37,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct InternalExtractorEdge
{
InternalExtractorEdge()
: start(0), target(0), type(0), direction(0), speed(0), name_id(0), is_roundabout(false),
: start(0), target(0), direction(0), speed(0), name_id(0), is_roundabout(false),
is_in_tiny_cc(false), is_duration_set(false), is_access_restricted(false),
is_contra_flow(false), is_split(false)
travel_mode(TRAVEL_MODE_INACCESSIBLE), is_split(false)
{
}
explicit InternalExtractorEdge(NodeID start,
NodeID target,
short type,
short direction,
double speed,
unsigned name_id,
@@ -52,30 +52,28 @@ struct InternalExtractorEdge
bool is_in_tiny_cc,
bool is_duration_set,
bool is_access_restricted,
bool is_contra_flow,
TravelMode travel_mode,
bool is_split)
: start(start), target(target), type(type), direction(direction), speed(speed),
: start(start), target(target), direction(direction), speed(speed),
name_id(name_id), is_roundabout(is_roundabout), is_in_tiny_cc(is_in_tiny_cc),
is_duration_set(is_duration_set), is_access_restricted(is_access_restricted),
is_contra_flow(is_contra_flow), is_split(is_split)
travel_mode(travel_mode), is_split(is_split)
{
BOOST_ASSERT(0 <= type);
}
// necessary static util functions for stxxl's sorting
static InternalExtractorEdge min_value()
{
return InternalExtractorEdge(0, 0, 0, 0, 0, 0, false, false, false, false, false, false);
return InternalExtractorEdge(0, 0, 0, 0, 0, false, false, false, false, TRAVEL_MODE_INACCESSIBLE, false);
}
static InternalExtractorEdge max_value()
{
return InternalExtractorEdge(
SPECIAL_NODEID, SPECIAL_NODEID, 0, 0, 0, 0, false, false, false, false, false, false);
SPECIAL_NODEID, SPECIAL_NODEID, 0, 0, 0, false, false, false, false, TRAVEL_MODE_INACCESSIBLE, false);
}
NodeID start;
NodeID target;
short type;
short direction;
double speed;
unsigned name_id;
@@ -83,7 +81,7 @@ struct InternalExtractorEdge
bool is_in_tiny_cc;
bool is_duration_set;
bool is_access_restricted;
bool is_contra_flow;
TravelMode travel_mode : 4;
bool is_split;
FixedPointCoordinate source_coordinate;
@@ -92,7 +90,7 @@ struct InternalExtractorEdge
struct CmpEdgeByStartID
{
typedef InternalExtractorEdge value_type;
using value_type = InternalExtractorEdge;
bool operator()(const InternalExtractorEdge &a, const InternalExtractorEdge &b) const
{
return a.start < b.start;
@@ -105,7 +103,7 @@ struct CmpEdgeByStartID
struct CmpEdgeByTargetID
{
typedef InternalExtractorEdge value_type;
using value_type = InternalExtractorEdge;
bool operator()(const InternalExtractorEdge &a, const InternalExtractorEdge &b) const
{
+2 -1
View File
@@ -36,7 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../DataStructures/Restriction.h"
#include "../Util/MachineInfo.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../Util/simple_logger.hpp"
#include "../typedefs.h"
#include <boost/assert.hpp>
@@ -49,6 +49,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <zlib.h>
#include <functional>
#include <iostream>
#include <limits>
#include <thread>
+46 -45
View File
@@ -32,9 +32,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../DataStructures/ImportNode.h"
#include "../Util/LuaUtil.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../Util/simple_logger.hpp"
#include "../typedefs.h"
#include <sstream>
ScriptingEnvironment::ScriptingEnvironment() {}
ScriptingEnvironment::ScriptingEnvironment(const char *file_name)
: file_name(file_name)
@@ -54,54 +56,53 @@ void ScriptingEnvironment::initLuaState(lua_State* lua_state)
luabind::module(lua_state)[
luabind::def("print", LUA_print<std::string>),
luabind::def("durationIsValid", durationIsValid),
luabind::def("parseDuration", parseDuration)
luabind::def("parseDuration", parseDuration),
luabind::class_<HashTable<std::string, std::string>>("keyVals")
.def("Add", &HashTable<std::string, std::string>::Add)
.def("Find", &HashTable<std::string, std::string>::Find)
.def("Holds", &HashTable<std::string, std::string>::Holds),
luabind::class_<ImportNode>("Node")
// .def(luabind::constructor<>())
.def_readwrite("lat", &ImportNode::lat)
.def_readwrite("lon", &ImportNode::lon)
.def_readonly("id", &ImportNode::node_id)
.def_readwrite("bollard", &ImportNode::bollard)
.def_readwrite("traffic_light", &ImportNode::trafficLight)
.def_readwrite("tags", &ImportNode::keyVals),
luabind::class_<ExtractionWay>("Way")
// .def(luabind::constructor<>())
.def_readonly("id", &ExtractionWay::id)
.def_readwrite("name", &ExtractionWay::name)
.def_readwrite("forward_speed", &ExtractionWay::forward_speed)
.def_readwrite("backward_speed", &ExtractionWay::backward_speed)
.def_readwrite("duration", &ExtractionWay::duration)
.def_readwrite("access", &ExtractionWay::access)
.def_readwrite("roundabout", &ExtractionWay::roundabout)
.def_readwrite("is_access_restricted", &ExtractionWay::isAccessRestricted)
.def_readwrite("ignore_in_grid", &ExtractionWay::ignoreInGrid)
.def_readwrite("tags", &ExtractionWay::keyVals)
.property("direction", &ExtractionWay::get_direction, &ExtractionWay::set_direction)
.property("forward_mode", &ExtractionWay::get_forward_mode, &ExtractionWay::set_forward_mode)
.property("backward_mode", &ExtractionWay::get_backward_mode, &ExtractionWay::set_backward_mode)
.enum_("constants")[
luabind::value("notSure", 0),
luabind::value("oneway", 1),
luabind::value("bidirectional", 2),
luabind::value("opposite", 3)
],
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::module(lua_state)[luabind::class_<HashTable<std::string, std::string>>("keyVals")
.def("Add", &HashTable<std::string, std::string>::Add)
.def("Find", &HashTable<std::string, std::string>::Find)
.def("Holds", &HashTable<std::string, std::string>::Holds)];
luabind::module(lua_state)[luabind::class_<ImportNode>("Node")
.def(luabind::constructor<>())
.def_readwrite("lat", &ImportNode::lat)
.def_readwrite("lon", &ImportNode::lon)
.def_readonly("id", &ImportNode::node_id)
.def_readwrite("bollard", &ImportNode::bollard)
.def_readwrite("traffic_light", &ImportNode::trafficLight)
.def_readwrite("tags", &ImportNode::keyVals)];
luabind::module(lua_state)
[luabind::class_<ExtractionWay>("Way")
.def(luabind::constructor<>())
.def_readonly("id", &ExtractionWay::id)
.def_readwrite("name", &ExtractionWay::name)
.def_readwrite("speed", &ExtractionWay::speed)
.def_readwrite("backward_speed", &ExtractionWay::backward_speed)
.def_readwrite("duration", &ExtractionWay::duration)
.def_readwrite("type", &ExtractionWay::type)
.def_readwrite("access", &ExtractionWay::access)
.def_readwrite("roundabout", &ExtractionWay::roundabout)
.def_readwrite("is_access_restricted", &ExtractionWay::isAccessRestricted)
.def_readwrite("ignore_in_grid", &ExtractionWay::ignoreInGrid)
.def_readwrite("tags", &ExtractionWay::keyVals)
.def_readwrite("direction", &ExtractionWay::direction)
.enum_("constants")[
luabind::value("notSure", 0),
luabind::value("oneway", 1),
luabind::value("bidirectional", 2),
luabind::value("opposite", 3)
]];
// fails on c++11/OS X 10.9
luabind::module(lua_state)[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))];
if (0 != luaL_dofile(lua_state, file_name.c_str()))
{
throw OSRMException("ERROR occured in scripting block");
luabind::object error_msg(luabind::from_stack(lua_state, -1));
std::ostringstream error_stream;
error_stream << error_msg;
throw OSRMException("ERROR occured in profile script:\n" + error_stream.str());
}
}
+12 -11
View File
@@ -34,7 +34,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../DataStructures/ImportNode.h"
#include "../DataStructures/InputReaderFactory.h"
#include "../DataStructures/Restriction.h"
#include "../Util/SimpleLogger.h"
#include "../Util/cast.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/StringUtil.h"
#include "../typedefs.h"
@@ -168,17 +169,17 @@ InputRestrictionContainer XMLParser::ReadXMLRestriction()
if (xmlStrEqual(role, (const xmlChar *)"to") &&
xmlStrEqual(type, (const xmlChar *)"way"))
{
restriction.toWay = StringToUint((const char *)ref);
restriction.toWay = cast::string_to_uint((const char *)ref);
}
if (xmlStrEqual(role, (const xmlChar *)"from") &&
xmlStrEqual(type, (const xmlChar *)"way"))
{
restriction.fromWay = StringToUint((const char *)ref);
restriction.fromWay = cast::string_to_uint((const char *)ref);
}
if (xmlStrEqual(role, (const xmlChar *)"via") &&
xmlStrEqual(type, (const xmlChar *)"node"))
{
restriction.restriction.viaNode = StringToUint((const char *)ref);
restriction.restriction.viaNode = cast::string_to_uint((const char *)ref);
}
if (nullptr != type)
@@ -230,9 +231,9 @@ ExtractionWay XMLParser::ReadXMLWay()
if (depth == child_depth && child_type == 15 &&
xmlStrEqual(child_name, (const xmlChar *)"way") == 1)
{
xmlChar *node_id = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"id");
way.id = StringToUint((char *)node_id);
xmlFree(node_id);
xmlChar *way_id = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"id");
way.id = cast::string_to_uint((char *)way_id);
xmlFree(way_id);
xmlFree(child_name);
break;
}
@@ -265,7 +266,7 @@ ExtractionWay XMLParser::ReadXMLWay()
xmlChar *ref = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"ref");
if (ref != nullptr)
{
way.path.push_back(StringToUint((const char *)ref));
way.path.push_back(cast::string_to_uint((const char *)ref));
xmlFree(ref);
}
}
@@ -281,19 +282,19 @@ ImportNode XMLParser::ReadXMLNode()
xmlChar *attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"lat");
if (attribute != nullptr)
{
node.lat = static_cast<int>(COORDINATE_PRECISION * StringToDouble((const char *)attribute));
node.lat = static_cast<int>(COORDINATE_PRECISION * cast::string_to_double((const char *)attribute));
xmlFree(attribute);
}
attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"lon");
if (attribute != nullptr)
{
node.lon = static_cast<int>(COORDINATE_PRECISION * StringToDouble((const char *)attribute));
node.lon = static_cast<int>(COORDINATE_PRECISION * cast::string_to_double((const char *)attribute));
xmlFree(attribute);
}
attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"id");
if (attribute != nullptr)
{
node.node_id = StringToUint((const char *)attribute);
node.node_id = cast::string_to_uint((const char *)attribute);
xmlFree(attribute);
}
+17 -11
View File
@@ -28,11 +28,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef FIXED_POINT_COORDINATE_H_
#define FIXED_POINT_COORDINATE_H_
#include <functional>
#include <iosfwd> //for std::ostream
#include <string>
#include <type_traits>
const float COORDINATE_PRECISION = 1000000.f;
constexpr float COORDINATE_PRECISION = 1000000.f;
struct FixedPointCoordinate
{
@@ -40,7 +40,15 @@ struct FixedPointCoordinate
int lon;
FixedPointCoordinate();
explicit FixedPointCoordinate(int lat, int lon);
FixedPointCoordinate(int lat, int lon);
template<class T>
FixedPointCoordinate(const T &coordinate) : lat(coordinate.lat), lon(coordinate.lon)
{
static_assert(std::is_same<decltype(lat), decltype(coordinate.lat)>::value, "coordinate types incompatible");
static_assert(std::is_same<decltype(lon), decltype(coordinate.lon)>::value, "coordinate types incompatible");
}
void Reset();
bool isSet() const;
bool isValid() const;
@@ -55,10 +63,8 @@ struct FixedPointCoordinate
static float ApproximateEuclideanDistance(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate);
static float ApproximateEuclideanDistance(const int lat1,
const int lon1,
const int lat2,
const int lon2);
static float
ApproximateEuclideanDistance(const int lat1, const int lon1, const int lat2, const int lon2);
static float ApproximateSquaredEuclideanDistance(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate);
@@ -81,10 +87,10 @@ struct FixedPointCoordinate
FixedPointCoordinate &nearest_location,
float &ratio);
static int OrderedPerpendicularDistanceApproximation(const FixedPointCoordinate& segment_source,
const FixedPointCoordinate& segment_target,
const FixedPointCoordinate& query_location);
static int
OrderedPerpendicularDistanceApproximation(const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location);
static float GetBearing(const FixedPointCoordinate &A, const FixedPointCoordinate &B);
+1 -1
View File
@@ -37,7 +37,7 @@ struct Header
{
Header& operator=(const Header& other) = default;
Header(const std::string & name, const std::string & value) : name(name), value(value) {}
Header(const Header && other) : name(std::move(other.name)), value(std::move(other.value)) {}
Header(Header && other) : name(std::move(other.name)), value(std::move(other.value)) {}
void Clear()
{
+9
View File
@@ -40,9 +40,15 @@ struct RouteParameters
RouteParameters();
void setZoomLevel(const short level);
void setNumberOfResults(const short number);
void setAlternateRouteFlag(const bool flag);
void setUTurn(const bool flag);
void setAllUTurns(const bool flag);
void setDeprecatedAPIFlag(const std::string &);
void setChecksum(const unsigned check_sum);
@@ -71,12 +77,15 @@ struct RouteParameters
bool geometry;
bool compression;
bool deprecatedAPI;
bool uturn_default;
unsigned check_sum;
short num_results;
std::string service;
std::string output_format;
std::string jsonp_parameter;
std::string language;
std::vector<std::string> hints;
std::vector<bool> uturns;
std::vector<FixedPointCoordinate> coordinates;
};
+4 -2
View File
@@ -30,6 +30,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <osrm/ServerPaths.h>
#include <memory>
class OSRM_impl;
struct RouteParameters;
@@ -41,10 +43,10 @@ class Reply;
class OSRM
{
private:
OSRM_impl *OSRM_pimpl_;
std::unique_ptr<OSRM_impl> OSRM_pimpl_;
public:
explicit OSRM(const ServerPaths &paths, const bool use_shared_memory = false);
explicit OSRM(ServerPaths paths, const bool use_shared_memory = false);
~OSRM();
void RunQuery(RouteParameters &route_parameters, http::Reply &reply);
};
+12 -13
View File
@@ -45,7 +45,9 @@ namespace boost { namespace interprocess { class named_mutex; } }
#include "../Server/DataStructures/InternalDataFacade.h"
#include "../Server/DataStructures/SharedBarriers.h"
#include "../Server/DataStructures/SharedDataFacade.h"
#include "../Util/SimpleLogger.h"
#include "../Util/make_unique.hpp"
#include "../Util/ProgramOptions.h"
#include "../Util/simple_logger.hpp"
#include <boost/assert.hpp>
#include <boost/interprocess/sync/named_condition.hpp>
@@ -56,16 +58,17 @@ namespace boost { namespace interprocess { class named_mutex; } }
#include <utility>
#include <vector>
OSRM_impl::OSRM_impl(const ServerPaths &server_paths, const bool use_shared_memory)
: use_shared_memory(use_shared_memory)
OSRM_impl::OSRM_impl(ServerPaths server_paths, const bool use_shared_memory)
{
if (use_shared_memory)
{
barrier = new SharedBarriers();
barrier = osrm::make_unique<SharedBarriers>();
query_data_facade = new SharedDataFacade<QueryEdge::EdgeData>();
}
else
{
// populate base path
populate_base_path(server_paths);
query_data_facade = new InternalDataFacade<QueryEdge::EdgeData>(server_paths);
}
@@ -85,10 +88,6 @@ OSRM_impl::~OSRM_impl()
{
delete plugin_pointer.second;
}
if (use_shared_memory)
{
delete barrier;
}
}
void OSRM_impl::RegisterPlugin(BasePlugin *plugin)
@@ -108,7 +107,7 @@ void OSRM_impl::RunQuery(RouteParameters &route_parameters, http::Reply &reply)
if (plugin_map.end() != iter)
{
reply.status = http::Reply::ok;
if (use_shared_memory)
if (barrier)
{
// lock update pending
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> pending_lock(
@@ -129,7 +128,7 @@ void OSRM_impl::RunQuery(RouteParameters &route_parameters, http::Reply &reply)
}
iter->second->HandleRequest(route_parameters, reply);
if (use_shared_memory)
if (barrier)
{
// lock query
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> query_lock(
@@ -154,12 +153,12 @@ void OSRM_impl::RunQuery(RouteParameters &route_parameters, http::Reply &reply)
// proxy code for compilation firewall
OSRM::OSRM(const ServerPaths &paths, const bool use_shared_memory)
: OSRM_pimpl_(new OSRM_impl(paths, use_shared_memory))
OSRM::OSRM(ServerPaths paths, const bool use_shared_memory)
: OSRM_pimpl_(osrm::make_unique<OSRM_impl>(paths, use_shared_memory))
{
}
OSRM::~OSRM() { delete OSRM_pimpl_; }
OSRM::~OSRM() { OSRM_pimpl_.reset(); }
void OSRM::RunQuery(RouteParameters &route_parameters, http::Reply &reply)
{
+5 -4
View File
@@ -36,6 +36,7 @@ struct RouteParameters;
#include "../DataStructures/QueryEdge.h"
#include <memory>
#include <unordered_map>
#include <string>
@@ -45,10 +46,10 @@ template <class EdgeDataT> class BaseDataFacade;
class OSRM_impl
{
private:
typedef std::unordered_map<std::string, BasePlugin *> PluginMap;
using PluginMap = std::unordered_map<std::string, BasePlugin *>;
public:
OSRM_impl(const ServerPaths &paths, const bool use_shared_memory);
OSRM_impl(ServerPaths paths, const bool use_shared_memory);
OSRM_impl(const OSRM_impl &) = delete;
virtual ~OSRM_impl();
void RunQuery(RouteParameters &route_parameters, http::Reply &reply);
@@ -56,8 +57,8 @@ class OSRM_impl
private:
void RegisterPlugin(BasePlugin *plugin);
PluginMap plugin_map;
bool use_shared_memory;
SharedBarriers *barrier;
// will only be initialized if shared memory is used
std::unique_ptr<SharedBarriers> barrier;
// base class pointer to the objects
BaseDataFacade<QueryEdge::EdgeData> *query_data_facade;
};
+10 -8
View File
@@ -35,7 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../DataStructures/QueryEdge.h"
#include "../DataStructures/SearchEngine.h"
#include "../Descriptors/BaseDescriptor.h"
#include "../Util/SimpleLogger.h"
#include "../Util/make_unique.hpp"
#include "../Util/StringUtil.h"
#include "../Util/TimingUtil.h"
@@ -47,22 +47,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include <vector>
template <class DataFacadeT> class DistanceTablePlugin : public BasePlugin
template <class DataFacadeT> class DistanceTablePlugin final : public BasePlugin
{
private:
std::shared_ptr<SearchEngine<DataFacadeT>> search_engine_ptr;
std::unique_ptr<SearchEngine<DataFacadeT>> search_engine_ptr;
public:
explicit DistanceTablePlugin(DataFacadeT *facade) : descriptor_string("table"), facade(facade)
{
search_engine_ptr = std::make_shared<SearchEngine<DataFacadeT>>(facade);
search_engine_ptr = osrm::make_unique<SearchEngine<DataFacadeT>>(facade);
}
virtual ~DistanceTablePlugin() {}
const std::string GetDescriptor() const { return descriptor_string; }
const std::string GetDescriptor() const final { return descriptor_string; }
void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply)
void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply) final
{
// check number of parameters
if (2 > route_parameters.coordinates.size())
@@ -77,7 +77,9 @@ template <class DataFacadeT> class DistanceTablePlugin : public BasePlugin
if (std::any_of(begin(route_parameters.coordinates),
end(route_parameters.coordinates),
[&](FixedPointCoordinate coordinate)
{ return !coordinate.isValid(); }))
{
return !coordinate.isValid();
}))
{
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
@@ -98,7 +100,7 @@ template <class DataFacadeT> class DistanceTablePlugin : public BasePlugin
!route_parameters.hints[i].empty())
{
PhantomNode current_phantom_node;
DecodeObjectFromBase64(route_parameters.hints[i], current_phantom_node);
ObjectEncoder::DecodeFromBase64(route_parameters.hints[i], current_phantom_node);
if (current_phantom_node.isValid(facade->GetNumberOfNodes()))
{
phantom_node_vector[i].emplace_back(std::move(current_phantom_node));
+12 -10
View File
@@ -30,11 +30,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "BasePlugin.h"
#include "../DataStructures/JSONContainer.h"
#include "../Util/StringUtil.h"
#include "../Util/cast.hpp"
#include <string>
class HelloWorldPlugin : public BasePlugin
class HelloWorldPlugin final : public BasePlugin
{
private:
std::string temp_string;
@@ -42,9 +42,9 @@ class HelloWorldPlugin : public BasePlugin
public:
HelloWorldPlugin() : descriptor_string("hello") {}
virtual ~HelloWorldPlugin() {}
const std::string GetDescriptor() const { return descriptor_string; }
const std::string GetDescriptor() const final { return descriptor_string; }
void HandleRequest(const RouteParameters &routeParameters, http::Reply &reply)
void HandleRequest(const RouteParameters &routeParameters, http::Reply &reply) final
{
reply.status = http::Reply::ok;
@@ -52,20 +52,22 @@ class HelloWorldPlugin : public BasePlugin
std::string temp_string;
json_result.values["title"] = "Hello World";
temp_string = IntToString(routeParameters.zoom_level);
temp_string = cast::integral_to_string(routeParameters.zoom_level);
json_result.values["zoom_level"] = temp_string;
temp_string = UintToString(routeParameters.check_sum);
temp_string = cast::integral_to_string(routeParameters.check_sum);
json_result.values["check_sum"] = temp_string;
json_result.values["instructions"] = (routeParameters.print_instructions ? "yes" : "no");
json_result.values["geometry"] = (routeParameters.geometry ? "yes" : "no");
json_result.values["compression"] = (routeParameters.compression ? "yes" : "no");
json_result.values["output_format"] = (!routeParameters.output_format.empty() ? "yes" : "no");
json_result.values["output_format"] =
(!routeParameters.output_format.empty() ? "yes" : "no");
json_result.values["jsonp_parameter"] = (!routeParameters.jsonp_parameter.empty() ? "yes" : "no");
json_result.values["jsonp_parameter"] =
(!routeParameters.jsonp_parameter.empty() ? "yes" : "no");
json_result.values["language"] = (!routeParameters.language.empty() ? "yes" : "no");
temp_string = UintToString(static_cast<unsigned>(routeParameters.coordinates.size()));
temp_string = cast::integral_to_string(routeParameters.coordinates.size());
json_result.values["location_count"] = temp_string;
JSON::Array json_locations;
@@ -77,7 +79,7 @@ class HelloWorldPlugin : public BasePlugin
json_coordinates.values.push_back(coordinate.lat / COORDINATE_PRECISION);
json_coordinates.values.push_back(coordinate.lon / COORDINATE_PRECISION);
json_location.values[UintToString(counter)] = json_coordinates;
json_location.values[cast::integral_to_string(counter)] = json_coordinates;
json_locations.values.push_back(json_location);
++counter;
}
+6 -7
View File
@@ -35,17 +35,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
// locates the nearest node in the road network for a given coordinate.
template <class DataFacadeT> class LocatePlugin : public BasePlugin
template <class DataFacadeT> class LocatePlugin final : public BasePlugin
{
public:
explicit LocatePlugin(DataFacadeT *facade) : descriptor_string("locate"), facade(facade) {}
const std::string GetDescriptor() const { return descriptor_string; }
const std::string GetDescriptor() const final { return descriptor_string; }
void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply)
void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply) final
{
// check number of parameters
if (route_parameters.coordinates.empty() ||
!route_parameters.coordinates.front().isValid())
if (route_parameters.coordinates.empty() || !route_parameters.coordinates.front().isValid())
{
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
@@ -63,8 +62,8 @@ template <class DataFacadeT> class LocatePlugin : public BasePlugin
reply.status = http::Reply::ok;
json_result.values["status"] = 0;
JSON::Array json_coordinate;
json_coordinate.values.push_back(result.lat/COORDINATE_PRECISION);
json_coordinate.values.push_back(result.lon/COORDINATE_PRECISION);
json_coordinate.values.push_back(result.lat / COORDINATE_PRECISION);
json_coordinate.values.push_back(result.lon / COORDINATE_PRECISION);
json_result.values["mapped_coordinate"] = json_coordinate;
}
+40 -15
View File
@@ -31,6 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "BasePlugin.h"
#include "../DataStructures/JSONContainer.h"
#include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/Range.h"
#include <string>
@@ -38,14 +39,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* This Plugin locates the nearest point on a street in the road network for a given coordinate.
*/
template <class DataFacadeT> class NearestPlugin : public BasePlugin
template <class DataFacadeT> class NearestPlugin final : public BasePlugin
{
public:
explicit NearestPlugin(DataFacadeT *facade) : facade(facade), descriptor_string("nearest") {}
const std::string GetDescriptor() const { return descriptor_string; }
const std::string GetDescriptor() const final { return descriptor_string; }
void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply)
void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply) final
{
// check number of parameters
if (route_parameters.coordinates.empty() || !route_parameters.coordinates.front().isValid())
@@ -53,12 +54,12 @@ template <class DataFacadeT> class NearestPlugin : public BasePlugin
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
}
auto number_of_results = static_cast<std::size_t>(route_parameters.num_results);
std::vector<PhantomNode> phantom_node_vector;
facade->IncrementalFindPhantomNodeForCoordinate(route_parameters.coordinates.front(),
phantom_node_vector,
route_parameters.zoom_level,
1);
static_cast<int>(number_of_results));
JSON::Object json_result;
if (phantom_node_vector.empty() || !phantom_node_vector.front().isValid())
@@ -69,17 +70,41 @@ template <class DataFacadeT> class NearestPlugin : public BasePlugin
{
reply.status = http::Reply::ok;
json_result.values["status"] = 0;
JSON::Array json_coordinate;
json_coordinate.values.push_back(phantom_node_vector.front().location.lat /
COORDINATE_PRECISION);
json_coordinate.values.push_back(phantom_node_vector.front().location.lon /
COORDINATE_PRECISION);
json_result.values["mapped_coordinate"] = json_coordinate;
std::string temp_string;
facade->GetName(phantom_node_vector.front().name_id, temp_string);
json_result.values["name"] = temp_string;
}
if (number_of_results > 1)
{
JSON::Array results;
auto vector_length = phantom_node_vector.size();
for (const auto i : osrm::irange<std::size_t>(0, std::min(number_of_results, vector_length)))
{
JSON::Array json_coordinate;
JSON::Object result;
json_coordinate.values.push_back(phantom_node_vector.at(i).location.lat /
COORDINATE_PRECISION);
json_coordinate.values.push_back(phantom_node_vector.at(i).location.lon /
COORDINATE_PRECISION);
result.values["mapped coordinate"] = json_coordinate;
std::string temp_string;
facade->GetName(phantom_node_vector.front().name_id, temp_string);
result.values["name"] = temp_string;
results.values.push_back(result);
}
json_result.values["results"] = results;
}
else
{
JSON::Array json_coordinate;
json_coordinate.values.push_back(phantom_node_vector.front().location.lat /
COORDINATE_PRECISION);
json_coordinate.values.push_back(phantom_node_vector.front().location.lon /
COORDINATE_PRECISION);
json_result.values["mapped_coordinate"] = json_coordinate;
std::string temp_string;
facade->GetName(phantom_node_vector.front().name_id, temp_string);
json_result.values["name"] = temp_string;
}
}
JSON::render(reply.content, json_result);
}
+3 -3
View File
@@ -33,15 +33,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
template <class DataFacadeT> class TimestampPlugin : public BasePlugin
template <class DataFacadeT> class TimestampPlugin final : public BasePlugin
{
public:
explicit TimestampPlugin(const DataFacadeT *facade)
: facade(facade), descriptor_string("timestamp")
{
}
const std::string GetDescriptor() const { return descriptor_string; }
void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply)
const std::string GetDescriptor() const final { return descriptor_string; }
void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply) final
{
reply.status = http::Reply::ok;
JSON::Object json_result;
+13 -10
View File
@@ -31,13 +31,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "BasePlugin.h"
#include "../Algorithms/ObjectToBase64.h"
#include "../DataStructures/QueryEdge.h"
#include "../DataStructures/SearchEngine.h"
#include "../Descriptors/BaseDescriptor.h"
#include "../Descriptors/GPXDescriptor.h"
#include "../Descriptors/JSONDescriptor.h"
#include "../Util/SimpleLogger.h"
#include "../Util/make_unique.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/StringUtil.h"
#include "../Util/TimingUtil.h"
@@ -49,16 +49,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include <vector>
template <class DataFacadeT> class ViaRoutePlugin : public BasePlugin
template <class DataFacadeT> class ViaRoutePlugin final : public BasePlugin
{
private:
std::unordered_map<std::string, unsigned> descriptor_table;
std::shared_ptr<SearchEngine<DataFacadeT>> search_engine_ptr;
std::unique_ptr<SearchEngine<DataFacadeT>> search_engine_ptr;
public:
explicit ViaRoutePlugin(DataFacadeT *facade) : descriptor_string("viaroute"), facade(facade)
{
search_engine_ptr = std::make_shared<SearchEngine<DataFacadeT>>(facade);
search_engine_ptr = osrm::make_unique<SearchEngine<DataFacadeT>>(facade);
descriptor_table.emplace("json", 0);
descriptor_table.emplace("gpx", 1);
@@ -67,16 +67,18 @@ template <class DataFacadeT> class ViaRoutePlugin : public BasePlugin
virtual ~ViaRoutePlugin() {}
const std::string GetDescriptor() const { return descriptor_string; }
const std::string GetDescriptor() const final { return descriptor_string; }
void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply)
void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply) final
{
// check number of parameters
if (2 > route_parameters.coordinates.size() ||
std::any_of(begin(route_parameters.coordinates),
end(route_parameters.coordinates),
[&](FixedPointCoordinate coordinate)
{ return !coordinate.isValid(); }))
{
return !coordinate.isValid();
}))
{
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
@@ -97,7 +99,7 @@ template <class DataFacadeT> class ViaRoutePlugin : public BasePlugin
if (checksum_OK && i < route_parameters.hints.size() &&
!route_parameters.hints[i].empty())
{
DecodeObjectFromBase64(route_parameters.hints[i], phantom_node_vector[i]);
ObjectEncoder::DecodeFromBase64(route_parameters.hints[i], phantom_node_vector[i]);
if (phantom_node_vector[i].isValid(facade->GetNumberOfNodes()))
{
continue;
@@ -125,7 +127,8 @@ template <class DataFacadeT> class ViaRoutePlugin : public BasePlugin
}
else
{
search_engine_ptr->shortest_path(raw_route.segment_end_coordinates, raw_route);
search_engine_ptr->shortest_path(
raw_route.segment_end_coordinates, route_parameters.uturns, raw_route);
}
if (INVALID_EDGE_WEIGHT == raw_route.shortest_path_length)
+4 -3
View File
@@ -2,7 +2,7 @@
For instructions on how to compile and run OSRM, please consult the Wiki at
https://github.com/DennisOSRM/Project-OSRM/wiki
https://github.com/Project-OSRM/osrm-backend/wiki
or use our free and daily updated online service at
@@ -35,6 +35,7 @@ When using the code in a (scientific) publication, please cite
| build config | branch | status |
|:-------------|:--------|:------------|
| Project OSRM | master | [![Build Status](https://travis-ci.org/DennisOSRM/Project-OSRM.png?branch=master)](https://travis-ci.org/DennisOSRM/Project-OSRM) |
| Project OSRM | develop | [![Build Status](https://travis-ci.org/DennisOSRM/Project-OSRM.png?branch=develop)](https://travis-ci.org/DennisOSRM/Project-OSRM) |
| Linux | master | [![Build Status](https://travis-ci.org/Project-OSRM/osrm-backend.png?branch=master)](https://travis-ci.org/DennisOSRM/Project-OSRM) |
| Linux | develop | [![Build Status](https://travis-ci.org/Project-OSRM/osrm-backend.png?branch=develop)](https://travis-ci.org/DennisOSRM/Project-OSRM) |
| Windows | master/develop | [![Build status](https://ci.appveyor.com/api/projects/status/4iuo3s9gxprmcjjh)](https://ci.appveyor.com/project/DennisOSRM/osrm-backend) |
| LUAbind fork | master | [![Build Status](https://travis-ci.org/DennisOSRM/luabind.png?branch=master)](https://travis-ci.org/DennisOSRM/luabind) |
+8 -1
View File
@@ -6,7 +6,7 @@ require 'sys/proctable'
BUILD_FOLDER = 'build'
DATA_FOLDER = 'sandbox'
PROFILE = 'examples/postgis'
PROFILE = 'bicycle'
OSRM_PORT = 5000
PROFILES_FOLDER = '../profiles'
@@ -181,3 +181,10 @@ end
desc "Stop, reprocess and restart."
task :update => [:down,:process,:up] do
end
desc "Remove test cache files."
task :sweep do
system "rm test/cache/*"
end
+115 -69
View File
@@ -29,23 +29,27 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define ALTERNATIVE_PATH_ROUTING_H
#include "BasicRoutingInterface.h"
#include "../DataStructures/Range.h"
#include "../DataStructures/SearchEngineData.h"
#include "../Util/container.hpp"
#include <boost/assert.hpp>
#include <unordered_map>
#include <unordered_set>
#include <vector>
const double VIAPATH_ALPHA = 0.10;
const double VIAPATH_EPSILON = 0.15; // alternative at most 15% longer
const double VIAPATH_GAMMA = 0.75; // alternative shares at most 75% with the shortest.
template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInterface<DataFacadeT>
template <class DataFacadeT> class AlternativeRouting final : private BasicRoutingInterface<DataFacadeT>
{
typedef BasicRoutingInterface<DataFacadeT> super;
typedef typename DataFacadeT::EdgeData EdgeData;
typedef SearchEngineData::QueryHeap QueryHeap;
typedef std::pair<NodeID, NodeID> SearchSpaceEdge;
using super = BasicRoutingInterface<DataFacadeT>;
using EdgeData = typename DataFacadeT::EdgeData;
using QueryHeap = SearchEngineData::QueryHeap;
using SearchSpaceEdge = std::pair<NodeID, NodeID>;
struct RankedCandidateNode
{
@@ -96,6 +100,11 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
int upper_bound_to_shortest_path_distance = INVALID_EDGE_WEIGHT;
NodeID middle_node = SPECIAL_NODEID;
EdgeWeight min_edge_offset =
std::min(0, -phantom_node_pair.source_phantom.GetForwardWeightPlusOffset());
min_edge_offset = std::min(min_edge_offset,
-phantom_node_pair.source_phantom.GetReverseWeightPlusOffset());
if (phantom_node_pair.source_phantom.forward_node_id != SPECIAL_NODEID)
{
// SimpleLogger().Write(logDEBUG) << "fwd-a insert: " <<
@@ -107,8 +116,8 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
}
if (phantom_node_pair.source_phantom.reverse_node_id != SPECIAL_NODEID)
{
// SimpleLogger().Write(logDEBUG) << "fwd-b insert: " <<
// phantom_node_pair.source_phantom.reverse_node_id << ", w: " <<
// SimpleLogger().Write(logDEBUG) << "fwd-b insert: " <<
// phantom_node_pair.source_phantom.reverse_node_id << ", w: " <<
// -phantom_node_pair.source_phantom.GetReverseWeightPlusOffset();
forward_heap1.Insert(phantom_node_pair.source_phantom.reverse_node_id,
-phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
@@ -144,7 +153,8 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
&middle_node,
&upper_bound_to_shortest_path_distance,
via_node_candidate_list,
forward_search_space);
forward_search_space,
min_edge_offset);
}
if (0 < reverse_heap1.Size())
{
@@ -153,7 +163,8 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
&middle_node,
&upper_bound_to_shortest_path_distance,
via_node_candidate_list,
reverse_search_space);
reverse_search_space,
min_edge_offset);
}
}
@@ -162,7 +173,7 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
return;
}
sort_unique_resize(via_node_candidate_list);
osrm::sort_unique_resize(via_node_candidate_list);
std::vector<NodeID> packed_forward_path;
std::vector<NodeID> packed_reverse_path;
@@ -170,49 +181,58 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
super::RetrievePackedPathFromSingleHeap(forward_heap1, middle_node, packed_forward_path);
super::RetrievePackedPathFromSingleHeap(reverse_heap1, middle_node, packed_reverse_path);
// this set is is used as an indicator if a node is on the shortest path
std::unordered_set<NodeID> nodes_in_path(packed_forward_path.size() +
packed_reverse_path.size());
nodes_in_path.insert(packed_forward_path.begin(), packed_forward_path.end());
nodes_in_path.insert(middle_node);
nodes_in_path.insert(packed_reverse_path.begin(), packed_reverse_path.end());
std::unordered_map<NodeID, int> approximated_forward_sharing;
std::unordered_map<NodeID, int> approximated_reverse_sharing;
unsigned index_into_forward_path = 0;
// sweep over search space, compute forward sharing for each current edge (u,v)
for (const SearchSpaceEdge &current_edge : forward_search_space)
{
const NodeID u = current_edge.first;
const NodeID v = current_edge.second;
if ((packed_forward_path.size() < index_into_forward_path) &&
(current_edge == forward_search_space[index_into_forward_path]))
if (nodes_in_path.find(v) != nodes_in_path.end())
{
// current_edge is on shortest path => sharing(u):=queue.GetKey(u);
++index_into_forward_path;
approximated_forward_sharing[v] = forward_heap1.GetKey(u);
// current_edge is on shortest path => sharing(v):=queue.GetKey(v);
approximated_forward_sharing.emplace(v, forward_heap1.GetKey(v));
}
else
{
// sharing (s) = sharing (t)
approximated_forward_sharing[v] = approximated_forward_sharing[u];
// current edge is not on shortest path. Check if we know a value for the other
// endpoint
const auto sharing_of_u_iterator = approximated_forward_sharing.find(u);
if (sharing_of_u_iterator != approximated_forward_sharing.end())
{
approximated_forward_sharing.emplace(v, sharing_of_u_iterator->second);
}
}
}
unsigned index_into_reverse_path = 0;
// sweep over search space, compute backward sharing
for (const SearchSpaceEdge &current_edge : reverse_search_space)
{
const NodeID u = current_edge.first;
const NodeID v = current_edge.second;
if ((packed_reverse_path.size() < index_into_reverse_path) &&
(current_edge == reverse_search_space[index_into_reverse_path]))
if (nodes_in_path.find(v) != nodes_in_path.end())
{
// current_edge is on shortest path => sharing(u):=queue.GetKey(u);
++index_into_reverse_path;
approximated_reverse_sharing[v] = reverse_heap1.GetKey(u);
approximated_reverse_sharing.emplace(v, reverse_heap1.GetKey(v));
}
else
{
// sharing (s) = sharing (t)
const auto rev_iterator = approximated_reverse_sharing.find(u);
const int rev_sharing =
(rev_iterator != approximated_reverse_sharing.end()) ? rev_iterator->second : 0;
approximated_reverse_sharing[v] = rev_sharing;
// current edge is not on shortest path. Check if we know a value for the other
// endpoint
const auto sharing_of_u_iterator = approximated_reverse_sharing.find(u);
if (sharing_of_u_iterator != approximated_reverse_sharing.end())
{
approximated_reverse_sharing.emplace(v, sharing_of_u_iterator->second);
}
}
}
@@ -251,8 +271,6 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
}
}
// SimpleLogger().Write() << preselected_node_list.size() << " passed preselection";
std::vector<NodeID> &packed_shortest_path = packed_forward_path;
std::reverse(packed_shortest_path.begin(), packed_shortest_path.end());
packed_shortest_path.emplace_back(middle_node);
@@ -264,10 +282,13 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
for (const NodeID node : preselected_node_list)
{
int length_of_via_path = 0, sharing_of_via_path = 0;
ComputeLengthAndSharingOfViaPath(
node, &length_of_via_path, &sharing_of_via_path, packed_shortest_path);
const int maximum_allowed_sharing = static_cast<int>(
upper_bound_to_shortest_path_distance * VIAPATH_GAMMA);
ComputeLengthAndSharingOfViaPath(node,
&length_of_via_path,
&sharing_of_via_path,
packed_shortest_path,
min_edge_offset);
const int maximum_allowed_sharing =
static_cast<int>(upper_bound_to_shortest_path_distance * VIAPATH_GAMMA);
if (sharing_of_via_path <= maximum_allowed_sharing &&
length_of_via_path <= upper_bound_to_shortest_path_distance * (1 + VIAPATH_EPSILON))
{
@@ -289,7 +310,8 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
upper_bound_to_shortest_path_distance,
&length_of_via_path,
&s_v_middle,
&v_t_middle))
&v_t_middle,
min_edge_offset))
{
// select first admissable
selected_via_node = candidate.node;
@@ -329,8 +351,8 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
v_t_middle,
packed_alternate_path);
raw_route_data.alt_source_traversed_in_reverse.push_back(
(packed_alternate_path.front() != phantom_node_pair.source_phantom.forward_node_id));
raw_route_data.alt_source_traversed_in_reverse.push_back((
packed_alternate_path.front() != phantom_node_pair.source_phantom.forward_node_id));
raw_route_data.alt_target_traversed_in_reverse.push_back(
(packed_alternate_path.back() != phantom_node_pair.target_phantom.forward_node_id));
@@ -339,7 +361,9 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
packed_alternate_path, phantom_node_pair, raw_route_data.unpacked_alternative);
raw_route_data.alternative_path_length = length_of_via_path;
} else {
}
else
{
BOOST_ASSERT(raw_route_data.alternative_path_length == INVALID_EDGE_WEIGHT);
}
}
@@ -373,7 +397,8 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
inline void ComputeLengthAndSharingOfViaPath(const NodeID via_node,
int *real_length_of_via_path,
int *sharing_of_via_path,
const std::vector<NodeID> &packed_shortest_path)
const std::vector<NodeID> &packed_shortest_path,
const EdgeWeight min_edge_offset)
{
engine_working_data.InitializeOrClearSecondThreadLocalStorage(
super::facade->GetNumberOfNodes());
@@ -399,6 +424,7 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
existing_forward_heap,
&s_v_middle,
&upper_bound_s_v_path_length,
min_edge_offset,
false);
}
// compute path <v,..,t> by reusing backward search from node t
@@ -411,6 +437,7 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
existing_reverse_heap,
&v_t_middle,
&upper_bound_of_v_t_path_length,
min_edge_offset,
true);
}
*real_length_of_via_path = upper_bound_s_v_path_length + upper_bound_of_v_t_path_length;
@@ -428,48 +455,52 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
// partial unpacking, compute sharing
// First partially unpack s-->v until paths deviate, note length of common path.
const unsigned s_v_min_path_size =
const int64_t s_v_min_path_size =
std::min(packed_s_v_path.size(), packed_shortest_path.size()) - 1;
for (unsigned i = 0; i < s_v_min_path_size; ++i)
for (const int64_t current_node : osrm::irange<int64_t>(0, s_v_min_path_size))
{
if (packed_s_v_path[i] == packed_shortest_path[i] &&
packed_s_v_path[i + 1] == packed_shortest_path[i + 1])
if (packed_s_v_path[current_node] == packed_shortest_path[current_node] &&
packed_s_v_path[current_node + 1] == packed_shortest_path[current_node + 1])
{
EdgeID edgeID =
facade->FindEdgeInEitherDirection(packed_s_v_path[i], packed_s_v_path[i + 1]);
EdgeID edgeID = facade->FindEdgeInEitherDirection(
packed_s_v_path[current_node], packed_s_v_path[current_node + 1]);
*sharing_of_via_path += facade->GetEdgeData(edgeID).distance;
}
else
{
if (packed_s_v_path[i] == packed_shortest_path[i])
if (packed_s_v_path[current_node] == packed_shortest_path[current_node])
{
super::UnpackEdge(
packed_s_v_path[i], packed_s_v_path[i + 1], partially_unpacked_via_path);
super::UnpackEdge(packed_shortest_path[i],
packed_shortest_path[i + 1],
super::UnpackEdge(packed_s_v_path[current_node],
packed_s_v_path[current_node + 1],
partially_unpacked_via_path);
super::UnpackEdge(packed_shortest_path[current_node],
packed_shortest_path[current_node + 1],
partially_unpacked_shortest_path);
break;
}
}
}
// traverse partially unpacked edge and note common prefix
for (int i = 0,
packed_path_length = std::min(partially_unpacked_via_path.size(),
partially_unpacked_shortest_path.size()) -
1;
(i < packed_path_length) &&
(partially_unpacked_via_path[i] == partially_unpacked_shortest_path[i] &&
partially_unpacked_via_path[i + 1] == partially_unpacked_shortest_path[i + 1]);
++i)
const int64_t packed_path_length =
std::min(partially_unpacked_via_path.size(), partially_unpacked_shortest_path.size()) -
1;
for (int64_t current_node = 0;
(current_node < packed_path_length) &&
(partially_unpacked_via_path[current_node] ==
partially_unpacked_shortest_path[current_node] &&
partially_unpacked_via_path[current_node + 1] ==
partially_unpacked_shortest_path[current_node + 1]);
++current_node)
{
EdgeID edgeID = facade->FindEdgeInEitherDirection(partially_unpacked_via_path[i],
partially_unpacked_via_path[i + 1]);
*sharing_of_via_path += facade->GetEdgeData(edgeID).distance;
EdgeID selected_edge =
facade->FindEdgeInEitherDirection(partially_unpacked_via_path[current_node],
partially_unpacked_via_path[current_node + 1]);
*sharing_of_via_path += facade->GetEdgeData(selected_edge).distance;
}
// Second, partially unpack v-->t in reverse order until paths deviate and note lengths
int via_path_index = packed_v_t_path.size() - 1;
int shortest_path_index = packed_shortest_path.size() - 1;
int64_t via_path_index = packed_v_t_path.size() - 1;
int64_t shortest_path_index = packed_shortest_path.size() - 1;
for (; via_path_index > 0 && shortest_path_index > 0;
--via_path_index, --shortest_path_index)
{
@@ -572,11 +603,17 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
NodeID *middle_node,
int *upper_bound_to_shortest_path_distance,
std::vector<NodeID> &search_space_intersection,
std::vector<SearchSpaceEdge> &search_space) const
std::vector<SearchSpaceEdge> &search_space,
const EdgeWeight min_edge_offset) const
{
const NodeID node = forward_heap.DeleteMin();
const int distance = forward_heap.GetKey(node);
const int scaled_distance = static_cast<int>(distance / (1. + VIAPATH_EPSILON));
// const NodeID parentnode = forward_heap.GetData(node).parent;
// SimpleLogger().Write() << (is_forward_directed ? "[fwd] " : "[rev] ") << "settled edge ("
// << parentnode << "," << node << "), dist: " << distance;
const int scaled_distance =
static_cast<int>((distance + min_edge_offset) / (1. + VIAPATH_EPSILON));
if ((INVALID_EDGE_WEIGHT != *upper_bound_to_shortest_path_distance) &&
(scaled_distance > *upper_bound_to_shortest_path_distance))
{
@@ -589,7 +626,6 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
if (reverse_heap.WasInserted(node))
{
search_space_intersection.emplace_back(node);
const int new_distance = reverse_heap.GetKey(node) + distance;
if (new_distance < *upper_bound_to_shortest_path_distance)
{
@@ -597,6 +633,11 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
{
*middle_node = node;
*upper_bound_to_shortest_path_distance = new_distance;
// SimpleLogger().Write() << "accepted middle_node " << *middle_node << " at
// distance " << new_distance;
// } else {
// SimpleLogger().Write() << "discarded middle_node " << *middle_node << "
// at distance " << new_distance;
}
}
}
@@ -641,7 +682,8 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
const int length_of_shortest_path,
int *length_of_via_path,
NodeID *s_v_middle,
NodeID *v_t_middle) const
NodeID *v_t_middle,
const EdgeWeight min_edge_offset) const
{
new_forward_heap.Clear();
new_reverse_heap.Clear();
@@ -658,6 +700,7 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
existing_forward_heap,
s_v_middle,
&upper_bound_s_v_path_length,
min_edge_offset,
false);
}
@@ -676,6 +719,7 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
existing_reverse_heap,
v_t_middle,
&upper_bound_of_v_t_path_length,
min_edge_offset,
true);
}
@@ -844,11 +888,13 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
{
if (!forward_heap3.Empty())
{
super::RoutingStep(forward_heap3, reverse_heap3, &middle, &upper_bound, true);
super::RoutingStep(
forward_heap3, reverse_heap3, &middle, &upper_bound, min_edge_offset, true);
}
if (!reverse_heap3.Empty())
{
super::RoutingStep(reverse_heap3, forward_heap3, &middle, &upper_bound, false);
super::RoutingStep(
reverse_heap3, forward_heap3, &middle, &upper_bound, min_edge_offset, false);
}
}
return (upper_bound <= t_test_path_length);
+53 -51
View File
@@ -31,8 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../DataStructures/RawRouteData.h"
#include "../DataStructures/SearchEngineData.h"
#include "../DataStructures/TurnInstructions.h"
#include "../Util/ContainerUtils.h"
#include "../Util/SimpleLogger.h"
// #include "../Util/simple_logger.hpp.h"
#include <boost/assert.hpp>
@@ -63,10 +62,15 @@ template <class DataFacadeT> class BasicRoutingInterface
SearchEngineData::QueryHeap &reverse_heap,
NodeID *middle_node_id,
int *upper_bound,
const int min_edge_offset,
const bool forward_direction) const
{
const NodeID node = forward_heap.DeleteMin();
const int distance = forward_heap.GetKey(node);
// const NodeID parentnode = forward_heap.GetData(node).parent;
// SimpleLogger().Write() << (forward_direction ? "[fwd] " : "[rev] ") << "settled edge (" << parentnode << "," << node << "), dist: " << distance;
if (reverse_heap.WasInserted(node))
{
const int new_distance = reverse_heap.GetKey(node) + distance;
@@ -76,18 +80,22 @@ template <class DataFacadeT> class BasicRoutingInterface
{
*middle_node_id = node;
*upper_bound = new_distance;
// SimpleLogger().Write() << "accepted middle node " << node << " at distance " << new_distance;
// } else {
// SimpleLogger().Write() << "discared middle node " << node << " at distance " << new_distance;
}
}
}
if (distance > *upper_bound)
if (distance + min_edge_offset > *upper_bound)
{
// SimpleLogger().Write() << "min_edge_offset: " << min_edge_offset;
forward_heap.DeleteAll();
return;
}
// Stalling
for (auto edge : facade->GetAdjacentEdgeRange(node))
for (const auto edge : facade->GetAdjacentEdgeRange(node))
{
const EdgeData &data = facade->GetEdgeData(edge);
const bool reverse_flag = ((!forward_direction) ? data.forward : data.backward);
@@ -108,7 +116,7 @@ template <class DataFacadeT> class BasicRoutingInterface
}
}
for (auto edge : facade->GetAdjacentEdgeRange(node))
for (const auto edge : facade->GetAdjacentEdgeRange(node))
{
const EdgeData &data = facade->GetEdgeData(edge);
bool forward_directionFlag = (forward_direction ? data.forward : data.backward);
@@ -171,8 +179,8 @@ template <class DataFacadeT> class BasicRoutingInterface
// facade->FindEdge does not suffice here in case of shortcuts.
// The above explanation unclear? Think!
EdgeID smaller_edge_id = SPECIAL_EDGEID;
int edge_weight = INT_MAX;
for (auto edge_id : facade->GetAdjacentEdgeRange(edge.first))
int edge_weight = std::numeric_limits<EdgeWeight>::max();
for (const auto edge_id : facade->GetAdjacentEdgeRange(edge.first))
{
const int weight = facade->GetEdgeData(edge_id).distance;
if ((facade->GetTarget(edge_id) == edge.second) && (weight < edge_weight) &&
@@ -192,7 +200,7 @@ template <class DataFacadeT> class BasicRoutingInterface
*/
if (SPECIAL_EDGEID == smaller_edge_id)
{
for (auto edge_id : facade->GetAdjacentEdgeRange(edge.second))
for (const auto edge_id : facade->GetAdjacentEdgeRange(edge.second))
{
const int weight = facade->GetEdgeData(edge_id).distance;
if ((facade->GetTarget(edge_id) == edge.first) && (weight < edge_weight) &&
@@ -218,6 +226,8 @@ template <class DataFacadeT> class BasicRoutingInterface
BOOST_ASSERT_MSG(!ed.shortcut, "original edge flagged as shortcut");
unsigned name_index = facade->GetNameIndexFromEdgeID(ed.id);
const TurnInstruction turn_instruction = facade->GetTurnInstructionForEdgeID(ed.id);
const TravelMode travel_mode = facade->GetTravelModeForEdgeID(ed.id);
if (!facade->EdgeIsCompressed(ed.id))
{
@@ -225,7 +235,8 @@ template <class DataFacadeT> class BasicRoutingInterface
unpacked_path.emplace_back(facade->GetGeometryIndexForEdgeID(ed.id),
name_index,
turn_instruction,
ed.distance);
ed.distance,
travel_mode);
}
else
{
@@ -233,20 +244,20 @@ template <class DataFacadeT> class BasicRoutingInterface
facade->GetUncompressedGeometry(facade->GetGeometryIndexForEdgeID(ed.id),
id_vector);
const int start_index =
const std::size_t start_index =
(unpacked_path.empty()
? ((start_traversed_in_reverse)
? id_vector.size() -
phantom_node_pair.source_phantom.fwd_segment_position - 1
: phantom_node_pair.source_phantom.fwd_segment_position)
: 0);
const int end_index = id_vector.size();
const std::size_t end_index = id_vector.size();
BOOST_ASSERT(start_index >= 0);
BOOST_ASSERT(start_index <= end_index);
for (int i = start_index; i < end_index; ++i)
for (std::size_t i = start_index; i < end_index; ++i)
{
unpacked_path.emplace_back(id_vector[i], name_index, TurnInstruction::NoTurn, 0);
unpacked_path.emplace_back(id_vector[i], name_index, TurnInstruction::NoTurn, 0, travel_mode);
}
unpacked_path.back().turn_instruction = turn_instruction;
unpacked_path.back().segment_duration = ed.distance;
@@ -258,42 +269,43 @@ template <class DataFacadeT> class BasicRoutingInterface
std::vector<unsigned> id_vector;
facade->GetUncompressedGeometry(phantom_node_pair.target_phantom.packed_geometry_id,
id_vector);
if (target_traversed_in_reverse)
{
std::reverse(id_vector.begin(), id_vector.end());
}
const bool is_local_path = (phantom_node_pair.source_phantom.packed_geometry_id ==
phantom_node_pair.target_phantom.packed_geometry_id) &&
unpacked_path.empty();
int start_index = 0;
int end_index = phantom_node_pair.target_phantom.fwd_segment_position;
if (target_traversed_in_reverse)
{
end_index =
id_vector.size() - phantom_node_pair.target_phantom.fwd_segment_position;
}
std::size_t start_index = 0;
if (is_local_path)
{
start_index = phantom_node_pair.source_phantom.fwd_segment_position;
end_index = phantom_node_pair.target_phantom.fwd_segment_position;
if (target_traversed_in_reverse)
{
start_index =
id_vector.size() - phantom_node_pair.source_phantom.fwd_segment_position;
end_index =
id_vector.size() - phantom_node_pair.target_phantom.fwd_segment_position;
}
}
BOOST_ASSERT(start_index >= 0);
for (int i = start_index; i != end_index; (start_index < end_index ? ++i : --i))
std::size_t end_index = phantom_node_pair.target_phantom.fwd_segment_position;
if (target_traversed_in_reverse)
{
BOOST_ASSERT(i >= -1);
std::reverse(id_vector.begin(), id_vector.end());
end_index =
id_vector.size() - phantom_node_pair.target_phantom.fwd_segment_position;
}
if (start_index > end_index)
{
start_index = std::min(start_index, id_vector.size()-1);
}
for (std::size_t i = start_index; i != end_index; (start_index < end_index ? ++i : --i))
{
BOOST_ASSERT(i < id_vector.size());
BOOST_ASSERT(phantom_node_pair.target_phantom.forward_travel_mode>0 );
unpacked_path.emplace_back(PathData{id_vector[i],
phantom_node_pair.target_phantom.name_id,
TurnInstruction::NoTurn,
0});
phantom_node_pair.target_phantom.name_id,
TurnInstruction::NoTurn,
0,
phantom_node_pair.target_phantom.forward_travel_mode});
}
}
@@ -304,8 +316,8 @@ template <class DataFacadeT> class BasicRoutingInterface
// the last node.
if (unpacked_path.size() > 1)
{
const unsigned last_index = unpacked_path.size() - 1;
const unsigned second_to_last_index = last_index - 1;
const std::size_t last_index = unpacked_path.size() - 1;
const std::size_t second_to_last_index = last_index - 1;
// looks like a trivially true check but tests for underflow
BOOST_ASSERT(last_index > second_to_last_index);
@@ -330,8 +342,8 @@ template <class DataFacadeT> class BasicRoutingInterface
recursion_stack.pop();
EdgeID smaller_edge_id = SPECIAL_EDGEID;
int edge_weight = INT_MAX;
for (auto edge_id : facade->GetAdjacentEdgeRange(edge.first))
int edge_weight = std::numeric_limits<EdgeWeight>::max();
for (const auto edge_id : facade->GetAdjacentEdgeRange(edge.first))
{
const int weight = facade->GetEdgeData(edge_id).distance;
if ((facade->GetTarget(edge_id) == edge.second) && (weight < edge_weight) &&
@@ -344,7 +356,7 @@ template <class DataFacadeT> class BasicRoutingInterface
if (SPECIAL_EDGEID == smaller_edge_id)
{
for (auto edge_id : facade->GetAdjacentEdgeRange(edge.second))
for (const auto edge_id : facade->GetAdjacentEdgeRange(edge.second))
{
const int weight = facade->GetEdgeData(edge_id).distance;
if ((facade->GetTarget(edge_id) == edge.first) && (weight < edge_weight) &&
@@ -355,7 +367,7 @@ template <class DataFacadeT> class BasicRoutingInterface
}
}
}
BOOST_ASSERT_MSG(edge_weight != INT_MAX, "edge weight invalid");
BOOST_ASSERT_MSG(edge_weight != std::numeric_limits<EdgeWeight>::max(), "edge weight invalid");
const EdgeData &ed = facade->GetEdgeData(smaller_edge_id);
if (ed.shortcut)
@@ -379,20 +391,10 @@ template <class DataFacadeT> class BasicRoutingInterface
const NodeID middle_node_id,
std::vector<NodeID> &packed_path) const
{
NodeID current_node_id = middle_node_id;
while (current_node_id != forward_heap.GetData(current_node_id).parent)
{
current_node_id = forward_heap.GetData(current_node_id).parent;
packed_path.emplace_back(current_node_id);
}
RetrievePackedPathFromSingleHeap(forward_heap, middle_node_id, packed_path);
std::reverse(packed_path.begin(), packed_path.end());
packed_path.emplace_back(middle_node_id);
current_node_id = middle_node_id;
while (current_node_id != reverse_heap.GetData(current_node_id).parent)
{
current_node_id = reverse_heap.GetData(current_node_id).parent;
packed_path.emplace_back(current_node_id);
}
RetrievePackedPathFromSingleHeap(reverse_heap, middle_node_id, packed_path);
}
inline void RetrievePackedPathFromSingleHeap(const SearchEngineData::QueryHeap &search_heap,
+4 -4
View File
@@ -39,10 +39,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <unordered_map>
#include <vector>
template <class DataFacadeT> class ManyToManyRouting : public BasicRoutingInterface<DataFacadeT>
template <class DataFacadeT> class ManyToManyRouting final : public BasicRoutingInterface<DataFacadeT>
{
typedef BasicRoutingInterface<DataFacadeT> super;
typedef SearchEngineData::QueryHeap QueryHeap;
using super = BasicRoutingInterface<DataFacadeT>;
using QueryHeap = SearchEngineData::QueryHeap;
SearchEngineData &engine_working_data;
struct NodeBucket
@@ -54,7 +54,7 @@ template <class DataFacadeT> class ManyToManyRouting : public BasicRoutingInterf
{
}
};
typedef std::unordered_map<NodeID, std::vector<NodeBucket>> SearchSpaceWithBuckets;
using SearchSpaceWithBuckets = std::unordered_map<NodeID, std::vector<NodeBucket>>;
public:
ManyToManyRouting(DataFacadeT *facade, SearchEngineData &engine_working_data)
+59 -42
View File
@@ -31,13 +31,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/assert.hpp>
#include "BasicRoutingInterface.h"
#include "../DataStructures/Range.h"
#include "../DataStructures/SearchEngineData.h"
#include "../typedefs.h"
template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInterface<DataFacadeT>
template <class DataFacadeT> class ShortestPathRouting final : public BasicRoutingInterface<DataFacadeT>
{
typedef BasicRoutingInterface<DataFacadeT> super;
typedef SearchEngineData::QueryHeap QueryHeap;
using super = BasicRoutingInterface<DataFacadeT>;
using QueryHeap = SearchEngineData::QueryHeap;
SearchEngineData &engine_working_data;
public:
@@ -49,14 +50,15 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
~ShortestPathRouting() {}
void operator()(const std::vector<PhantomNodes> &phantom_nodes_vector,
const std::vector<bool> &uturn_indicators,
RawRouteData &raw_route_data) const
{
int distance1 = 0;
int distance2 = 0;
bool search_from_1st_node = true;
bool search_from_2nd_node = true;
NodeID middle1 = UINT_MAX;
NodeID middle2 = UINT_MAX;
NodeID middle1 = SPECIAL_NODEID;
NodeID middle2 = SPECIAL_NODEID;
std::vector<std::vector<NodeID>> packed_legs1(phantom_nodes_vector.size());
std::vector<std::vector<NodeID>> packed_legs2(phantom_nodes_vector.size());
@@ -72,7 +74,7 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
QueryHeap &forward_heap2 = *(engine_working_data.forwardHeap2);
QueryHeap &reverse_heap2 = *(engine_working_data.backwardHeap2);
int current_leg = 0;
std::size_t current_leg = 0;
// Get distance to next pair of target nodes.
for (const PhantomNodes &phantom_node_pair : phantom_nodes_vector)
{
@@ -80,36 +82,50 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
forward_heap2.Clear();
reverse_heap1.Clear();
reverse_heap2.Clear();
int local_upper_bound1 = INT_MAX;
int local_upper_bound2 = INT_MAX;
int local_upper_bound1 = INVALID_EDGE_WEIGHT;
int local_upper_bound2 = INVALID_EDGE_WEIGHT;
middle1 = UINT_MAX;
middle2 = UINT_MAX;
middle1 = SPECIAL_NODEID;
middle2 = SPECIAL_NODEID;
const bool allow_u_turn = current_leg > 0 && uturn_indicators.size() > current_leg && uturn_indicators[current_leg-1];
EdgeWeight min_edge_offset = 0;
// insert new starting nodes into forward heap, adjusted by previous distances.
if (search_from_1st_node &&
if ((allow_u_turn || search_from_1st_node) &&
phantom_node_pair.source_phantom.forward_node_id != SPECIAL_NODEID)
{
forward_heap1.Insert(
phantom_node_pair.source_phantom.forward_node_id,
distance1 - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(),
(allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(),
phantom_node_pair.source_phantom.forward_node_id);
min_edge_offset = std::min(min_edge_offset, (allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset());
// SimpleLogger().Write(logDEBUG) << "fwd-a2 insert: " << phantom_node_pair.source_phantom.forward_node_id << ", w: " << (allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset();
forward_heap2.Insert(
phantom_node_pair.source_phantom.forward_node_id,
distance1 - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(),
(allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(),
phantom_node_pair.source_phantom.forward_node_id);
min_edge_offset = std::min(min_edge_offset, (allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset());
// SimpleLogger().Write(logDEBUG) << "fwd-b2 insert: " << phantom_node_pair.source_phantom.forward_node_id << ", w: " << (allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset();
}
if (search_from_2nd_node &&
if ((allow_u_turn || search_from_2nd_node) &&
phantom_node_pair.source_phantom.reverse_node_id != SPECIAL_NODEID)
{
forward_heap1.Insert(
phantom_node_pair.source_phantom.reverse_node_id,
distance2 - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
(allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
phantom_node_pair.source_phantom.reverse_node_id);
min_edge_offset = std::min(min_edge_offset, (allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset());
// SimpleLogger().Write(logDEBUG) << "fwd-a2 insert: " << phantom_node_pair.source_phantom.reverse_node_id <<
// ", w: " << (allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset();
forward_heap2.Insert(
phantom_node_pair.source_phantom.reverse_node_id,
distance2 - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
(allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
phantom_node_pair.source_phantom.reverse_node_id);
min_edge_offset = std::min(min_edge_offset, (allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset());
// SimpleLogger().Write(logDEBUG) << "fwd-b2 insert: " << phantom_node_pair.source_phantom.reverse_node_id <<
// ", w: " << (allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset();
}
// insert new backward nodes into backward heap, unadjusted.
@@ -118,27 +134,31 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
reverse_heap1.Insert(phantom_node_pair.target_phantom.forward_node_id,
phantom_node_pair.target_phantom.GetForwardWeightPlusOffset(),
phantom_node_pair.target_phantom.forward_node_id);
}
// SimpleLogger().Write(logDEBUG) << "rev-a insert: " << phantom_node_pair.target_phantom.forward_node_id <<
// ", w: " << phantom_node_pair.target_phantom.GetForwardWeightPlusOffset();
}
if (phantom_node_pair.target_phantom.reverse_node_id != SPECIAL_NODEID)
{
reverse_heap2.Insert(phantom_node_pair.target_phantom.reverse_node_id,
phantom_node_pair.target_phantom.GetReverseWeightPlusOffset(),
phantom_node_pair.target_phantom.reverse_node_id);
// SimpleLogger().Write(logDEBUG) << "rev-a insert: " << phantom_node_pair.target_phantom.reverse_node_id <<
// ", w: " << phantom_node_pair.target_phantom.GetReverseWeightPlusOffset();
}
// run two-Target Dijkstra routing step.
while (0 < (forward_heap1.Size() + reverse_heap1.Size()))
{
if (0 < forward_heap1.Size())
if (!forward_heap1.Empty())
{
super::RoutingStep(
forward_heap1, reverse_heap1, &middle1, &local_upper_bound1, true);
forward_heap1, reverse_heap1, &middle1, &local_upper_bound1, min_edge_offset, true);
}
if (0 < reverse_heap1.Size())
if (!reverse_heap1.Empty())
{
super::RoutingStep(
reverse_heap1, forward_heap1, &middle1, &local_upper_bound1, false);
reverse_heap1, forward_heap1, &middle1, &local_upper_bound1, min_edge_offset, false);
}
}
@@ -146,15 +166,15 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
{
while (0 < (forward_heap2.Size() + reverse_heap2.Size()))
{
if (0 < forward_heap2.Size())
if (!forward_heap2.Empty())
{
super::RoutingStep(
forward_heap2, reverse_heap2, &middle2, &local_upper_bound2, true);
forward_heap2, reverse_heap2, &middle2, &local_upper_bound2, min_edge_offset, true);
}
if (0 < reverse_heap2.Size())
if (!reverse_heap2.Empty())
{
super::RoutingStep(
reverse_heap2, forward_heap2, &middle2, &local_upper_bound2, false);
reverse_heap2, forward_heap2, &middle2, &local_upper_bound2, min_edge_offset, false);
}
}
}
@@ -180,7 +200,7 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
}
// Was at most one of the two paths not found?
BOOST_ASSERT_MSG((INT_MAX != distance1 || INT_MAX != distance2), "no path found");
BOOST_ASSERT_MSG((INVALID_EDGE_WEIGHT != distance1 || INVALID_EDGE_WEIGHT != distance2), "no path found");
// Unpack paths if they exist
std::vector<NodeID> temporary_packed_leg1;
@@ -202,15 +222,17 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
}
// if one of the paths was not found, replace it with the other one.
if (temporary_packed_leg1.empty())
if ((allow_u_turn && local_upper_bound1 > local_upper_bound2) || temporary_packed_leg1.empty())
{
temporary_packed_leg1.clear();
temporary_packed_leg1.insert(temporary_packed_leg1.end(),
temporary_packed_leg2.begin(),
temporary_packed_leg2.end());
local_upper_bound1 = local_upper_bound2;
}
if (temporary_packed_leg2.empty())
if ((allow_u_turn && local_upper_bound2 > local_upper_bound1) || temporary_packed_leg2.empty())
{
temporary_packed_leg2.clear();
temporary_packed_leg2.insert(temporary_packed_leg2.end(),
temporary_packed_leg1.begin(),
temporary_packed_leg1.end());
@@ -223,7 +245,7 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
BOOST_ASSERT((0 == current_leg) || !packed_legs1[current_leg - 1].empty());
BOOST_ASSERT((0 == current_leg) || !packed_legs2[current_leg - 1].empty());
if (0 < current_leg)
if (!allow_u_turn && 0 < current_leg)
{
const NodeID end_id_of_segment1 = packed_legs1[current_leg - 1].back();
const NodeID end_id_of_segment2 = packed_legs2[current_leg - 1].back();
@@ -236,13 +258,8 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
std::swap(temporary_packed_leg1, temporary_packed_leg2);
std::swap(local_upper_bound1, local_upper_bound2);
}
}
// remove the shorter path if both legs end at the same segment
if (0 < current_leg)
{
const NodeID start_id_of_leg1 = temporary_packed_leg1.front();
const NodeID start_id_of_leg2 = temporary_packed_leg2.front();
// remove the shorter path if both legs end at the same segment
if (start_id_of_leg1 == start_id_of_leg2)
{
const NodeID last_id_of_packed_legs1 = packed_legs1[current_leg - 1].back();
@@ -270,7 +287,7 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
temporary_packed_leg2.end());
BOOST_ASSERT(packed_legs2[current_leg].size() == temporary_packed_leg2.size());
if ((packed_legs1[current_leg].back() == packed_legs2[current_leg].back()) &&
if (!allow_u_turn && (packed_legs1[current_leg].back() == packed_legs2[current_leg].back()) &&
phantom_node_pair.target_phantom.isBidirected())
{
const NodeID last_node_id = packed_legs2[current_leg].back();
@@ -292,24 +309,24 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
}
raw_route_data.unpacked_path_segments.resize(packed_legs1.size());
for (unsigned i = 0; i < packed_legs1.size(); ++i)
for (const std::size_t index : osrm::irange<std::size_t>(0, packed_legs1.size()))
{
BOOST_ASSERT(!phantom_nodes_vector.empty());
BOOST_ASSERT(packed_legs1.size() == raw_route_data.unpacked_path_segments.size());
PhantomNodes unpack_phantom_node_pair = phantom_nodes_vector[i];
PhantomNodes unpack_phantom_node_pair = phantom_nodes_vector[index];
super::UnpackPath(
// -- packed input
packed_legs1[i],
packed_legs1[index],
// -- start and end of (sub-)route
unpack_phantom_node_pair,
// -- unpacked output
raw_route_data.unpacked_path_segments[i]);
raw_route_data.unpacked_path_segments[index]);
raw_route_data.source_traversed_in_reverse.push_back(
(packed_legs1[i].front() != phantom_nodes_vector[i].source_phantom.forward_node_id));
(packed_legs1[index].front() != phantom_nodes_vector[index].source_phantom.forward_node_id));
raw_route_data.target_traversed_in_reverse.push_back(
(packed_legs1[i].back() != phantom_nodes_vector[i].target_phantom.forward_node_id));
(packed_legs1[index].back() != phantom_nodes_vector[index].target_phantom.forward_node_id));
}
raw_route_data.shortest_path_length = std::min(distance1, distance2);
}
+6 -3
View File
@@ -39,8 +39,8 @@ struct APIGrammar : qi::grammar<Iterator>
{
explicit APIGrammar(HandlerT * h) : APIGrammar::base_type(api_call), handler(h)
{
api_call = qi::lit('/') >> string[boost::bind(&HandlerT::setService, handler, ::_1)] >> *(query);
query = ('?') >> (+(zoom | output | jsonp | checksum | location | hint | cmp | language | instruction | geometry | alt_route | old_API) ) ;
api_call = qi::lit('/') >> string[boost::bind(&HandlerT::setService, handler, ::_1)] >> *(query) >> -(uturns);
query = ('?') >> (+(zoom | output | jsonp | checksum | location | hint | u | cmp | language | instruction | geometry | alt_route | old_API | num_results) ) ;
zoom = (-qi::lit('&')) >> qi::lit('z') >> '=' >> qi::short_[boost::bind(&HandlerT::setZoomLevel, handler, ::_1)];
output = (-qi::lit('&')) >> qi::lit("output") >> '=' >> string[boost::bind(&HandlerT::setOutputFormat, handler, ::_1)];
@@ -51,9 +51,12 @@ struct APIGrammar : qi::grammar<Iterator>
cmp = (-qi::lit('&')) >> qi::lit("compression") >> '=' >> qi::bool_[boost::bind(&HandlerT::setCompressionFlag, handler, ::_1)];
location = (-qi::lit('&')) >> qi::lit("loc") >> '=' >> (qi::double_ >> qi::lit(',') >> qi::double_)[boost::bind(&HandlerT::addCoordinate, handler, ::_1)];
hint = (-qi::lit('&')) >> qi::lit("hint") >> '=' >> stringwithDot[boost::bind(&HandlerT::addHint, handler, ::_1)];
u = (-qi::lit('&')) >> qi::lit("u") >> '=' >> qi::bool_[boost::bind(&HandlerT::setUTurn, handler, ::_1)];
uturns = (-qi::lit('&')) >> qi::lit("uturns") >> '=' >> qi::bool_[boost::bind(&HandlerT::setAllUTurns, handler, ::_1)];
language = (-qi::lit('&')) >> qi::lit("hl") >> '=' >> string[boost::bind(&HandlerT::setLanguage, handler, ::_1)];
alt_route = (-qi::lit('&')) >> qi::lit("alt") >> '=' >> qi::bool_[boost::bind(&HandlerT::setAlternateRouteFlag, handler, ::_1)];
old_API = (-qi::lit('&')) >> qi::lit("geomformat") >> '=' >> string[boost::bind(&HandlerT::setDeprecatedAPIFlag, handler, ::_1)];
num_results = (-qi::lit('&')) >> qi::lit("num_results") >> '=' >> qi::short_[boost::bind(&HandlerT::setNumberOfResults, handler, ::_1)];
string = +(qi::char_("a-zA-Z"));
stringwithDot = +(qi::char_("a-zA-Z0-9_.-"));
@@ -63,7 +66,7 @@ struct APIGrammar : qi::grammar<Iterator>
qi::rule<Iterator> api_call, query;
qi::rule<Iterator, std::string()> service, zoom, output, string, jsonp, checksum, location, hint,
stringwithDot, stringwithPercent, language, instruction, geometry,
cmp, alt_route, old_API;
cmp, alt_route, u, uturns, old_API, num_results;
HandlerT * handler;
};
+13 -11
View File
@@ -33,18 +33,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../../DataStructures/EdgeBasedNode.h"
#include "../../DataStructures/ImportNode.h"
#include "../../DataStructures/PhantomNodes.h"
#include "../../DataStructures/Range.h"
#include "../../DataStructures/TurnInstructions.h"
#include "../../Util/OSRMException.h"
#include "../../Util/StringUtil.h"
#include "../../typedefs.h"
#include <boost/range/irange.hpp>
#include <osrm/Coordinate.h>
#include <string>
typedef decltype(boost::irange(0u,0u)) EdgeRange;
typedef osrm::range<EdgeID> EdgeRange;
template <class EdgeDataT> class BaseDataFacade
{
@@ -63,9 +62,9 @@ template <class EdgeDataT> class BaseDataFacade
virtual NodeID GetTarget(const EdgeID e) const = 0;
virtual EdgeDataT &GetEdgeData(const EdgeID e) = 0;
// virtual EdgeDataT &GetEdgeData(const EdgeID e) = 0;
// virtual const EdgeDataT &GetEdgeData( const EdgeID e ) const = 0;
virtual const EdgeDataT &GetEdgeData(const EdgeID e) const = 0;
virtual EdgeID BeginEdges(const NodeID n) const = 0;
@@ -93,18 +92,21 @@ template <class EdgeDataT> class BaseDataFacade
virtual TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const = 0;
virtual TravelMode GetTravelModeForEdgeID(const unsigned id) const = 0;
virtual bool LocateClosestEndPointForCoordinate(const FixedPointCoordinate &input_coordinate,
FixedPointCoordinate &result,
const unsigned zoom_level = 18) const = 0;
const unsigned zoom_level = 18) = 0;
virtual bool FindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
PhantomNode &resulting_phantom_node,
const unsigned zoom_level) const = 0;
const unsigned zoom_level) = 0;
virtual bool IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
std::vector<PhantomNode> &resulting_phantom_node_vector,
const unsigned zoom_level,
const unsigned number_of_results) const = 0;
virtual bool
IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
std::vector<PhantomNode> &resulting_phantom_node_vector,
const unsigned zoom_level,
const unsigned number_of_results) = 0;
virtual unsigned GetCheckSum() const = 0;
+64 -41
View File
@@ -42,7 +42,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../../Util/BoostFileSystemFix.h"
#include "../../Util/GraphLoader.h"
#include "../../Util/ProgramOptions.h"
#include "../../Util/SimpleLogger.h"
#include "../../Util/simple_logger.hpp"
#include <osrm/Coordinate.h>
@@ -66,13 +66,16 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
ShM<NodeID, false>::vector m_via_node_list;
ShM<unsigned, false>::vector m_name_ID_list;
ShM<TurnInstruction, false>::vector m_turn_instruction_list;
ShM<TravelMode, false>::vector m_travel_mode_list;
ShM<char, false>::vector m_names_char_list;
ShM<bool, false>::vector m_egde_is_compressed;
ShM<bool, false>::vector m_edge_is_compressed;
ShM<unsigned, false>::vector m_geometry_indices;
ShM<unsigned, false>::vector m_geometry_list;
std::shared_ptr<StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, false>::vector, false>>
m_static_rtree;
boost::thread_specific_ptr<
StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, false>::vector, false>> m_static_rtree;
boost::filesystem::path ram_index_path;
boost::filesystem::path file_index_path;
RangeTable<16, false> m_name_table;
void LoadTimestamp(const boost::filesystem::path &timestamp_path)
@@ -143,7 +146,8 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
m_via_node_list.resize(number_of_edges);
m_name_ID_list.resize(number_of_edges);
m_turn_instruction_list.resize(number_of_edges);
m_egde_is_compressed.resize(number_of_edges);
m_travel_mode_list.resize(number_of_edges);
m_edge_is_compressed.resize(number_of_edges);
unsigned compressed = 0;
@@ -154,8 +158,9 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
m_via_node_list[i] = current_edge_data.via_node;
m_name_ID_list[i] = current_edge_data.name_id;
m_turn_instruction_list[i] = current_edge_data.turn_instruction;
m_egde_is_compressed[i] = current_edge_data.compressed_geometry;
if (m_egde_is_compressed[i])
m_travel_mode_list[i] = current_edge_data.travel_mode;
m_edge_is_compressed[i] = current_edge_data.compressed_geometry;
if (m_edge_is_compressed[i])
{
++compressed;
}
@@ -192,13 +197,12 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
geometry_stream.close();
}
void LoadRTree(const boost::filesystem::path &ram_index_path,
const boost::filesystem::path &file_index_path)
void LoadRTree()
{
BOOST_ASSERT_MSG(!m_coordinate_list->empty(), "coordinates must be loaded before r-tree");
m_static_rtree = std::make_shared<StaticRTree<RTreeLeaf>>(
ram_index_path, file_index_path, m_coordinate_list);
m_static_rtree.reset(
new StaticRTree<RTreeLeaf>(ram_index_path, file_index_path, m_coordinate_list));
}
void LoadStreetNames(const boost::filesystem::path &names_file)
@@ -220,7 +224,7 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
}
public:
~InternalDataFacade()
virtual ~InternalDataFacade()
{
delete m_query_graph;
m_static_rtree.reset();
@@ -266,10 +270,10 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
const boost::filesystem::path &timestamp_path = paths_iterator->second;
paths_iterator = server_paths.find("ramindex");
BOOST_ASSERT(server_paths.end() != paths_iterator);
const boost::filesystem::path &ram_index_path = paths_iterator->second;
ram_index_path = paths_iterator->second;
paths_iterator = server_paths.find("fileindex");
BOOST_ASSERT(server_paths.end() != paths_iterator);
const boost::filesystem::path &file_index_path = paths_iterator->second;
file_index_path = paths_iterator->second;
paths_iterator = server_paths.find("nodesdata");
BOOST_ASSERT(server_paths.end() != paths_iterator);
const boost::filesystem::path &nodes_data_path = paths_iterator->second;
@@ -287,7 +291,7 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
SimpleLogger().Write() << "loading graph data";
AssertPathExists(hsgr_path);
LoadGraph(hsgr_path);
SimpleLogger().Write() << "loading egde information";
SimpleLogger().Write() << "loading edge information";
AssertPathExists(nodes_data_path);
AssertPathExists(edges_data_path);
LoadNodeAndEdgeInformation(nodes_data_path, edges_data_path);
@@ -297,7 +301,6 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
SimpleLogger().Write() << "loading r-tree";
AssertPathExists(ram_index_path);
AssertPathExists(file_index_path);
LoadRTree(ram_index_path, file_index_path);
SimpleLogger().Write() << "loading timestamp";
LoadTimestamp(timestamp_path);
SimpleLogger().Write() << "loading street names";
@@ -306,68 +309,83 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
}
// search graph access
unsigned GetNumberOfNodes() const { return m_query_graph->GetNumberOfNodes(); }
unsigned GetNumberOfNodes() const final { return m_query_graph->GetNumberOfNodes(); }
unsigned GetNumberOfEdges() const { return m_query_graph->GetNumberOfEdges(); }
unsigned GetNumberOfEdges() const final { return m_query_graph->GetNumberOfEdges(); }
unsigned GetOutDegree(const NodeID n) const { return m_query_graph->GetOutDegree(n); }
unsigned GetOutDegree(const NodeID n) const final { return m_query_graph->GetOutDegree(n); }
NodeID GetTarget(const EdgeID e) const { return m_query_graph->GetTarget(e); }
NodeID GetTarget(const EdgeID e) const final { return m_query_graph->GetTarget(e); }
EdgeDataT &GetEdgeData(const EdgeID e) { return m_query_graph->GetEdgeData(e); }
// EdgeDataT &GetEdgeData(const EdgeID e) final { return m_query_graph->GetEdgeData(e); }
const EdgeDataT &GetEdgeData(const EdgeID e) const { return m_query_graph->GetEdgeData(e); }
EdgeDataT &GetEdgeData(const EdgeID e) const final { return m_query_graph->GetEdgeData(e); }
EdgeID BeginEdges(const NodeID n) const { return m_query_graph->BeginEdges(n); }
EdgeID BeginEdges(const NodeID n) const final { return m_query_graph->BeginEdges(n); }
EdgeID EndEdges(const NodeID n) const { return m_query_graph->EndEdges(n); }
EdgeID EndEdges(const NodeID n) const final { return m_query_graph->EndEdges(n); }
EdgeRange GetAdjacentEdgeRange(const NodeID node) const
EdgeRange GetAdjacentEdgeRange(const NodeID node) const final
{
return m_query_graph->GetAdjacentEdgeRange(node);
};
// searches for a specific edge
EdgeID FindEdge(const NodeID from, const NodeID to) const
EdgeID FindEdge(const NodeID from, const NodeID to) const final
{
return m_query_graph->FindEdge(from, to);
}
EdgeID FindEdgeInEitherDirection(const NodeID from, const NodeID to) const
EdgeID FindEdgeInEitherDirection(const NodeID from, const NodeID to) const final
{
return m_query_graph->FindEdgeInEitherDirection(from, to);
}
EdgeID FindEdgeIndicateIfReverse(const NodeID from, const NodeID to, bool &result) const
EdgeID FindEdgeIndicateIfReverse(const NodeID from, const NodeID to, bool &result) const final
{
return m_query_graph->FindEdgeIndicateIfReverse(from, to, result);
}
// node and edge information access
FixedPointCoordinate GetCoordinateOfNode(const unsigned id) const
FixedPointCoordinate GetCoordinateOfNode(const unsigned id) const final
{
return m_coordinate_list->at(id);
};
bool EdgeIsCompressed(const unsigned id) const { return m_egde_is_compressed.at(id); }
bool EdgeIsCompressed(const unsigned id) const { return m_edge_is_compressed.at(id); }
TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const
TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const final
{
return m_turn_instruction_list.at(id);
}
TravelMode GetTravelModeForEdgeID(const unsigned id) const
{
return m_travel_mode_list.at(id);
}
bool LocateClosestEndPointForCoordinate(const FixedPointCoordinate &input_coordinate,
FixedPointCoordinate &result,
const unsigned zoom_level = 18) const
const unsigned zoom_level = 18) final
{
if (!m_static_rtree.get())
{
LoadRTree();
}
return m_static_rtree->LocateClosestEndPointForCoordinate(
input_coordinate, result, zoom_level);
}
bool FindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
PhantomNode &resulting_phantom_node,
const unsigned zoom_level) const
const unsigned zoom_level) final
{
if (!m_static_rtree.get())
{
LoadRTree();
}
return m_static_rtree->FindPhantomNodeForCoordinate(
input_coordinate, resulting_phantom_node, zoom_level);
}
@@ -376,20 +394,25 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
std::vector<PhantomNode> &resulting_phantom_node_vector,
const unsigned zoom_level,
const unsigned number_of_results) const
const unsigned number_of_results) final
{
if (!m_static_rtree.get())
{
LoadRTree();
}
return m_static_rtree->IncrementalFindPhantomNodeForCoordinate(
input_coordinate, resulting_phantom_node_vector, zoom_level, number_of_results);
}
unsigned GetCheckSum() const { return m_check_sum; }
unsigned GetCheckSum() const final { return m_check_sum; }
unsigned GetNameIndexFromEdgeID(const unsigned id) const
unsigned GetNameIndexFromEdgeID(const unsigned id) const final
{
return m_name_ID_list.at(id);
};
void GetName(const unsigned name_id, std::string &result) const
void GetName(const unsigned name_id, std::string &result) const final
{
if (UINT_MAX == name_id)
{
@@ -408,13 +431,13 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
}
}
virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const
virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const final
{
return m_via_node_list.at(id);
}
virtual void GetUncompressedGeometry(const unsigned id, std::vector<unsigned> &result_nodes)
const
virtual void GetUncompressedGeometry(const unsigned id,
std::vector<unsigned> &result_nodes) const final
{
const unsigned begin = m_geometry_indices.at(id);
const unsigned end = m_geometry_indices.at(id + 1);
@@ -424,7 +447,7 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
result_nodes.begin(), m_geometry_list.begin() + begin, m_geometry_list.begin() + end);
}
std::string GetTimestamp() const { return m_timestamp; }
std::string GetTimestamp() const final { return m_timestamp; }
};
#endif // INTERNAL_DATA_FACADE
+90 -58
View File
@@ -38,7 +38,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../../DataStructures/StaticRTree.h"
#include "../../Util/BoostFileSystemFix.h"
#include "../../Util/ProgramOptions.h"
#include "../../Util/SimpleLogger.h"
#include "../../Util/make_unique.hpp"
#include "../../Util/simple_logger.hpp"
#include <algorithm>
#include <memory>
@@ -55,8 +56,9 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
typedef typename RangeTable<16, true>::BlockT NameIndexBlock;
typedef typename QueryGraph::InputEdge InputEdge;
typedef typename super::RTreeLeaf RTreeLeaf;
typedef typename StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, true>::vector, true>::TreeNode
RTreeNode;
using SharedRTree = StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, true>::vector, true>;
using TimeStampedRTreePair = std::pair<unsigned, std::shared_ptr<SharedRTree>>;
using RTreeNode = typename SharedRTree::TreeNode;
SharedDataLayout *data_layout;
char *shared_memory;
@@ -67,24 +69,24 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
unsigned CURRENT_TIMESTAMP;
unsigned m_check_sum;
unsigned m_number_of_nodes;
std::shared_ptr<QueryGraph> m_query_graph;
std::shared_ptr<SharedMemory> m_layout_memory;
std::shared_ptr<SharedMemory> m_large_memory;
std::unique_ptr<QueryGraph> m_query_graph;
std::unique_ptr<SharedMemory> m_layout_memory;
std::unique_ptr<SharedMemory> m_large_memory;
std::string m_timestamp;
std::shared_ptr<ShM<FixedPointCoordinate, true>::vector> m_coordinate_list;
ShM<NodeID, true>::vector m_via_node_list;
ShM<unsigned, true>::vector m_name_ID_list;
ShM<TurnInstruction, true>::vector m_turn_instruction_list;
ShM<TravelMode, true>::vector m_travel_mode_list;
ShM<char, true>::vector m_names_char_list;
ShM<unsigned, true>::vector m_name_begin_indices;
ShM<bool, true>::vector m_egde_is_compressed;
ShM<bool, true>::vector m_edge_is_compressed;
ShM<unsigned, true>::vector m_geometry_indices;
ShM<unsigned, true>::vector m_geometry_list;
std::shared_ptr<StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, true>::vector, true>>
m_static_rtree;
boost::thread_specific_ptr<std::pair<unsigned, std::shared_ptr<SharedRTree>>> m_static_rtree;
boost::filesystem::path file_index_path;
std::shared_ptr<RangeTable<16, true>> m_name_table;
@@ -105,23 +107,22 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
m_timestamp.begin());
}
void LoadRTree(const boost::filesystem::path &file_index_path)
void LoadRTree()
{
BOOST_ASSERT_MSG(!m_coordinate_list->empty(), "coordinates must be loaded before r-tree");
RTreeNode *tree_ptr =
data_layout->GetBlockPtr<RTreeNode>(shared_memory, SharedDataLayout::R_SEARCH_TREE);
m_static_rtree =
std::make_shared<StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, true>::vector, true>>(
m_static_rtree.reset(new TimeStampedRTreePair(CURRENT_TIMESTAMP,
osrm::make_unique<SharedRTree>(
tree_ptr,
data_layout->num_entries[SharedDataLayout::R_SEARCH_TREE],
file_index_path,
m_coordinate_list);
m_coordinate_list)));
}
void LoadGraph()
{
m_number_of_nodes = data_layout->num_entries[SharedDataLayout::GRAPH_NODE_LIST];
GraphNode *graph_nodes_ptr =
data_layout->GetBlockPtr<GraphNode>(shared_memory, SharedDataLayout::GRAPH_NODE_LIST);
@@ -140,9 +141,16 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
FixedPointCoordinate *coordinate_list_ptr = data_layout->GetBlockPtr<FixedPointCoordinate>(
shared_memory, SharedDataLayout::COORDINATE_LIST);
m_coordinate_list = std::make_shared<ShM<FixedPointCoordinate, true>::vector>(
m_coordinate_list = osrm::make_unique<ShM<FixedPointCoordinate, true>::vector>(
coordinate_list_ptr, data_layout->num_entries[SharedDataLayout::COORDINATE_LIST]);
TravelMode *travel_mode_list_ptr = data_layout->GetBlockPtr<TravelMode>(
shared_memory, SharedDataLayout::TRAVEL_MODE);
typename ShM<TravelMode, true>::vector travel_mode_list(
travel_mode_list_ptr,
data_layout->num_entries[SharedDataLayout::TRAVEL_MODE]);
m_travel_mode_list.swap(travel_mode_list);
TurnInstruction *turn_instruction_list_ptr = data_layout->GetBlockPtr<TurnInstruction>(
shared_memory, SharedDataLayout::TURN_INSTRUCTION);
typename ShM<TurnInstruction, true>::vector turn_instruction_list(
@@ -181,8 +189,8 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
data_layout->GetBlockPtr<char>(shared_memory, SharedDataLayout::NAME_CHAR_LIST);
typename ShM<char, true>::vector names_char_list(
names_list_ptr, data_layout->num_entries[SharedDataLayout::NAME_CHAR_LIST]);
m_name_table = std::make_shared<RangeTable<16, true>>(
name_offsets, name_blocks, names_char_list.size());
m_name_table = osrm::make_unique<RangeTable<16, true>>(
name_offsets, name_blocks, static_cast<unsigned>(names_char_list.size()));
m_names_char_list.swap(names_char_list);
}
@@ -191,10 +199,10 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
{
unsigned *geometries_compressed_ptr = data_layout->GetBlockPtr<unsigned>(
shared_memory, SharedDataLayout::GEOMETRIES_INDICATORS);
typename ShM<bool, true>::vector egde_is_compressed(
typename ShM<bool, true>::vector edge_is_compressed(
geometries_compressed_ptr,
data_layout->num_entries[SharedDataLayout::GEOMETRIES_INDICATORS]);
m_egde_is_compressed.swap(egde_is_compressed);
m_edge_is_compressed.swap(edge_is_compressed);
unsigned *geometries_index_ptr =
data_layout->GetBlockPtr<unsigned>(shared_memory, SharedDataLayout::GEOMETRIES_INDEX);
@@ -210,11 +218,12 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
}
public:
virtual ~SharedDataFacade() {}
SharedDataFacade()
{
data_timestamp_ptr = (SharedDataTimestamp *)SharedMemoryFactory::Get(
CURRENT_REGIONS, sizeof(SharedDataTimestamp), false, false)->Ptr();
CURRENT_LAYOUT = LAYOUT_NONE;
CURRENT_DATA = DATA_NONE;
CURRENT_TIMESTAMP = 0;
@@ -244,13 +253,9 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
m_large_memory.reset(SharedMemoryFactory::Get(CURRENT_DATA));
shared_memory = (char *)(m_large_memory->Ptr());
std::ofstream out("debug.bin");
out.write(shared_memory, data_layout->GetSizeOfLayout());
out.close();
const char *file_index_ptr =
data_layout->GetBlockPtr<char>(shared_memory, SharedDataLayout::FILE_INDEX_PATH);
boost::filesystem::path file_index_path(file_index_ptr);
file_index_path = boost::filesystem::path(file_index_ptr);
if (!boost::filesystem::exists(file_index_path))
{
SimpleLogger().Write(logDEBUG) << "Leaf file name " << file_index_path.string();
@@ -262,65 +267,72 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
LoadChecksum();
LoadNodeAndEdgeInformation();
LoadGeometries();
LoadRTree(file_index_path);
LoadTimestamp();
LoadViaNodeList();
LoadNames();
data_layout->PrintInformation();
SimpleLogger().Write() << "number of geometries: " << m_coordinate_list->size();
for (unsigned i = 0; i < m_coordinate_list->size(); ++i)
{
if (!GetCoordinateOfNode(i).isValid())
{
SimpleLogger().Write() << "coordinate " << i << " not valid";
}
}
}
}
// search graph access
unsigned GetNumberOfNodes() const { return m_query_graph->GetNumberOfNodes(); }
unsigned GetNumberOfNodes() const final { return m_query_graph->GetNumberOfNodes(); }
unsigned GetNumberOfEdges() const { return m_query_graph->GetNumberOfEdges(); }
unsigned GetNumberOfEdges() const final { return m_query_graph->GetNumberOfEdges(); }
unsigned GetOutDegree(const NodeID n) const { return m_query_graph->GetOutDegree(n); }
unsigned GetOutDegree(const NodeID n) const final { return m_query_graph->GetOutDegree(n); }
NodeID GetTarget(const EdgeID e) const { return m_query_graph->GetTarget(e); }
NodeID GetTarget(const EdgeID e) const final { return m_query_graph->GetTarget(e); }
EdgeDataT &GetEdgeData(const EdgeID e) { return m_query_graph->GetEdgeData(e); }
EdgeDataT &GetEdgeData(const EdgeID e) const final { return m_query_graph->GetEdgeData(e); }
// const EdgeDataT &GetEdgeData( const EdgeID e ) const {
// return m_query_graph->GetEdgeData(e);
// }
EdgeID BeginEdges(const NodeID n) const final { return m_query_graph->BeginEdges(n); }
EdgeID BeginEdges(const NodeID n) const { return m_query_graph->BeginEdges(n); }
EdgeID EndEdges(const NodeID n) const final { return m_query_graph->EndEdges(n); }
EdgeID EndEdges(const NodeID n) const { return m_query_graph->EndEdges(n); }
EdgeRange GetAdjacentEdgeRange(const NodeID node) const
EdgeRange GetAdjacentEdgeRange(const NodeID node) const final
{
return m_query_graph->GetAdjacentEdgeRange(node);
};
// searches for a specific edge
EdgeID FindEdge(const NodeID from, const NodeID to) const
EdgeID FindEdge(const NodeID from, const NodeID to) const final
{
return m_query_graph->FindEdge(from, to);
}
EdgeID FindEdgeInEitherDirection(const NodeID from, const NodeID to) const
EdgeID FindEdgeInEitherDirection(const NodeID from, const NodeID to) const final
{
return m_query_graph->FindEdgeInEitherDirection(from, to);
}
EdgeID FindEdgeIndicateIfReverse(const NodeID from, const NodeID to, bool &result) const
EdgeID FindEdgeIndicateIfReverse(const NodeID from, const NodeID to, bool &result) const final
{
return m_query_graph->FindEdgeIndicateIfReverse(from, to, result);
}
// node and edge information access
FixedPointCoordinate GetCoordinateOfNode(const unsigned id) const
FixedPointCoordinate GetCoordinateOfNode(const NodeID id) const final
{
return m_coordinate_list->at(id);
};
virtual bool EdgeIsCompressed(const unsigned id) const { return m_egde_is_compressed.at(id); }
virtual bool EdgeIsCompressed(const unsigned id) const final
{
return m_edge_is_compressed.at(id);
}
virtual void GetUncompressedGeometry(const unsigned id, std::vector<unsigned> &result_nodes)
const
virtual void GetUncompressedGeometry(const unsigned id,
std::vector<unsigned> &result_nodes) const final
{
const unsigned begin = m_geometry_indices.at(id);
const unsigned end = m_geometry_indices.at(id + 1);
@@ -330,29 +342,44 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
result_nodes.begin(), m_geometry_list.begin() + begin, m_geometry_list.begin() + end);
}
virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const
virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const final
{
return m_via_node_list.at(id);
}
TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const
TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const final
{
return m_turn_instruction_list.at(id);
}
TravelMode GetTravelModeForEdgeID(const unsigned id) const
{
return m_travel_mode_list.at(id);
}
bool LocateClosestEndPointForCoordinate(const FixedPointCoordinate &input_coordinate,
FixedPointCoordinate &result,
const unsigned zoom_level = 18) const
const unsigned zoom_level = 18) final
{
return m_static_rtree->LocateClosestEndPointForCoordinate(
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
{
LoadRTree();
}
return m_static_rtree->second->LocateClosestEndPointForCoordinate(
input_coordinate, result, zoom_level);
}
bool FindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
PhantomNode &resulting_phantom_node,
const unsigned zoom_level) const
const unsigned zoom_level) final
{
return m_static_rtree->FindPhantomNodeForCoordinate(
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
{
LoadRTree();
}
return m_static_rtree->second->FindPhantomNodeForCoordinate(
input_coordinate, resulting_phantom_node, zoom_level);
}
@@ -360,20 +387,25 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
std::vector<PhantomNode> &resulting_phantom_node_vector,
const unsigned zoom_level,
const unsigned number_of_results) const
const unsigned number_of_results) final
{
return m_static_rtree->IncrementalFindPhantomNodeForCoordinate(
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
{
LoadRTree();
}
return m_static_rtree->second->IncrementalFindPhantomNodeForCoordinate(
input_coordinate, resulting_phantom_node_vector, zoom_level, number_of_results);
}
unsigned GetCheckSum() const { return m_check_sum; }
unsigned GetCheckSum() const final { return m_check_sum; }
unsigned GetNameIndexFromEdgeID(const unsigned id) const
unsigned GetNameIndexFromEdgeID(const unsigned id) const final
{
return m_name_ID_list.at(id);
};
void GetName(const unsigned name_id, std::string &result) const
void GetName(const unsigned name_id, std::string &result) const final
{
if (UINT_MAX == name_id)
{
@@ -392,7 +424,7 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
}
}
std::string GetTimestamp() const { return m_timestamp; }
std::string GetTimestamp() const final { return m_timestamp; }
};
#endif // SHARED_DATA_FACADE_H
+5 -2
View File
@@ -29,14 +29,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define SHARED_DATA_TYPE_H_
#include "../../Util/OSRMException.h"
#include "../../Util/SimpleLogger.h"
#include "../../Util/simple_logger.hpp"
#include <cstdint>
#include <array>
// Added at the start and end of each block as sanity check
constexpr char CANARY[] = "OSRM";
static const char CANARY[] = "OSRM";
struct SharedDataLayout
{
@@ -50,6 +50,7 @@ struct SharedDataLayout
GRAPH_EDGE_LIST,
COORDINATE_LIST,
TURN_INSTRUCTION,
TRAVEL_MODE,
R_SEARCH_TREE,
GEOMETRIES_INDEX,
GEOMETRIES_LIST,
@@ -82,6 +83,7 @@ struct SharedDataLayout
SimpleLogger().Write(logDEBUG) << "timestamp_length: " << num_entries[TIMESTAMP];
SimpleLogger().Write(logDEBUG) << "coordinate_list_size: " << num_entries[COORDINATE_LIST];
SimpleLogger().Write(logDEBUG) << "turn_instruction_list_size: " << num_entries[TURN_INSTRUCTION];
SimpleLogger().Write(logDEBUG) << "travel_mode_list_size: " << num_entries[TRAVEL_MODE];
SimpleLogger().Write(logDEBUG) << "r_search_tree_size: " << num_entries[R_SEARCH_TREE];
SimpleLogger().Write(logDEBUG) << "geometries_indicators: " << num_entries[GEOMETRIES_INDICATORS]
<< "/" << ((num_entries[GEOMETRIES_INDICATORS] / 8) + 1);
@@ -98,6 +100,7 @@ struct SharedDataLayout
SimpleLogger().Write(logDEBUG) << "GRAPH_EDGE_LIST " << ": " << GetBlockSize(GRAPH_EDGE_LIST );
SimpleLogger().Write(logDEBUG) << "COORDINATE_LIST " << ": " << GetBlockSize(COORDINATE_LIST );
SimpleLogger().Write(logDEBUG) << "TURN_INSTRUCTION " << ": " << GetBlockSize(TURN_INSTRUCTION );
SimpleLogger().Write(logDEBUG) << "TRAVEL_MODE " << ": " << GetBlockSize(TRAVEL_MODE );
SimpleLogger().Write(logDEBUG) << "R_SEARCH_TREE " << ": " << GetBlockSize(R_SEARCH_TREE );
SimpleLogger().Write(logDEBUG) << "GEOMETRIES_INDEX " << ": " << GetBlockSize(GEOMETRIES_INDEX );
SimpleLogger().Write(logDEBUG) << "GEOMETRIES_LIST " << ": " << GetBlockSize(GEOMETRIES_LIST );
+3 -4
View File
@@ -27,7 +27,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <osrm/Reply.h>
#include "../../Util/StringUtil.h"
#include "../../Util/cast.hpp"
namespace http
{
@@ -38,7 +38,7 @@ void Reply::SetSize(const unsigned size)
{
if ("Content-Length" == h.name)
{
h.value = UintToString(size);
h.value = cast::integral_to_string(size);
}
}
}
@@ -87,8 +87,7 @@ Reply Reply::StockReply(Reply::status_type status)
const std::string status_string = reply.ToString(status);
reply.content.insert(reply.content.end(), status_string.begin(), status_string.end());
reply.headers.emplace_back("Access-Control-Allow-Origin", "*");
reply.headers.emplace_back("Content-Length",
UintToString(static_cast<unsigned>(reply.content.size())));
reply.headers.emplace_back("Content-Length", cast::integral_to_string(reply.content.size()));
reply.headers.emplace_back("Content-Type", "text/html");
return reply;
}
+13 -13
View File
@@ -25,13 +25,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "APIGrammar.h"
#include "RequestHandler.h"
#include "APIGrammar.h"
#include "Http/Request.h"
#include "../DataStructures/JSONContainer.h"
#include "../Library/OSRM.h"
#include "../Util/SimpleLogger.h"
#include "../Util/simple_logger.hpp"
#include "../Util/StringUtil.h"
#include "../typedefs.h"
@@ -61,17 +62,17 @@ void RequestHandler::handle_request(const http::Request &req, http::Reply &reply
// req.agent << ( 0 == req.agent.length() ? "- " :" ") << request;
time_t ltime;
struct tm *Tm;
struct tm *time_stamp;
ltime = time(nullptr);
Tm = localtime(&ltime);
time_stamp = localtime(&ltime);
// log timestamp
SimpleLogger().Write() << (Tm->tm_mday < 10 ? "0" : "") << Tm->tm_mday << "-"
<< (Tm->tm_mon + 1 < 10 ? "0" : "") << (Tm->tm_mon + 1) << "-"
<< 1900 + Tm->tm_year << " " << (Tm->tm_hour < 10 ? "0" : "")
<< Tm->tm_hour << ":" << (Tm->tm_min < 10 ? "0" : "") << Tm->tm_min
<< ":" << (Tm->tm_sec < 10 ? "0" : "") << Tm->tm_sec << " "
SimpleLogger().Write() << (time_stamp->tm_mday < 10 ? "0" : "") << time_stamp->tm_mday << "-"
<< (time_stamp->tm_mon + 1 < 10 ? "0" : "") << (time_stamp->tm_mon + 1) << "-"
<< 1900 + time_stamp->tm_year << " " << (time_stamp->tm_hour < 10 ? "0" : "")
<< time_stamp->tm_hour << ":" << (time_stamp->tm_min < 10 ? "0" : "") << time_stamp->tm_min
<< ":" << (time_stamp->tm_sec < 10 ? "0" : "") << time_stamp->tm_sec << " "
<< req.endpoint.to_string() << " " << req.referrer
<< (0 == req.referrer.length() ? "- " : " ") << req.agent
<< (0 == req.agent.length() ? "- " : " ") << request;
@@ -87,11 +88,11 @@ void RequestHandler::handle_request(const http::Request &req, http::Reply &reply
{
reply = http::Reply::StockReply(http::Reply::badRequest);
reply.content.clear();
const unsigned position = static_cast<unsigned>(std::distance(request.begin(), iter));
const auto position = std::distance(request.begin(), iter);
JSON::Object json_result;
json_result.values["status"] = 400;
std::string message = "Query string malformed close to position ";
message += UintToString(position);
message += cast::integral_to_string(position);
json_result.values["status_message"] = message;
JSON::render(reply.content, json_result);
return;
@@ -112,8 +113,7 @@ void RequestHandler::handle_request(const http::Request &req, http::Reply &reply
}
// set headers
reply.headers.emplace_back("Content-Length",
UintToString(static_cast<unsigned>(reply.content.size())));
reply.headers.emplace_back("Content-Length", cast::integral_to_string(reply.content.size()));
if ("gpx" == route_parameters.output_format)
{ // gpx file
reply.headers.emplace_back("Content-Type", "application/gpx+xml; charset=UTF-8");
+1 -1
View File
@@ -44,7 +44,7 @@ class RequestHandler
{
public:
typedef APIGrammar<std::string::iterator, RouteParameters> APIGrammarParser;
using APIGrammarParser = APIGrammar<std::string::iterator, RouteParameters>;
RequestHandler();
RequestHandler(const RequestHandler &) = delete;
+13 -9
View File
@@ -25,9 +25,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Http/Request.h"
#include "RequestParser.h"
#include "Http/Request.h"
namespace http
{
@@ -264,18 +265,21 @@ RequestParser::consume(Request &req, char input, http::CompressionType *compress
return false;
default: // expecting_newline_3:
return (input == '\n');
// default:
// return false;
// default:
// return false;
}
}
inline bool RequestParser::isChar(int c) { return c >= 0 && c <= 127; }
inline bool RequestParser::isChar(int character) { return character >= 0 && character <= 127; }
inline bool RequestParser::isCTL(int c) { return (c >= 0 && c <= 31) || (c == 127); }
inline bool RequestParser::isTSpecial(int c)
inline bool RequestParser::isCTL(int character)
{
switch (c)
return (character >= 0 && character <= 31) || (character == 127);
}
inline bool RequestParser::isTSpecial(int character)
{
switch (character)
{
case '(':
case ')':
@@ -302,5 +306,5 @@ inline bool RequestParser::isTSpecial(int c)
}
}
inline bool RequestParser::isDigit(int c) { return c >= '0' && c <= '9'; }
inline bool RequestParser::isDigit(int character) { return character >= '0' && character <= '9'; }
}
+21 -10
View File
@@ -28,14 +28,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef SERVER_H
#define SERVER_H
#include "../Util/StringUtil.h"
#include "Connection.h"
#include "RequestHandler.h"
#include "../Util/cast.hpp"
#include "../Util/make_unique.hpp"
#include "../Util/simple_logger.hpp"
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <zlib.h>
#include <functional>
#include <memory>
#include <thread>
@@ -44,11 +48,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
class Server
{
public:
// Note: returns a shared instead of a unique ptr as it is captured in a lambda somewhere else
static std::shared_ptr<Server> CreateServer(std::string &ip_address, int ip_port, unsigned requested_num_threads)
{
SimpleLogger().Write() << "http 1.1 compression handled by zlib version " << zlibVersion();
const unsigned hardware_threads = std::max(1u, std::thread::hardware_concurrency());
const unsigned real_num_threads = std::min(hardware_threads, requested_num_threads);
return std::make_shared<Server>(ip_address, ip_port, real_num_threads);
}
explicit Server(const std::string &address, const int port, const unsigned thread_pool_size)
: thread_pool_size(thread_pool_size), acceptor(io_service),
new_connection(new http::Connection(io_service, request_handler)), request_handler()
new_connection(std::make_shared<http::Connection>(io_service, request_handler)), request_handler()
{
const std::string port_string = IntToString(port);
const std::string port_string = cast::integral_to_string(port);
boost::asio::ip::tcp::resolver resolver(io_service);
boost::asio::ip::tcp::resolver::query query(address, port_string);
@@ -63,9 +77,6 @@ class Server
boost::bind(&Server::HandleAccept, this, boost::asio::placeholders::error));
}
Server() = delete;
Server(const Server &) = delete;
void Run()
{
std::vector<std::shared_ptr<std::thread>> threads;
@@ -75,9 +86,9 @@ class Server
boost::bind(&boost::asio::io_service::run, &io_service));
threads.push_back(thread);
}
for (unsigned i = 0; i < threads.size(); ++i)
for (auto thread : threads)
{
threads[i]->join();
thread->join();
}
}
@@ -91,7 +102,7 @@ class Server
if (!e)
{
new_connection->start();
new_connection.reset(new http::Connection(io_service, request_handler));
new_connection = std::make_shared<http::Connection>(io_service, request_handler);
acceptor.async_accept(
new_connection->socket(),
boost::bind(&Server::HandleAccept, this, boost::asio::placeholders::error));

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