Compare commits

...

1873 Commits

Author SHA1 Message Date
Dennis Luxen 1d3932e8c5 fix an off-by-one issue in the output JSON 2014-06-27 16:18:38 +02:00
Dennis Luxen 3f85b30d4a remove some unneeded includes 2014-06-27 10:38:28 +02:00
Dennis Luxen e4c398aa23 make std::hash specialization for std::pair<> fully generic 2014-06-27 09:50:57 +02:00
Dennis Luxen f9417555d0 remove superflous include 2014-06-27 09:50:26 +02:00
Dennis Luxen 5d3123b97f reformat code using clang-format 2014-06-26 13:50:29 +02:00
dmbreaker 25080aaf1d Non-explicit constructor and hash-functions. 2014-06-26 13:50:29 +02:00
dmbreaker 05ac4b5ab6 Fixes to fulfill remarks. 2014-06-26 13:50:29 +02:00
dmbreaker 07e13e2499 Replaced std::pair with classes.
Looks like fixed wrong restriction type in CheckForEmanatingIsOnlyTurn (now RestrictionTarget instead if RestrictionSource).
2014-06-26 13:50:29 +02:00
dmbreaker 2d9645b9b0 Added structures for RestrictionTarget and RestrictionSource. 2014-06-26 13:50:29 +02:00
Dennis Luxen 65ccbedab2 Merge pull request #1103 from dmbreaker/feature/graph_comments
Added some graphical explanations for variables.
2014-06-26 12:16:44 +02:00
Dennis Luxen 631567864b Merge pull request #1098 from TheMarex/rangetable-covertity
Fix coverity warning in RangeTable
2014-06-26 12:15:35 +02:00
Dennis Luxen 39d479128c add better comment to document the source of the hash_combine work 2014-06-26 12:14:47 +02:00
Dennis Luxen 4c0b315c07 Merge pull request #1094 from gberaudo/fixes
Several fixes: remove dead code, fix Int->String conversion for INT_MIN, remove duplicated coordinate from encoded polyline.
2014-06-26 11:54:45 +02:00
dmbreaker 264e83a1f3 Added comments with graphical representation of variables. 2014-06-26 12:31:45 +04:00
Dennis Luxen 2b2ed50721 add a hash combine implementation that has some minor performance guarantees 2014-06-25 18:50:46 +02:00
Dennis Luxen 31fbf99109 fail hard when building tools and not all prequisites are met 2014-06-25 10:53:51 +02:00
Dennis Luxen 63381ad221 fix compilation on GCC 4.8.2, type of priority_queue<> is not properly deduced 2014-06-24 18:31:34 +02:00
Guillaume Beraudo 6ee2d1103e Remove duplicated point in polyline encoded data
First point was outputted twice.
Add test case.
2014-06-24 17:25:36 +02:00
Guillaume Beraudo bee18dba54 Display warning when routing without street names.
Indeed, street names are optional for routing.
2014-06-24 17:18:52 +02:00
Guillaume Beraudo 481e445e8a Fix printInt when value=INT_MIN (was overflowing) 2014-06-24 17:18:52 +02:00
Guillaume Beraudo 129f7b7441 Remove unused polyline method 2014-06-24 17:18:52 +02:00
Guillaume Beraudo d6bc3c5175 Remove unused test method 2014-06-24 17:18:52 +02:00
Dennis Luxen de7c56c6bc remove remaining NULL pointers by nullptrs 2014-06-24 16:50:00 +02:00
Dennis Luxen 0c59ecfa14 remove dead code, produce empty route when origin and destination are the same 2014-06-24 16:09:25 +02:00
Patrick Niklaus f67241a3cb Fix coverity warning in RangeTable 2014-06-24 13:26:27 +02:00
Dennis Luxen 3b2893944c remove non-existing dependency 2014-06-24 12:45:16 +02:00
Dennis Luxen dd7d6df4c6 streamline PBF parsing code 2014-06-24 12:25:19 +02:00
Dennis Luxen efbda436f3 properly cast from int to bool 2014-06-24 11:46:32 +02:00
Dane Springmeyer 2064934939 link -lrt to osrm-prepare 2014-06-23 16:02:58 -07:00
Dennis Luxen b36cf7c450 remove debug output 2014-06-23 17:34:20 +02:00
Dennis Luxen a24dd3dee2 use incremental NN query for Nearest plugin 2014-06-23 17:33:55 +02:00
Dennis Luxen 7b22f08869 remove dead code 2014-06-23 17:32:52 +02:00
Dennis Luxen 840929754a remove debug output 2014-06-23 17:32:24 +02:00
Dennis Luxen 51fd332806 add incremental query to Facades 2014-06-23 16:56:01 +02:00
Dennis Luxen 4d7e0f6b79 use incremental NN query for distance table generation 2014-06-23 16:55:38 +02:00
Dennis Luxen b74a573ec5 add typedef for an array of phantom node vectors 2014-06-23 16:54:57 +02:00
Dennis Luxen 5faf88afdb implement incremental NN query for R-tree 2014-06-23 16:54:31 +02:00
Dennis Luxen 5e1110930e use proper floating point literal instead of implicit cast from int 2014-06-23 14:42:37 +02:00
Dennis Luxen f11adf5f80 fix signed/unsigned comparison 2014-06-23 14:35:09 +02:00
Dennis Luxen 40a71e09a6 use an explicit downcast to initialize variable 2014-06-23 13:22:46 +02:00
Dennis Luxen 1231847a3c replace hashmap with a dummy vector based implementation as the number of tags per object is tiny 2014-06-23 13:22:14 +02:00
Dennis Luxen b06a73e893 replace hashmap with a dummy vector based implementation as the number of tags per object is tiny 2014-06-23 13:21:56 +02:00
Dennis Luxen f99f194927 use proper interface of HashTable, use prefix increment 2014-06-23 12:13:01 +02:00
Dennis Luxen eac7d07ef6 rename variables to cut OCLint warnings 2014-06-23 12:11:56 +02:00
Dennis Luxen 60d70a9f4c fix leak on shutdown 2014-06-20 17:32:20 +02:00
Dennis Luxen c944783590 don't downcast from std:.size_t to unsigned 2014-06-20 17:32:03 +02:00
Dennis Luxen 8104a8aea1 reformat to cut long line 2014-06-20 16:49:33 +02:00
Dennis Luxen a4db678895 reformat to cut long line 2014-06-20 16:48:34 +02:00
Dennis Luxen da33d02461 reformat to cut long line 2014-06-20 16:47:09 +02:00
Dennis Luxen 9b4071006e reformat to cut long line 2014-06-20 16:39:58 +02:00
Dennis Luxen b3cdd5b3bf reformat to cut long line 2014-06-20 16:36:15 +02:00
Dennis Luxen 93e53ec612 fix comparison to accept 0 distance results in distance table 2014-06-19 19:52:15 +02:00
Dennis Luxen ea8319e2b9 add more asserts to test for data corruption during MBR merging in StaticRTree 2014-06-19 17:52:59 +02:00
Dennis Luxen 2fae253c62 use std::size_t consistently and avoid possible loss of data 2014-06-19 11:14:28 +02:00
Dennis Luxen e204b257ad add proper size_t->unsigned cast 2014-06-19 10:40:24 +02:00
Dennis Luxen dd83d8ed61 make size of table compact 2014-06-19 10:40:04 +02:00
Dennis Luxen 61f3d85af1 add even more cast sanity 2014-06-18 11:49:01 +02:00
Dennis Luxen 804e515847 stream line code a bit in Reply 2014-06-18 11:25:56 +02:00
Dennis Luxen 35977b6c7f add explicit cast 2014-06-18 11:24:50 +02:00
Dennis Luxen 23f1d3d83b add explicit cast 2014-06-18 11:20:24 +02:00
Dennis Luxen b8ea935424 cast bearing to unsigned 2014-06-18 11:17:51 +02:00
Dennis Luxen 7c0866f626 stream line code a bit in Reply 2014-06-18 11:17:23 +02:00
Dennis Luxen 0f2062b739 round bearing value to integers 2014-06-18 11:00:13 +02:00
Dennis Luxen e91454eeee use auto keyword to deduce types automatically 2014-06-18 10:59:43 +02:00
Dennis Luxen 58134200df use float consistently in DescriptionFactory 2014-06-18 10:44:46 +02:00
Dennis Luxen f6bab21928 use double consistently in JSONDescriptor 2014-06-18 10:44:09 +02:00
Dennis Luxen 011910811b use float consistently in Contractor 2014-06-18 10:43:26 +02:00
Dennis Luxen bbc0ba147a reformat Descriptors/JSONDescriptor.h 2014-06-18 10:15:38 +02:00
Dennis Luxen 922a4331db reformat source file datastore.cpp 2014-06-18 09:42:45 +02:00
Dennis Luxen 8f7f1e2683 reformat source file Server/RequestHandler.cpp 2014-06-18 09:40:53 +02:00
Dennis Luxen 1980cc007f cast parameters before c'ting Coordinate 2014-06-17 19:10:26 +02:00
Dennis Luxen 39611f7477 couple more explicit casts 2014-06-17 18:52:01 +02:00
Dennis Luxen e3d659576f cast std::size_t and unsigned in a proper way 2014-06-17 16:01:06 +02:00
Dennis Luxen 46d4670b74 cast float to unsigned in a proper way 2014-06-17 16:00:42 +02:00
Dennis Luxen 15ca6d5ca9 use explicit casts where feasible 2014-06-17 15:57:03 +02:00
Dennis Luxen 58f23cda4a use explicit casts where feasible 2014-06-17 15:51:43 +02:00
Dennis Luxen a58d8420a2 add some formatting whitespace 2014-06-17 15:48:47 +02:00
Dennis Luxen 96f834fb81 use explicit casts 2014-06-17 15:47:59 +02:00
Dennis Luxen 86617eccb1 use explicit casts 2014-06-17 15:47:40 +02:00
Dennis Luxen f2936d1c2d add disabled HipChat notifications to Windows build 2014-06-17 15:47:16 +02:00
Dennis Luxen 0fc8e04ab5 use proper data types to avoid uncessary casts 2014-06-17 15:30:28 +02:00
Dennis Luxen a65e2d3115 downcast size_t to unsigned 2014-06-17 13:19:59 +02:00
Dennis Luxen ca6e25b11c make many more conversions explicit 2014-06-17 13:18:55 +02:00
Dennis Luxen 3ec6a6f5bc remove ignored parameter 2014-06-17 13:09:58 +02:00
Dennis Luxen c12fae47e7 allow results at high latitudes to be a bit more imprecise 2014-06-17 13:00:13 +02:00
Dennis Luxen 604d2c698b replace fp divisions by multiplications 2014-06-17 12:50:29 +02:00
Dennis Luxen 5d14016366 add static_casts to avoid unnecessary conversion from double to float 2014-06-17 12:37:55 +02:00
Dennis Luxen b112becbba use explicit casts to mitigate MSVC warnings 2014-06-17 12:15:40 +02:00
Dennis Luxen e68a09fb3c fix windows deploy on develop branch, partially fixes #1085 2014-06-16 15:13:19 +02:00
Dennis Luxen 30e9b4513a Merge branch 'alex85k-develop' into develop 2014-06-16 13:43:26 +02:00
alex85k 671b14dac0 pack only develop version to zip on AppVeyor 2014-06-16 16:02:14 +06:00
Porjo 82e99988e8 Change content-type header for JSON data 2014-06-16 09:29:34 +02:00
Dennis Luxen 313a7ed7fa Merge pull request #1076 from alex85k/patch-mingw
Add Mingw support (tune libraries and disable cpuid with #ifdef)
2014-06-15 21:55:18 +02:00
Dennis Luxen cf3365574e Merge branch 'TheMarex-thread-control' into develop 2014-06-15 12:35:26 +02:00
Dennis Luxen 0e1f6f50ea Merge branch 'thread-control' of https://github.com/TheMarex/Project-OSRM into TheMarex-thread-control 2014-06-15 12:35:15 +02:00
Dennis Luxen 5b6518d4a9 Merge branch 'TheMarex-diffencoding' into develop 2014-06-15 12:10:18 +02:00
Patrick Niklaus c009dce591 Another VC2013 fix 2014-06-15 11:42:59 +02:00
Patrick Niklaus 40e2d7932b Fix VC2013 issues 2014-06-15 11:29:36 +02:00
Patrick Niklaus e29b7a6eae Fix some minor style issues 2014-06-15 11:04:10 +02:00
Patrick Niklaus a3e9cbc000 Allow user to force thread number
This allows the user to do (potentially) stupid things, but warns him.
The default is TBBs default, so probably the right thing.
To enforce thread numbers in extractor it must be passed to the child
threads.
2014-06-14 17:02:43 +02:00
Patrick Niklaus aedcc2ff40 Add array inlcude 2014-06-12 22:01:23 +02:00
Patrick Niklaus 4c17aeb180 Removed SSE code in RangeTable to rely on compiler optimazation 2014-06-12 22:01:23 +02:00
Patrick Niklaus ef60ae652c Fix edge cases in RangeTable 2014-06-12 22:01:23 +02:00
Patrick Niklaus 1d62ed028e Fix off-by-one since back() gives last value inside [begin,end) 2014-06-12 22:01:23 +02:00
Patrick Niklaus 50bf7694c2 Constify some parts of RangeTable 2014-06-12 22:01:22 +02:00
Patrick Niklaus 807f1d7c1c Initial support for SharedDataFacade
SharedDataLayout was refactored to include canary values at the
boundaries of each memory block. This makes it easy to detect overruns
and block-size mismatches between osrm-datastore and the
SharedDataFacade.
2014-06-12 22:01:22 +02:00
Patrick Niklaus 7a7d0c09d9 Integrate RangeTable into server 2014-06-12 22:00:03 +02:00
Patrick Niklaus f90ce77da4 Use differential encoding for name offsets
Each name is represented as an integer range in a vector of chars.
Instead of storing the absolute offset inside this array, we can store
only the offset to the previous entry (the string size). By doing this we reduce
the number of bytes need to store an offset from 4 to 1 bytes (if we
set a maximum string length of 255).
This is however slower, since the absolute offset must be computed on
each querry by summing up all previous lengths. To limit the
performance inpact we only do this for blocks of a certain size (16).
2014-06-12 22:00:03 +02:00
Dennis Luxen d27ac27bc7 remove one fwd decl, add more comments to Connection 2014-06-12 13:46:07 +02:00
Dennis Luxen 44c6a64bf4 make c'tor of NodeInfo explicit 2014-06-11 18:26:34 +02:00
Dennis Luxen 2d6eae9391 make conversion explicit 2014-06-11 18:15:36 +02:00
Dennis Luxen ba440550a6 make conversion explicit 2014-06-11 18:15:31 +02:00
Dennis Luxen 8e24fee9da explicitly cast from int to bool 2014-06-11 17:44:50 +02:00
alex85k 1148652101 Add Mingw support (tune libraries and disable cpuid with #ifdef) 2014-06-11 20:58:53 +06:00
Dennis Luxen ed01eeaeb3 reformat SharedMemoryFactory according to code guidelines 2014-06-11 15:22:51 +02:00
Dennis Luxen 096f187d6f remove empty line 2014-06-11 15:19:11 +02:00
Dennis Luxen fa35eb1959 adapt for merge, add deployment details 2014-06-11 15:17:51 +02:00
Dennis Luxen 8d89d30c74 Merge branch 'alex85k-win-038' into develop 2014-06-11 15:15:05 +02:00
alex85k f1bde40939 add appveyor.yml template 2014-06-11 18:38:03 +06:00
alex85k 4e7ccaa298 use std::memcpy instead of std::copy (avoid checked iterators assertions) 2014-06-11 18:38:02 +06:00
alex85k d0284991ed patch Ruby files for successful testing on Windows 2014-06-11 18:38:01 +06:00
alex85k c4998990e5 disable io-benchmark on Windows 2014-06-11 18:38:01 +06:00
alex85k 42d3ee9b94 workaround for std::packaged_task<void()> problem on MSVC 2014-06-11 18:38:00 +06:00
alex85k be5c3e41e1 Replace sizeof asserts with warning on Windows 2014-06-11 18:37:26 +06:00
alex85k 3282d410c4 Add basic shared memory support for Windows OS 2014-06-11 18:15:17 +06:00
Alexei Kasatkin 75303c95f8 Avoid constexpr by #ifdef (not supported in MSVC18) 2014-06-11 18:15:16 +06:00
Alexei Kasatkin 0209272831 fix includes and definitions (avoid unistd.h, isatty, fix min,max, round and M_PI) 2014-06-11 18:15:15 +06:00
Alexei Kasatkin 0e16c4ed97 Add more Boost libraries on Windows, fix TBB debug linking, stop building
on old Microsoft compilers
2014-06-11 18:15:14 +06:00
Dennis Luxen e49720f34a add include 2014-06-11 13:44:10 +02:00
Dennis Luxen 8aee371d81 further include untangling, chops 5sec compile time 2014-06-11 12:25:57 +02:00
Dennis Luxen 71c4f81b59 avoid signed/unsigned comparison 2014-06-10 18:08:58 +02:00
Dennis Luxen 3127fafc88 Merge branch 'patch-6' of https://github.com/alex85k/Project-OSRM into develop 2014-06-10 17:40:56 +02:00
Dennis Luxen 4e6bdf28cc fixes #1041, some only_ turn restrictions are inverted under certain conditions 2014-06-10 17:26:22 +02:00
Dennis Luxen 621a5a86a0 fixes #1041, some only_ turn restrictions are inverted under certain conditions 2014-06-10 17:26:05 +02:00
Dennis Luxen d80c8cbd2f add another turn restriction test 2014-06-10 17:23:24 +02:00
Dennis Luxen 686f1aeeb2 reformat some code 2014-06-10 17:23:07 +02:00
alex85k e27a69bab7 Use one more .string().c_str() call 2014-06-10 20:34:21 +06:00
Dennis Luxen 4ee2e1d049 fix long line 2014-06-10 10:49:45 +02:00
Dennis Luxen 2102648102 fix short variable name 2014-06-10 10:48:43 +02:00
Dennis Luxen 8611e40172 Merge branch 'TheMarex-fix-cucumber' into develop 2014-06-09 18:41:37 +02:00
Dennis Luxen 7d5b88fff8 Merge branch 'fix-cucumber' of https://github.com/TheMarex/Project-OSRM into TheMarex-fix-cucumber 2014-06-09 18:41:18 +02:00
Dennis Luxen cfd9aa31a9 add algorithm include 2014-06-09 18:32:07 +02:00
Dennis Luxen 62aea4c321 refactored function names 2014-06-09 18:10:46 +02:00
Dennis Luxen f75fcb3041 refactor RequestHandler to remove code duplication, nested blocks and object copies 2014-06-09 18:06:23 +02:00
Dennis Luxen 971c557d85 explicitly initialize Header member 2014-06-09 17:58:17 +02:00
Dennis Luxen ea05aa225e rename some function names in Reply 2014-06-09 17:57:35 +02:00
Dennis Luxen 56cdabff6a add move c'tor to Header 2014-06-09 17:57:03 +02:00
Dennis Luxen 15f62e680a use inplace construction for Headers instead of explicit objects and copying 2014-06-09 17:55:16 +02:00
Dennis Luxen 0af4e16c21 use inplace construction for Headers instead of explicit objects and copying 2014-06-09 17:54:46 +02:00
Dennis Luxen c7b90bac1a add explicit unsigned->string conversion 2014-06-09 17:50:50 +02:00
Patrick Niklaus 4b81331d53 Don't reset response, so log_fail won't crash cucumber 2014-06-09 14:33:30 +02:00
Dennis Luxen 47ab0cbf62 reduce some code duplication 2014-06-09 12:11:44 +02:00
Dennis Luxen f5b079b8e7 add more comments to reduce NCSS number 2014-06-09 11:58:23 +02:00
Emil Tin 21c4691d40 cuke: make File.tail utility more robust 2014-06-08 12:06:34 +02:00
Dennis Luxen 3726706608 remove another superflous include 2014-06-06 19:19:45 +02:00
Dennis Luxen 28a53aa147 remove superflous include 2014-06-06 19:18:44 +02:00
Dennis Luxen 2ad572490c const as const can 2014-06-06 18:06:05 +02:00
Dennis Luxen 0ed9caf969 fix a couple of implicit signed/unsigned conversions 2014-06-06 18:05:07 +02:00
Dennis Luxen 63ee376f71 removing constexpr at one position 2014-06-06 18:01:01 +02:00
Dennis Luxen 67bcb98a84 make some constants explicit floats to cut down on MSVC conversion warnings 2014-06-06 15:39:29 +02:00
Dennis Luxen 9cd91ae99c Merge pull request #1066 from alex85k/patch-path-cstr
Obtain char* from boost::filesystem::path on all systems
2014-06-06 12:02:32 +02:00
Dennis Luxen d111a0e5e6 guard against an empty alternative path in ExtractRouteNames 2014-06-06 11:50:14 +02:00
Dennis Luxen 11d4c04cea removed left-overs from win/, i.e. a previous windows porting attempt 2014-06-06 11:33:47 +02:00
Dennis Luxen 01773c2a00 fix and refactor the selection of RouteNames 2014-06-06 11:30:12 +02:00
alex85k 1079bf7843 sort vectors before using std::set_difference
discussed in https://github.com/DennisOSRM/Project-OSRM/pull/998#issuecomment-45238338
The vectors are better to be sorted up to ``name_id_comperator`` before running std::set_difference. Elsewhere we get debug checked iterator assertions on Windows and theretically possible incorrect results.
2014-06-06 10:27:35 +02:00
Dennis Luxen 05bcfd2c1c Merge pull request #1065 from alex85k/patch-skip-zero-rw
skip zero bytes reading or wrtiting
2014-06-06 10:22:49 +02:00
Alexei Kasatkin 5357a6a4fd get char* from boost::filesystem::path 2014-06-05 23:48:54 +06:00
Alexei Kasatkin b6787b0014 safeguard: do not read/write 0 bytes (iostream) 2014-06-05 23:16:19 +06:00
Dennis Luxen a32116d24c Merge pull request #1063 from alex85k/patch-6
simplify static asserts
2014-06-05 18:58:08 +02:00
alex85k a03b698e5a simplify static asserts
Simplify static asserts to make them compatible with older compilers and MSVC 2013
2014-06-05 22:55:22 +06:00
Dennis Luxen fa0c5db18c include <string> as it is needed 2014-06-05 18:29:22 +02:00
Dennis Luxen bc063ded7a make sure result is always > 0, hits when origin and destination are on the same one-way segment in reversed order 2014-06-05 18:28:54 +02:00
Dennis Luxen 846505cbc8 Merge pull request #1051 from TheMarex/linker-fix
Fix linking for linux
2014-06-05 18:14:33 +02:00
Dennis Luxen 964118d1d6 add more comments and rename a couple of badly named variables 2014-06-05 17:27:00 +02:00
Patrick Niklaus c43b67ea2e Fixes build using gcc 4.9 with LTO.
Otherwise sem_close is not found.
2014-06-05 17:26:19 +02:00
Dennis Luxen f68af08931 fix short variable names and long lines 2014-06-05 15:40:52 +02:00
Dennis Luxen cdd5a41965 remove duplicate edges from NodeBasedGraph 2014-06-05 15:33:24 +02:00
Dennis Luxen e13ee59af3 remove some code lint 2014-06-05 15:14:39 +02:00
Dennis Luxen 9eb183e01d Merge branch 'alex85k-patch-timing' into develop 2014-06-05 11:22:52 +02:00
Dennis Luxen 1163417722 Merge branch 'patch-timing' of https://github.com/alex85k/Project-OSRM into alex85k-patch-timing
Conflicts:
	extractor.cpp
2014-06-05 11:22:26 +02:00
Dennis Luxen 3edc48cda5 Merge branch 'alex85k-patch-6' into develop 2014-06-05 11:04:35 +02:00
Dennis Luxen 2c01425ee5 Merge branch 'patch-6' of https://github.com/alex85k/Project-OSRM into alex85k-patch-6 2014-06-05 11:04:17 +02:00
Dennis Luxen ed9c72814f Merge pull request #1058 from alex85k/patch-4
add a safe-guard against bad input
2014-06-05 11:02:39 +02:00
Dennis Luxen adbbe2b097 fix broken transmission of checksum/hinting mechanism on shared memory 2014-06-05 10:55:27 +02:00
alex85k 7335e0809a Globally rename UUID to FingerPrint 2014-06-05 10:31:19 +02:00
alex85k 75dabb75e2 Use TimingUtil.h for all time measurement,
and make TimingUtil.h Windows-compatible
2014-06-04 19:52:34 +06:00
alex85k 15adcd24be Remove extra mutex unlocking in ConcurrentQueue.h
As discussed in https://github.com/DennisOSRM/Project-OSRM/pull/998 , unlocking the mutex is performed on destruction. Second unlocking gives an assertion (for debug version) for Windows and FreeBSD 10.
2014-06-04 18:01:48 +06:00
alex85k e98ba99331 add a safe-guard against bad input
do not write empty original_edge_data_vector to file
2014-06-04 16:02:18 +06:00
Dennis Luxen 11459d38d0 Merge pull request #1052 from alex85k/patch-4
add a cmake option WITH_TOOLS
2014-06-03 14:58:36 +02:00
alex85k baf4ea2e8c add a cmake option WITH_TOOLS 2014-06-03 18:38:33 +06:00
Dennis Luxen 6a29168c14 use EdgeWeight typedef where possible 2014-06-03 11:28:39 +02:00
Dennis Luxen a4689c7a27 add some comments to reduce NCSS complexity 2014-06-03 10:49:25 +02:00
Dennis Luxen 8fda5a187b rename variable to a shorter name 2014-06-03 10:44:09 +02:00
Dennis Luxen 7b78270f4b safe-guard against broken input data 2014-06-02 19:23:50 +02:00
Dennis Luxen afd3599a9c remove depth of nested block 2014-06-02 18:18:27 +02:00
Dennis Luxen 4bc8562cd0 further reduce lint 2014-06-02 18:18:03 +02:00
Dennis Luxen 11fed4c06c remove variable name lint 2014-06-02 16:05:19 +02:00
Dennis Luxen 9416a983c6 rename one char variable names 2014-06-02 16:04:44 +02:00
Dennis Luxen 8108c6320d use lambda for complex initialization 2014-06-02 15:56:06 +02:00
Dennis Luxen b40b931568 unlinting DouglasPeucker 2014-06-02 09:48:43 +02:00
Dennis Luxen 282f70ea91 remove debug output 2014-05-30 19:48:34 +02:00
Dennis Luxen a671f63a3e Apply strong heuristics to speed up line generalization 2014-05-30 19:10:37 +02:00
Dennis Luxen f3ad14cb7f use integer approximation for polyline generalization 2014-05-30 14:34:04 +02:00
Dennis Luxen 21eb5b661d add integer based approximation for perpendicular distance 2014-05-30 14:33:37 +02:00
Dennis Luxen 87fe073118 re-layout parameters 2014-05-30 13:30:54 +02:00
Dennis Luxen 507dadebf4 fix a couple of variable names 2014-05-30 10:15:35 +02:00
Dennis Luxen 7dac8c621c fix a couple of OCLint warning, i.e. short variable names and useless parantheses 2014-05-30 10:01:55 +02:00
Dennis Luxen 19f4ebf3c5 make threshold values floats by construction 2014-05-30 10:01:18 +02:00
Dennis Luxen c21b40bebc further renaming of variable names, reduces legacy lint 2014-05-29 19:25:17 +02:00
Dennis Luxen 0766c3c62d refactor member names in ImportEdge 2014-05-29 18:46:20 +02:00
Dennis Luxen cc40eb709c moved ImportNode/Edge into compile units 2014-05-29 18:31:20 +02:00
Dennis Luxen 3625308585 moved ImportNode/Edge into compile units 2014-05-29 18:31:02 +02:00
Dennis Luxen df3a7676eb streamline branch-and-bound query code in R-tree 2014-05-29 17:16:24 +02:00
Dennis Luxen 8f6077e973 add proper c'tor to PhantomNode 2014-05-29 17:15:41 +02:00
Dennis Luxen e6689144c4 remove debug output 2014-05-29 16:27:08 +02:00
Dennis Luxen a67de410bf move TreeNode exploration into its own function, fix performance regression 2014-05-29 15:36:14 +02:00
Dennis Luxen 54ec1a89de use complex const variable initialization w/ lambda functions instead of conditional operator 2014-05-29 12:47:03 +02:00
Dennis Luxen 4b5f744c6f move distance calculations to float 2014-05-28 18:34:48 +02:00
Dennis Luxen df978345d7 rename start->source 2014-05-28 18:20:47 +02:00
Dennis Luxen facc07c60d use correct edge weight type in PathData 2014-05-28 18:20:29 +02:00
Dennis Luxen 2f203ac22c rename start->source 2014-05-28 18:19:27 +02:00
Dennis Luxen cc864191b8 remove some unneeded flags when compiling with clang 2014-05-28 18:18:57 +02:00
Dennis Luxen 547455245e link against UUID (needed in node-OSRM) 2014-05-28 16:09:51 +02:00
Dennis Luxen b0d7449bb4 add type traits include 2014-05-28 12:53:18 +02:00
Dennis Luxen aed04c7d55 server cast int to string only where it is needed 2014-05-28 12:34:48 +02:00
Dennis Luxen bb5973f2fd rename variable 2014-05-28 12:34:24 +02:00
Dennis Luxen f801fd1f0d fix inverted logic 2014-05-28 12:06:57 +02:00
Dennis Luxen 44ca12ead6 fix inverted logic 2014-05-28 12:05:42 +02:00
Dennis Luxen 9c48389f74 collapse if statements 2014-05-28 12:03:07 +02:00
Dennis Luxen acefb5a5f3 remove debug output 2014-05-27 19:05:37 +02:00
Dennis Luxen 3d691a3aec implements #947, free osrm-datastore's shared memory 2014-05-27 18:14:43 +02:00
Dennis Luxen 38ebdbb563 implements #949, wrong duration on first segment 2014-05-27 16:54:10 +02:00
Dennis Luxen 1090325c31 remove superflous check 2014-05-27 14:50:59 +02:00
Dennis Luxen f8ba4b9312 use C++11 shrinktofit() instead of swap tricks 2014-05-27 12:16:53 +02:00
Dennis Luxen 49a1dfff60 fix off-by-one issue related to #1020 2014-05-27 12:09:05 +02:00
Dennis Luxen 5f4d342d45 move last leg handling into DescribeLeg() function 2014-05-27 11:48:19 +02:00
Dennis Luxen e1c1f79068 remove todo marker 2014-05-27 11:44:47 +02:00
Dennis Luxen a716fa252f implements #792 2014-05-27 11:16:55 +02:00
Dennis Luxen 0b12e4d8be remove assert 2014-05-27 10:45:57 +02:00
Dennis Luxen 6ad6c94355 further CMakeLists.txt lint removal 2014-05-26 18:42:29 +02:00
Dennis Luxen 78270c8155 fix unneeded variable warning in release build 2014-05-26 18:40:21 +02:00
Dennis Luxen 4573ae21e6 unlinting CMakeLists.txt 2014-05-26 18:36:11 +02:00
Dennis Luxen 0ab6220635 add some more constness 2014-05-26 18:35:37 +02:00
Dennis Luxen 3b51976b96 remove unneeded include 2014-05-26 18:11:32 +02:00
Dennis Luxen c35211b2f6 add some const keywords where applicable 2014-05-26 17:37:44 +02:00
Dennis Luxen f62515e13b commented assertion that is triggered on trivial instances 2014-05-26 16:03:08 +02:00
Dennis Luxen 7f2daf8926 some variables renamed to replace camel case 2014-05-26 16:02:15 +02:00
Dennis Luxen 0325861ef3 remove an unneeded parameter 2014-05-26 15:31:30 +02:00
Dennis Luxen 37f8285a6e implements #1020 2014-05-26 15:31:09 +02:00
Dennis Luxen d3906cffdc add property to mark end of leg 2014-05-26 15:30:06 +02:00
Dennis Luxen bee1c77efe make variable const 2014-05-26 15:29:28 +02:00
Dennis Luxen 7250a82286 remove dead code 2014-05-26 13:08:10 +02:00
Dennis Luxen 984457f9c6 remove useless parantheses, straighten includes 2014-05-26 12:49:49 +02:00
Dennis Luxen 5db23f7e46 make short variable names more legible 2014-05-26 12:49:24 +02:00
Dennis Luxen f4f49b2b46 remove unused variable 2014-05-26 12:42:47 +02:00
Dennis Luxen 58b35f6e2d make short variable names more legible 2014-05-26 12:41:25 +02:00
Dennis Luxen b51ad16756 remove useless parantheses 2014-05-26 12:37:00 +02:00
Dennis Luxen d790bda7d2 implements #986, streamline error messages 2014-05-26 12:33:35 +02:00
Dennis Luxen 15ce232f61 partially fixes #1034 2014-05-26 11:59:13 +02:00
Dennis Luxen d999a47600 partially fixes #1034 2014-05-26 11:47:01 +02:00
Dennis Luxen 644286111f add test for #1034 2014-05-26 11:46:01 +02:00
Dennis Luxen 917b1cbd6c fix index of instructions 2014-05-26 11:38:35 +02:00
Dennis Luxen 6d1b585212 remove unneeded output 2014-05-26 10:19:45 +02:00
Dennis Luxen 6ca35a6264 remove debug output 2014-05-26 09:25:42 +02:00
Dennis Luxen 0290b1b4e0 Merge branch 'dmbreaker-develop' into develop 2014-05-23 14:50:23 +02:00
Dennis Luxen 1d86bf3e56 Merge branch 'develop' of https://github.com/dmbreaker/Project-OSRM into dmbreaker-develop 2014-05-23 14:50:05 +02:00
Dennis Luxen 3fd8ab8d3a use parallel sorting when loading OSRM data files 2014-05-23 14:49:50 +02:00
Dennis Luxen d240ae3b03 sort edges in StaticGraph in parallel 2014-05-23 14:32:40 +02:00
Emil Tin b875765c52 update test to avoid single ring 2014-05-23 12:52:32 +02:00
shipenok 2bdec31219 minor fix to open result in browser 2014-05-23 14:27:55 +04:00
Emil Tin a9eebdb1fa fix test related to via points and #1034 2014-05-23 11:45:18 +02:00
Emil Tin b25f3a9e91 update test related to via points and #1034 2014-05-23 11:42:44 +02:00
Emil Tin 06f3375a97 test showing bug related to via points. see #1034 2014-05-23 11:23:11 +02:00
Dennis Luxen 5057ae920c replace a couple of std::sort calls with tbb::parallel_sort 2014-05-22 19:07:29 +02:00
Dennis Luxen 6a03f13d55 fixes #1032:
- remove left-overs from OpenMP
- replace omp_* calls with TBB equivalents
2014-05-22 18:39:11 +02:00
Dennis Luxen 20cbfd95d6 remove OpenMP references from CMakeLists.txt 2014-05-22 18:39:11 +02:00
Dennis Luxen 885dbe1e65 Merge pull request #1028 from TheMarex/tbb-port
Port from OpenMP to TBB
2014-05-22 16:57:06 +02:00
Dennis Luxen 7d7cce5c72 add better and more precise comments to Restrictionmap 2014-05-22 14:53:53 +02:00
Dennis Luxen 0c66f84555 add static assertions to SearchEngine 2014-05-22 14:41:27 +02:00
Dennis Luxen 044e41c079 make temporary variables const 2014-05-22 14:41:02 +02:00
Dennis Luxen 8dc631e13c pull math functions from std namespace 2014-05-22 14:22:10 +02:00
Dennis Luxen d93b4feb99 add some static asserts to guard against memory usage regressions 2014-05-22 12:41:25 +02:00
Dennis Luxen 0b873f590c fix typo in error message 2014-05-22 12:24:34 +02:00
Dennis Luxen f52d637f58 do less work when compressing geometries 2014-05-22 11:41:32 +02:00
Patrick Niklaus e2daf5c2fc Make some temporary variables const 2014-05-21 21:49:22 +02:00
Patrick Niklaus bef113001a Add TBB to travis.ymk 2014-05-21 21:49:22 +02:00
Patrick Niklaus f0b403bc2e Set requested threads in TBB 2014-05-21 21:49:22 +02:00
Patrick Niklaus a21fb5fc89 Use append operator instead of function, because function is inplace. 2014-05-21 21:49:22 +02:00
Patrick Niklaus bbc0424563 Set number of threads in TBB 2014-05-21 21:49:22 +02:00
Patrick Niklaus f487845e9d Port Contractor to TBB 2014-05-21 21:49:22 +02:00
Patrick Niklaus 77641a9fce Port StaticRTree to use TBB 2014-05-21 21:49:22 +02:00
Patrick Niklaus 56d93eb18b Replace omp atomic with std variant 2014-05-21 21:49:22 +02:00
Patrick Niklaus da1fd96d4e Port extractor to TBB 2014-05-21 21:49:22 +02:00
Dennis Luxen d1fdc7061f fix signed/unsigned comparison 2014-05-21 14:23:09 +02:00
Dennis Luxen 2822382797 Merge pull request #1030 from DennisOSRM/features/json-generator
Distance tables and JSON generator
2014-05-21 14:10:03 +02:00
Dennis Luxen 35c9021bdf reduce debug verbosity in RestrictionMap 2014-05-21 12:39:52 +02:00
Dennis Luxen 493b13364f move geographical distance computation to floats 2014-05-21 12:33:54 +02:00
Dennis Luxen a8ff3231a8 reduce debug verbosity 2014-05-21 12:33:14 +02:00
Dennis Luxen c2a750a690 use 100 locations at max for dist table 2014-05-21 12:29:45 +02:00
Dennis Luxen 6a9541833a add a leg to roundabout to remove edge case 2014-05-21 10:47:34 +02:00
Dennis Luxen 9117b45899 move more distance calculations to float 2014-05-21 10:03:30 +02:00
Dennis Luxen 812cf36d52 use floats instead of doubles for distance computations 2014-05-20 19:29:09 +02:00
Dennis Luxen 4aa7420d6a remove unneeded includes 2014-05-20 18:54:03 +02:00
Dennis Luxen 1802839a22 add approximator for perpendicular distance 2014-05-20 16:23:47 +02:00
Dennis Luxen 9a2d701e2e fix issue #1025:
- add function to count directed outgoing edges
- generate correct instruction for staying on a roundabout
- move test from @bug namespace to the general one
2014-05-20 15:40:14 +02:00
Dennis Luxen 69ad3f3365 add curly braces to one line if 2014-05-20 15:37:18 +02:00
Dennis Luxen d53eb881c2 revert to old boost based regex as GCC does not properly implement it prior to GCC 4.90 2014-05-20 14:33:03 +02:00
Dennis Luxen e28e45f38e remove unused variable 2014-05-20 14:33:03 +02:00
Dennis Luxen bf6ca22b00 fix #1021, always check if files exist 2014-05-20 14:33:03 +02:00
Dennis Luxen b8acbae3e8 fix #1021, always check if files exist 2014-05-20 14:33:03 +02:00
Dennis Luxen 4ec9f2c00f fix #1021, always check if files exist 2014-05-20 14:33:03 +02:00
Dennis Luxen 4fc329a1eb remove superflous way in test setup 2014-05-20 14:33:02 +02:00
Dennis Luxen 0574a60bc2 replace boost::unordered_map, move hash function for pairs into its own header 2014-05-20 14:33:02 +02:00
Dennis Luxen e490c4afed use consistent typedef'ed types 2014-05-20 14:33:02 +02:00
Dennis Luxen d028a30f87 fixes issue #1019:
- fix ignored turn restriction on chains of degree-2 nodes
- add a cucumber test to test for potential regressions
2014-05-20 14:33:02 +02:00
Dennis Luxen 75a2d4d00a minor code refactoring, wip 2014-05-20 14:33:02 +02:00
Dennis Luxen a122a1e8c7 remove comment 2014-05-20 14:33:02 +02:00
Dennis Luxen 8fe09c85b6 move atan2 lookup into trig header 2014-05-20 14:33:02 +02:00
Dennis Luxen bc951de2a5 use trig functions from std namespace 2014-05-20 14:33:01 +02:00
Dennis Luxen c970cd13cc flip bearings by 180 2014-05-20 14:33:01 +02:00
Dennis Luxen 8983c0f927 move GetBearing(.) function into FixedPointCoordinate 2014-05-20 14:33:01 +02:00
Dennis Luxen a47467f29b store facade ptr in c'tor, save a param in sub-sequent function calls 2014-05-20 14:33:01 +02:00
Dennis Luxen ef206eb4d9 clean up code a bit 2014-05-20 14:33:01 +02:00
Dennis Luxen da5eec1c5f refactor route name extraction into its own class, fix name extraction 2014-05-20 14:33:01 +02:00
Dennis Luxen a69b3535a5 fix typo 2014-05-20 14:33:01 +02:00
Dennis Luxen f4c23f3259 fix comparison 2014-05-20 14:33:01 +02:00
Dennis Luxen e36e9fd629 make comparsion explicitly unsigned 2014-05-20 14:33:00 +02:00
Dennis Luxen d2f19353ed remove some debug output 2014-05-20 14:33:00 +02:00
Dennis Luxen 2d498cb88b adapt JSON parsing in tests to allow for omitted fields 2014-05-20 14:33:00 +02:00
Dennis Luxen a80815d57a implements output generation through a dedicated JSON container:
- JSON syntax is not scattered over several files, but one place
- Reduces code duplication
- breaking changes:
  - new property in json(p) formatted response: "found_alternative": True/False
  - returned filenames now response.js(on) or route.gpx
  - /hello plugin returns JSON now
2014-05-20 14:33:00 +02:00
Dennis Luxen acab77f4f8 add simple isValid() function to PhantomNodes 2014-05-20 14:33:00 +02:00
Emil Tin bddad0c57c add test for roundabout with oneone links 2014-05-20 13:27:32 +02:00
Dennis Luxen 3968349480 deactivate LTO on debug build 2014-05-16 15:00:31 +02:00
Dennis Luxen 3ae17761b3 rename variables 2014-05-14 08:54:36 +02:00
Dennis Luxen 9a28bdbf76 reorder some includes 2014-05-14 08:53:26 +02:00
Dennis Luxen e769821e0f use range based for loops to traverse graphs 2014-05-13 16:56:30 +02:00
Dennis Luxen 9b68821f05 move common code into its own header 2014-05-13 13:30:52 +02:00
Dennis Luxen b2adb22b2d remove whitespace 2014-05-13 12:41:40 +02:00
Dennis Luxen 981941edf4 leave early to reduce scope nesting 2014-05-13 12:22:42 +02:00
Dennis Luxen 111dea89a9 use std::abs instead of hand-rolled substitute 2014-05-13 12:22:14 +02:00
Dennis Luxen 2720f4de9c add parantheses to fix compiler warning 2014-05-13 10:22:54 +02:00
Dennis Luxen 21645643b0 minor reformatting 2014-05-13 10:20:39 +02:00
Dennis Luxen c6a07acd90 use std::packaged_task and std::future to simulate boost::thread::timed_join() 2014-05-13 10:03:37 +02:00
Dennis Luxen 1816e6607e remove boost::thread from Server 2014-05-13 10:02:36 +02:00
Dennis Luxen 37dd05a9b5 Merge branch 'TheMarex-atan-perf' into develop 2014-05-13 10:00:45 +02:00
Patrick Niklaus 529997de9b Add atan based on lookup table. Again 6% improvement. 2014-05-13 02:20:33 +02:00
Patrick Niklaus 4f37270300 Simple fix that improves runtime of edge based egde generation by 26% 2014-05-13 01:00:24 +02:00
Dennis Luxen faf9c96442 fix regression in debug build 2014-05-12 18:09:25 +02:00
Dennis Luxen f7e09686e5 Merge branch 'TheMarex-lto-fix' into develop 2014-05-12 11:05:26 +02:00
Dennis Luxen 8eef8204e7 Merge branch 'lto-fix' of https://github.com/TheMarex/Project-OSRM into TheMarex-lto-fix 2014-05-12 11:05:15 +02:00
Dennis Luxen 8b8e08f0f5 use less than 4GB on 32 bits. fixes #1008 2014-05-12 10:57:02 +02:00
Dennis Luxen a6bfec22b5 return gracefully instead of failing of geometry is only a single node 2014-05-12 10:33:37 +02:00
Patrick Niklaus d05c4fa9ed Fix lto option in gcc 4.9 by using gcc-ar / gcc-ranlib 2014-05-11 21:56:09 +02:00
Dennis Luxen 07231d3706 reformatting RequestHandler 2014-05-11 18:06:52 +02:00
Dennis Luxen 584ba10726 reformatting RequestHandler 2014-05-11 18:03:05 +02:00
Dennis Luxen 24a61dc650 remove unused function parameters 2014-05-11 17:58:37 +02:00
Dennis Luxen 7e7aa6aaee workaround incomplete std::shared_ptr compatibility of old boost versions 2014-05-11 16:51:14 +02:00
Dennis Luxen 35c5be6475 add missing includes <string> and <limits> 2014-05-10 14:54:46 +02:00
Dennis Luxen fcf3eb6193 fix yet another missing include on GCC 4.7 (again) 2014-05-09 19:55:27 +02:00
Dennis Luxen 5226b200e7 fix yet another missing include on GCC 4.7 2014-05-09 19:50:16 +02:00
Dennis Luxen 5f57152156 fix missing include 2014-05-09 19:46:37 +02:00
Dennis Luxen 633ef26054 fix compile warning 2014-05-09 19:42:15 +02:00
Dennis Luxen 285bd4f542 further climits madness 2014-05-09 19:41:36 +02:00
Dennis Luxen e706fb973f build fixes on GCC 2014-05-09 19:35:09 +02:00
Dennis Luxen 8dc7afed4e remove even more climits 2014-05-09 19:26:37 +02:00
Dennis Luxen 0c7f996de6 use std numeric limits instead of climits 2014-05-09 19:22:38 +02:00
Dennis Luxen 985a8e9f97 removing boost cref and betting on move semantics 2014-05-09 19:10:11 +02:00
Dennis Luxen 5e26e4c22d replacing all boost unordereds 2014-05-09 18:40:07 +02:00
Dennis Luxen 00e27e4b5c replace left-overs from boost::shared_ptr usage 2014-05-09 17:04:55 +02:00
Dennis Luxen b3ec9c9323 reformat 2014-05-09 16:48:58 +02:00
Dennis Luxen 84ffedd95d replace boost::shared_ptr 2014-05-09 16:47:42 +02:00
Dennis Luxen 455dc26a5d add constexpr for invalid name id 2014-05-09 16:18:06 +02:00
Dennis Luxen 0fccd0f0d2 refactor Extractor/ 2014-05-09 16:17:31 +02:00
Dennis Luxen 7e639d6bc1 remove white space 2014-05-09 16:16:51 +02:00
Dennis Luxen 694ce9d04f add forgotten include 2014-05-09 15:12:42 +02:00
Dennis Luxen aebe8572f9 reformat NodeBasedGraph 2014-05-09 14:21:52 +02:00
Dennis Luxen c98eed612a C++11-fy Contractor/ 2014-05-09 14:21:33 +02:00
Dennis Luxen 5f0ee417b1 move BFS component exploration into Algorithms/ 2014-05-09 14:21:02 +02:00
Dennis Luxen a6b4658138 move BFS component exploration into Algorithms/ 2014-05-09 14:20:45 +02:00
Dennis Luxen 1a57aff0f4 remove unneeded boost include 2014-05-09 14:12:10 +02:00
Dennis Luxen afc0bac232 remove boost/noncopyable, fwd decl 2014-05-09 14:08:56 +02:00
Dennis Luxen ac1c59b724 port TimingUtil header to C++11s <chrono> 2014-05-09 11:49:03 +02:00
Dennis Luxen 1f9806386e port TimingUtil header to C++11s <chrono> 2014-05-09 11:48:48 +02:00
Dennis Luxen 1b67120704 readd <chrono> include lost in rebase 2014-05-09 11:31:37 +02:00
Dennis Luxen 5579388896 Merge branch 'TheMarex-ebgf-refactor' into develop 2014-05-09 11:29:48 +02:00
Dennis Luxen 49c972983d Merge branch 'ebgf-refactor' of https://github.com/TheMarex/Project-OSRM into TheMarex-ebgf-refactor 2014-05-09 11:29:30 +02:00
Dennis Luxen 3cb34f8036 remove debug output 2014-05-09 11:23:56 +02:00
Dennis Luxen 3c5b2286a3 adjust speeds to universally use 4/5th of the free-flow speed as expected avg speed
- this is a workaround until we get more thourough work done on the cost model
- this is related to #955 and #989
2014-05-09 11:11:14 +02:00
Patrick Niklaus 845972daa5 Add timing to EBGF 2014-05-09 00:56:07 +02:00
Patrick Niklaus e00ef38305 Apply clang-format on BFSComponentExplorer and RestrictionMap 2014-05-09 00:37:05 +02:00
Patrick Niklaus 22d0861f6d Move BFSComponentExplorer to Contractor/ 2014-05-09 00:37:05 +02:00
Patrick Niklaus 5265f38c35 Switched to std::shared_ptr in Contractor/ 2014-05-09 00:37:05 +02:00
Patrick Niklaus d13cd4d4b3 Apply clang-format on Contractor/ 2014-05-09 00:31:52 +02:00
Patrick Niklaus 79d33d669c Apply clang-modernize to Contractor/ 2014-05-09 00:06:25 +02:00
Patrick Niklaus 439f6e62bc Replace numeric_limits with SPECIAL_NODEID / SPECIAL_EDGEID 2014-05-09 00:06:25 +02:00
Patrick Niklaus 3ef054bbac Split EBGF::Run into smaller sub-functions
I'm not too happy with this yet. It is not really clear cut.
Also, I would like to move the logging in ::Run, seems messy in the
sub-functions.
2014-05-09 00:05:27 +02:00
Patrick Niklaus 5a13c6cc3f Move BFSComponentExplorer to own header. 2014-05-09 00:05:27 +02:00
Patrick Niklaus b7750ff742 Reorder initialization to fix warnings 2014-05-09 00:05:27 +02:00
Patrick Niklaus 2c0fa2a9f6 Split RestrictionMap and NodeBasedGraph from EdgeBasedGraphFactory
First step in an effort to simplify EdgeBasedGraphFactory.
2014-05-09 00:05:27 +02:00
Dennis Luxen 881a57bf8d refactor and migrate root directory 2014-05-08 19:40:32 +02:00
Dennis Luxen c924b2067c refactor and migrate root directory 2014-05-08 19:40:29 +02:00
Dennis Luxen fdd0c8470f refactor Tools dir for C++11 2014-05-08 18:34:58 +02:00
Dennis Luxen 1960c38468 refactor Tools dir for C++11 2014-05-08 18:33:38 +02:00
Dennis Luxen 3074a0146e remove superflous boost include 2014-05-08 18:26:07 +02:00
Dennis Luxen f060dfda40 refactor list of const static int into scoped enum 2014-05-08 18:04:05 +02:00
Dennis Luxen b0ead129ca use proper types instead of implicit casts 2014-05-08 16:39:38 +02:00
Dennis Luxen abe9c4d53c use nullptr instead of NULL 2014-05-08 16:39:17 +02:00
Dennis Luxen 15a95ff425 remove superflous includes 2014-05-08 15:49:32 +02:00
Dennis Luxen 37b8f97d60 C++11 migration:
- use lambda functions instead of binding member functions
- replace boost::mutex by STLs <mutex>
- reformat according to new guidelines
2014-05-08 15:47:48 +02:00
Dennis Luxen 88a4bb4d12 implement locking properly with std::mutex and std::lock_guard<> 2014-05-08 15:25:06 +02:00
Dennis Luxen 50594febc7 consequently use emplace back instead of push 2014-05-08 11:18:46 +02:00
Dennis Luxen 9587923e55 make variable names consistent, migrate Plugins 2014-05-08 11:15:19 +02:00
Dennis Luxen 2850a074ea make sure parameter is not negative
- fixes coverity issue 1198843 Argument cannot be negative
2014-05-08 08:56:51 +02:00
Dennis Luxen bed5c8002f pass parameter by ref instead of by val:
- fixes coverity issue 1212009 Big parameter passed by value
2014-05-08 08:48:55 +02:00
Dennis Luxen cc982a578d deactivate the cool put_time thing in C++11 as GCC craps out again 2014-05-07 19:30:22 +02:00
Dennis Luxen e12ad48822 migrate DataStructures to C++11 2014-05-07 18:39:16 +02:00
Dennis Luxen 6abbb06ff6 replace UINT_MAX by numeric limits max() 2014-05-07 17:25:35 +02:00
Dennis Luxen 3d68769503 reformat Server source and migrate it to C++11 2014-05-07 17:14:57 +02:00
Dennis Luxen bd316e7e98 reformat Server/RequestHandler according to guideline 2014-05-07 17:08:30 +02:00
Dennis Luxen 3f4c4d675b reformat Server/APIGrammar according to guideline 2014-05-07 17:06:28 +02:00
Dennis Luxen 4b7e5b7445 reformat Server/APIGrammar according to guideline 2014-05-07 17:05:33 +02:00
Dennis Luxen 996dbdde00 reformat Server/DataStructure according to guideline 2014-05-07 17:03:58 +02:00
Dennis Luxen db67f2ddf1 reformat files according to guidelines, remove superflous inclue 2014-05-07 16:58:32 +02:00
Dennis Luxen 7b9b2fd23a use C++11's put time to put the timestamp 2014-05-07 16:50:48 +02:00
Dennis Luxen 700747801c use proper include prefix 2014-05-07 16:46:52 +02:00
Dennis Luxen cb30f4668e fix broken include 2014-05-07 16:45:48 +02:00
Dennis Luxen 9710f39cad remove (almost) all BOOST_FOREACH calls 2014-05-07 16:17:47 +02:00
Dennis Luxen e3244dd649 migrate Library dir to C++11, use fwd decls 2014-05-07 16:17:14 +02:00
Dennis Luxen abd20776a2 reformat file in Include 2014-05-07 15:37:39 +02:00
Dennis Luxen 5d8b4cb261 use numeric limits instead of C-style UINT_MAX 2014-05-07 15:37:22 +02:00
Dennis Luxen 9ee615020f break out RouteParameters into compile unit 2014-05-07 15:36:53 +02:00
Dennis Luxen acef734643 break out RouteParameters into compile unit 2014-05-07 15:33:24 +02:00
Dennis Luxen 0ff7ac6aad migrate HilbertValue class to C++11, use fwd decl, remove boost/integer 2014-05-07 14:47:23 +02:00
Dennis Luxen 859502c504 remove boost/integer include 2014-05-07 14:46:46 +02:00
Dennis Luxen 9c2926ef8a remove boost/integer include 2014-05-07 14:44:18 +02:00
Dennis Luxen 3188bc5aba add include for Linux 2014-05-07 14:30:38 +02:00
Dennis Luxen bf9d9512a0 fix typo 2014-05-07 14:24:04 +02:00
Dennis Luxen ba03f99e09 migrate UUID class to C++11, untangle includes, cut back compile time 2014-05-07 14:13:41 +02:00
Dennis Luxen 8e89f80588 make space usage more tight in Coordinate->String conversion 2014-05-07 14:12:57 +02:00
Dennis Luxen 07e245eb02 migrate StringUtil.h to C++11 2014-05-07 14:12:28 +02:00
Dennis Luxen ea12c6fde6 untangle includes a bit 2014-05-07 14:11:59 +02:00
Dennis Luxen 38c7d07e50 remove old way to delete copy c'tor 2014-05-07 12:32:39 +02:00
Dennis Luxen a0a835bbe6 migrate SimpleLogger to C++11 2014-05-07 12:18:13 +02:00
Dennis Luxen c09e897dab migrate ProgramOptions to C++11 2014-05-07 12:05:51 +02:00
Dennis Luxen c5a3937c80 use constexpr to aid compiler 2014-05-07 12:04:42 +02:00
Dennis Luxen 8e6cc09d2f reformat OSRMException.h 2014-05-07 11:55:29 +02:00
Dennis Luxen dee3529f14 reformat OpenMPWrapper.h 2014-05-07 11:42:41 +02:00
Dennis Luxen bf5d83d228 reformat MercartorUtil.h 2014-05-07 11:42:13 +02:00
Dennis Luxen c2b7336817 reformat MachineInfo.h 2014-05-07 11:38:22 +02:00
Dennis Luxen fc6017c0dd reformat LuaUtil.h 2014-05-07 11:38:11 +02:00
Dennis Luxen 821cc3a177 add missing semi-colon 2014-05-07 10:39:35 +02:00
Dennis Luxen 8939cef020 further C++11 migration 2014-05-07 10:39:35 +02:00
Dennis Luxen fb17653651 add chrono in more places 2014-05-07 10:39:35 +02:00
Dennis Luxen f8a07c7a03 add chrono include 2014-05-07 10:39:35 +02:00
Dennis Luxen eb89436df3 replace all timing by C++11's chrono 2014-05-07 10:39:35 +02:00
Dennis Luxen c1e7ba7118 replace all timing by C++11's chrono 2014-05-07 10:39:34 +02:00
Dennis Luxen ffddea75a4 remove dead code 2014-05-07 10:39:34 +02:00
Dennis Luxen 380111a604 move Azimuth.h to C++11 2014-05-07 10:39:34 +02:00
Dennis Luxen dd4461d473 remove broken assert 2014-05-07 10:39:34 +02:00
Dennis Luxen 2706a0bec1 revert:
- GCC <4.8 does not support thread_local keyword.
- sticking with boost::thread_specific_ptr<> for now
2014-05-07 10:39:34 +02:00
Dennis Luxen 46b207e08e mega-patch:
- fix regression that turned tree into binary search
- use C++11 emplace and thread local facility
- sort out includes
- use much faster approximations to save on trigonometry
- use higher fan-out but make leafs a little more compact
- replace raw C-style array by C++11's std::array
2014-05-07 10:39:34 +02:00
Dennis Luxen d3eda80969 fix include order 2014-05-07 10:38:32 +02:00
Dennis Luxen 66fb5fc9c8 allow approximation of euclidian distances by lat/lon components 2014-05-07 10:38:31 +02:00
Dennis Luxen 2d3fb858ad move StaticGraph to C++11 2014-05-07 10:38:31 +02:00
Dennis Luxen 7bf74c0917 replace UINT_MAX with proper numeric limits call 2014-05-07 10:38:31 +02:00
Dennis Luxen 5b22dffa6f move BinaryHeap to C++11 2014-05-07 10:38:31 +02:00
Dennis Luxen 3ca9420801 fix signed/unsigned comparison 2014-05-07 10:38:31 +02:00
Dennis Luxen 3c948a82c0 reintroduce pesky cmath include 2014-05-07 10:38:31 +02:00
Dennis Luxen c33c6188a8 migrating Algorithms directory to C++11 2014-05-07 10:38:31 +02:00
Dennis Luxen 0d8f2e1b18 remove debug counter, thx @springmeyer 2014-05-07 10:38:31 +02:00
Dennis Luxen 17ed4f908c (partially) migrate Descriptors to use C++11 syntax 2014-05-07 10:38:31 +02:00
Dennis Luxen 946bfb9a26 migrate plugins directory to C++11 2014-05-07 10:38:31 +02:00
Dennis Luxen 6c2c48a611 install luabind manually on Travis 2014-05-07 10:38:30 +02:00
Dennis Luxen 1f36cf9242 bump boost to 1.54 on Travis 2014-05-07 10:38:30 +02:00
Dennis Luxen 3ddac9ac5d fix typo 2014-05-07 10:38:30 +02:00
Dennis Luxen 1b22b348b0 pull boost 1.54 from correct ppa 2014-05-07 10:38:30 +02:00
Dennis Luxen f68721af07 ignore patch if already applied 2014-05-07 10:38:30 +02:00
Dennis Luxen d53b7de5ec patch boost the correct way 2014-05-07 10:38:30 +02:00
Dennis Luxen b25f3891c8 don't install unnecessary libs, patch boost 2014-05-07 10:38:30 +02:00
Dennis Luxen ca58c9ce09 install all libboost 1.49 more explicitly on travis 2014-05-07 10:38:30 +02:00
Dennis Luxen 7a2a535f87 install all libboost 1.49 explicitly on travis 2014-05-07 10:38:30 +02:00
Dennis Luxen 17d220187a install libboost 1.49 explicitly on travis 2014-05-07 10:38:29 +02:00
Dennis Luxen d3a4857826 bump min boost version to 1.49, install from ppa 2014-05-07 10:38:29 +02:00
Dennis Luxen e64fec15b0 pick up g++-4.7 thru cmake variable 2014-05-07 10:38:29 +02:00
Dennis Luxen 3d5f566d86 pick up g++-4.7 thru environment variable 2014-05-07 10:38:29 +02:00
Dennis Luxen c87b63cb24 add ppa quietly 2014-05-07 10:38:29 +02:00
Dennis Luxen cd95f9310b bump builds on travis to gcc/g++ 4.7 2014-05-07 10:38:29 +02:00
Dennis Luxen 297128c19c activate C+11 flags by default 2014-05-07 10:38:29 +02:00
Dennis Luxen 25a385c940 activate C+11 flags by default 2014-05-07 10:38:29 +02:00
Dennis Luxen 181e814139 fix twisted conversion, fixes #1000 2014-05-07 10:38:29 +02:00
Patrick Niklaus 52e5483dfb Display number threads that are really used 2014-05-07 10:38:29 +02:00
Patrick Niklaus 56f6c795ed Fix typos 2014-05-07 10:38:29 +02:00
Dennis Luxen 5d8cfa465b flush less often to disk 2014-05-07 10:38:28 +02:00
Dennis Luxen b6ca4a7a46 fix potential resource leak 2014-05-07 10:38:28 +02:00
Dennis Luxen a45508a96b fix coverity issues 2014-05-07 10:38:28 +02:00
Dennis Luxen a45d274847 fix Linux cmath include 2014-05-07 10:38:28 +02:00
Dennis Luxen e3cc896a42 consolidate duplicated distance calculations 2014-05-07 10:38:28 +02:00
Dennis Luxen 99a47ae87b reduce debug verbosity 2014-05-07 10:38:28 +02:00
Emil Tin b1388b6f30 remove spurious test file 2014-05-07 10:38:28 +02:00
Emil Tin 2cddf90e49 test different status message and query parsing 2014-05-07 10:38:28 +02:00
Emil Tin 85148d1283 tests covering no route found 2014-05-07 10:38:28 +02:00
Dennis Luxen 7b0b378abc fix a performance regression 2014-05-07 10:35:56 +02:00
Dennis Luxen a1ecab2f95 refactor xml parser, uses faster string to double conversion 2014-04-29 16:05:34 +02:00
Dennis Luxen b7704f0c7f fix regression that seg faults if path not found 2014-04-29 11:46:05 +02:00
Dennis Luxen d6962f3a09 fix geometry load on shared memory 2014-04-29 09:50:29 +02:00
Dennis Luxen e44ebe0743 minor refactoring of code layout 2014-04-28 19:37:42 +02:00
Dennis Luxen f02ec41fbc move raw pointer to smart ptrs 2014-04-28 19:37:23 +02:00
Dennis Luxen d0b4ffd154 fix openmp woes on linux 2014-04-28 18:23:56 +02:00
Dennis Luxen 265af1f790 minor refactoring 2014-04-28 17:27:15 +02:00
Dennis Luxen 241d6b482e reenable traffic signal penalty in car profile 2014-04-28 17:26:31 +02:00
Dennis Luxen 45f0af2afc remove unnecessary else statements 2014-04-28 15:08:54 +02:00
Dennis Luxen 7955066d5c remove bitwise operator in conditional 2014-04-28 15:06:26 +02:00
Dennis Luxen ec3f9695cd remove redundant local variable 2014-04-28 13:26:20 +02:00
Dennis Luxen 018c144c76 minor refactoring 2014-04-28 13:19:35 +02:00
Dennis Luxen 56e88b2a56 minor refactoring 2014-04-28 13:19:26 +02:00
Dennis Luxen a2bdc5d8d9 minor refactoring 2014-04-28 13:08:25 +02:00
Dennis Luxen 1b257f7547 fix inverted logic 2014-04-28 13:03:20 +02:00
Dennis Luxen 5d6b05979d remove unused variable 2014-04-28 12:59:24 +02:00
Dennis Luxen 538f8d040a avoid short variable name 2014-04-28 12:58:40 +02:00
Dennis Luxen 7d52aa1272 avoid short variable name 2014-04-28 12:58:00 +02:00
Dennis Luxen d316202834 avoid private static function 2014-04-28 12:56:32 +02:00
Dennis Luxen 0167dfc3c9 shorten line 2014-04-28 12:54:11 +02:00
Dennis Luxen 02dc3dee04 shorten line 2014-04-28 12:52:55 +02:00
Dennis Luxen a5d3bc9578 make function call more legible 2014-04-28 12:52:06 +02:00
Dennis Luxen cfbc6b0441 remove useless parantheses 2014-04-28 12:50:44 +02:00
Dennis Luxen 8c5f8e995e stream-lined error messages: partially implements #986 2014-04-28 11:55:46 +02:00
Dennis Luxen b77dd6699d Merge pull request #992 from DennisOSRM/feature/remove_geometry
Feature/remove geometry
2014-04-28 11:34:49 +02:00
Dennis Luxen 9a153708e6 minor reformatting / shaping up 2014-04-25 16:00:39 +02:00
Dennis Luxen e0027a78e1 fix signed unsigned comparison 2014-04-25 15:48:10 +02:00
Dennis Luxen 51e8113a69 make tests use fuzzy matching instead of tweaked expectations 2014-04-25 15:24:18 +02:00
Dennis Luxen 78f5753a3a fix signed/unsigned comparison 2014-04-25 14:42:06 +02:00
Dennis Luxen 16ca8da438 remove deactivated debug out for good 2014-04-25 13:31:08 +02:00
Dennis Luxen ca6515c58a fix tests to reflect proper rounding of travel times 2014-04-25 13:23:27 +02:00
Dennis Luxen 2ec952032a fix rounding of travel times 2014-04-25 13:22:58 +02:00
Dennis Luxen b0b67a0cdc fix typo setting potentially wrong flags in debug build 2014-04-24 18:14:35 +02:00
Dennis Luxen 0eed39cdf1 rebase branch onto develop 2014-04-24 18:13:50 +02:00
Dennis Luxen ace59411cb fix and/or remove unused variables 2014-04-24 13:31:04 +02:00
Dennis Luxen ef7619d664 fix signed/unsigned comparison 2014-04-24 13:31:04 +02:00
Dennis Luxen 0f8a32f38c shape up code 2014-04-24 13:31:04 +02:00
Dennis Luxen c6a58ff1b4 remove debug lint again 2014-04-24 13:31:04 +02:00
Dennis Luxen 45f751720a fix unpacking of geometry for shared memory 2014-04-24 13:31:04 +02:00
Dennis Luxen ca016e2818 fix unpacking of geometry for shared memory 2014-04-24 13:31:04 +02:00
Dennis Luxen 5da01946b8 fix unpacking of geometry for shared memory 2014-04-24 13:17:11 +02:00
Dennis Luxen 8b3002a685 fix unpacking of geometry for shared memory 2014-04-24 13:17:11 +02:00
Dennis Luxen ede5cca2e7 fix unpacking of geometry for shared memory 2014-04-24 13:17:11 +02:00
Dennis Luxen d0e158ca07 fix unpacking of geometry for shared memory 2014-04-24 13:17:11 +02:00
Dennis Luxen 09dc21af31 remove debug lint 2014-04-24 13:17:11 +02:00
Dennis Luxen 2435fadfbd use boost filesystem specialization instead of the ones from std 2014-04-24 13:15:26 +02:00
Dennis Luxen edef9c11f7 add default clause to switch statement albeit technically superflous 2014-04-24 13:06:57 +02:00
Dennis Luxen 2c9edcaf23 remove debug code 2014-04-24 13:06:57 +02:00
Dennis Luxen 18861d58b5 compile fix for linux / wrong include 2014-04-24 13:06:57 +02:00
Dennis Luxen 9b3dab8055 implement loading of compressed geometries 2014-04-24 13:06:56 +02:00
Dennis Luxen 7a6a5f6612 implement population of shared vector<bool> overload (manually, yikes) 2014-04-24 13:06:56 +02:00
Dennis Luxen f468fcc2b6 implement more details of shared memory store 2014-04-24 13:06:56 +02:00
Dennis Luxen 5d93c68790 remove further debug things 2014-04-24 13:06:56 +02:00
Dennis Luxen fa04706484 remove debug code, add C++11 todo 2014-04-24 13:06:56 +02:00
Dennis Luxen d09be5a80e remove debug code, make variables const 2014-04-24 13:06:56 +02:00
Dennis Luxen a4d6e5c9cc reformat geometry compressor according to new guidelines 2014-04-24 13:06:56 +02:00
Dennis Luxen 4f85fd28cf add todo for the switch to C++11 2014-04-24 13:06:56 +02:00
Dennis Luxen 39914cd933 remove some debug code 2014-04-24 13:06:56 +02:00
Dennis Luxen 038e8cc8b8 remove unneeded edge-offset during query 2014-04-24 13:06:55 +02:00
Dennis Luxen db5fd5506d partial implementation of new datastore functions 2014-04-24 13:06:55 +02:00
Dennis Luxen f2be495e95 implement shared data facade geometry loader and getter functions 2014-04-24 13:06:55 +02:00
Dennis Luxen 6d8465a04d implement geometry uncompressing using STL 2014-04-24 13:06:55 +02:00
Dennis Luxen 4bb5270f25 cut back debug verbosity 2014-04-24 13:06:55 +02:00
Dennis Luxen 0f06c71796 remove debug output 2014-04-24 13:06:55 +02:00
Dennis Luxen 5b8d8a83dd fix mangled offsets and edge weights on compressed edges (all tests passing) 2014-04-24 13:06:55 +02:00
Dennis Luxen 8ec3d549a6 further fixes but forward/reverse edge weights are reversed 2014-04-24 13:06:55 +02:00
Dennis Luxen 394e369b54 fix edge-expanded offsets 2014-04-24 13:06:55 +02:00
Dennis Luxen 899ab9ddc0 remove some uncommented code 2014-04-24 13:06:54 +02:00
Dennis Luxen 8ae467985f turn off colored logging if output is redirected to file 2014-04-24 13:06:54 +02:00
Dennis Luxen 9ccc8a7404 remove first segment if distance is 0 (down to 7 failed) 2014-04-24 12:55:53 +02:00
Dennis Luxen 0b89a9d554 ignore last edge-expanded segment if it spans over to undistinguishable node-based nodes (down to 9 failed) 2014-04-24 12:55:53 +02:00
Dennis Luxen 752fb880be switch edge-expanded street name indexes to be first segment names (18 failed tests left) 2014-04-24 12:55:53 +02:00
Dennis Luxen 549bcb502b minor renaming efforts 2014-04-24 12:55:53 +02:00
Dennis Luxen 44077cb007 refactor and streamline use of TurnInstructionsClass members 2014-04-24 12:55:53 +02:00
Dennis Luxen 7b5902a580 rename phantom nodes members 2014-04-24 12:55:53 +02:00
Dennis Luxen 2861bacd2a fix check for invalid phantom nodes (20 failed left) 2014-04-24 12:55:53 +02:00
Dennis Luxen 776ac3bb2a remove superflous include 2014-04-24 12:55:52 +02:00
Dennis Luxen b429d9f509 remove unreachable code 2014-04-24 12:55:52 +02:00
Dennis Luxen 26397e4692 remove debug output 2014-04-24 12:55:52 +02:00
Dennis Luxen 48d23194af fix traffic signal penalty in compressed graph 2014-04-24 12:55:52 +02:00
Dennis Luxen bcaea1a617 remove debug output 2014-04-24 12:54:25 +02:00
Dennis Luxen 12b43d206c unpack properly when source and target are reversed on same edge 2014-04-24 12:54:24 +02:00
Dennis Luxen 9cc49f6ff3 remove debug output 2014-04-24 12:54:24 +02:00
Dennis Luxen 87f036e538 fixing sentinel nodes in adjacency list graph data structure 2014-04-24 12:54:24 +02:00
Dennis Luxen fdebec6448 correct partial distances 2014-04-24 12:51:18 +02:00
Dennis Luxen ba37836e24 allow graphs with zero edges to load 2014-04-24 12:51:18 +02:00
Dennis Luxen b60cfd9294 last segment gets it proper name now 2014-04-24 12:51:17 +02:00
Dennis Luxen bc0665cd9f fix offsets for start and end 2014-04-24 12:51:17 +02:00
Dennis Luxen 0dbe5e6593 fix shortest ch query for certain cases 2014-04-24 12:51:17 +02:00
Dennis Luxen 9b33aaa11a fix test for borked lat/lons 2014-04-24 12:51:17 +02:00
Dennis Luxen 024b78da7c Forward decl to cut compile times 2014-04-24 12:51:17 +02:00
Dennis Luxen 2a64297506 Forward decl to cut compile times 2014-04-24 12:51:17 +02:00
Dennis Luxen 09c76939f1 minor code beauty issue 2014-04-24 12:51:17 +02:00
Dennis Luxen 0b3f3bdf92 fix test for borked lat/lons 2014-04-24 12:51:17 +02:00
Dennis Luxen 3b29eeb6b6 unpacking start and target edge fixes plus some refactoring 2014-04-24 12:51:16 +02:00
Dennis Luxen 985270bb02 parse maxspeed in LUA 2014-04-24 12:51:16 +02:00
Dennis Luxen 6b91d6692f unpacking target correctly, also partial unpacking origin and destination are on the very same packed edge 2014-04-24 12:47:36 +02:00
Dennis Luxen eca09e6c81 unpacking of target segment works 2014-04-24 12:47:00 +02:00
Dennis Luxen 874c579f86 correctly unpacking the first segment 2014-04-24 12:15:48 +02:00
Dennis Luxen a0bddab169 3/4 unpack cases working 2014-04-24 12:15:04 +02:00
Dennis Luxen b679a94930 first segment needs to be properly cut 2014-04-24 12:15:04 +02:00
Dennis Luxen 5bde545ce3 All good, but needs unpacking of start and end 2014-04-24 12:07:46 +02:00
Dennis Luxen e68c750389 remove boost typedefs 2014-04-24 12:05:43 +02:00
Dennis Luxen f16cb3c52d compressed geometries get serialized in R-tree 2014-04-24 12:05:43 +02:00
Dennis Luxen f7d5b0db9c uncompressed edges get serialized correctly'ish 2014-04-24 12:05:43 +02:00
Dennis Luxen ba0b664e3f further copy edits 2014-04-24 12:05:43 +02:00
Dennis Luxen 149d037824 further copy edits 2014-04-24 12:05:43 +02:00
Dennis Luxen d0349d9b0d further copy edits 2014-04-24 12:05:42 +02:00
Dennis Luxen c71c8b0047 Unpacking of intermediate paths 2014-04-24 12:03:19 +02:00
Dennis Luxen 3be644265b remove remnants of C-Style includes 2014-04-24 11:38:54 +02:00
Dennis Luxen cd6874ca60 remove remnants of C-Style includes 2014-04-24 11:28:12 +02:00
Dennis Luxen 7083978f9d remove remnants of C-Style includes 2014-04-24 11:28:12 +02:00
Dennis Luxen 4d132489c1 remove remnants of C-Style includes 2014-04-24 11:28:11 +02:00
Dennis Luxen b5170ed1fd remove trivial geometry nodes 2014-04-24 11:28:11 +02:00
Dennis Luxen cc915dbef2 take 2: workaround platform dependend outputs, discussed in #986 2014-04-21 19:25:24 +02:00
Dennis Luxen 9a5bf1ee95 workaround platform dependend outputs, discussed in #986 2014-04-21 18:31:45 +02:00
Dennis Luxen a14b6af5c0 Merge branch 'develop' of https://github.com/DennisOSRM/Project-OSRM into develop 2014-04-21 17:41:54 +02:00
Dennis Luxen ec372ad01d implement tests marked todo, implements #986 2014-04-21 17:40:08 +02:00
Dennis Luxen 8a412ef69e implementing option tests marked @todo 2014-04-21 17:40:08 +02:00
Dennis Luxen c978364f49 implementing option tests marked @todo 2014-04-21 17:40:07 +02:00
Emil Tin 61d2a99dd4 remove left-over feature file 2014-04-21 17:40:07 +02:00
Emil Tin fdba916d83 cuke: fix options test, should use osrm file, not osm 2014-04-21 17:40:07 +02:00
Emil Tin a12209e61d cuke: test options for osrm-extract and osrm-prepare 2014-04-21 17:40:07 +02:00
Patrick Niklaus fc6607ce9e better error messages for extractor
Previously extractor would just crash because of unhandled exceptions.
Now it displays meaningful error messages.
2014-04-21 17:40:07 +02:00
Dennis Luxen 62ccbc7490 use insert(.) on unordered map instead of access operator, potential resource leak 2014-04-21 17:40:07 +02:00
Dennis Luxen b2b36984e1 make single parameter c'tor explicit 2014-04-21 17:40:07 +02:00
Dennis Luxen c10208407d Revert "fix resource leak, coverity issue 1198844"
This reverts commit 3a1a51ac46.
2014-04-21 17:40:07 +02:00
Dennis Luxen 64720c2d2e several lints fixed that were detected by facebook's flint 2014-04-21 17:40:07 +02:00
Dennis Luxen da81e4839a reverse include order 2014-04-21 17:40:07 +02:00
Dennis Luxen 25013afdd2 make single argument c'tor explicit (thx flint) 2014-04-21 17:40:06 +02:00
Dennis Luxen 678829ab28 fix include order (thx flint) 2014-04-21 17:40:06 +02:00
Dennis Luxen d8dffa9d71 make single paramter c'tors explicit (thx flint) 2014-04-21 17:40:06 +02:00
Dennis Luxen be8810077a make single paramter c'tors explicit (thx flint) 2014-04-21 17:40:06 +02:00
Dennis Luxen ee4ecb9783 fix inverted logic 2014-04-21 17:40:06 +02:00
Dennis Luxen eaed8572f0 make all error messages JSON 2014-04-21 17:40:06 +02:00
Dennis Luxen e91e6fb068 check for invalid parameter, coverity issue 1198843, also reformat source 2014-04-21 17:40:06 +02:00
Dennis Luxen cb17a0a49b fix resource leak, coverity issue 1198844 2014-04-21 17:40:06 +02:00
Dennis Luxen 248df9ca2d catch exceptions that may occur, coverity issue 1198845 2014-04-21 17:40:06 +02:00
Dennis Luxen fa615ed9f4 don't binpack parameters on 100 column width 2014-04-21 17:40:05 +02:00
Dennis Luxen 65aa4af6d9 allow 120 char wide columns 2014-04-21 17:40:05 +02:00
Dennis Luxen df56ad476e add clang format style file (to change) 2014-04-21 17:40:05 +02:00
Dennis Luxen 8e20fa89e8 catch exceptions that may occur, coverity issue 1198846 2014-04-21 17:40:05 +02:00
Dennis Luxen 76058729e0 dont reset coloring when it wasn't set in the first place, partially fixes Windows woes. See #979 2014-04-21 17:40:05 +02:00
Dennis Luxen 88a0cc8c9c dont reset coloring when it wasn't set in the first place 2014-04-21 17:40:05 +02:00
Dennis Luxen 2ea45c0c58 implement tests marked todo, implements #986 2014-04-21 17:29:48 +02:00
Dennis Luxen bf27f41f52 implementing option tests marked @todo 2014-04-21 17:21:02 +02:00
Dennis Luxen 853f6012d5 implementing option tests marked @todo 2014-04-21 17:20:15 +02:00
Emil Tin 14ad02777f remove left-over feature file 2014-04-21 17:18:30 +02:00
Emil Tin c1eb00f6d5 cuke: fix options test, should use osrm file, not osm 2014-04-21 16:07:03 +02:00
Emil Tin e5adaf974d cuke: test options for osrm-extract and osrm-prepare 2014-04-21 15:24:42 +02:00
Patrick Niklaus 727a29600d better error messages for extractor
Previously extractor would just crash because of unhandled exceptions.
Now it displays meaningful error messages.
2014-04-19 13:19:48 +02:00
Dennis Luxen a5ebdb9243 use insert(.) on unordered map instead of access operator, potential resource leak 2014-04-17 11:05:26 +02:00
Dennis Luxen 2ef37ee798 make single parameter c'tor explicit 2014-04-17 10:30:15 +02:00
Dennis Luxen c23575786c Revert "fix resource leak, coverity issue 1198844"
This reverts commit 3a1a51ac46.
2014-04-16 18:13:59 +02:00
Dennis Luxen 5a0d693c93 several lints fixed that were detected by facebook's flint 2014-04-16 16:59:40 +02:00
Dennis Luxen c6902528b3 reverse include order 2014-04-16 16:22:13 +02:00
Dennis Luxen f90993be86 make single argument c'tor explicit (thx flint) 2014-04-16 16:21:16 +02:00
Dennis Luxen e7db076648 fix include order (thx flint) 2014-04-16 16:16:42 +02:00
Dennis Luxen 6d52a7d3d4 make single paramter c'tors explicit (thx flint) 2014-04-16 16:15:49 +02:00
Dennis Luxen 3368b492b9 make single paramter c'tors explicit (thx flint) 2014-04-16 16:13:48 +02:00
Dennis Luxen 1222aa6d25 fix inverted logic 2014-04-09 23:10:58 -04:00
Dennis Luxen 67efd150d4 make all error messages JSON 2014-04-09 18:12:45 -04:00
Dennis Luxen 9894f2e053 check for invalid parameter, coverity issue 1198843, also reformat source 2014-04-09 12:03:19 -04:00
Dennis Luxen 3a1a51ac46 fix resource leak, coverity issue 1198844 2014-04-09 11:59:48 -04:00
Dennis Luxen a1b5429f4e catch exceptions that may occur, coverity issue 1198845 2014-04-09 11:57:15 -04:00
Dennis Luxen b11e39554f don't binpack parameters on 100 column width 2014-04-09 11:55:59 -04:00
Dennis Luxen a92c764945 allow 120 char wide columns 2014-04-09 11:48:48 -04:00
Dennis Luxen f581396f1d add clang format style file (to change) 2014-04-09 11:44:56 -04:00
Dennis Luxen 6814926f05 catch exceptions that may occur, coverity issue 1198846 2014-04-09 11:34:15 -04:00
Dennis Luxen b8f882dba4 dont reset coloring when it wasn't set in the first place, partially fixes Windows woes. See #979 2014-04-07 15:11:04 -04:00
Dennis Luxen 783e8edf71 dont reset coloring when it wasn't set in the first place 2014-04-07 15:07:07 -04:00
Dennis Luxen 966f1d654e Merge branch 'develop' for release v0.3.8 2014-04-04 15:35:37 +02:00
Dennis Luxen 02adaac468 remove an empty line to test jenkins web hook, take 2 2014-04-03 19:45:00 +02:00
Dennis Luxen 2b2a0d685f remove an empty line to test jenkins web hook 2014-04-03 19:27:13 +02:00
Dennis Luxen 6f2ec17640 pass path as ref to JSONDescriptor.h 2014-04-03 18:28:16 +02:00
Dennis Luxen 6c158f5a1b move typedef into a single line 2014-04-03 12:08:51 +02:00
Emil Tin df83dfdfe8 cuke: test travel time of individual instructions 2014-04-02 16:05:09 +02:00
Dennis Luxen 165c252fc8 disable lto partitioning when possible (fixes GCC < 4.8 issues, e.g. Debian stock compiler) 2014-04-02 10:49:32 +02:00
Dennis Luxen d21f63d327 activate LTO on platforms that support it, ie. most recent compilers 2014-04-01 18:11:45 +02:00
Dennis Luxen 05c33bee78 Merge pull request #973 from DennisOSRM/fix/clean_profile_indentation
cleanup indentation of lua profiles
2014-04-01 17:07:39 +02:00
Emil Tin 762dd17512 cleanup indentation of lua profiles 2014-04-01 15:40:52 +02:00
Emil Tin 5f7065848e clean cucumber comments, fixes 'file to long' problem with latest version of cucumber 2014-04-01 15:30:55 +02:00
Emil Tin 65e020a627 cuke: use new speed tests where relevant 2014-04-01 14:56:25 +02:00
Emil Tin 793e477898 active tests for fixed bugs 2014-04-01 14:56:25 +02:00
Dennis Luxen a5232f857e failed tests fail the build, see #970 2014-04-01 12:41:48 +02:00
Dennis Luxen 0ef7a72b33 Merge PR #970 'experimental/cuke_import_format' into develop 2014-04-01 12:02:56 +02:00
Emil Tin 717787ff62 travis: set osrm timeout to 60s 2014-03-31 21:46:01 +02:00
Emil Tin 2d599a5190 cuke: optional timeout 2014-03-31 21:45:53 +02:00
Emil Tin e73145d558 travis: set osrm timeout to 60s 2014-03-31 16:55:39 +02:00
Emil Tin 220e7748a9 cuke: use .osm by default, add tests for .pbf 2014-03-31 16:55:39 +02:00
Emil Tin 72f41c5b4f check for empty input in extractor, same msg in prepare 2014-03-31 16:55:39 +02:00
Emil Tin 775627473a remove .osm deprecation warning 2014-03-31 16:55:39 +02:00
Emil Tin ba2356d2ba cuke: optional timeout 2014-03-31 16:55:01 +02:00
Emil Tin 179f53b21b cuke: fix test for -v on travis 2014-03-31 15:29:00 +02:00
Emil Tin 3ccd3b5650 cuke: increase osrm launch/shutdown timeout 2014-03-31 13:55:29 +02:00
Dennis Luxen 224655f8cb fix osmosis install on Travis CI. May fix #970 2014-03-31 11:53:10 +02:00
Emil Tin fd96c7c488 fix travel speeds for cars 2014-03-27 18:22:04 +01:00
Emil Tin 45c96f73c2 cuke test showing odd car speeds 2014-03-27 18:02:42 +01:00
Emil Tin c5893ef6e8 cuke: check for invalid expectation formats 2014-03-27 17:32:37 +01:00
Emil Tin 8b1f09d302 cuke: test speed, fix logging, clear log files on each run 2014-03-27 10:38:03 +01:00
Emil Tin cb1b824a75 cuke: improve routability tables, test for speed 2014-03-27 10:38:02 +01:00
Emil Tin b0ce9e4af7 cuke: don't use scenario outlines, to fix problem with jenkins 2014-03-27 10:38:02 +01:00
Dennis Luxen aae3637e0c implements #958 2014-03-25 14:54:52 +01:00
Dennis Luxen 33faa2f252 set output size on StockReplies properly 2014-03-24 18:13:40 +01:00
andrewbts 482d79ef4b Fix comment typo
SharedDataFacade.h is for the shared memory case; old comment implied the opposite.
2014-03-24 15:52:54 +01:00
Dennis Luxen 6bdd517c43 new cucumber profile for Jenkins that doesn't fail because of an old Gherkin bug 2014-03-24 14:29:19 +01:00
Dennis Luxen a337109618 implements #961 2014-03-24 12:16:30 +01:00
Dennis Luxen 0ae5ace520 Merge PR #960 2014-03-24 11:30:55 +01:00
Dennis Luxen a4306cddef remove NO-BREAK SPACE (U+00A0) that broke testing 2014-03-24 10:16:32 +01:00
Dennis Luxen 1f97c5518e fixes build errors from 9e10b94 2014-03-24 10:06:42 +01:00
Clint Harris 1823a4da36 Added missing Boost date_time component. Resolves issue #925. 2014-03-22 12:30:24 -04:00
Clint Harris d60caf7095 CMake now adds RPATH info to executables. Resolves issue #960. 2014-03-22 11:44:51 -04:00
Emil Tin 9e10b94339 cuke: test file options 2014-03-22 12:01:07 +01:00
Emil Tin 7048dd754d cuke: check exit code as last step, add step to non-existing file 2014-03-22 00:47:20 +01:00
Emil Tin de29e17d95 cuke: add a few options steps 2014-03-22 00:38:53 +01:00
Emil Tin c299989ff7 reorganize options tests 2014-03-22 00:33:23 +01:00
Emil Tin 0b655ea6a1 trial option 2014-03-22 00:16:45 +01:00
Dennis Luxen 538827942a workaround for inconsistent error messages across boost versions 2014-03-20 14:38:16 +01:00
Dennis Luxen 8bd5f69e04 fixes #958, activates 2 additional tests 2014-03-20 13:19:36 +01:00
Dennis Luxen c470ea9fa1 lock to RAM on Linux only after options are parsed 2014-03-20 09:53:05 +01:00
Emil Tin c1806476af cuke: test osrm-routed options 2014-03-19 19:28:24 +01:00
Emil Tin af41c9f6e4 cuke: detach osrm-routed to avoid zombie processes 2014-03-19 18:03:47 +01:00
Dennis Luxen 823e8d24b5 deactivate file validation as it is externally handled 2014-03-18 16:27:46 +01:00
Dennis Luxen 4028c0b24f implement proper checks for conflicting inputs 2014-03-18 16:22:42 +01:00
Dennis Luxen 2e4ff30103 fix parameter regression when using shared memory 2014-03-18 10:51:36 +01:00
Dennis Luxen 121dcca7e3 refactor a bit for better readability 2014-03-17 15:46:13 +01:00
Dennis Luxen 5adfe2d46b transfrom short switch statements into readable if statements 2014-03-17 15:45:47 +01:00
Dennis Luxen 03f4aaa2d6 make functions const, make short variable name more telling 2014-03-17 15:31:13 +01:00
Dennis Luxen d67c3f36ff call function object instead of static function 2014-03-17 15:28:42 +01:00
Dennis Luxen e199d30beb move static function into funtion object 2014-03-17 15:27:33 +01:00
Dennis Luxen 27e2de2b1f fix inverted logic 2014-03-17 15:19:24 +01:00
Dennis Luxen 8a6d07342e remove redundant local variable 2014-03-17 15:14:29 +01:00
Dennis Luxen ab39457fe1 move bit-wise operator out of conditions 2014-03-17 15:13:36 +01:00
Dennis Luxen e6933ea413 avoid private static member functions 2014-03-17 15:12:13 +01:00
Dennis Luxen 422e0c44d5 reverse inverted logic 2014-03-17 14:55:33 +01:00
Dennis Luxen ad03b409ab make variable names more telling 2014-03-17 14:42:24 +01:00
Dennis Luxen 38ae213260 make variable names more telling 2014-03-17 14:40:10 +01:00
Dennis Luxen 6a0a59896e make variable names more telling 2014-03-17 14:39:24 +01:00
Dennis Luxen 187cb56364 split long line in two 2014-03-17 14:37:33 +01:00
Dennis Luxen 1fe96d0d22 remove collapsable if statement 2014-03-17 14:36:34 +01:00
Dennis Luxen 52b859b3e6 remove pesky fun ptr from CRC32 computation 2014-03-17 11:07:01 +01:00
Dennis Luxen 9483b781e2 provide better feedback on command lines 2014-03-14 11:14:19 +01:00
Dennis Luxen 791f475168 implement #951, better command line handling 2014-03-14 10:15:39 +01:00
Dennis Luxen 6b69d6dce2 implements #951 2014-03-13 22:48:09 +01:00
Dennis Luxen 720abbc81e minor tweak to disable C++11 flag on demand 2014-03-13 22:08:03 +01:00
Dennis Luxen e3183cfd16 set stdlib explicitly, fix indentations 2014-03-13 13:28:58 +01:00
Dennis Luxen e07423f260 minor copy-edits to PR #946 2014-03-12 13:56:25 +01:00
Daniel Karch ecfda146b2 minor change 2014-03-12 10:48:54 +01:00
Daniel Karch f923f508f5 applied requested changes to EdgeBasedNode.h 2014-03-12 10:24:35 +01:00
Daniel Karch b465dabe77 Refactored the EdgeBasedNode class.
This includes more robust computations in ComputePerpendicularDistance.
There were cases where ComputePerpendicularDistance divided by zero and had
to handle special cases, even though this was not necessary.
2014-03-11 16:40:20 +01:00
Dennis Luxen d8d6b91257 std lib adjustable on all versions of OS X 2014-03-06 14:48:20 +01:00
Dennis Luxen 0946fac11f Escape characters in JSON instead of HTML-entetizing, implements #895 2014-03-04 14:54:41 +01:00
Dennis Luxen c50b69c654 Escape characters in JSON instead of HTML-entetizing, implements #895 2014-03-04 14:54:34 +01:00
Dennis Luxen 32bf99ba40 decode all URIs, fixes #937, 386 2014-03-04 13:56:11 +01:00
Dennis Luxen 0baa8215ef fix unitialized variable warning 2014-03-04 13:52:41 +01:00
Dennis Luxen 85a007d87b set backward speed properly, partially fixes #936 2014-03-03 15:31:57 +01:00
Dennis Luxen 7b14de13ec assign complete edge data if duplicate shortcut edge has lower weight 2014-03-03 14:08:34 +01:00
Dennis Luxen 117ebe1c32 add switch to override stdlib implementation on OS X < 10.9 2014-02-27 11:07:53 +01:00
Dennis Luxen 2b010811d8 fixes #932, and partially also fixes #921 2014-02-25 12:50:08 +01:00
Dennis Luxen 4b94f1fa83 implements compilation issues on non-X86(-64) targets, also see #921 2014-02-25 10:57:57 +01:00
Dennis Luxen d73f3ebd1b fix tests for scaled maxspeeds 2014-02-14 18:23:25 +01:00
Dennis Luxen 4c48cda4cd refactor HashTable facade class 2014-02-14 18:18:26 +01:00
Dennis Luxen 9e64ccdbf2 scale maxspeeds to 2/3 to be more realistic and in sync with the default profile 2014-02-14 18:17:37 +01:00
Dennis Luxen aedf9d3a91 run debug build on different port 2014-02-14 18:17:00 +01:00
Dennis Luxen 0ee94a5729 add new tool to ignore list 2014-02-13 18:11:53 +01:00
Dennis Luxen 2130630293 run tests on different ports 2014-02-12 16:34:46 +01:00
Dennis Luxen 445cf5d42c ignore broken osmosis from Travis CI repo 2014-02-12 16:25:57 +01:00
Dennis Luxen 08f13a1776 install osmosis manually 2014-02-12 16:22:26 +01:00
Dennis Luxen f406dc51fa Merge branch 'patch-1' of https://github.com/alex85k/Project-OSRM into alex85k-patch-1 2014-02-12 15:27:12 +01:00
Dennis Luxen 7580777e43 implement and use portable implementation of canonical file paths, see #909, this time against dev branch 2014-02-11 15:55:22 +01:00
Dennis Luxen ea30005762 fixes and closes #914 and updates #907 2014-02-11 14:34:47 +01:00
Dennis Luxen 7794cd6274 do not instantiate shared memory facility in routed, fixes #905 and #910 2014-02-11 11:35:29 +01:00
Dennis Luxen 45a4fe44f7 disable cucumber tests until the travis CI issues are sorted out 2014-02-10 16:53:29 +01:00
Dennis Luxen 1d225078eb install osmosis manually, take three 2014-02-10 16:01:48 +01:00
Dennis Luxen 533caf8c0f install osmosis manually, take two 2014-02-10 15:45:24 +01:00
Dennis Luxen e6c25ae290 install osmosis manually 2014-02-10 15:35:36 +01:00
Dennis Luxen 264077acac install libpostgis-java to fulfil dependencies 2014-02-10 15:21:48 +01:00
Dennis Luxen 0ff18881b6 explicit rvm use, workaround for Travis CI testing woes 2014-02-10 15:02:05 +01:00
Dennis Luxen 9e0e536dbc fix yml syntax 2014-02-10 11:58:56 +01:00
Dennis Luxen 1a9e54ba33 install bundler without sudo, change Travis environment 2014-02-10 11:57:48 +01:00
Dennis Luxen 9378af1057 fixes #907, segfault when ampersands where missing 2014-02-10 11:43:26 +01:00
Dennis Luxen cd6075a884 Merge pull request #906 from andrewbts/patch-1
Fix comment typo
2014-02-05 20:41:12 +01:00
andrewbts 1da3a00b92 Fix comment typo
SharedDataFacade.h is for the shared memory case; old comment implied the opposite.
2014-02-05 11:19:33 -08:00
alex85k 275961f088 Fix assertion in debug version
When running tests on FreeBSD 10 on debug verion I got boost assertion errors in mutex.hpp:79 . 

It seems that mutex unlock is not needed (it is already unlocked and behavior is undefined).
2014-02-04 19:56:23 +06:00
Dennis Luxen f14fac3f7d fixes off-by-one and testing issue discussed in 889 2014-02-01 16:02:43 +01:00
Dennis Luxen ce784e0491 distinguish between left and right, thx @emiltin 2014-01-27 12:58:23 +01:00
Dennis Luxen 65ad3bb941 fix test regression 2014-01-27 12:55:17 +01:00
Dennis Luxen b5b4280c3b remove c-style calls to fabs 2014-01-27 11:26:34 +01:00
Dennis Luxen 0649f6e607 preparing call of turn penalty function 2014-01-27 11:18:26 +01:00
Dennis Luxen 22c2efded9 Some mild refactoring of the BinaryHeap code. style only 2014-01-24 11:24:23 +01:00
Dennis Luxen 7825279405 reverting back to two cores on travis 2014-01-24 10:17:57 +01:00
Dennis Luxen 2623c7023c compile on travis with the maximum number of cores 2014-01-23 13:47:05 +01:00
Dennis Luxen 2138fdfadf re-enable cucumber tests on travis CI 2014-01-23 13:44:40 +01:00
Dennis Luxen 40517e3010 implements #872 2014-01-23 13:31:29 +01:00
Dennis Luxen 1341214044 Add fwd decl to slash compile time 2014-01-23 13:30:38 +01:00
Dennis Luxen 34e2ef13cf use z0 parameters on z0 2014-01-23 13:20:57 +01:00
Dennis Luxen 058219528d fix floating point accuracy woes on certain hardware platforms 2014-01-22 19:35:30 +01:00
Dennis Luxen f4bd175616 fixes #881 2014-01-22 14:52:31 +01:00
Dennis Luxen fea0c07e1c implements #386 2014-01-21 16:31:29 +01:00
Dennis Luxen f684fa9a7b fix tests to resemble the fixed duration calculation 2014-01-21 16:11:51 +01:00
Dennis Luxen 2855b94aa8 remove disabled debug output 2014-01-21 15:12:06 +01:00
Dennis Luxen 9958aaae4f fixes #871 2014-01-20 19:24:20 +01:00
Dennis Luxen 289e5ada2c catch prev. uncaught exception, coverity issue 1121925 2014-01-09 18:21:07 +01:00
Dennis Luxen 648eed6532 fix resource leak, performance issue, alternative route success rate. coverity issue 971431 2014-01-09 18:05:29 +01:00
Dennis Luxen d94955d51e fix resource leak, coverity issue #1121924 2014-01-09 17:11:31 +01:00
Dennis Luxen 046fe93f1f refactor ExtractorStructs.h for faster compiles. achieves approx. 10 secs 2014-01-09 16:13:35 +01:00
Dennis Luxen ce60af5029 fixes issues #770 and #856 2014-01-08 17:18:59 +01:00
Dennis Luxen dbe70ffc8a save 4 bytes per internal edge 2014-01-08 17:11:31 +01:00
Dennis Luxen 8acf081be3 remove dead function decl 2013-12-27 15:47:51 +01:00
Dennis Luxen c5f6065280 reorder code to make it a bit more readable 2013-12-27 12:38:08 +01:00
Dennis Luxen 07509ba5c9 remove left-over debug output 2013-12-27 12:15:17 +01:00
Dennis Luxen 8b3c8f7093 refactoring variable names and layout to be more readable 2013-12-23 17:55:29 +01:00
Dane Springmeyer c3e0b68399 fix pkg-config --static when pthread is reported 2013-12-21 13:14:48 -05:00
Dane Springmeyer f0dd1fdfc7 pkg-config fixes 2013-12-20 14:00:30 -05:00
DennisOSRM 5fd8c0938a include and typo fixes 2013-12-20 18:14:09 +01:00
DennisOSRM b3f4aa4504 further include cleanup 2013-12-20 18:01:53 +01:00
DennisOSRM 4718cf6cc0 fixed signed/unsigned comparison 2013-12-20 15:30:39 +01:00
DennisOSRM ac07c78664 build libOSRM static library implicitly. Overridable by -DBUILD_SHARED_LIBS:BOOL=OFF 2013-12-20 13:24:25 +01:00
DennisOSRM 4a3db7e2c3 Merging PR #847 manually 2013-12-20 13:15:57 +01:00
DennisOSRM a23158f986 remove deleted files 2013-12-20 13:14:02 +01:00
DennisOSRM 838322299a generate pkgconfig file 2013-12-20 13:13:35 +01:00
DennisOSRM 41f3f53540 move includes to include/osrm 2013-12-20 13:12:56 +01:00
Dennis Luxen a26d982f52 deactivate dead code 2013-12-19 19:19:26 +01:00
Dane Springmeyer 5e4121ac58 libosrm as static lib 2013-12-18 18:08:25 -05:00
Dennis Luxen 81d8c8f9bf don't inline code in debug build 2013-12-18 18:33:24 +01:00
Dennis Luxen 0c34addfa7 fix signed/unsigned comparison 2013-12-18 15:50:14 +01:00
Dennis Luxen 6a68fe6a4f fix comparison between signed and unsigned integer 2013-12-18 13:19:23 +01:00
Dennis Luxen 0d246a4422 enable profiling information in debug build 2013-12-18 13:16:32 +01:00
Dennis Luxen 991c9f2f8b remove superflous include 2013-12-18 12:01:16 +01:00
Dennis Luxen ffd36b5489 add missing include 2013-12-18 12:00:58 +01:00
Dennis Luxen b9149658a8 remove unused variable 2013-12-18 12:00:35 +01:00
Dennis Luxen 21ff3fbccd un-lint'ing CMakeLists.txt 2013-12-17 21:42:00 +01:00
Dennis Luxen 90efbefbec install includes to include/osrm 2013-12-17 20:26:15 +01:00
Dennis Luxen 8f89d75edc remove deleted files from repo 2013-12-17 18:02:49 +01:00
Dennis Luxen 5d082f53ae remove deleted files from repo 2013-12-17 18:02:34 +01:00
Dennis Luxen 591d79ba49 remove deleted files from repo 2013-12-17 18:02:24 +01:00
Dennis Luxen 5ee6ede824 remove deleted files from repo 2013-12-17 18:02:01 +01:00
Dennis Luxen 095a58b1bd remove deleted files from repo 2013-12-17 18:01:42 +01:00
Dennis Luxen fd2f000075 install lib header files with make install target 2013-12-17 17:59:44 +01:00
Dane Springmeyer bb244646df bake gitdescription and uuid into OSRM library to avoid failure points of linking them directly 2013-12-16 18:49:35 -05:00
Dane Springmeyer 238dd07cf6 fix linking order to unbreak linux builds against static protobuf and libz 2013-12-16 17:03:17 -05:00
Dennis Luxen aea5e446e5 minor efficiency improvements 2013-12-16 19:52:57 +01:00
Dennis Luxen 203beff4d2 remove dead code 2013-12-16 18:33:08 +01:00
Dennis Luxen cb6f4ad646 (partially) sanitize capitalization 2013-12-16 17:58:57 +01:00
Dennis Luxen f7b72dd136 minor typo 2013-12-16 17:52:45 +01:00
Dennis Luxen 96aff57275 fixes #731, perpendicular projection to nearest location 2013-12-16 17:36:36 +01:00
Dennis Luxen 4b46d07380 remove debug output 2013-12-16 17:32:55 +01:00
Dennis Luxen 204f7c918e remove empty line 2013-12-16 17:26:18 +01:00
Dennis Luxen b1c83e6588 link against right pthreads library 2013-12-16 17:25:17 +01:00
Dennis Luxen c55bd11377 Merge PR 838
Conflicts:
	CMakeLists.txt
2013-12-16 12:52:41 +01:00
Dennis Luxen 885a9df356 remove duplicate symbol 2013-12-16 11:39:38 +01:00
Dennis Luxen 0a373018c6 properly link osrm-prepare 2013-12-16 11:36:59 +01:00
Dennis Luxen 8c4c1a56fd reduce compile time by using fwd decls 2013-12-16 11:29:38 +01:00
Dennis Luxen de790c7c19 delete file 2013-12-16 11:21:46 +01:00
Dennis Luxen 3c2bf76103 implements #839, check for 32 bits properly, bump required boost version to 1.46 2013-12-16 11:21:30 +01:00
Dane Springmeyer 13bc41fc36 CMake: Respect CXXFLAGS set in environment
Without this change the `CXXFLAGS` environment setting is not respected (tested on OS X 10.8/clang++)
2013-12-15 15:32:15 -05:00
Dennis Luxen 758027e2e0 untangling includes to cut down compile time 2013-12-13 18:49:05 -05:00
Dennis Luxen 25b352aeab add/delete several files 2013-12-13 17:27:31 -05:00
Dennis Luxen b030fe7db2 break out Coordinate in compile unit 2013-12-13 17:26:57 -05:00
Dennis Luxen 9b09c9f0c3 move includes into compile unit 2013-12-13 12:34:21 -05:00
Dennis Luxen de73809bb9 remove unneeded includes 2013-12-13 12:33:41 -05:00
Dennis Luxen 7144f69683 movve osrm class into hidden object 2013-12-13 12:32:24 -05:00
Dennis Luxen c3396fa6fd add compile targets for the main binaries (not the aux utils) 2013-12-13 10:55:57 -05:00
Dennis Luxen 924a41a2f4 Initialize pointer always 2013-12-13 09:52:57 -05:00
Dennis Luxen a492bf3885 kill superflous semicolon 2013-12-13 09:52:22 -05:00
Dennis Luxen 662714fca3 add another minor viaroute check 2013-12-12 18:37:36 -05:00
Dennis Luxen 4fc4e93ab5 adapt tests to changed output, killed version and transactionId 2013-12-12 18:37:00 -05:00
Dennis Luxen d0b5929a9e explicitly give the locations of all via locations in response 2013-12-12 18:35:23 -05:00
Dennis Luxen 58dc98460b remove left-over todo marker 2013-12-12 18:33:27 -05:00
Dennis Luxen e0dd4848b0 add function to set edge target 2013-12-12 18:32:12 -05:00
Dennis Luxen cef01f5dbc remove superflous blank padding 2013-12-12 18:31:08 -05:00
Dennis Luxen 88af9c545b add util funtion to iterate adjacent pairs of a stl compliant container 2013-12-12 18:29:51 -05:00
Dennis Luxen cd1f45e248 Util/ContainerUtils.h 2013-12-12 18:28:39 -05:00
Dennis Luxen d5eee3138f fixes issues #768, #794, #812 2013-12-11 15:36:32 -05:00
Dennis Luxen fdfe0ce63d Implements #822 (partially) 2013-12-09 14:20:35 -05:00
Dennis Luxen ba6641ed9a fix node-OSRM build, https://github.com/DennisOSRM/node-OSRM/issues/19 2013-12-09 12:03:02 -05:00
Dennis Luxen fb13e3ddb8 add new include 2013-12-09 11:47:42 -05:00
Dennis Luxen ca17efd764 break out OriginalEdgeData class into its own include 2013-12-09 11:45:45 -05:00
Dennis Luxen dd104a49f6 break-out Requesthandler into compile unit 2013-12-09 10:54:17 -05:00
Dennis Luxen b849d008d2 break-out Requesthandler into compile unit 2013-12-09 10:48:32 -05:00
Dennis Luxen 1e09935501 make counters available in release and debug build, take2 2013-12-09 09:17:38 -05:00
Dennis Luxen d7e558350b make counters available in release and debug build 2013-12-09 09:04:44 -05:00
Dennis Luxen 04afe8fbf1 remove pesky sstream 2013-12-08 19:43:43 +01:00
Dennis Luxen 392726bad3 remove pesky sstream 2013-12-08 19:42:48 +01:00
Dennis Luxen 19285d61ab reorder includes to cut compile time 2013-12-08 19:38:13 +01:00
Dennis Luxen 015b29e8a3 remove superflous ifdef 2013-12-08 19:12:01 +01:00
Dennis Luxen aff61dbc3e remove unused include 2013-12-08 19:11:38 +01:00
Dennis Luxen 37f5d755f1 break out header file in compile unit 2013-12-08 19:11:22 +01:00
Dennis Luxen 98cd3465d3 remove dead code 2013-12-08 19:11:03 +01:00
Dennis Luxen 009f08dca3 Refactoring PathData class 2013-12-08 19:10:10 +01:00
Dennis Luxen 2edf4906a4 refactoring SegmentInformation to fit into a cache line 2013-12-08 18:33:53 +01:00
Dennis Luxen ee6c15b997 remove self include 2013-12-08 16:30:08 +01:00
Dennis Luxen 03df07e4b6 rebasing develop on master branch. 2013-12-08 15:52:53 +01:00
Dennis Luxen 501f2f8267 workaround for #783 2013-12-08 15:52:23 +01:00
Dennis Luxen e949677c48 fixes #808 2013-12-08 15:52:23 +01:00
Dennis Luxen b2512915ae cache dependencies on travis ci 2013-12-08 15:52:23 +01:00
Dennis Luxen dc9db06cc8 reverting skeleton, introducing later 2013-12-08 15:52:23 +01:00
Dennis Luxen cb5931aaeb add skeleton for geometry compression 2013-12-08 15:52:23 +01:00
Dennis Luxen da17e55657 don't use clang specific defines 2013-12-08 15:52:22 +01:00
Dennis Luxen f47d944349 do not seek in temporary storage 2013-12-08 15:52:22 +01:00
Dennis Luxen 682079adc6 add buffering to temporary storage 2013-12-08 15:52:22 +01:00
Dennis Luxen f0fb97e67c add buffering to temporary storage 2013-12-08 15:52:22 +01:00
Dennis Luxen 6e5058f95f further refactoring and code simplification 2013-12-08 15:52:22 +01:00
Dennis Luxen 31b8997518 partially fixes #768, #794, #812 2013-12-08 15:52:22 +01:00
Dennis Luxen 76a9723268 remove dead code 2013-12-08 15:52:22 +01:00
Dennis Luxen 5fe79764de implements #801 2013-12-08 15:52:22 +01:00
Dennis Luxen 186859fcf0 clean up of build config 2013-12-08 15:52:22 +01:00
Dennis Luxen b545d60453 temporarily fixes #811 plus 16 others 2013-12-08 15:52:22 +01:00
DennisOSRM f68a046080 cast to larger data type on 32bits, probably fixes #809 2013-12-08 15:52:22 +01:00
Dennis Luxen f77fa5b34c clear memory early by swap trick 2013-12-08 15:52:21 +01:00
Dennis Luxen 38bf0c276c moving BFS exploration into its own function 2013-12-08 15:52:21 +01:00
Dennis Luxen ef5c8c24a8 fixing coverity issue 2013-12-08 15:52:21 +01:00
Dennis Luxen 4e8fb92e07 renaming file 2013-12-08 15:52:21 +01:00
Dennis Luxen 4f1ff5b24c renaming file 2013-12-08 15:52:21 +01:00
Dennis Luxen 22abc27b6b use explicit unsigned type in max operation 2013-12-08 15:52:21 +01:00
Dennis Luxen 19f6d885fe remove potential division by zero 2013-12-08 15:52:21 +01:00
Dennis Luxen b19a633441 add geometry compressor 2013-12-08 15:52:21 +01:00
Dennis Luxen 997dcad799 make rtree query do O(1) allocations only 2013-12-08 15:52:21 +01:00
Dennis Luxen e35efd001c move implementation details out of templat'ized container code 2013-12-08 15:52:21 +01:00
Dennis Luxen 50d6b10be4 move distance computation from r-tree to element type class 2013-12-08 15:52:21 +01:00
Dennis Luxen 5ef7ea794a move Hilbert curve computation in compile unit 2013-12-08 15:52:20 +01:00
Dennis Luxen e70485f1fd workaround for #783 2013-12-06 15:08:36 +01:00
Rodolphe Quiedeville f55f8a3629 [options] string is more explicit 2013-12-06 13:23:25 +01:00
Dennis Luxen fbbd6caf97 Merge pull request #818 from rodo/master
Add missing option '-p' in help message
2013-12-06 04:14:59 -08:00
Dennis Luxen bde3f95ae9 fixes #808 2013-12-06 12:06:51 +01:00
Dennis Luxen a5c406a4dd cache dependencies on travis ci 2013-12-06 10:14:42 +01:00
Rodolphe Quiedeville 58a57543ce [options] string is more explicit 2013-12-04 15:48:28 +01:00
Dennis Luxen e32bc5e186 reverting skeleton, introducing later 2013-11-29 19:00:00 +01:00
Dennis Luxen 7a5f45ac94 add skeleton for geometry compression 2013-11-29 18:49:02 +01:00
Dennis Luxen 657f7577bf don't use clang specific defines 2013-11-29 16:37:36 +01:00
Dennis Luxen 48355447f9 do not seek in temporary storage 2013-11-29 16:27:26 +01:00
Dennis Luxen c8f7e6331b add buffering to temporary storage 2013-11-29 15:38:21 +01:00
Dennis Luxen 40bb27c95f add buffering to temporary storage 2013-11-29 15:38:15 +01:00
Dennis Luxen 78f8124c63 further refactoring and code simplification 2013-11-28 18:50:12 +01:00
Dennis Luxen 94d5bcbf1c partially fixes #768, #794, #812 2013-11-28 15:26:13 +01:00
Dennis Luxen ad5d8c6f9a remove dead code 2013-11-28 15:24:23 +01:00
Dennis Luxen 4911601b24 implements #801 2013-11-27 23:24:00 +01:00
Dennis Luxen cb86d3d829 clean up of build config 2013-11-27 17:27:47 +01:00
Dennis Luxen 24c6314f1a Merge branch 'develop' of https://github.com/DennisOSRM/Project-OSRM into develop 2013-11-27 16:37:48 +01:00
Dennis Luxen 02e2b3bd47 temporarily fixes #811 plus 16 others 2013-11-27 16:37:40 +01:00
DennisOSRM ec84b3a0ca cast to larger data type on 32bits, probably fixes #809 2013-11-26 22:41:01 +01:00
Dennis Luxen 4455e816aa clear memory early by swap trick 2013-11-26 19:56:45 +01:00
Dennis Luxen 3df89c0dfe moving BFS exploration into its own function 2013-11-26 19:43:30 +01:00
Dennis Luxen f5d22c904f fixing coverity issue 2013-11-26 19:41:55 +01:00
Dennis Luxen 2233c44d36 renaming file 2013-11-26 19:41:36 +01:00
Dennis Luxen d5f6c1c15c renaming file 2013-11-26 19:41:32 +01:00
Dennis Luxen e36a27307b use explicit unsigned type in max operation 2013-11-26 14:27:19 +01:00
Dennis Luxen cf527ed819 remove potential division by zero 2013-11-26 14:25:53 +01:00
Dennis Luxen a8e8833a8d add geometry compressor 2013-11-25 19:05:58 +01:00
Dennis Luxen 349df0dc94 make rtree query do O(1) allocations only 2013-11-22 18:58:58 +01:00
Dennis Luxen 0e33f638e6 move implementation details out of templat'ized container code 2013-11-22 18:43:01 +01:00
Dennis Luxen 50ccfbf554 move distance computation from r-tree to element type class 2013-11-22 18:05:47 +01:00
Dennis Luxen e2c093856c move Hilbert curve computation in compile unit 2013-11-22 18:05:41 +01:00
Dennis Luxen 992458ae4b fix indentation 2013-11-21 00:06:00 +01:00
Dennis Luxen 8c16686150 remove dead code 2013-11-21 00:05:37 +01:00
Dennis Luxen 7cbadfbd12 remove dead code 2013-11-21 00:05:28 +01:00
Dennis Luxen 0e43697ee0 fixes issue #804 2013-11-20 18:24:06 +01:00
DennisOSRM 7de27df309 fix linking on Ubuntu 13.10 2013-11-20 16:22:39 +01:00
DennisOSRM b06db1ba39 Merge branch 'dep-liblua' of https://github.com/NochEinDirk/Project-OSRM-contribute into NochEinDirk-dep-liblua 2013-11-20 10:56:47 +01:00
Dennis Luxen 5fe24cb689 report a warning if shared memory segment cannot be locked into RAM 2013-11-19 10:38:59 +01:00
Dennis Luxen 733d1384a4 fixes #803 2013-11-19 10:18:59 +01:00
Dennis Luxen 99e9d0d023 ignore impassable ways, requested by HOT 2013-11-18 16:54:52 +01:00
Dennis Luxen 2bd1e46ab9 Remove left-over merge hunk 2013-11-18 11:54:39 +01:00
Dennis Luxen cabaad4b17 replaced contigouos output data with collection of small'ish sub blocks. saves (re-)allocations. also removed a remaining stringstream 2013-11-14 17:16:26 -05:00
Dennis Luxen 8b6fe691ed add missing files 2013-11-14 12:44:36 -05:00
Dennis Luxen ccf9efdaa5 rename file, untangle more includes 2013-11-14 12:42:57 -05:00
Dennis Luxen bf66bec4c7 rename file, untangle more includes 2013-11-14 12:42:50 -05:00
Dennis Luxen 3319709526 rename file, untangle more includes 2013-11-14 12:42:33 -05:00
Dennis Luxen 7ceab5c88c lock data into RAM on Linux 2013-11-14 12:33:09 -05:00
Dennis Luxen 94d4789e68 pull include from correct position 2013-11-14 12:31:51 -05:00
Dennis Luxen b13985d550 remove old files 2013-11-14 12:31:20 -05:00
Dennis Luxen dc4a3e9b89 untangle server and http components 2013-11-14 12:29:56 -05:00
Dennis Luxen d538c35532 moving and splitting of http protocal data types 2013-11-14 12:28:28 -05:00
Dennis Luxen cfd26321b5 lock shared memory into RAM by default on Linux 2013-11-14 10:03:56 -05:00
Dennis Luxen 61d955f3de move Reply into compile unit 2013-11-13 18:42:57 -05:00
Dennis Luxen a9f54c44e9 move Reply into compile unit 2013-11-13 18:42:42 -05:00
Dennis Luxen 125877035f move polyline generalizer into compile unit 2013-11-13 17:48:58 -05:00
Dennis Luxen 8f4b0c8078 de-templetize polyline generalizer 2013-11-13 17:33:19 -05:00
Dennis Luxen 1863e85bf5 move polyline compressor into compile unit 2013-11-13 17:32:44 -05:00
Dennis Luxen 488c6099fc remove test suite from travis 2013-11-13 16:48:15 -05:00
Dennis Luxen 67abc6d2cf removing dead legacy code 2013-11-13 16:11:31 -05:00
Dennis Luxen c56a57c0ba refactor legacy code 2013-11-13 15:52:01 -05:00
Dennis Luxen 30b2c1ad61 refactor input restrictions class 2013-11-13 15:23:44 -05:00
Dennis Luxen 5e279363e4 sort data externally with 4GB of RAM 2013-11-13 11:09:20 -05:00
Dennis Luxen abb7509f03 link against libc++ on OS X Mavericks by default 2013-11-13 11:08:27 -05:00
Dennis Luxen 1cd60c05f3 renaming a couple of variables to be more obvious 2013-11-12 19:02:26 -05:00
Dennis Luxen 510cc22484 Refactor name of legacy class _Node into more telling name ExternalMemoryNode 2013-11-12 18:23:09 -05:00
Dennis Luxen 3da664236c reverting premature revert 2013-11-12 17:39:24 -05:00
Dennis Luxen 7e35a7fe0c remove deprecated stxxl calls to be ready for the 1.4.0 release 2013-11-12 17:33:03 -05:00
Dennis Luxen 58ef7db5d6 allow 64 bit sizes for shared memory regions 2013-11-12 15:01:40 -05:00
Dennis Luxen f9de4a394c minor code shrink 2013-11-11 15:50:33 -05:00
Dennis Luxen dced5816df RVO optimization of output buffer generation 2013-11-11 15:17:52 -05:00
Dennis Luxen 690ac740d2 support ANSI colors in logging class 2013-11-11 13:19:38 -05:00
Dennis Luxen 89d0412e22 fix include order 2013-11-08 10:08:27 -05:00
Dennis Luxen a305752faf access unordered map through iterators only 2013-11-08 09:47:32 -05:00
Dirk L 469b139e89 .travis.yml: Inconsistency between Master and Develop branch?! 2013-11-08 15:33:12 +01:00
Dirk L 8f5d9c4816 Merge branch 'develop' into dep-liblua 2013-11-08 15:20:56 +01:00
Dirk L 7102c77e0b Merge branch 'master' into dep-liblua 2013-11-08 15:10:53 +01:00
Dennis Luxen 115ae21f1f implements #733 2013-11-08 08:56:03 -05:00
Dennis Luxen 8d3fdf45b9 implements #781 2013-11-06 17:13:09 -05:00
Dennis Luxen 1e7e5ea57c Merge pull request #779 from springmeyer/better-file-not-found-error
Better file not found error
2013-11-05 03:03:23 -08:00
Dane Springmeyer 7c8b91456f match exact error from develop branch ~3 months ago 2013-11-04 17:06:02 -08:00
Dane Springmeyer dc960f30f5 if a file cannot be found print that preamble instead of just the filename 2013-11-04 16:56:41 -08:00
Dane Springmeyer ba12e31280 osx build: only set -std=c++11 flag for >= 10.9 2013-11-04 14:37:25 -08:00
Dennis Luxen 027a4081a2 fix loading of ini files 2013-11-01 15:24:13 +01:00
Dennis Luxen 190def17e5 fix coverity issue 1121924, Resource leak 2013-10-31 14:05:06 +01:00
Dennis Luxen 9730526d33 fix coverity issue 1121925, Uncaught exception 2013-10-31 13:21:52 +01:00
Dennis Luxen c87c843308 fix coverity issue 1121926, Uninitialized pointer field 2013-10-31 13:16:46 +01:00
Dennis Luxen 6453cdf0d6 replace all casserts with Boost.Assert 2013-10-30 18:52:23 +01:00
Dennis Luxen 5f80c33b24 lock update when queries are still running 2013-10-30 17:05:49 +01:00
Dennis Luxen a33542c9b5 link libosrm against librt on linux/gcc 2013-10-30 16:35:23 +01:00
Dennis Luxen 3a1d98648f link tool against librt on linux/gcc 2013-10-30 16:33:16 +01:00
Dennis Luxen 4ec79d61d0 Merge branch 'shared_memory' into develop 2013-10-30 15:10:07 +01:00
Dennis Luxen b4f055f80c fix check for shared or internal memory 2013-10-30 14:17:32 +01:00
Dennis Luxen 6bf35c679f add timestamp to management data structure 2013-10-30 14:15:55 +01:00
Dennis Luxen 3349d43c00 output build ID to tools 2013-10-30 13:04:22 +01:00
Dennis Luxen ced961d24c delete renamed file 2013-10-30 13:03:38 +01:00
Dennis Luxen 419f708d87 build unlock tool and link against git descriptor 2013-10-30 13:01:49 +01:00
Dennis Luxen bbc1c04042 rename tool 2013-10-30 11:52:40 +01:00
Dennis Luxen 7a6865637d release all locks 2013-10-30 11:51:20 +01:00
Dennis Luxen ae96420925 output file paths only if internal memory is used 2013-10-30 11:47:48 +01:00
Dennis Luxen 2822812d0d dont require local file parameter for shared memory input 2013-10-30 11:45:06 +01:00
Dennis Luxen c8ab430491 less verbose output 2013-10-30 11:42:05 +01:00
Dennis Luxen bb87f28e80 remove debug output 2013-10-30 11:41:06 +01:00
Dennis Luxen 6db671215a warn if shared memory segment could not be allocated properly 2013-10-29 18:52:13 +01:00
Dennis Luxen 64566ec6cf fix pesky resource leak that took me two f*#+ing days to figure out. No thanks to you, valgrind 2013-10-29 18:45:01 +01:00
Dennis Luxen faaf97ef62 return if removal of shmem segment was successful 2013-10-29 18:43:11 +01:00
Dennis Luxen 67d6efed21 make release build less verbose 2013-10-28 15:17:03 +01:00
Dennis Luxen 571d9bd610 print info on shared data only on reload 2013-10-28 15:11:53 +01:00
Dennis Luxen 4144698540 make data store less verbose in release mode 2013-10-28 14:56:25 +01:00
Dennis Luxen 9bf6bf2c78 link against on linux/gcc 2013-10-28 14:51:20 +01:00
Dennis Luxen cc9236b8db move lock outside of try/catch 2013-10-28 14:39:55 +01:00
Dennis Luxen 0103b59e61 close previously allocated filestream 2013-10-28 14:21:31 +01:00
Dennis Luxen e9f6531db7 remove comma at end of enum 2013-10-28 10:54:15 +01:00
Dennis Luxen 62c2c750ea load correct segment, remove some debug output 2013-10-25 22:26:27 +02:00
Dennis Luxen 3e5e3175e0 check for new data with every query 2013-10-25 19:32:06 +02:00
Dennis Luxen 54c5af30d9 refetch data if changed 2013-10-25 19:31:39 +02:00
Dennis Luxen ca4a3361c0 load data into other data store 2013-10-25 19:31:21 +02:00
Dennis Luxen 47d302221d add ram index file name to layout, rename data types 2013-10-25 17:45:03 +02:00
Dennis Luxen ed215657e6 remove deprecatedd swap method 2013-10-25 17:43:01 +02:00
Dennis Luxen 3e63b14192 add ability to _not_ destroy prev allocated memory 2013-10-25 14:00:34 +02:00
Dennis Luxen 86433ab3a8 fix indentation 2013-10-25 11:19:02 +02:00
Dennis Luxen 7214800d93 add marker where current shared data resides 2013-10-25 11:16:18 +02:00
Dennis Luxen 29f298fa4a load into seperate area, mark swap as todo 2013-10-23 20:06:00 +02:00
Dennis Luxen ef35bc77cb add simple lock barrier tool to block the flow of queries 2013-10-23 13:31:05 +02:00
Dennis Luxen 6ae880f61e finished locking implementation in queries. YAY\! 2013-10-23 13:22:59 +02:00
Dennis Luxen 0d1149310c implement shared lock in query 2013-10-22 19:06:47 +02:00
Dennis Luxen 51d32bb8d3 set todo marker 2013-10-22 19:06:23 +02:00
Dennis Luxen 49a8980dea use named mtx's and condition for interprocess communication 2013-10-22 13:26:39 +02:00
Dennis Luxen 9fe1680c56 remove superflous include 2013-10-21 19:08:23 +02:00
Dennis Luxen b7db65a023 rename condidition variable and add mutex for pending update 2013-10-21 19:07:49 +02:00
Dennis Luxen 4c02002265 iron out skeleton for implementation of shared sync 2013-10-21 19:06:58 +02:00
Dennis Luxen d0198649f2 use doubles in mercartor projection functions 2013-10-21 17:13:02 +02:00
Dennis Luxen 32c1fd082d fix build for tools 2013-10-21 12:01:19 +02:00
Dennis Luxen 363bf42b95 reinstate previous regex 2013-10-21 12:00:52 +02:00
Dennis Luxen a1ab2232f3 use iterator based regex replace 2013-10-21 11:46:17 +02:00
Dennis Luxen cf69f43166 add proper licence header to newly added files 2013-10-21 11:45:16 +02:00
Dennis Luxen 9833438733 add better comment 2013-10-18 21:58:07 +02:00
Emil Tin 67c5e3966a fix some indentation and spelling 2013-10-18 18:33:56 +02:00
Emil Tin aa0927911d example showing use of PostGIS data 2013-10-18 18:24:13 +02:00
Emil Tin 13c9e1ed58 allowing read-only access to osm way/node id from lua 2013-10-18 12:31:08 +02:00
Dennis Luxen 19a457ab7d implement update barrier 2013-10-17 18:11:53 +02:00
Dennis Luxen 0926bff0cc fix issue #761 2013-10-16 17:38:09 +02:00
Dennis Luxen 53a0bc963a indicate the type of memory to the user 2013-10-16 13:40:40 +02:00
Dennis Luxen a2819d822a load data from server.ini only iff no parameters are give 2013-10-16 13:27:44 +02:00
Dennis Luxen 175112d97d fix status messages during configure 2013-10-16 11:58:29 +02:00
Dennis Luxen dced47024f replace FLT_EPSILON with proper C++ variant 2013-10-15 18:42:25 +02:00
Dennis Luxen ffc361406e move git descriptor into a static library that is linked against all tools 2013-10-15 18:28:14 +02:00
Dennis Luxen 852c648235 use program options in data store tool 2013-10-15 18:24:49 +02:00
Dennis Luxen 1197b96c49 add shared memory option to command line parameters 2013-10-15 17:06:45 +02:00
Dennis Luxen f21fe81e16 remove superflous include guard 2013-10-15 17:06:22 +02:00
Dennis Luxen 593dfd0108 Merging and rebasing of develop into shared_memory
Conflicts:
	DataStructures/SearchEngine.h
	DataStructures/StaticRTree.h
	Descriptors/DescriptionFactory.cpp
	Library/OSRM.cpp
	Library/OSRM.h
	RoutingAlgorithms/BasicRoutingInterface.h
	RoutingAlgorithms/ShortestPathRouting.h
	Server/DataStructures/BaseDataFacade.h
	Server/DataStructures/InternalDataFacade.h
	Server/DataStructures/QueryObjectsStorage.cpp
	Server/DataStructures/SharedDataFacade.h
	routed.cpp
2013-10-15 17:04:53 +02:00
Dennis Luxen aaf0fb9d12 Rework facades to accept ServerPaths object as configuration 2013-10-15 15:44:40 +02:00
Dennis Luxen 02e9f8aef3 Rework facades to accept ServerPaths object as configuration 2013-10-15 15:44:35 +02:00
Dennis Luxen 424055c04e fix iterator concept implementation 2013-10-15 14:35:36 +02:00
Dennis Luxen 02daf17326 fix iterator concept implementation 2013-10-15 14:35:36 +02:00
Dennis Luxen a666f0d52e change EdgeBasedNode namespace 2013-10-15 14:35:36 +02:00
DennisOSRM 27a760c58c Move edge-based node out ouf surrounding class 2013-10-15 14:35:36 +02:00
Dennis Luxen 0ba12f48c6 state type of template class member function explicitly 2013-10-15 14:35:35 +02:00
Dennis Luxen eaaf54d886 make C++11 default on OS X 2013-10-15 14:35:35 +02:00
Dennis Luxen 4b3d634fe9 always compile with C++11 on OS X (Linux to follow) 2013-10-15 14:35:35 +02:00
Dennis Luxen f77a699ea4 remove problematic luabind code 2013-10-15 14:35:35 +02:00
Dennis Luxen e989e38cc2 further compile fixes for clang 3.3 (OS X 10.9) 2013-10-15 14:35:35 +02:00
Dennis Luxen 6a900ed6e7 remove unneeded member 2013-10-15 14:35:35 +02:00
Dennis Luxen 29e6b85f79 Add explicit shmem id for data loading 2013-10-15 14:35:34 +02:00
Dennis Luxen 2641408d53 fail gracefully when lock file is not present 2013-10-15 14:35:34 +02:00
Dennis Luxen 5b79226183 add static function to remove shared memory 2013-10-15 14:35:34 +02:00
Dennis Luxen 98f9f0cd48 make shmem swappable by ref and ptr 2013-10-15 14:35:34 +02:00
Dennis Luxen cf7e107ad1 check if shmem segment exists 2013-10-15 14:35:34 +02:00
Dennis Luxen ab66c1aa1b mild refactoring of debug outputs 2013-10-15 14:35:34 +02:00
Dennis Luxen 5b03366909 checking if data files actually exist 2013-10-15 14:35:34 +02:00
Dennis Luxen 7824e1446a removing completed todo markers 2013-10-15 14:35:34 +02:00
Dennis Luxen 59cf1a4937 deciding which memory subsystem to use depending on server.ini 2013-10-15 14:35:33 +02:00
Dennis Luxen 252113c838 implementing the fetch of name ids in shared memory 2013-10-15 14:32:45 +02:00
Dennis Luxen e2f84d1acd commenting unneeded variables 2013-10-15 14:32:45 +02:00
Dennis Luxen 204dcecb28 fixing typo in build configuration 2013-10-15 14:32:44 +02:00
Dennis Luxen 70bbfbea12 fixing include typo 2013-10-15 14:32:44 +02:00
Dennis Luxen 2221a0a908 removing extra ; 2013-10-15 14:32:44 +02:00
Dennis Luxen 203b215093 loading correct file with rtree leafs and not inner nodes 2013-10-15 14:32:44 +02:00
Dennis Luxen 76ee84dae8 printing debug output 2013-10-15 14:32:44 +02:00
Dennis Luxen 79e1c87a01 swapping correct vectors 2013-10-15 14:32:44 +02:00
Dennis Luxen ed208114be properly loading all data into shared memory 2013-10-15 14:32:44 +02:00
Dennis Luxen 7dd711b37c use only one pointer for shared layout 2013-10-15 14:32:44 +02:00
Dennis Luxen 4852802d66 load graph into shared memory 2013-10-15 14:32:44 +02:00
Dennis Luxen c495b1faab graph format now canonical 2013-10-15 14:32:43 +02:00
Dennis Luxen eb5bd8e6ac load timestamp into shared memory 2013-10-15 14:32:43 +02:00
Dennis Luxen ff7dcf9c17 load coordinate list into shared memory 2013-10-15 14:32:43 +02:00
Dennis Luxen 2b12a16c84 load orig edge information 2013-10-15 14:32:43 +02:00
Dennis Luxen 4d00b2ebbb Renaming variables to properly reflect its content 2013-10-15 14:32:43 +02:00
Dennis Luxen 1ba5abbaef add all binaries to ignore list 2013-10-15 14:32:43 +02:00
Dennis Luxen b87a98bbda street name file is now more canonical 2013-10-15 14:32:43 +02:00
Dennis Luxen f76361a345 changing file format for coordinates to be canonical 2013-10-15 14:32:43 +02:00
Dennis Luxen f25bab9555 create lock file if it does not exist 2013-10-15 14:32:42 +02:00
Dennis Luxen ed78b8429f adding proper typedefs s.t. all used types are known 2013-10-15 14:32:42 +02:00
Dennis Luxen 94e9dd8f28 store name id of edges in shmem, too 2013-10-15 14:32:42 +02:00
Dennis Luxen 90215ca0dd move shmem stored sizes to 64 bits 2013-10-15 14:32:42 +02:00
Dennis Luxen 34eb647fcb implementing loading of data into shared memory 2013-10-15 14:32:42 +02:00
Dennis Luxen 83205290de Reordering resource aquisition 2013-10-15 14:32:42 +02:00
Dennis Luxen 02fd528c32 removing debug output 2013-10-15 14:32:42 +02:00
Dennis Luxen e05193f46d osrm-datastore handles manangement of shared memory 2013-10-15 14:32:42 +02:00
Dennis Luxen 14e2d900b5 All tests are passing for internal memory\! 2013-10-15 14:32:41 +02:00
Dennis Luxen ba4290340d removing debug output and calling it a day 2013-10-15 14:32:41 +02:00
Dennis Luxen 5a04700bae create sentinel to adjancency array during preprocessing 2013-10-15 14:32:41 +02:00
Dennis Luxen 999f50dce9 inverting assertion 2013-10-15 14:32:41 +02:00
Dennis Luxen 9522e6e714 properly check for (non-)empty vectors 2013-10-15 14:32:41 +02:00
Dennis Luxen 7836ea4479 implement GetName() for shared memory (copy&paste) 2013-10-15 14:32:40 +02:00
Dennis Luxen 37e8ab8de1 implement operator()+ for shared memory iterator 2013-10-15 14:32:40 +02:00
Dennis Luxen 34048497e7 implement GetName for internal memory 2013-10-15 14:32:40 +02:00
Dennis Luxen 5197422482 fetch ptr from shared memory to via node list 2013-10-15 14:32:40 +02:00
Dennis Luxen d9987c2734 load street names into internal memory 2013-10-15 14:32:40 +02:00
Dennis Luxen c9671b4712 load via node information from shared memory 2013-10-15 14:32:40 +02:00
Dennis Luxen bbf03e3060 Load r-tree search data structure from shared memory 2013-10-15 14:32:40 +02:00
Dennis Luxen e35a78e3cf some further refactoring of variable names and code formatting 2013-10-15 14:32:40 +02:00
Dennis Luxen e318be6a88 call function in parent class 2013-10-15 14:32:40 +02:00
Dennis Luxen 1dab0ebc25 moving common code to parent class 2013-10-15 14:32:40 +02:00
Dennis Luxen 687e58e9d4 removing dead code 2013-10-15 14:32:39 +02:00
Dennis Luxen 993a4aa675 adding auxiliary typedef 2013-10-15 14:32:39 +02:00
Dennis Luxen c991510b0f minor simplification of code 2013-10-15 14:32:39 +02:00
Dennis Luxen c8025bf004 moving fwd decl of static members to root of include graph 2013-10-15 14:31:32 +02:00
Dennis Luxen 9f5767a80c remove superflous includes 2013-10-15 14:31:32 +02:00
Dennis Luxen ffb05d6271 demangling includes 2013-10-15 14:31:32 +02:00
Dennis Luxen 2dd2d3dd7b adjust facade to pass compilation 2013-10-15 14:31:32 +02:00
Dennis Luxen be29c7fca0 call facade where appropriate 2013-10-15 14:31:32 +02:00
Dennis Luxen 2c23a3c0b3 link against proper objects 2013-10-15 14:31:31 +02:00
Dennis Luxen 37e3ead8e9 use flexible shared mem interfaces 2013-10-15 14:31:31 +02:00
Dennis Luxen b018ea7b1b Give all data types in shared memory 2013-10-15 14:31:31 +02:00
Dennis Luxen d6cdca35d4 Use typedef instead of base class 2013-10-15 14:31:31 +02:00
Dennis Luxen a09d150b47 Further stl interface implementation 2013-10-15 14:31:31 +02:00
Dennis Luxen 7cf46afc48 Remove old facade from UUID generation 2013-10-15 14:31:31 +02:00
Dennis Luxen 056c95670f Added list of all data types in shared memory 2013-10-15 14:31:31 +02:00
Dennis Luxen 35dffe43d9 further implementation of the vector interface for shared memory 2013-10-15 14:31:30 +02:00
Dennis Luxen 19c26f0733 removing old data facade, good riddance 2013-10-15 14:31:30 +02:00
Dennis Luxen 388ff10ff5 const'ing new function 2013-10-15 14:31:04 +02:00
Dennis Luxen 8c7be8e45f moving common code into function 2013-10-15 14:31:04 +02:00
Dennis Luxen 579aa67cde further minor refactoring 2013-10-15 14:31:04 +02:00
Dennis Luxen 725f86a0d2 replace cassert by boost asserts 2013-10-15 14:26:27 +02:00
Dennis Luxen 50a6ef18d2 Refactoring shortest path search variable names 2013-10-15 14:24:53 +02:00
Dennis Luxen 1b3e924450 added auxiliary Empty() function 2013-10-15 14:19:54 +02:00
DennisOSRM a33e08e299 superflous typedef changed meaning of name for GCC 2013-10-15 14:19:53 +02:00
DennisOSRM 45dee5a666 Styleguide refactoring 2013-10-15 14:19:53 +02:00
DennisOSRM 642473244e fixing include typos 2013-10-15 14:19:53 +02:00
Dennis Luxen e92f344335 Workarounds for various boost versions and their lovely quirks 2013-10-15 14:19:53 +02:00
Dennis Luxen 7951795ea4 Implementation of internal data storage 2013-10-15 14:19:53 +02:00
Dennis Luxen 101fbcca90 further refactoring of variable names 2013-10-15 14:19:53 +02:00
Dennis Luxen d562132a4a further refactoring of variable names 2013-10-15 14:19:53 +02:00
Dennis Luxen 7152ab39ff further refactoring of variable names 2013-10-15 14:19:52 +02:00
Dennis Luxen 39c5279f5d further refactoring of variable names 2013-10-15 14:19:52 +02:00
Dennis Luxen fef0e16f9c replacing cassert by boost asserts 2013-10-15 14:19:52 +02:00
Dennis Luxen fb1361b00d Reworking data access to go always through facades 2013-10-15 14:19:52 +02:00
Dennis Luxen 64c75c8b57 Refactoring base descriptor class 2013-10-15 14:19:52 +02:00
Dennis Luxen f4e015a255 renamed utility class 2013-10-15 14:19:52 +02:00
Dennis Luxen 242b68c488 initial refactoring of variable names 2013-10-15 14:19:52 +02:00
Dennis Luxen 9452c7e0c7 further implementation of data facades 2013-10-15 14:19:52 +02:00
Dennis Luxen ab1d3d1ced Properly instantiate plugins 2013-10-15 14:17:44 +02:00
Dennis Luxen 41df92bb93 Use new data facade in all descriptors 2013-10-15 14:17:44 +02:00
Dennis Luxen 427db3f29a Don't build deleted classes 2013-10-15 14:14:54 +02:00
Dennis Luxen b5600bdd7f Rewiring routing algorithms 2013-10-15 14:14:54 +02:00
Dennis Luxen a2153b668a Rewiring query plugins 2013-10-15 14:14:54 +02:00
Dennis Luxen 7d52c82c3b Moving DataStructures to new data facade pattern 2013-10-15 14:14:54 +02:00
Dennis Luxen 092f1a4959 corrected include fence 2013-10-15 14:14:11 +02:00
Dennis Luxen 21bee7e40c Further includes in Facades 2013-10-15 14:14:10 +02:00
Dennis Luxen a9ac0ac725 Mockups for data facades 2013-10-15 14:12:30 +02:00
Dennis Luxen 5dc1ed6696 plugging in base facade ptr 2013-10-15 14:09:40 +02:00
Dennis Luxen b55f66e69c added graph data access 2013-10-15 14:08:49 +02:00
Dennis Luxen ab637e22b1 instantiate different inherited class at bcp that provides all data 2013-10-15 14:06:48 +02:00
Dennis Luxen fa665c5494 Facade base class to provide all data access 2013-10-15 14:05:42 +02:00
Dennis Luxen e91b75a1bb use empty() instead of comparisons 2013-10-15 14:04:12 +02:00
Dennis Luxen 4c6f85fd25 Further includes in Facades 2013-10-15 14:04:12 +02:00
Dennis Luxen f09e9b7790 make plugins templates that plug into data facade 2013-10-15 14:04:12 +02:00
Dennis Luxen b51d3da7e5 Mockups for data facades 2013-10-15 14:04:11 +02:00
Dennis Luxen 861dbd5977 plugging in base facade ptr 2013-10-15 14:02:31 +02:00
Dennis Luxen 5001fcdd53 added graph data access 2013-10-15 14:02:31 +02:00
Dennis Luxen eeb47dc724 remove unneeded white spaces 2013-10-15 14:02:31 +02:00
Dennis Luxen 5556dff11e instantiate different inherited class at bcp that provides all data 2013-10-15 14:00:50 +02:00
Dennis Luxen 18b57fa6aa Facade base class to provide all data access 2013-10-15 13:45:45 +02:00
Dennis Luxen 12bb4d75fd Adding shared memory data types 2013-10-15 13:45:45 +02:00
Dennis Luxen 411d8d4d98 fix iterator concept implementation 2013-10-15 12:00:20 +02:00
Dennis Luxen 748df0b21a fix iterator concept implementation 2013-10-15 11:56:27 +02:00
Dennis Luxen 8d98316a89 change EdgeBasedNode namespace 2013-10-15 11:52:41 +02:00
Dennis Luxen c6b45a8e09 .. 2013-10-14 17:22:10 +02:00
Dennis Luxen d42920674a compile with -std=c++11 on os x 10.9 2013-10-14 17:21:40 +02:00
Dennis Luxen c66fced161 rename createhierarchy.cpp to more canonical name 2013-10-14 17:03:46 +02:00
Dennis Luxen d3dee115ab Merging changes from develop branch to prepare for v.0.3.6 branch
Conflicts:
	README.TXT
2013-10-14 13:54:36 +02:00
Dennis Luxen 77aa965533 ../AUTHORS.TXT 2013-10-14 13:47:06 +02:00
Dennis Luxen 29499f21c5 License change to (simplified) 2-clause BSD. Good riddance, AGPL 2013-10-14 13:42:28 +02:00
DennisOSRM 18d8968ae7 add C include for NULL 2013-10-13 17:55:50 +02:00
DennisOSRM 467cf73635 load timestamp properly 2013-10-13 14:26:42 +02:00
DennisOSRM 457519eae3 Fixes resource leaks and removes deprecated c_str() calls where possible 2013-10-13 14:13:08 +02:00
DennisOSRM 2a1c24763d fix path typo 2013-10-12 15:21:36 +02:00
DennisOSRM 92196dc207 pull config from program options 2013-10-12 15:20:58 +02:00
DennisOSRM f73723f9af link simple client against git descriptor 2013-10-12 15:20:32 +02:00
DennisOSRM 26ab8755b6 move program options for routed/simpleclient into common header 2013-10-12 15:19:59 +02:00
DennisOSRM d91382208d ignore server.ini 2013-10-12 15:18:51 +02:00
Emil Tin 5f90ed8b3e support capitalized option names in extract/prepare 2013-10-12 09:59:42 +02:00
Emil Tin 644fad8355 allow old capitalized option names in routed, few other adjustments 2013-10-12 09:59:42 +02:00
Emil Tin c4904cc365 test nearest/locate with high lat/lon, fix fuzzy match of negative numbers 2013-10-12 09:59:42 +02:00
Emil Tin 613e38d7f8 use boost program_options in osrm-prepare/routed 2013-10-12 09:59:42 +02:00
DennisOSRM dee7c339b3 Move edge-based node out ouf surrounding class 2013-10-11 16:14:59 +02:00
DennisOSRM b80cda66a9 fixes issue #755 2013-10-11 14:58:19 +02:00
DennisOSRM 411bcbcbde remove debug output 2013-10-11 14:55:34 +02:00
Dennis Luxen 352bf8839b state type of template class member function explicitly 2013-10-10 17:25:02 +02:00
Dennis Luxen 18f438a528 make C++11 default on OS X 2013-10-10 15:34:10 +02:00
Dennis Luxen 076944da5d always compile with C++11 on OS X (Linux to follow) 2013-10-10 14:32:10 +02:00
Dennis Luxen acbba95032 remove problematic luabind code 2013-10-10 14:31:28 +02:00
Dennis Luxen 75f77783ff further compile fixes for clang 3.3 (OS X 10.9) 2013-10-09 18:58:37 +02:00
Dennis Luxen 87e0f074e8 remove unneeded member 2013-10-09 17:34:48 +02:00
Dennis Luxen 2211c69455 Add explicit shmem id for data loading 2013-10-08 18:10:31 +02:00
Dennis Luxen a7449c913c fail gracefully when lock file is not present 2013-10-08 16:25:02 +02:00
Dennis Luxen aaec0e641b add static function to remove shared memory 2013-10-08 15:47:43 +02:00
Dennis Luxen 5afed2d396 make shmem swappable by ref and ptr 2013-10-08 15:26:19 +02:00
Dennis Luxen 843348338a check if shmem segment exists 2013-10-08 14:40:49 +02:00
Dennis Luxen 061ebc7942 fixing #412, wrong offsets cause supoptimal routes with via points 2013-10-04 17:10:40 +02:00
Dennis Luxen 822c1c97e3 fixing #412, wrong offsets cause supoptimal routes with via points 2013-10-04 16:47:59 +02:00
Emil Tin 65df6aa4a0 failing test showing weird loop, issue 412 2013-10-04 13:32:05 +02:00
Emil Tin 32719690ac update ruby gems used for cucumber testing 2013-10-02 20:10:13 +02:00
Emil Tin f83748fdc2 change test file to cuke table 2013-10-02 20:10:01 +02:00
Emil Tin a354d7c00b use testbot for testing for weird loops 2013-10-02 19:28:41 +02:00
Dennis Luxen 41f7312263 Merge branch 'develop' of https://github.com/DennisOSRM/Project-OSRM into develop 2013-10-02 14:40:34 +02:00
Dennis Luxen d3804d2c2c replacing hard coded values by literal 2013-10-02 14:39:52 +02:00
Emil Tin 96184b83a3 minor whitespace cleanup 2013-10-02 13:53:09 +02:00
Emil Tin 9bcc057176 mark projection tests as todo 2013-10-02 13:48:49 +02:00
Emil Tin 20f3213477 test projection onto ways at high lat 2013-10-02 13:43:33 +02:00
Dennis Luxen bf8505a285 removing all FLT_EPSILONs 2013-10-02 13:05:54 +02:00
Dennis Luxen 770a07cc28 replacing all occurrences of DBL_MAX 2013-10-02 12:00:25 +02:00
Dennis Luxen 3f80f52ca5 refactoring some variable names 2013-10-02 11:57:34 +02:00
Dennis Luxen 52f6e149ec removing debug output 2013-10-02 11:40:05 +02:00
Dennis Luxen 6893df9103 replacing c-style numeric limits with proper C++ style 2013-10-02 11:38:09 +02:00
Dennis Luxen 60546c9788 adding data to check egressions of #726 2013-10-02 11:26:26 +02:00
Dennis Luxen 12f91564fb adding test to check regressions of #726 2013-10-02 11:25:51 +02:00
Dennis Luxen ca448e682a using wider margin for expected result 2013-10-02 11:23:13 +02:00
Dennis Luxen 2b077d140f Fixing #726, rounding woes and machine epsilon 2013-10-02 11:22:42 +02:00
Dennis Luxen 0f58ff8356 mild refactoring of debug outputs 2013-10-01 18:01:19 +02:00
Dennis Luxen 940b740b24 checking if data files actually exist 2013-10-01 17:37:52 +02:00
Dennis Luxen 0f258f94a8 removing completed todo markers 2013-10-01 16:53:15 +02:00
Dennis Luxen fd7b22f639 deciding which memory subsystem to use depending on server.ini 2013-10-01 16:48:40 +02:00
Dennis Luxen ca3464512d implementing the fetch of name ids in shared memory 2013-10-01 13:25:11 +02:00
Dennis Luxen f59cb6417f commenting unneeded variables 2013-10-01 13:24:25 +02:00
Dennis Luxen 74ccb53607 Merge branch 'shared_memory' of https://github.com/DennisOSRM/Project-OSRM into shared_memory 2013-09-30 16:12:26 +02:00
Dennis Luxen e4c6e98099 fixing typo in build configuration 2013-09-30 16:12:19 +02:00
Dennis Luxen cfab0fa245 fixing include typo 2013-09-30 16:03:46 +02:00
Dennis Luxen 08d861e87c removing extra ; 2013-09-30 16:01:51 +02:00
Dennis Luxen 73234e7782 loading correct file with rtree leafs and not inner nodes 2013-09-30 15:55:29 +02:00
Dennis Luxen de8d28ea5f printing debug output 2013-09-30 15:54:32 +02:00
Dennis Luxen ed7b478ee0 swapping correct vectors 2013-09-30 15:50:26 +02:00
Dennis Luxen ff9a216990 properly loading all data into shared memory 2013-09-30 14:21:00 +02:00
Dennis Luxen 58c94159b1 use only one pointer for shared layout 2013-09-30 11:28:53 +02:00
Dennis Luxen 7a1bd4d53a load graph into shared memory 2013-09-27 17:45:23 +02:00
Dennis Luxen 5d7c23c62a graph format now canonical 2013-09-27 15:01:25 +02:00
Dennis Luxen d91d911051 load timestamp into shared memory 2013-09-27 13:53:49 +02:00
Dennis Luxen cd0cab465d load coordinate list into shared memory 2013-09-27 13:14:30 +02:00
Dennis Luxen a45b887c5b load orig edge information 2013-09-27 12:59:33 +02:00
Dennis Luxen f965b7129b Renaming variables to properly reflect its content 2013-09-27 12:00:58 +02:00
Dennis Luxen e894ce00c9 add all binaries to ignore list 2013-09-27 11:48:25 +02:00
Dennis Luxen 333aba8be6 street name file is now more canonical 2013-09-26 18:19:51 +02:00
Dennis Luxen e9d93ae210 changing file format for coordinates to be canonical 2013-09-26 11:52:15 +02:00
Dennis Luxen 043c8be747 create lock file if it does not exist 2013-09-26 11:28:51 +02:00
Dennis Luxen 1be67518df adding proper typedefs s.t. all used types are known 2013-09-25 19:06:50 +02:00
Dennis Luxen 4bf1987bb7 store name id of edges in shmem, too 2013-09-25 18:59:07 +02:00
Dennis Luxen ae45eed2b1 move shmem stored sizes to 64 bits 2013-09-25 18:58:39 +02:00
Dennis Luxen 572a9393aa implementing loading of data into shared memory 2013-09-25 18:40:08 +02:00
Dennis Luxen 7579c41a35 Reordering resource aquisition 2013-09-25 18:26:10 +02:00
Dennis Luxen 4e589c2575 removing debug output 2013-09-25 18:00:12 +02:00
Dennis Luxen 026da34ce9 osrm-datastore handles manangement of shared memory 2013-09-25 15:31:49 +02:00
Dennis Luxen 0daf49a1da All tests are passing for internal memory\! 2013-09-25 14:31:48 +02:00
Dennis Luxen f57e4c6c14 removing debug output and calling it a day 2013-09-24 18:59:44 +02:00
Dennis Luxen 14bd1d01f2 create sentinel to adjancency array during preprocessing 2013-09-24 18:48:02 +02:00
Dennis Luxen 918e20b164 inverting assertion 2013-09-24 16:45:34 +02:00
Dennis Luxen 6a0e90ef90 properly check for (non-)empty vectors 2013-09-24 16:24:27 +02:00
Dennis Luxen 71fe8ed80d implement GetName() for shared memory (copy&paste) 2013-09-24 15:12:06 +02:00
Dennis Luxen 581c9c570b implement operator()+ for shared memory iterator 2013-09-24 15:10:06 +02:00
Dennis Luxen b25fe3d127 implement GetName for internal memory 2013-09-24 14:44:25 +02:00
Dennis Luxen fc4aef6d89 fetch ptr from shared memory to via node list 2013-09-24 13:54:28 +02:00
Dennis Luxen 6b4fa6a40d load street names into internal memory 2013-09-24 13:53:38 +02:00
Dennis Luxen 6756eea209 load via node information from shared memory 2013-09-24 13:33:38 +02:00
Dennis Luxen bf3cd37b49 Load r-tree search data structure from shared memory 2013-09-24 12:07:34 +02:00
Dennis Luxen cc7caa9e16 some further refactoring of variable names and code formatting 2013-09-24 11:02:24 +02:00
Dennis Luxen 633060562f call function in parent class 2013-09-24 10:58:24 +02:00
Dennis Luxen cc48546f62 moving common code to parent class 2013-09-24 10:57:54 +02:00
Dennis Luxen 96cc44e521 Compile fixes on RHEL5/Fedora, see #541 2013-09-24 10:33:29 +02:00
Dennis Luxen f2d9e4b2df removing dead code 2013-09-24 10:16:57 +02:00
Dennis Luxen 049c7ad1f0 adding auxiliary typedef 2013-09-24 10:16:07 +02:00
Dennis Luxen 226dad651b minor simplification of code 2013-09-24 10:10:50 +02:00
Dennis Luxen 0977cabc79 moving fwd decl of static members to root of include graph 2013-09-24 09:55:02 +02:00
Dennis Luxen 0b5e8a086e remove superflous includes 2013-09-24 09:45:33 +02:00
Dennis Luxen e024ea5ee1 demangling includes 2013-09-24 09:39:12 +02:00
Dennis Luxen 6f71092aa4 adjust facade to pass compilation 2013-09-23 19:00:08 +02:00
Dennis Luxen edce44df97 call facade where appropriate 2013-09-23 18:59:43 +02:00
Dennis Luxen 54551d9f37 link against proper objects 2013-09-23 18:59:13 +02:00
Dennis Luxen 8521b5501f use flexible shared mem interfaces 2013-09-23 18:03:07 +02:00
Dennis Luxen 396dc21903 Give all data types in shared memory 2013-09-23 18:02:45 +02:00
Dennis Luxen 5e2b0ba46c Use typedef instead of base class 2013-09-23 18:02:16 +02:00
Dennis Luxen cce5d775de Further stl interface implementation 2013-09-23 18:01:30 +02:00
Dennis Luxen 248a239c7b Remove old facade from UUID generation 2013-09-23 13:42:35 +02:00
Dennis Luxen 83655e9aef Added list of all data types in shared memory 2013-09-23 13:41:53 +02:00
Dennis Luxen 973d115edf further implementation of the vector interface for shared memory 2013-09-23 13:30:21 +02:00
Dennis Luxen aaa9f89550 removing old data facade, good riddance 2013-09-23 11:35:33 +02:00
Dennis Luxen 8afad5614a const'ing new function 2013-09-22 22:29:03 +02:00
Dennis Luxen a9fdabf926 moving common code into function 2013-09-22 22:18:54 +02:00
Dennis Luxen b5b262c722 further minor refactoring 2013-09-21 22:21:33 +02:00
Dennis Luxen d1e1190cbd replace cassert by boost asserts 2013-09-21 22:18:27 +02:00
Dennis Luxen 9812eaaca7 Refactoring shortest path search variable names 2013-09-21 22:10:41 +02:00
Dennis Luxen 4520e04d37 added auxiliary Empty() function 2013-09-21 21:51:07 +02:00
DennisOSRM 5679b5862f superflous typedef changed meaning of name for GCC 2013-09-20 21:40:27 +02:00
DennisOSRM e72dc38d77 Styleguide refactoring 2013-09-20 21:07:57 +02:00
DennisOSRM 71fcfa4935 fixing include typos 2013-09-20 21:05:47 +02:00
Dennis Luxen c4463036c3 Workarounds for various boost versions and their lovely quirks 2013-09-20 19:41:45 +02:00
Dennis Luxen b343a17b29 Implementation of internal data storage 2013-09-20 18:30:47 +02:00
Dennis Luxen 0b0fb249bf further refactoring of variable names 2013-09-20 13:13:06 +02:00
Dennis Luxen 8d689974a7 further refactoring of variable names 2013-09-20 13:11:23 +02:00
Dennis Luxen 375c81d38d further refactoring of variable names 2013-09-20 13:09:33 +02:00
Dennis Luxen 0ef4f36d44 further refactoring of variable names 2013-09-20 13:08:18 +02:00
Dennis Luxen c85f6c1228 replacing cassert by boost asserts 2013-09-20 11:35:59 +02:00
Dennis Luxen 0cabc81693 Reworking data access to go always through facades 2013-09-20 11:09:07 +02:00
Dennis Luxen 12b4fff81e Refactoring base descriptor class 2013-09-19 22:28:02 +02:00
Dennis Luxen 27b6627110 renamed utility class 2013-09-19 22:10:49 +02:00
Dennis Luxen 387014dd37 initial refactoring of variable names 2013-09-19 19:07:18 +02:00
Dennis Luxen d5c91b9bda further implementation of data facades 2013-09-19 18:55:49 +02:00
Dennis Luxen 370f4f6257 Properly instantiate plugins 2013-09-19 18:55:19 +02:00
Dennis Luxen 49a665488e Use new data facade in all descriptors 2013-09-19 18:54:30 +02:00
Dennis Luxen 29da133726 Don't build deleted classes 2013-09-19 18:54:09 +02:00
Dennis Luxen 1194bb8ae3 Rewiring routing algorithms 2013-09-19 18:53:34 +02:00
Dennis Luxen 7599124aa0 Rewiring query plugins 2013-09-19 18:53:10 +02:00
Dennis Luxen 01d2d91ecc Moving DataStructures to new data facade pattern 2013-09-19 18:52:42 +02:00
Dirk L 6980d19214 Merge branch 'develop' into develop-lua 2013-09-19 15:05:30 +02:00
Dennis Luxen ac14a7b0da corrected include fence 2013-09-19 13:59:09 +02:00
Dennis Luxen 23f00ab533 Merge branch 'shared_memory' of https://github.com/DennisOSRM/Project-OSRM into shared_memory 2013-09-19 12:01:04 +02:00
Dennis Luxen 39122bd61d use empty() instead of comparisons 2013-09-19 12:00:36 +02:00
Dennis Luxen c5824765f9 Further includes in Facades 2013-09-19 12:00:36 +02:00
Dennis Luxen 547e942c66 make plugins templates that plug into data facade 2013-09-19 12:00:36 +02:00
Dennis Luxen 2ab04e7e2f Mockups for data facades 2013-09-19 12:00:36 +02:00
Dennis Luxen a08fef172e plugging in base facade ptr 2013-09-19 12:00:35 +02:00
Dennis Luxen a04f77e7e0 added graph data access 2013-09-19 12:00:35 +02:00
Dennis Luxen 4900f3e54d remove unneeded white spaces 2013-09-19 12:00:35 +02:00
Dennis Luxen 34ee6411d5 instantiate different inherited class at bcp that provides all data 2013-09-19 12:00:35 +02:00
Dennis Luxen 5abe7bc7e5 Facade base class to provide all data access 2013-09-19 12:00:35 +02:00
Dennis Luxen a48aef4039 Adding shared memory data types 2013-09-19 12:00:35 +02:00
Dennis Luxen e1198f29ce Refactoring according to new coding guidelines 2013-09-19 11:54:24 +02:00
Dennis Luxen 329e619c8c fixing coverity issue 1046674 Uninitialized pointer field 2013-09-19 10:42:28 +02:00
Dennis Luxen 9a9e1b46ef fixing coverity issue 1061045 Resource leak 2013-09-19 10:32:27 +02:00
Dennis Luxen cc94ab6411 use empty() instead of comparisons 2013-09-19 10:19:54 +02:00
Dennis Luxen e67541e82f Further includes in Facades 2013-09-18 18:33:10 +02:00
Dennis Luxen d907be264b make plugins templates that plug into data facade 2013-09-18 18:32:50 +02:00
Dennis Luxen 003c1df53e Mockups for data facades 2013-09-18 17:49:49 +02:00
Emil Tin 6470838065 cleanup indentation of ruby files 2013-09-18 08:16:19 +02:00
Emil Tin a178555838 update text in cuke test 2013-09-17 21:04:02 +02:00
Dennis Luxen f844e9e702 plugging in base facade ptr 2013-09-17 18:55:53 +02:00
Dennis Luxen 8753dbdb0f added graph data access 2013-09-17 18:45:33 +02:00
Dennis Luxen 1bd24f7042 remove unneeded white spaces 2013-09-17 18:37:52 +02:00
Dennis Luxen 66d58bf047 instantiate different inherited class at bcp that provides all data 2013-09-17 18:37:08 +02:00
Dennis Luxen 1e5c4b0d79 Facade base class to provide all data access 2013-09-17 18:35:43 +02:00
Dennis Luxen 711d402f17 Merge branch 'shared_memory' of https://github.com/DennisOSRM/Project-OSRM into shared_memory 2013-09-17 18:34:35 +02:00
Dennis Luxen e19f54a378 Adding shared memory data types 2013-09-17 15:28:08 +02:00
Dennis Luxen 5294fc4767 Fixing another coverity issue 2013-09-17 15:27:51 +02:00
Dennis Luxen 7ed3a1df04 removing dead code 2013-09-17 15:15:52 +02:00
Dennis Luxen 2d45354f50 Fixes coverity issue 1061545 Uninitialized scalar field 2013-09-17 15:06:12 +02:00
Dennis Luxen 9f6d13f4c3 Fixes coverity issue 2013-09-17 14:47:15 +02:00
Dennis Luxen 57a31d0ec9 Fixing coverity issue 2013-09-17 14:47:15 +02:00
Dennis Luxen da277d9816 Adding shared memory data types 2013-09-17 14:23:06 +02:00
Dirk L 22dabc5180 Merge branch 'develop' into develop-lua 2013-09-13 18:44:27 +02:00
Emil Tin 47f11fc3a6 bike: normal speed on paths with asphalt, add tests 2013-09-12 14:15:50 +02:00
Dirk L 91a2e56215 Merge branch 'dep-liblua' into develop-lua 2013-09-11 18:27:51 +02:00
Dirk L e6681af9d0 CMakeLists.txt: Lua5.2 support.
Because the current Debian unstable is using

  * Luabind which is depending on Lua5.2

  * LuaJIT which has a Lua5.1 API

the code were using the Lua5.1 header files but were linked against
Lua5.2 library.

Now both are using Lua5.2 (libluajit-5.1-dev must not be installed
during CMAKE !), which seems to work for the OSRM-Extractor.
2013-09-11 17:25:33 +02:00
Dennis Luxen d9e3c43c91 further adjustments to benchmark 2013-09-11 14:27:41 +02:00
Dennis Luxen f84de4ac21 Moving timing back to reliable but uugly code 2013-09-09 16:26:44 +02:00
Dennis Luxen 3089231476 split io benchmark into two parts. also fixed things on Linux 2013-09-09 16:26:07 +02:00
Emil Tin 0f94fb9d6d update foot profile, add tests for access, barriers, ferries, names, surface, more 2013-09-08 22:51:44 +02:00
Emil Tin 01097f7225 foot tests for ferries and restrictions 2013-09-07 18:19:52 +02:00
Dennis Luxen a25e4e1ed8 Fixes #737 2013-09-07 11:16:45 +02:00
Dennis Luxen 9e75595754 explicitly use boost 1.46 2013-09-05 21:43:12 +02:00
Dennis Luxen f6d5945b59 Moving to boost 1.46 on travis 2013-09-05 21:36:21 +02:00
Dennis Luxen 250eb20851 removing boost::chrono timers 2013-09-05 21:33:10 +02:00
Dennis Luxen d2b00c4995 Moving timing back to gettimeofday instead of boost::chrono 2013-09-05 21:28:45 +02:00
Dennis Luxen 89c73d89b4 Install all boost dev packages on travis 2013-09-05 20:58:33 +02:00
Dennis Luxen fcd63bf9eb Merge branch 'develop' of https://github.com/DennisOSRM/Project-OSRM into develop 2013-09-05 20:22:59 +02:00
Dennis Luxen 9a0cf6a609 add correct package 2013-09-05 20:22:23 +02:00
Emil Tin 6c32d97b23 organize cuke test with @todo and @bug 2013-09-05 20:00:42 +02:00
Emil Tin c9e40d3e59 cuke profiles for running @todo or @bug tests 2013-09-05 19:18:04 +02:00
Dennis Luxen dc920a7e39 Moving repeated statistics into function 2013-09-05 14:36:18 +02:00
Dennis Luxen 07262387e0 Give read/write performance, too 2013-09-05 12:32:30 +02:00
Dennis Luxen 97e2ac689e Fixed timings to collect absolute numbers and not CPU seconds 2013-09-05 12:20:17 +02:00
Dennis Luxen 286a80d03b Fixed the way statistics are collected 2013-09-05 12:19:47 +02:00
Dennis Luxen 3aaf31fdb9 add boost timer library 2013-09-05 12:19:16 +02:00
Dennis Luxen 71ae5764cc add boost timer library 2013-09-05 12:18:37 +02:00
Dennis Luxen 2e41ed153b Merge branch 'develop' of https://github.com/DennisOSRM/Project-OSRM into develop 2013-09-04 14:26:31 +02:00
Dennis Luxen 9ee422e6ba Output reorder, also shows median 2013-09-04 14:26:20 +02:00
Dennis Luxen 8a008d1808 new hard disk benchmark tool 2013-09-04 12:30:16 +02:00
Emil Tin d78faea737 better regex for matching origin in cuke test 2013-09-01 21:48:19 +02:00
Emil Tin 3cf72e93e6 allow setting origin in cuke tests 2013-08-31 23:35:26 +02:00
Emil Tin caa02bbca1 test bearing at high lat 2013-08-31 12:52:36 +02:00
Emil Tin 33e64aee6f update Rakefile to work with new osrm-extract options 2013-08-30 13:02:57 +02:00
Emil Tin d17150270e enable passing .osm file to cuke tests 2013-08-30 12:56:52 +02:00
Emil Tin 463a297f0c remove incorrect cuke tag 2013-08-30 12:55:17 +02:00
Emil Tin 407d73a735 removing trailing whitespace in cuke/ruby files 2013-08-29 19:39:45 +02:00
Emil Tin b5bfdb56dc cleanup indentation of cuke files 2013-08-29 19:29:13 +02:00
Emil Tin 58b7ef8431 cuke profile for running all test (including todo/bug) 2013-08-29 16:29:59 +02:00
Emil Tin 2211dfb741 test for u-turn at via point (failing) 2013-08-29 16:29:21 +02:00
Emil Tin 1d6e602473 test nearest/locate at high lat/lon, fix fuzzy match of negative numbers 2013-08-28 09:49:56 +02:00
DennisOSRM a6c52fd154 Fixes coordinate conversion issue. Thx @kkaefer 2013-08-27 14:15:23 +02:00
Emil Tin 7a5bceae4c tests for /locate 2013-08-26 22:25:43 +02:00
DennisOSRM 6f3e7f9e56 Fixes #721 2013-08-26 14:16:34 +02:00
Dennis Luxen fb9822b507 street name list is now a char array /w indices array 2013-08-20 17:05:36 +02:00
Dennis Luxen d0db09cb92 Adds Vlad's patch from issue #709 2013-08-20 13:17:19 +02:00
Dennis Luxen 189fbb3f7e Fixes coverity issue CID 1063352, use after free bug 2013-08-20 10:04:58 +02:00
Dennis Luxen 887c95fe2a Fixes five silly Conditional jump or move depends on uninitialised value(s) 2013-08-19 18:07:54 +02:00
Dennis Luxen fdbeb951eb Fixes #655 2013-08-19 17:36:15 +02:00
Dennis Luxen 9d23dee3fc Merge branch 'develop' into experimental/program_options 2013-08-19 17:03:47 +02:00
Dennis Luxen 70b8cef318 Fixes #709, out-of-source builds from arbitrary directories 2013-08-19 16:55:56 +02:00
Dennis Luxen e1620b8fa2 Refactoring StronglyConnectedComponents.h 2013-08-19 16:04:00 +02:00
Dennis Luxen dabc9589e9 fix type in car profile 2013-08-19 13:56:57 +02:00
Dennis Luxen da98900e3a fixing regression in osrm-components 2013-08-19 13:42:34 +02:00
Dennis Luxen b584ba9149 removing super-flous returns in car profile 2013-08-16 17:10:02 +02:00
Dennis Luxen d24ba6d13d Mild perfomance fixed for PBF extraction 2013-08-16 17:09:27 +02:00
Dennis Luxen aba078a9d8 Refactoring internal style of ConcurrentQueue 2013-08-16 17:09:04 +02:00
Dennis Luxen 161487d6c2 Refactoring members of NodeInformationHelpDesk 2013-08-16 14:06:04 +02:00
Dennis Luxen d851dd7196 bit packing ImportEdge members 2013-08-16 13:34:28 +02:00
Dennis Luxen cf29621aa7 Making edge factor more verbose 2013-08-16 11:08:07 +02:00
Dennis Luxen 9e46577f43 Merge branch 'develop' 2013-08-15 15:54:31 +02:00
Dennis Luxen b7980b83df removing dead comments 2013-08-15 15:51:07 +02:00
Dennis Luxen 0a0bed7ae0 Refactoring graph factory 2013-08-14 18:43:01 +02:00
Emil Tin e42b8fc37d use boost program_options in extractor 2013-08-14 15:15:35 +02:00
Dennis Luxen b01e30acfd Moving DataStructures out of Plugin directory 2013-08-14 14:09:42 +02:00
Dennis Luxen 311c50df9f Moving DataStructures out of Plugin directory 2013-08-14 13:57:57 +02:00
Dennis Luxen c2f9467f61 Moving DataStructures out of Plugin directory 2013-08-14 13:54:59 +02:00
Dennis Luxen 06c8656b9e Moving DataStructures out of Plugin directory 2013-08-14 13:41:23 +02:00
Dennis Luxen 4748bca8a4 Refactoring _Coordinate class 2013-08-14 13:12:28 +02:00
Dennis Luxen 916387748c Refactor _Restriction class 2013-08-14 11:59:46 +02:00
Dennis Luxen 216d7dcb86 Fixing typos 2013-08-14 11:59:01 +02:00
Dennis Luxen 23f2c7e6f5 move windows specific defines behind define-fence 2013-08-14 11:58:23 +02:00
Dennis Luxen c8e0e5eca2 Export compile commands 2013-08-14 11:57:54 +02:00
Dennis Luxen 3167d3f451 Export compile commands 2013-08-14 11:57:33 +02:00
Dennis Luxen beb9c1ba74 use proper check for empty string 2013-08-13 18:37:21 +02:00
Dennis Luxen dcd88260e9 Add a few braces here and there 2013-08-13 18:36:23 +02:00
Dennis Luxen 5f4f631fc5 Remove dead code 2013-08-13 18:35:54 +02:00
Dennis Luxen dc6fda03a1 move const value to left-hand side of comparison 2013-08-13 18:35:22 +02:00
Dennis Luxen 764ad81537 Some mild refactoring 2013-08-13 18:34:33 +02:00
Dennis Luxen e26c41095f Some mild refactoring 2013-08-13 18:33:20 +02:00
Dennis Luxen d7bd78d612 correct timing of durations 2013-08-13 18:21:14 +02:00
Dennis Luxen c50b4c72d7 Refactoring of Plugins 2013-08-13 18:09:20 +02:00
Dennis Luxen 124e555ed0 Disabling debug output in release build 2013-08-13 10:48:02 +02:00
Dennis Luxen aeba3aa209 fixes #695 for bike profile 2013-08-12 18:00:56 +02:00
Emil Tin e50b5202b8 updated tests for car maxspeed forw/backw 2013-08-12 17:37:51 +02:00
Dennis Luxen 32c7578629 fixes #695, maxspeed:forward incorrectly made any way routable 2013-08-12 13:19:07 +02:00
Dennis Luxen 5bc5e0e8e9 logging into wrong channel 2013-08-11 23:25:22 +02:00
Dennis Luxen 7ee4692e84 properly order includes 2013-08-11 23:01:15 +02:00
Dennis Luxen 679688705d properly order includes 2013-08-11 22:53:31 +02:00
Dennis Luxen 83f0a2c094 Applying syntactic sugar 2013-08-11 22:49:33 +02:00
Dennis Luxen 504817058b remove checks for data that is not used here, log information through SimpleLogger 2013-08-11 22:35:13 +02:00
Dennis Luxen 45754b27de remove ignored const qualifiers 2013-08-11 22:10:05 +02:00
Dennis Luxen a75ae8bbef enable output for tools 2013-08-10 14:43:49 +02:00
Dennis Luxen c3e6dc69bb implements https://github.com/DennisOSRM/Project-OSRM/commit/0765ebf7355b0c4d70ca88f0dc78452dc84ede6c#commitcomment-3828005 2013-08-09 21:33:30 +02:00
Dennis Luxen 0285bb6ea5 Implements https://github.com/DennisOSRM/Project-OSRM/commit/34735b8aad06098d09d3fb907137697799a281e4#commitcomment-3828247 2013-08-09 20:16:26 +02:00
Dennis Luxen a542292ce2 Check if files exist and contain data, fixes #693 2013-08-09 17:47:11 +02:00
Dennis Luxen 0765ebf735 Implements #692 2013-08-09 14:47:09 +02:00
Dennis Luxen e86e8c37a8 const'ing parameters 2013-08-09 13:49:30 +02:00
Dennis Luxen 149a42cc94 Fixing coverity issue 1046672 and a potential memory leak 2013-08-09 13:24:05 +02:00
Dennis Luxen 8de4613a3e Fix coverity errors 1061543 751298 2013-08-09 12:55:08 +02:00
Dennis Luxen 60950c57e3 Fix coverity error 1061544 2013-08-09 12:53:23 +02:00
Dennis Luxen 4727bb5c9b Fix coverity error 1061545 2013-08-09 12:51:21 +02:00
Dennis Luxen 1e1e254897 Pass values by const ref 2013-08-09 12:50:21 +02:00
Dennis Luxen df5455121c Output uses new logging facility 2013-08-09 12:49:49 +02:00
Dennis Luxen 0e2570b204 enable logging for deamon 2013-08-08 16:23:28 +02:00
Dennis Luxen f57519b909 adapt tool to output logs with new mechanism 2013-08-08 16:20:05 +02:00
Dennis Luxen 088393ca12 Remove superflous output of endline 2013-08-08 16:19:25 +02:00
Dennis Luxen 375dc63db3 Make output conditional 2013-08-08 15:57:16 +02:00
Dennis Luxen 503324162f Configure project for actually different build types 2013-08-08 14:58:58 +02:00
Dennis Luxen 5445b64376 Configure project for actually different build types 2013-08-08 14:58:40 +02:00
Dennis Luxen 7fe997d38c Add missing newline on EOF 2013-08-08 14:53:49 +02:00
Dennis Luxen d7673dad7b fixing release build 2013-08-08 14:39:51 +02:00
Dennis Luxen 44eed9282b Adding new SimpleLogger class 2013-08-08 14:25:57 +02:00
Dennis Luxen 0eeb94b24c Merge branch 'develop' of https://github.com/DennisOSRM/Project-OSRM into develop 2013-08-08 14:18:13 +02:00
Dennis Luxen ef221e1c6c Replacing log macros by more sophisticated mechanism 2013-08-08 14:17:01 +02:00
Emil Tin 75cdefa4fe show name of missing .ini file 2013-08-07 21:33:43 +02:00
Dennis Luxen a609a1c6c2 Move common code into base class 2013-08-07 14:02:10 +02:00
Dennis Luxen f4906a97b9 pass const refs instead of copy 2013-08-07 14:01:56 +02:00
Dennis Luxen 21ffd441fa Refactoring base config class into proper ini file name 2013-08-06 17:46:49 +02:00
Dennis Luxen a82383d78e Refactoring base config class into proper ini file name 2013-08-06 17:33:26 +02:00
Dennis Luxen b405029f0f Refactoring base config class into proper ini file name 2013-08-06 17:23:40 +02:00
Dennis Luxen db7d4f56b3 Fix build with updated hash table 2013-08-06 16:58:31 +02:00
Dennis Luxen 3151197471 boost timer library not needed 2013-08-06 16:50:20 +02:00
Dennis Luxen e06fe6935a refactor Hashtable 2013-08-06 16:39:04 +02:00
Dennis Luxen e7cec83a4c Use boost timer to provide platform independent timing 2013-08-06 14:28:03 +02:00
Dennis Luxen e5f0ad4f0b Use boost timer to provide platform independent timing 2013-08-06 14:27:36 +02:00
Dennis Luxen cabbe70e47 reverting premature checkin 2013-08-06 14:01:03 +02:00
Dennis Luxen b86c3681bb reverting premature checkin 2013-08-06 13:54:04 +02:00
Dennis Luxen 0f8239bc8e Fixing build of tools 2013-08-06 12:28:19 +02:00
Dennis Luxen 13f5baf608 Moving node data structure into more meaningful class name 2013-08-05 19:35:47 +02:00
Dennis Luxen 4f5d7f79bd fixing tests for enhanced coordinate preceision 2013-08-05 19:00:09 +02:00
Dennis Luxen 23899613c3 Implement #495 2013-08-05 18:37:42 +02:00
Dennis Luxen db46a915cc simple wrapper around std::exception 2013-08-05 17:37:30 +02:00
Dennis Luxen b591aa013d Remove dead code 2013-08-05 17:35:16 +02:00
Dennis Luxen c0db8b71dd Merge branch 'develop' of https://github.com/DennisOSRM/Project-OSRM into develop 2013-08-05 17:30:17 +02:00
Dennis Luxen 444bf41fa4 use exceptions instead of hard abort 2013-08-05 17:29:34 +02:00
Dennis Luxen 54302a53e1 use exceptions instead of hard abort 2013-08-05 17:28:57 +02:00
Emil Tin 63059cfab3 make cuke tests work with ruby 2.x 2013-08-02 09:35:28 +02:00
Dennis Luxen ec7d3a9885 Fixing boost filesystem to work on old installations, too 2013-08-01 15:56:18 +02:00
Dennis Luxen 960b55fd6c accidentially called deprecated boost filesystem function 2013-07-31 22:55:20 +02:00
Dennis Luxen 3067ba60ae convert relative path in server.ini to absolute paths 2013-07-31 22:05:44 +02:00
Dennis Luxen c9a756eddc Updateing Readme to give proper reference (again) 2013-07-31 13:12:25 +02:00
Dennis Luxen d4ea5fc74f Updateing Readme to give proper reference 2013-07-31 13:09:25 +02:00
Dennis Luxen 92e52f1a5d Updateing Readme to display build status 2013-07-31 13:04:04 +02:00
Dennis Luxen ef1d75db83 Add proper support for travis CI
Conflicts:
	.travis.yml
2013-07-31 11:38:03 +02:00
Dennis Luxen f03d1a5d27 check release and debug builds in travis 2013-07-31 11:33:23 +02:00
Dennis Luxen 8a55b706ca testing with cucumber 2013-07-31 11:22:02 +02:00
Dennis Luxen 357133677a Add project to travis CI 2013-07-31 11:17:08 +02:00
Dennis Luxen 1b6c660a8f Merge pull request #689 from svenluzar/feature/roundabout4bikes
pull request moved to develop branch: roundabout handling from car profile moved to bike profile
2013-07-31 02:13:38 -07:00
Dennis Luxen 111e68831e Merge branch 'feature/roundabout4bikes' of https://github.com/svenluzar/Project-OSRM 2013-07-31 11:11:10 +02:00
Dennis Luxen d9f6732ce2 Add Travis CI build support 2013-07-31 11:10:49 +02:00
Sven Luzar f2b81ba86c pull request moved to develop branch: roundabout handling from car profile moved to bike profile 2013-07-30 21:37:57 +02:00
Emil Tin 2542112301 fix cuke test for roundabout/cars 2013-07-30 18:00:44 +02:00
Emil Tin a45215ddf2 cuke test roundabout exit nr 2013-07-30 17:58:00 +02:00
Emil Tin cb28b2de07 cuke test for roundabout instructions 2013-07-30 17:01:25 +02:00
Dennis Luxen bf0b43aa24 Platform specific linker flags 2013-07-23 11:49:23 +02:00
Dennis Luxen 811d6deb41 Don't link against LuaJIT on OS X 2013-07-23 11:38:15 +02:00
Dennis Luxen bcdd9374c7 Compile fixes on OS X 2013-07-23 10:18:42 +02:00
DennisOSRM f70174d1d1 Link internal tools against UUID 2013-07-22 17:54:04 +02:00
DennisOSRM 4a39a4af1c Check for valid data files. Implements #224 2013-07-22 16:34:06 +02:00
DennisOSRM 0367399c89 Partial refactoring 2013-07-22 16:32:19 +02:00
DennisOSRM c5db4dc15f Check for correct magic number 2013-07-19 18:05:54 +02:00
DennisOSRM 31fbfa3a70 Link against UUID 2013-07-19 18:05:15 +02:00
DennisOSRM 3515ddcfe6 Automatic rebuild 2013-07-19 16:58:13 +02:00
DennisOSRM 90303d5952 further addition to cmake script 2013-07-19 16:36:57 +02:00
DennisOSRM 9a02421091 Some mild refactoring 2013-07-19 15:02:45 +02:00
DennisOSRM 4961b819f3 Trigger rebuild of fingerprint everytime 2013-07-19 15:00:41 +02:00
DennisOSRM 61c2ea9225 Trigger rebuild of fingerprint everytime 2013-07-19 14:53:47 +02:00
DennisOSRM f5f7269f70 Trigger rebuild of fingerprint everytime 2013-07-19 14:38:12 +02:00
DennisOSRM 03f1430ddc Trigger rebuild of fingerprint everytime 2013-07-19 14:37:40 +02:00
DennisOSRM c3dab15eb6 Several lookup fixes and fingerprinting of files with input IO, thx @alex85k 2013-07-18 14:11:45 +02:00
DennisOSRM a4f6ec516b Remove unnecessary file 2013-07-17 16:29:11 +02:00
DennisOSRM 1ca213cec6 Remove duplicate license header 2013-07-17 16:27:50 +02:00
DennisOSRM b782c8560c add forgotten include file 2013-07-17 16:27:09 +02:00
DennisOSRM d2e68068bf fixes #659 2013-07-17 16:23:57 +02:00
DennisOSRM 129a846393 add bit size to config object 2013-07-17 15:27:38 +02:00
DennisOSRM 15308931e9 (partially) adding new fingerprint objects 2013-07-17 14:47:22 +02:00
DennisOSRM 4dffeedd1c (partially) adding new fingerprint objects 2013-07-17 14:47:13 +02:00
DennisOSRM d0c4111429 Merge branch 'patch-3' of https://github.com/tyrasd/Project-OSRM into tyrasd-patch-3 2013-07-17 13:23:06 +02:00
DennisOSRM f579b6f971 Fixes #670 2013-07-17 13:20:48 +02:00
DennisOSRM f5124de327 Partially fixes #646. Values were incorrectly casted to int32_t and not uint32_t 2013-07-09 14:25:32 +02:00
DennisOSRM 9ab86ae2bf Fixes issue #663 2013-07-09 14:08:24 +02:00
DennisOSRM 51a7d3ff50 merge conflict CMakeLists.txt 2013-07-09 13:38:44 +02:00
DennisOSRM 80b9afc14d Merge branch 'libosrm' of https://github.com/DennisOSRM/Project-OSRM into libosrm 2013-07-08 15:10:43 +02:00
DennisOSRM 92ae8f37ba Reorder parameters 2013-07-08 14:59:51 +02:00
DennisOSRM df1f828488 Pass references instead of value types 2013-07-08 14:52:43 +02:00
DennisOSRM d8c97da087 Remove dead code and reformat 2013-07-08 14:51:55 +02:00
DennisOSRM 9d29e5d87a Base64 needs 3-byte padded inputs 2013-07-08 14:51:21 +02:00
DennisOSRM bf62147802 Fixing unneeded explicit conversion 2013-07-08 10:27:41 +02:00
Dennis Luxen 34735b8aad throw an exception when server.ini is missing 2013-07-05 22:36:51 +02:00
DennisOSRM 932b2b9acf Move pointer to member variables 2013-07-03 16:56:52 +02:00
DennisOSRM 7ab4472865 Fix non-critical memory leak 2013-07-03 16:54:51 +02:00
DennisOSRM e1e79206f9 fixing include typo 2013-07-03 16:01:59 +02:00
DennisOSRM 7ebe6de022 Proper check for luajit 2013-07-03 13:46:55 +02:00
DennisOSRM b234760e92 Check if platform supports 64 bits 2013-07-03 13:32:31 +02:00
DennisOSRM 3119e4b82b Use LuaJIT if available 2013-07-03 11:41:14 +02:00
DennisOSRM 2c3f05e6f1 Merge branch 'develop' of https://github.com/DennisOSRM/Project-OSRM into develop 2013-07-03 10:03:08 +02:00
Dennis Luxen 5b5da8698e Fix missing profile.lua 2013-07-02 22:59:46 +02:00
Dennis Luxen c3c0c8d881 readding profile.lua 2013-07-02 22:51:52 +02:00
Dennis Luxen 9de5e31a7a readding profile.lua 2013-07-02 22:51:21 +02:00
Martin Raifer dbf15c2db2 add test case for overruled implied oneways
On a motorway `oneway=no` should overrule the implied oneway rule.
2013-06-30 10:41:29 +02:00
Emil Tin c9c900b364 default cucumber profiles doesn't run @todo or @stress tests 2013-06-30 10:37:25 +02:00
Emil Tin 5c07204351 update rakefile for convenient cmake setup 2013-06-30 10:21:21 +02:00
Dennis Luxen 828b370ea1 Merging develop branch into master for v0.3.4 release 2013-06-28 10:30:34 -04:00
Dennis Luxen de947d8b17 Add forgotten include 2013-06-28 10:23:58 -04:00
Dennis Luxen 8cb5e68b1a fixing coding style on OpenMP wrapper 2013-06-28 10:22:47 -04:00
Dennis Luxen 99aef2a178 fixing coding style on OpenMP wrapper 2013-06-28 10:14:31 -04:00
Dennis Luxen fff1460dfb ignore osrm-cli tool 2013-06-27 16:11:13 -04:00
Dennis Luxen e3b619fd54 Moved File 2013-06-27 16:09:40 -04:00
Dennis Luxen 29e363e7fb some refactoring 2013-06-27 16:09:21 -04:00
Dennis Luxen c209245b0e Moving cli client to tools directory 2013-06-27 16:09:01 -04:00
Dennis Luxen 4194ce3095 Moving cli client to tools directory 2013-06-27 16:08:33 -04:00
Dennis Luxen a0e9f59e04 Adding a simple example on how to call the lib 2013-06-27 13:21:33 -04:00
Dennis Luxen c940c2722e Fixing errors from static analysis 2013-06-27 11:44:55 -04:00
Dennis Luxen 5c84c12f40 Fixing errors from static analysis 2013-06-27 11:44:32 -04:00
Dennis Luxen 1bcacfab74 minor code massage 2013-06-27 10:57:40 -04:00
Dennis Luxen 1f5f8a76fb Removing files that are not used anymore 2013-06-27 09:54:58 -04:00
Dennis Luxen cfa8b1f0dd Moving coordinate auxiliary functions into the appropriate place 2013-06-27 09:45:28 -04:00
Dennis Luxen aecbcdd390 move OSRM core into library 2013-06-26 20:05:42 -04:00
Dennis Luxen 74729a372b some refactoring 2013-06-26 20:05:03 -04:00
Dennis Luxen 63d8abe32f First implementation of moving the algorithmic core into a library 2013-06-26 19:48:22 -04:00
Dennis Luxen 2c397bfa0b First implementation of moving the algorithmic core into a library 2013-06-26 19:48:02 -04:00
Dennis Luxen bfef8f39b7 First implementation of moving the algorithmic core into a library 2013-06-26 19:47:47 -04:00
Dennis Luxen 4430cbc3cb First implementation of moving the algorithmic core into a library 2013-06-26 19:47:16 -04:00
Dennis Luxen ae20bac3c5 disabling debug output 2013-06-26 14:08:39 -04:00
Dennis Luxen d9a26c4062 fixing bug from premature commit 2013-06-26 13:50:07 -04:00
Dennis Luxen 48cb374d94 refactored some parameter setting 2013-06-26 13:40:25 -04:00
Dennis Luxen 9d6bd91279 some optimization to speed up pbf parsing 2013-06-26 13:39:45 -04:00
Dennis Luxen 163cfda282 Fixing test to reflect new nn grid data structure 2013-06-26 11:35:25 -04:00
Dennis Luxen 72cda375c8 removing copied profile 2013-06-26 10:41:48 -04:00
Dennis Luxen ecb4a08655 const'ing several private function parameters 2013-06-26 09:52:50 -04:00
Dennis Luxen 05c50bc64f adding missing include 2013-06-26 09:50:06 -04:00
Dennis Luxen 747e4a7061 Reorder include block according to style guide 2013-06-26 09:49:00 -04:00
Dennis Luxen 2b8b876713 Reorder include block according to style guide 2013-06-26 09:43:13 -04:00
Dennis Luxen f13694b539 fixing tests to reflect new r-tree data structure 2013-06-26 09:34:01 -04:00
Dennis Luxen 648f9c9723 replacing nearest neighbor grid by static r-tree 2013-06-26 09:32:03 -04:00
Dennis Luxen 0a6c37b726 Removing unused variable 2013-06-26 09:30:03 -04:00
DennisOSRM b43a51f912 Merge branch 'develop' of https://github.com/DennisOSRM/Project-OSRM into develop 2013-06-25 20:49:51 +02:00
Dennis Luxen fa328c5a78 don't about if timestamp is missing, just warn 2013-06-25 13:27:39 -04:00
Dennis Luxen 728bcc2b10 Removing debug output 2013-06-25 13:27:03 -04:00
Dennis Luxen 941903a243 Give number of edges when serializing graph 2013-06-25 10:57:39 -04:00
Dennis Luxen 4c8579b340 fixing test to actually test wanted behavior 2013-06-25 10:56:02 -04:00
Dennis Luxen 17416a09f1 fixing include order 2013-06-24 17:03:24 -04:00
Dennis Luxen fdda21b114 use explicit data types 2013-06-24 17:02:28 -04:00
Dennis Luxen c75ae957f1 Remove GUARANTEE macro 2013-06-24 16:56:10 -04:00
Dennis Luxen 8c678126f1 Remove GUARANTEE macro 2013-06-24 16:55:58 -04:00
Dennis Luxen 2b0590f9bd Remove GUARANTEE macro 2013-06-24 16:55:43 -04:00
Dennis Luxen a31992aac7 Remove GUARANTEE macro 2013-06-24 16:50:07 -04:00
Dennis Luxen 829d2505e3 restructured include block 2013-06-24 16:47:35 -04:00
Dennis Luxen df30498365 counting generated edges correctly 2013-06-24 16:39:35 -04:00
Dennis Luxen 5d553bf9f2 const as const can 2013-06-24 16:39:04 -04:00
Dennis Luxen 03e3673dbb Catching any left-over exception that may occur during preprocessing (stxxl) 2013-06-24 16:16:43 -04:00
Dennis Luxen 25b8b37f00 Restructure include block 2013-06-24 16:11:50 -04:00
Dennis Luxen 665f97e782 Move lua includes where they belong 2013-06-24 16:11:33 -04:00
Dennis Luxen 48a007febd minor style fix 2013-06-24 16:11:15 -04:00
Dennis Luxen 155e0fada6 Fixed an integer overflow in assertion 2013-06-24 16:05:27 -04:00
Dennis Luxen fe2f1d32b5 80 char wrap 2013-06-24 14:52:53 -04:00
Dennis Luxen 2fcbb19e72 80 char wrap 2013-06-24 14:43:36 -04:00
Dennis Luxen 06a50d637a De-template-izing some of the code for faster (re-)compile 2013-06-24 14:12:34 -04:00
Dennis Luxen 811b33e31a De-template-izing some of the code for faster (re-)compile 2013-06-24 14:12:29 -04:00
Dennis Luxen 54c83ee940 De-template-izing some of the code for faster (re-)compile 2013-06-24 14:12:25 -04:00
Dennis Luxen 7406e83dde De-template-izing some of the code for faster (re-)compile 2013-06-24 14:12:16 -04:00
Dennis Luxen dc2c7d5339 De-template-izing some of the code for faster (re-)compile 2013-06-24 14:12:08 -04:00
Dennis Luxen aaa25e5d48 De-template-izing some of the code for faster (re-)compile 2013-06-24 14:11:53 -04:00
Dennis Luxen b757bd0ea2 Update README.TXT 2013-06-15 22:07:07 +03:00
Dennis Luxen dd971d6b7d Fixing test for new Rtree 2013-06-05 11:38:45 +02:00
Emil Tin c07966408b add test for consecutive oneways, fails for car 2013-06-03 00:00:14 +02:00
Emil Tin 2557956b68 fix failing car maxspeed test 2013-06-03 00:00:14 +02:00
Emil Tin 735260d21b fix nearest test definition 2013-06-03 00:00:14 +02:00
DennisOSRM e5b0e43e18 Removing typo 2013-05-23 13:45:16 +02:00
DennisOSRM aa42b2494c Avoids the implicit lock of #630 2013-05-22 12:06:53 +02:00
DennisOSRM f057054172 Replacing stringstream based int->string conversion with boost karma
based generator
2013-05-22 11:59:12 +02:00
DennisOSRM c39314c643 Manuelly merging branch 'remove-lexical-cast2' into develop 2013-05-22 11:56:43 +02:00
Dennis Luxen ae018b759c Merge pull request #629 from springmeyer/cmake-fixes
fix spelling error and lacking boost header includes
2013-05-15 03:55:15 -07:00
Dane Springmeyer 556b498e06 remove lexical cast, its evil 2013-05-14 20:12:47 -07:00
Dane Springmeyer 19f1110421 fix spelling error and lacking boost header includes 2013-05-14 20:09:18 -07:00
Dennis Luxen cc73ed19b3 Merge pull request #628 from springmeyer/scons-clang-avoid-exit
Allow configure to work with clang and openmp disabled
2013-05-14 13:04:40 -07:00
Dane Springmeyer ccb7cc40df allow configure to work with clang and openmp disabled 2013-05-14 11:42:38 -07:00
Dennis Luxen 6d61e950d6 Removing superflous semicolon 2013-05-13 08:06:25 -04:00
Dennis Luxen 438c6e616c Merge branch 'develop' of https://github.com/DennisOSRM/Project-OSRM into develop 2013-05-12 18:49:36 -04:00
Dennis Luxen 8d2396b81f Additional settings for OS X build without warnings 2013-05-12 18:49:14 -04:00
Emil Tin 9588ef00a5 use alt=false during cucumber testing 2013-05-10 17:17:24 +02:00
Emil Tin 411603ea03 new geofabrik download url 2013-05-07 14:12:27 +02:00
Emil Tin 67addfdb37 test via points 2013-05-05 11:14:09 +02:00
Emil Tin 3afcd31f61 bike: use both ref&name when available 2013-04-28 11:42:21 +02:00
Emil Tin 7ac901cb08 update rake task to work with bins in /build 2013-04-27 17:01:43 +02:00
Emil Tin fcdee8f5d5 handle surfaces in bike profile 2013-04-27 17:00:25 +02:00
Emil Tin a7c32dfa95 rake shortcut for recompiling in build folder 2013-04-26 10:31:13 +02:00
Emil Tin 36f3c0f77a make cuke use bins in build/ 2013-04-26 10:22:32 +02:00
DennisOSRM dad4981a57 remove scons files from ignored list 2013-04-23 19:04:23 +02:00
Dennis Luxen df53357ef1 Good riddance, scons. 2013-04-23 11:21:02 +02:00
Dennis Luxen 85e333127a Manually merging cmake support 2013-04-22 22:24:40 +02:00
Dennis Luxen d52d86ae82 Manually merging cmake support 2013-04-22 22:23:53 +02:00
Dennis Luxen f62293275f Template arguments were uneccessarily defined 2013-04-22 16:42:14 +02:00
Emil Tin af490bae8e fix timestamp test 2013-04-16 16:56:05 +02:00
Emil Tin edf5a0f677 test processing flow example 2013-04-13 12:13:31 +02:00
Emil Tin 5eecd0a57d cuke: keep number nodes locally, not in osm file 2013-04-13 11:38:41 +02:00
Emil Tin 1fc11a6b06 return way type in encoded form for unnamed streets 2013-04-08 16:23:42 +02:00
Emil Tin 3516538813 remove .mode reference from bike profile 2013-04-08 11:27:12 +02:00
Emil Tin e3af8cb2e8 move name test 2013-04-08 11:19:17 +02:00
Emil Tin 16cd822555 mark failing name test as todo 2013-04-08 10:54:49 +02:00
Emil Tin 5938368a09 test for way name when way+area overlap 2013-04-08 10:21:23 +02:00
Emil Tin 50f865b81c add test for pushing bikes on footways etc 2013-04-08 10:04:17 +02:00
Emil Tin 96cd09471b encode way types for unnamed ways in bike profile 2013-04-08 10:04:17 +02:00
Emil Tin cf6c1e97bb add test for current contraflow instructions 2013-04-08 10:04:17 +02:00
Emil Tin f557e1efb4 remove test tag 2013-04-06 17:49:37 +02:00
Emil Tin 8893fd1656 test for bearing param (todo) 2013-03-18 21:26:36 +01:00
Emil Tin 081831e6ea test for mode flag (todo) 2013-03-18 15:51:41 +01:00
DennisOSRM 46c3ce0e34 Fixing 32 bit node id issue 2013-03-08 11:06:14 +01:00
DennisOSRM 6031a45c68 Avoid aborts like issue #601 2013-03-06 13:50:09 +01:00
DennisOSRM ca64887cba Partially implements #569, thx @lonvia 2013-03-03 18:26:29 +01:00
DennisOSRM 3f1d67ca4c Workaround for #557 2013-03-03 18:05:36 +01:00
DennisOSRM ff09af2812 Fixes #597, compile issues with boost filesystem2. 2013-03-03 17:38:35 +01:00
DennisOSRM 42b68fa834 Merging changes for 0.3.3 2013-03-01 10:31:02 +01:00
DennisOSRM 2cc2c967d1 Compute turn angles in mercartor projection. Implements issues #596,
#532
2013-02-28 13:34:48 +01:00
DennisOSRM bec4e4437d Minor code refactoring 2013-02-27 19:47:04 +01:00
Emil Tin f9abfbf68a compute turn penalties in lua profiles 2013-02-27 19:33:33 +01:00
DennisOSRM 53af4ee39f Cleaning of several regressions in the parsing code. 2013-02-27 17:36:44 +01:00
DennisOSRM af5f2f85da Workaround for failing tests 2013-02-26 09:57:29 +01:00
DennisOSRM ea83231da5 Fixing incorrect initialization of hash function 2013-02-25 18:47:17 +01:00
Project OSRM c4693602ef Adding geometry to production rules 2013-02-25 14:52:35 +01:00
Emil Tin 3c8dd85966 respect use_restricions in xml import 2013-02-23 13:53:06 +01:00
Emil Tin 0399022d25 update turn instruction test 2013-02-23 09:00:44 +01:00
drxzcl c6840496c0 Add basic CORS headers to allow cross-site access.
Add ¨Access-Control-Allow-Origin: *¨ to the HTTP headers of all replies.
This allows use in a cross-origin AJAX situation.

In compliance with the recommendations of section 4.2 of RFC2616, the header
is added before the existing entity headers.
2013-02-22 16:01:30 +01:00
DennisOSRM f7657280b6 Merge branch 'develop' of https://github.com/DennisOSRM/Project-OSRM into develop 2013-02-22 15:50:07 +01:00
Emil Tin f88a4baf79 update bike tests 2013-02-22 15:49:44 +01:00
Emil Tin b051f715e6 add 'no' to barrier whitelist in bike profile 2013-02-22 15:49:44 +01:00
Emil Tin 81a05c89e4 update bike speeds 2013-02-22 15:49:44 +01:00
Emil Tin cc55b016e9 don't push against oneway flow on roundabout. fixes #591 2013-02-22 15:49:44 +01:00
DennisOSRM ae8e51074e Removing superflous inline statements 2013-02-22 15:49:44 +01:00
Emil Tin 313b93169d turn off turn restrictions for bicycle and foot, update tests 2013-02-22 15:49:44 +01:00
Emil Tin db148741e9 code cleanup 2013-02-22 15:49:43 +01:00
Emil Tin 1ecad20a0d support xml, move duplicated xml/pbf code to base 2013-02-22 15:49:43 +01:00
Emil Tin 22c5c539c2 default to using turn restrictions 2013-02-22 15:49:43 +01:00
Emil Tin d59e526e1e lua setting for using turn restrictions 2013-02-22 15:49:43 +01:00
Emil Tin 94fa0047db update bike tests 2013-02-19 08:54:23 +01:00
Emil Tin 26e2f9ddd1 add 'no' to barrier whitelist in bike profile 2013-02-19 08:38:10 +01:00
Emil Tin 23254b4f24 update bike speeds 2013-02-19 08:38:10 +01:00
Emil Tin 9a44f16846 don't push against oneway flow on roundabout. fixes #591 2013-02-15 17:02:49 +01:00
DennisOSRM cad0069be2 Minor refactoring/reordering 2013-02-14 17:12:52 +01:00
DennisOSRM f315a013b8 Refactoring InputEdge type and removing dead code 2013-02-14 17:12:12 +01:00
DennisOSRM f780aa6160 Saving 4 bytes on each original edge. Simplifying handling of original
edge data
2013-02-14 17:11:18 +01:00
DennisOSRM 0f03beb2b5 replacing c-style size_t with the one from std namespace 2013-02-12 15:46:40 +01:00
DennisOSRM 7e39c43896 allocate data in chunks of 8MB 2013-02-12 15:24:35 +01:00
DennisOSRM 906d28fa5d Correct wrong allocation, use std::vector for node array and pass PODs
by value not ref
2013-02-12 15:23:09 +01:00
DennisOSRM 4d017f5d49 Saving 4 bytes per edge 2013-02-12 11:35:59 +01:00
DennisOSRM 6410314b0b Add license attribution to GPX output 2013-02-12 10:57:33 +01:00
DennisOSRM 1c0202e790 Reordering initializations 2013-02-11 15:20:37 +01:00
DennisOSRM 918c978551 Fixes issue #585 2013-02-11 15:06:33 +01:00
DennisOSRM 3d1a85bbea Fixing compilation issues on various compilers, i.e. old GCC, clang,
ICPC
2013-02-10 18:18:39 +01:00
Dennis Luxen 1a442c36e9 Implementing #566 2013-02-10 15:05:31 +01:00
Emil Tin a4e322f085 don't allow bikes on highway=construction, fixes #582 2013-02-06 16:58:18 +01:00
DennisOSRM 0b1d268b09 Fixing issue that enters infinite loop under certain conditions 2013-02-06 15:23:57 +01:00
DennisOSRM c2be6bc019 Fixes issue #567 2013-02-05 16:06:10 +01:00
DennisOSRM 9e11e832da fixing symlink 2013-02-05 09:50:14 +01:00
DennisOSRM 348e656671 Merge branch 'feature/opposite_direction' into develop 2013-02-04 18:38:15 +01:00
DennisOSRM 54cdf6d6f2 maxspeed:forward and :backward get parsed and tests pass. Implements
#569 partially.
2013-02-04 15:58:35 +01:00
DennisOSRM 7c5ca8f199 ignore changes on profile symlink 2013-02-04 13:11:03 +01:00
DennisOSRM ee42d94e2d Fix test to reflect changed maxspeed behavior 2013-02-04 13:10:31 +01:00
DennisOSRM 91baa9dfd7 Merge completed 2013-02-04 13:05:05 +01:00
DennisOSRM 572b176401 Fixes issue #579 2013-02-04 12:13:30 +01:00
Emil Tin 97f1dc0749 update maxspeed tests, remove maxspeed from foot profile 2013-02-04 11:30:46 +01:00
Emil Tin d67ac1a708 fuzzy matching in routability tables, ported from opposite branch 2013-02-04 10:33:25 +01:00
DennisOSRM 2707001a3a Merge branch 'feature/opposite_direction' of https://DennisOSRM@github.com/DennisOSRM/Project-OSRM.git into feature/opposite_direction 2013-02-03 23:25:06 +01:00
Emil Tin bb1064ac42 remove a nearest test, for now 2013-02-03 21:01:10 +01:00
Emil Tin 436cc692da a few more test for nearest api 2013-02-03 20:37:22 +01:00
Emil Tin 76decf2e8b fix nearest test 2013-02-03 20:24:46 +01:00
Emil Tin ccdd0f599a test nearest API 2013-02-03 20:17:06 +01:00
Emil Tin c65fed1d38 simplify testbot maxspeed forw/back test 2013-02-03 18:23:23 +01:00
DennisOSRM c36ec7c95b Replacing profile.lua by a symlink 2013-02-03 18:17:22 +01:00
DennisOSRM 305ce04284 replacing by symlink 2013-02-03 18:16:36 +01:00
DennisOSRM 034ce137a9 removing file 2013-02-03 18:15:39 +01:00
Emil Tin 73c81a0a6c Removing debug output 2013-02-03 18:13:57 +01:00
DennisOSRM 7544727f7a Turn on all warnings during build by default 2013-02-03 17:08:15 +01:00
DennisOSRM 961a379f79 Fixing signed/unsigned comparison warnings 2013-02-03 17:07:31 +01:00
DennisOSRM 9ffcaa5550 Fixed offset, moved rvalues to the left in comparisons and const'ed a
few things.
2013-02-03 16:56:59 +01:00
DennisOSRM 2dbae6ce51 Refactoring routing algorithms, alternative computation hastened by
sweeping the search space only once. Should fix #572
2013-02-03 16:47:32 +01:00
Emil Tin f7505e8877 test car maxspeed forw/backw (@todo) 2013-02-03 15:43:12 +01:00
Emil Tin c453f8e7a9 test car maxspeed forw/backw (@todo) 2013-02-03 15:42:14 +01:00
Emil Tin 3a4695713d test bike maxspeed forw/backw (@todo) 2013-02-03 15:34:41 +01:00
DennisOSRM 7d9d0878de Adding templated utility functions for repeated operations on containers 2013-02-03 14:59:10 +01:00
DennisOSRM 26729ca482 Fixing useless comparison 2013-02-03 14:57:40 +01:00
DennisOSRM 405600783e introducing further typedefs to make code more readable 2013-02-03 14:55:49 +01:00
DennisOSRM 5b5e9296b3 Adding const to parameter and rehash to give map 1000 buckets 2013-02-03 14:54:22 +01:00
Emil Tin dd5d520b53 update profile and tests for pushing of bikes 2013-02-03 14:46:18 +01:00
Emil Tin b3d517943a fuzzy ranges on routability tables, value shortcuts 2013-02-03 14:03:37 +01:00
DennisOSRM 59ca59d431 Using unordered_set where it suffices 2013-02-03 13:19:23 +01:00
DennisOSRM 78c92be14b Fixes issue #577, syntax error in JSONP response 2013-02-01 13:21:12 +01:00
DennisOSRM adf0c726ef Further changes to duration handling 2013-01-30 14:03:21 +01:00
DennisOSRM 9ecfed4e56 linking to car profile 2013-01-30 13:47:24 +01:00
DennisOSRM 9db884f371 Fixing duration parsing 2013-01-30 13:46:20 +01:00
DennisOSRM e0c211085c Handle route=shuttle_train again 2013-01-29 17:36:28 +01:00
DennisOSRM 555bfaf37a Merge branch 'develop' of https://github.com/DennisOSRM/Project-OSRM into develop 2013-01-29 17:19:54 +01:00
DennisOSRM bcf4af4a2f Duration tag now handles 'hh:mm', 'mm' as well as 'hh:mm:ss' 2013-01-29 10:11:04 +01:00
DennisOSRM 6a71163912 Merging further changes 2013-01-28 11:11:11 +01:00
Emil Tin cb2fcf4f52 add @todo tag to partial way duration test 2013-01-28 09:39:18 +01:00
Emil Tin 061d78c681 test partial duration of ways 2013-01-28 08:30:34 +01:00
DennisOSRM 0ffa973ec6 Exit gracefully when data is empty 2013-01-27 23:08:45 +01:00
DennisOSRM 03de87c213 Parsing duration when present 2013-01-27 23:06:23 +01:00
DennisOSRM 59481dd762 Adding duration member to way 2013-01-27 23:05:27 +01:00
DennisOSRM 86f4aebead Fixes test to expect time in minutes not seconds 2013-01-27 23:03:04 +01:00
DennisOSRM a92950d234 Fixes how durations are parsed 2013-01-27 23:01:37 +01:00
DennisOSRM ccdc6f1a63 Removing dead code 2013-01-27 23:00:06 +01:00
DennisOSRM 62cc8f456c Rebasing branch on develop 2013-01-27 14:49:47 +01:00
DennisOSRM f7c6b9a0f7 Fixed direction flag on split edges 2013-01-27 14:36:57 +01:00
DennisOSRM 01a6e3c619 Fixed the computation of reverse edge weight 2013-01-27 14:36:57 +01:00
DennisOSRM 6948d56e5d Fixing edge array sentinel at position n+1 2013-01-27 14:36:57 +01:00
DennisOSRM 6373b3e49c Adding first implementation of back() reference function 2013-01-27 14:36:57 +01:00
DennisOSRM 91dc1b6639 Adding curly braces where appropriate 2013-01-27 14:36:57 +01:00
DennisOSRM 6317b08090 Fixing test cases to check for different speeds in opposite direction 2013-01-27 14:36:57 +01:00
Emil Tin aae0547cca better testbot maxspeed handling, fix test 2013-01-27 14:36:56 +01:00
Emil Tin 4f9c422e2f test maxspeed forward/backward 2013-01-27 14:36:56 +01:00
Emil Tin 3595ac08f7 fix tag on @opposite test 2013-01-27 14:36:56 +01:00
Emil Tin 5339f440bd test forward/backward maxspeed (car) 2013-01-27 14:36:56 +01:00
Emil Tin 86d7442a5f support comments in test tables 2013-01-27 14:36:56 +01:00
DennisOSRM e6e5626a2c Implementing logic when route is going against one-way flow (think
bikes!)
2013-01-27 14:36:56 +01:00
DennisOSRM 4a52dd1c5b Fixing constant 2013-01-27 14:36:56 +01:00
DennisOSRM dd1302e8b1 Added new TurnInstruction that indicates when to go against oneway
streets. It's important for cycling.
2013-01-27 14:36:56 +01:00
DennisOSRM 7b4b7232fc Fixing test for opposite directions 2013-01-27 14:36:56 +01:00
DennisOSRM b069725df0 Support for backward speed in extractor 2013-01-27 14:36:56 +01:00
Emil Tin aa9d8c773f fix name of duration test 2013-01-26 19:06:30 +01:00
Emil Tin c68a03d05c add test scenario matching wiki graph explanation 2013-01-26 18:59:31 +01:00
Emil Tin cbea651cf8 test duration on ways 2013-01-26 18:58:33 +01:00
DennisOSRM b4ee345966 removing left-over debug output 2013-01-23 11:52:18 +01:00
DennisOSRM 296e7ccb08 Removing dead code 2013-01-23 11:34:16 +01:00
Emil Tin 43bb53e789 better testbot maxspeed handling, fix test 2013-01-19 16:00:44 +01:00
Emil Tin 384be58230 test maxspeed forward/backward 2013-01-19 13:10:11 +01:00
Emil Tin 46d1a87b89 fix tag on @opposite test 2013-01-19 13:07:21 +01:00
Emil Tin 7c8bf18cc6 test forward/backward maxspeed (car) 2013-01-19 13:06:52 +01:00
Emil Tin 35255d052d support comments in test tables 2013-01-19 13:06:52 +01:00
DennisOSRM cf5c776990 Implementing logic when route is going against one-way flow (think
bikes!)
2013-01-18 21:28:13 +01:00
DennisOSRM 9961172d70 Fixing constant 2013-01-18 19:33:51 +01:00
DennisOSRM c1c46544a6 Further optimizations 2013-01-18 19:08:22 +01:00
DennisOSRM fc24dbf9b7 Added new TurnInstruction that indicates when to go against oneway
streets. It's important for cycling.
2013-01-18 19:06:03 +01:00
DennisOSRM 7f311551dd Fixing test for opposite directions 2013-01-18 19:01:36 +01:00
DennisOSRM 1a6c01769e Support for backward speed in extractor 2013-01-18 19:01:36 +01:00
DennisOSRM 9da4e18099 Reordering padded struct 2013-01-18 18:59:38 +01:00
DennisOSRM b19e2fbafe Fixing test for opposite directions 2013-01-18 16:42:04 +01:00
DennisOSRM 7f69857376 Support for backward speed in extractor 2013-01-18 16:40:12 +01:00
DennisOSRM a64420d700 further const'ing 2013-01-11 22:22:57 +01:00
DennisOSRM 2ccd3da5b3 replacing unsafe strcpy operations 2013-01-11 22:13:02 +01:00
DennisOSRM 845c73af73 Removing unused table, Uninitialized scalar field (UNINIT_CTOR),
Coverity CID 751302
2013-01-11 20:44:35 +01:00
DennisOSRM f7d79209dc Fixing dereference after null check (Coverity: CID 967038) 2013-01-11 20:20:22 +01:00
DennisOSRM 0017aef89a Merge branch 'develop' of https://DennisOSRM@github.com/DennisOSRM/Project-OSRM.git into develop 2013-01-11 18:36:17 +01:00
DennisOSRM 7449f81ed4 Reordering members in struct to actually exploit four byte padding,
partially fixes #563
2013-01-11 18:36:00 +01:00
Emil Tin 724e96f0c1 test different forw/backw settings (@todo) 2013-01-11 18:16:17 +01:00
DennisOSRM 8158e7f1c5 Using explicit 64bit integer instead of compiler-dependent long long 2013-01-11 18:16:08 +01:00
Emil Tin 7d7baa70a9 test routes parsing (@todo) 2013-01-10 17:06:16 +01:00
Emil Tin 2e3947cc6d support list of ways in relations tests 2013-01-10 17:05:41 +01:00
Emil Tin 54774726b2 test separate weight/speed, still marked as @todo 2013-01-10 14:00:48 +01:00
DennisOSRM 2af9fcad68 Saving 3 bytes per original edge. 2013-01-06 19:38:03 +01:00
DennisOSRM fd79e81fe5 Removing explicit namespace usage 2013-01-06 19:06:17 +01:00
DennisOSRM 2b5e110719 Splitting utility header with ambigious name into two files with better
names
2013-01-06 19:03:04 +01:00
DennisOSRM 864c2d9f49 stray const keyword removed that prevented build 2013-01-06 17:58:02 +01:00
DennisOSRM 764fe533e8 Adding forgotten commit 2013-01-06 17:54:17 +01:00
DennisOSRM f1f59d770e Forgotten file. 2013-01-06 17:51:45 +01:00
DennisOSRM 950baaa9fc Merge branch 'develop' of https://DennisOSRM@github.com/DennisOSRM/Project-OSRM.git into develop 2013-01-06 17:48:30 +01:00
DennisOSRM 5b3aacb4b2 removing stringstream 2013-01-06 17:48:18 +01:00
Emil Tin d6adc56b3a add test for multiple except tag values in restrictions 2013-01-06 15:44:15 +01:00
DennisOSRM dbe1a4255c type change 2013-01-06 13:02:10 +01:00
DennisOSRM eed20b2271 several fixes to replace copied parameters with const refs. 2013-01-06 13:00:58 +01:00
DennisOSRM e70adbb1cb Using const-refs instead of copies when iterating vectors 2013-01-06 12:59:36 +01:00
DennisOSRM 06c22a478f fixing typo 2013-01-06 12:39:12 +01:00
Emil Tin 565b0e97d1 rename @weight test to @fastest 2013-01-06 11:51:45 +01:00
DennisOSRM 00168cb12f Removing dead code. 2013-01-05 22:47:12 +01:00
DennisOSRM ffdaa71086 Implementation of turn restriction exceptions 2013-01-05 19:20:25 +01:00
DennisOSRM 5de2aa1cbf fixing test and removing todo tag 2013-01-05 17:35:50 +01:00
DennisOSRM 64988ed831 Adding functionality for turn restriction exceptions to profile 2013-01-05 17:32:39 +01:00
DennisOSRM fa050ad616 Fixing registration of package path. 2013-01-05 17:27:10 +01:00
Project OSRM d2458f3169 Merge pull request #550 from ibikecph/lua_require
easy lua require()
2013-01-05 03:03:13 -08:00
Emil Tin 551af0e45a fix a few restrictions tests 2013-01-04 16:09:00 +01:00
DennisOSRM 4ac5440a4a Removing debug output 2013-01-04 12:49:31 +01:00
DennisOSRM 7c54d4e62f Fixes the Birminingham speed limit bug reported by Philip Barnes 2013-01-04 12:31:43 +01:00
DennisOSRM 8ab5915983 Add symlink to the profile in the respective folde 2013-01-04 12:23:25 +01:00
DennisOSRM 877865a4b1 removing profile 2013-01-04 12:22:09 +01:00
Dennis Luxen 7cf4d37595 Merge branch 'develop' of https://github.com/DennisOSRM/Project-OSRM into develop 2013-01-02 00:41:08 +01:00
Dennis Luxen 80add9f820 Splitting monolithic extraction code into compile units 2013-01-02 00:33:39 +01:00
Dennis Luxen 12a35c1214 Splitting monolithic extraction code into compile units 2013-01-02 00:33:14 +01:00
Dennis Luxen 9379d2462e Splitting monolithic extraction code into compile units 2013-01-02 00:32:34 +01:00
Emil Tin c5e8bed1fb increase stxxl allocation used in tests, to avoid reallocation 2013-01-02 00:02:48 +01:00
Emil Tin 4aa7ade32c ordering includes alphabetically 2013-01-01 23:20:16 +01:00
Emil Tin c4ed218a7a Revert "remove unused struct MinimalEdgeData"
This reverts commit 0235cf5d8e.
2013-01-01 23:01:52 +01:00
Emil Tin ff417fac01 update ferry tests 2013-01-01 18:41:38 +01:00
Emil Tin 0f4207f85e show total running time when extracting 2013-01-01 17:25:40 +01:00
Emil Tin f4431ed837 simple rake tasks for extracting/preparing separately 2013-01-01 17:10:30 +01:00
Emil Tin 0235cf5d8e remove unused struct MinimalEdgeData 2012-12-31 11:22:56 +01:00
DennisOSRM 8fc8a4e303 Removing last remaining 'using namespace std' statement 2012-12-29 21:02:26 +01:00
DennisOSRM 943c15927a Fixing data type issue that prevented large files on windows. See issue
#55
2012-12-29 14:14:01 +01:00
Emil Tin 28f0782b17 code cleanup, merge Lua.h and LuaUtil.h 2012-12-28 22:40:00 +01:00
Emil Tin 09e331a76b fix gitignore to avoid ignoring subfolders. add missing lua file 2012-12-28 22:40:00 +01:00
Emil Tin ce43b09991 support lua require() 2012-12-28 22:40:00 +01:00
DennisOSRM f9ab8426ce Merging changes for 0.3.2 2012-12-26 18:37:57 +01:00
DennisOSRM b869184c10 Replaced submodule with a text referencing the subproject directly 2012-12-26 18:32:57 +01:00
DennisOSRM 68e39b8053 Removing Docs submodule 2012-12-26 18:29:16 +01:00
DennisOSRM 8e023418e4 Removing superflous file 2012-12-23 20:03:12 +01:00
342 changed files with 32880 additions and 20094 deletions
+54
View File
@@ -0,0 +1,54 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
ConstructorInitializerIndentWidth: 4
AlignEscapedNewlinesLeft: false
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: true
AlwaysBreakTemplateDeclarations: false
AlwaysBreakBeforeMultilineStrings: false
BreakBeforeBinaryOperators: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BinPackParameters: false
ColumnLimit: 100
ConstructorInitializerAllOnOneLineOrOnePerLine: false
DerivePointerBinding: false
ExperimentalAutoDetectBinPacking: false
IndentCaseLabels: false
MaxEmptyLinesToKeep: 1
KeepEmptyLinesAtTheStartOfBlocks: true
NamespaceIndentation: None
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakString: 1000
PenaltyBreakFirstLessLess: 120
PenaltyExcessCharacter: 1000
PenaltyReturnTypeOnItsOwnLine: 60
PointerBindsToType: false
SpacesBeforeTrailingComments: 1
Cpp11BracedListStyle: true
Standard: Cpp11
IndentWidth: 4
TabWidth: 8
UseTab: Never
BreakBeforeBraces: Allman
IndentFunctionDeclarationAfterType: false
SpacesInParentheses: false
SpacesInAngles: false
SpaceInEmptyParentheses: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: true
SpaceBeforeAssignmentOperators: true
ContinuationIndentWidth: 4
CommentPragmas: '^ IWYU pragma:'
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
SpaceBeforeParens: ControlStatements
...
+26 -17
View File
@@ -33,11 +33,11 @@ ehthumbs.db
Icon?
Thumbs.db
# SCons related files #
# build related files #
#######################
SconsBuilder*
.scon*
.build
/build/
/Util/FingerPrint.cpp
/Util/GitDescription.cpp
# Eclipse related files #
#########################
@@ -54,30 +54,39 @@ stxxl.errlog
# compiled protobuffers #
#########################
DataStructures/pbf-proto/*.pb.h
DataStructures/pbf-proto/*.pb.cc
/DataStructures/pbf-proto/*.pb.h
/DataStructures/pbf-proto/*.pb.cc
# External Libs #
#################
lib/
win/lib
/lib/
/win/lib
# Visual Studio Temp + build Files #
####################################
win/*.user
win/*.ncb
win/*.suo
win/Debug/
win/Release/
win/bin/
win/bin-debug/
/win/*.user
/win/*.ncb
/win/*.suo
/win/Debug/
/win/Release/
/win/bin/
/win/bin-debug/
/osrm-extract
/osrm-io-benchmark
/osrm-components
/osrm-routed
/osrm-datastore
/osrm-prepare
/osrm-unlock-all
/osrm-cli
/nohup.out
# Sandbox folder #
###################
sandbox/
/sandbox/
test/profile.lua
/test/profile.lua
# Deprecated config file #
##########################
/server.ini
-3
View File
@@ -1,3 +0,0 @@
[submodule "Docs"]
path = Docs
url = https://github.com/DennisSchiefer/Project-OSRM-Web.git
+54
View File
@@ -0,0 +1,54 @@
language: cpp
compiler:
- gcc
# - clang
# Make sure CMake is installed
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 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
before_script:
- rvm use 1.9.3
- gem install bundler
- bundle install
- mkdir build
- cd build
- cmake .. $CMAKEOPTIONS
script:
- make -j 2
- cd ..
- cucumber -p verify
after_script:
# - cd ..
# - cucumber -p verify
branches:
only:
- master
- develop
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
notifications:
irc:
channels:
- irc.oftc.net#osrm
on_success: change
on_failure: always
use_notice: true
skip_join: false
recipients:
- dennis@mapbox.com
email:
on_success: change
on_failure: always
-11
View File
@@ -1,11 +0,0 @@
The following people contributed code to the Open Source Routing Machine:
Christian Vetter
Dennis Luxen
Ruslan Krenzler
Frederik Ramm
Bharath Vissapragada
Pascal Neis
Sasa Ivetic
Emil Tin
Henning Moll
+148
View File
@@ -0,0 +1,148 @@
#ifndef __BFS_COMPONENT_EXPLORER_H__
#define __BFS_COMPONENT_EXPLORER_H__
#include "../typedefs.h"
#include "../DataStructures/DynamicGraph.h"
#include "../DataStructures/RestrictionMap.h"
#include <queue>
#include <unordered_set>
// Explores the components of the given graph while respecting turn restrictions
// and barriers.
template <typename GraphT> class BFSComponentExplorer
{
public:
BFSComponentExplorer(const GraphT &dynamicGraph,
const RestrictionMap &restrictions,
const std::unordered_set<NodeID> &barrier_nodes)
: m_graph(dynamicGraph), m_restriction_map(restrictions), m_barrier_nodes(barrier_nodes)
{
BOOST_ASSERT(m_graph.GetNumberOfNodes() > 0);
}
/*!
* Returns the size of the component that the node belongs to.
*/
inline unsigned int GetComponentSize(NodeID node)
{
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(); }
/*!
* Computes the component sizes.
*/
void run()
{
std::queue<std::pair<NodeID, NodeID>> bfs_queue;
unsigned current_component = 0;
BOOST_ASSERT(m_component_index_list.empty());
BOOST_ASSERT(m_component_index_size.empty());
unsigned num_nodes = m_graph.GetNumberOfNodes();
m_component_index_list.resize(num_nodes, std::numeric_limits<unsigned>::max());
BOOST_ASSERT(num_nodes > 0);
// put unexplorered node with parent pointer into queue
for (NodeID node = 0; node < num_nodes; ++node)
{
if (std::numeric_limits<unsigned>::max() == m_component_index_list[node])
{
unsigned size = ExploreComponent(bfs_queue, node, current_component);
// push size into vector
m_component_index_size.emplace_back(size);
++current_component;
}
}
}
private:
/*!
* Explores the current component that starts at node using BFS.
*/
inline unsigned ExploreComponent(std::queue<std::pair<NodeID, NodeID>> &bfs_queue,
NodeID node,
unsigned current_component)
{
/*
Graphical representation of variables:
u v w
*---------->*---------->*
e2
*/
bfs_queue.emplace(node, node);
// mark node as read
m_component_index_list[node] = current_component;
unsigned current_component_size = 1;
while (!bfs_queue.empty())
{
// fetch element from BFS queue
std::pair<NodeID, NodeID> current_queue_item = bfs_queue.front();
bfs_queue.pop();
const NodeID v = current_queue_item.first; // current node
const NodeID u = current_queue_item.second; // parent
// increment size counter of current component
++current_component_size;
const bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end());
if (!is_barrier_node)
{
const NodeID to_node_of_only_restriction =
m_restriction_map.CheckForEmanatingIsOnlyTurn(u, v);
for (auto e2 : m_graph.GetAdjacentEdgeRange(v))
{
const NodeID w = m_graph.GetTarget(e2);
if (to_node_of_only_restriction != std::numeric_limits<unsigned>::max() &&
w != to_node_of_only_restriction)
{
// At an only_-restriction but not at the right turn
continue;
}
if (u != w)
{
// only add an edge if turn is not a U-turn except
// when it is at the end of a dead-end street.
if (!m_restriction_map.CheckIfTurnIsRestricted(u, v, w))
{
// only add an edge if turn is not prohibited
if (std::numeric_limits<unsigned>::max() == m_component_index_list[w])
{
// insert next (node, parent) only if w has
// not yet been explored
// mark node as read
m_component_index_list[w] = current_component;
bfs_queue.emplace(w, v);
}
}
}
}
}
}
return current_component_size;
}
std::vector<unsigned> m_component_index_list;
std::vector<NodeID> m_component_index_size;
const GraphT &m_graph;
const RestrictionMap &m_restriction_map;
const std::unordered_set<NodeID> &m_barrier_nodes;
};
#endif
-49
View File
@@ -1,49 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef BRESENHAM_H_
#define BRESENHAM_H_
#include <cmath>
#include <vector>
typedef std::pair<unsigned, unsigned> BresenhamPixel;
inline void Bresenham (int x0, int y0, int x1, int y1, std::vector<BresenhamPixel> &resultList) {
int dx = std::abs(x1-x0);
int dy = std::abs(y1-y0);
int sx = (x0 < x1 ? 1 : -1);
int sy = (y0 < y1 ? 1 : -1);
int err = dx - dy;
while(true) {
resultList.push_back(std::make_pair(x0,y0));
if(x0 == x1 && y0 == y1) break;
int e2 = 2* err;
if ( e2 > -dy) {
err -= dy;
x0 += sx;
}
if(e2 < dx) {
err+= dx;
y0 += sy;
}
}
}
#endif /* BRESENHAM_H_ */
-85
View File
@@ -1,85 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#include "CRC32.h"
CRC32::CRC32() : crc(0) {
crcFunction = detectBestCRC32C();
}
unsigned CRC32::SoftwareBasedCRC32(char *str, unsigned len, unsigned ) {
boost::crc_optimal<32, 0x1EDC6F41, 0x0, 0x0, true, true> CRC32_Processor;
CRC32_Processor.process_bytes( str, len);
return CRC32_Processor.checksum();
}
unsigned CRC32::SSEBasedCRC32( char *str, unsigned len, unsigned crc) {
unsigned q=len/sizeof(unsigned),
r=len%sizeof(unsigned),
*p=(unsigned*)str/*, crc*/;
//crc=0;
while (q--) {
__asm__ __volatile__(
".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;"
:"=S"(crc)
:"0"(crc), "c"(*p)
);
++p;
}
str=(char*)p;
while (r--) {
__asm__ __volatile__(
".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;"
:"=S"(crc)
:"0"(crc), "c"(*str)
);
++str;
}
return crc;
}
CRC32::CRC32CFunctionPtr CRC32::detectBestCRC32C() {
static const int SSE42_BIT = 20;
unsigned ecx = cpuid(1);
bool hasSSE42 = ecx & (1 << SSE42_BIT);
if (hasSSE42) {
std::cout << "using hardware base sse computation" << std::endl;
return &CRC32::SSEBasedCRC32; //crc32 hardware accelarated;
} else {
std::cout << "using software base sse computation" << std::endl;
return &CRC32::SoftwareBasedCRC32; //crc32cSlicingBy8;
}
}
unsigned CRC32::cpuid(unsigned functionInput) {
unsigned eax;
unsigned ebx;
unsigned ecx;
unsigned edx;
asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (functionInput));
return ecx;
}
unsigned CRC32::operator()(char *str, unsigned len){
crc =((*this).*(crcFunction))(str, len, crc);
return crc;
}
-46
View File
@@ -1,46 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef CRC32_H_
#define CRC32_H_
#include <boost/crc.hpp> // for boost::crc_32_type
#include <iostream>
class CRC32 {
private:
unsigned crc;
unsigned slowcrc_table[1<<8];
typedef boost::crc_optimal<32, 0x1EDC6F41, 0x0, 0x0, true, true> my_crc_32_type;
typedef unsigned (CRC32::*CRC32CFunctionPtr)(char *str, unsigned len, unsigned crc);
unsigned SoftwareBasedCRC32(char *str, unsigned len, unsigned crc);
unsigned SSEBasedCRC32( char *str, unsigned len, unsigned crc);
unsigned cpuid(unsigned functionInput);
CRC32CFunctionPtr detectBestCRC32C();
CRC32CFunctionPtr crcFunction;
public:
CRC32();
unsigned operator()(char *str, unsigned len);
virtual ~CRC32() {};
};
#endif /* CRC32_H_ */
+183
View File
@@ -0,0 +1,183 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <osrm/Coordinate.h>
#include "DouglasPeucker.h"
#include "../DataStructures/SegmentInformation.h"
#include "../Util/SimpleLogger.h"
#include <boost/assert.hpp>
#include <cmath>
#include <algorithm>
struct CoordinatePairCalculator
{
CoordinatePairCalculator() = delete;
CoordinatePairCalculator(const FixedPointCoordinate &coordinate_a,
const FixedPointCoordinate &coordinate_b)
{
// initialize distance calculator with two fixed coordinates a, b
const float RAD = 0.017453292519943295769236907684886f;
first_lat = (coordinate_a.lat / COORDINATE_PRECISION) * RAD;
first_lon = (coordinate_a.lon / COORDINATE_PRECISION) * RAD;
second_lat = (coordinate_b.lat / COORDINATE_PRECISION) * RAD;
second_lon = (coordinate_b.lon / COORDINATE_PRECISION) * RAD;
}
int operator()(FixedPointCoordinate &other) const
{
// set third coordinate c
const float RAD = 0.017453292519943295769236907684886f;
const float earth_radius = 6372797.560856f;
const float float_lat1 = (other.lat / COORDINATE_PRECISION) * RAD;
const float float_lon1 = (other.lon / COORDINATE_PRECISION) * RAD;
// compute distance (a,c)
const float x_value_1 = (first_lon - float_lon1) * cos((float_lat1 + first_lat) / 2.f);
const float y_value_1 = first_lat - float_lat1;
const float dist1 = sqrt(std::pow(x_value_1, 2) + std::pow(y_value_1, 2)) * earth_radius;
// compute distance (b,c)
const float x_value_2 = (second_lon - float_lon1) * cos((float_lat1 + second_lat) / 2.f);
const float y_value_2 = second_lat - float_lat1;
const float dist2 = sqrt(std::pow(x_value_2, 2) + std::pow(y_value_2, 2)) * earth_radius;
// return the minimum
return static_cast<int>(std::min(dist1, dist2));
}
float first_lat;
float first_lon;
float second_lat;
float second_lon;
};
DouglasPeucker::DouglasPeucker()
: douglas_peucker_thresholds({512440, // z0
256720, // z1
122560, // z2
56780, // z3
28800, // z4
14400, // z5
7200, // z6
3200, // z7
2400, // z8
1000, // z9
600, // z10
120, // z11
60, // z12
45, // z13
36, // z14
20, // z15
8, // z16
6, // z17
4 // z18
})
{
}
void DouglasPeucker::Run(std::vector<SegmentInformation> &input_geometry, const unsigned zoom_level)
{
// check if input data is invalid
BOOST_ASSERT_MSG(!input_geometry.empty(), "geometry invalid");
if (input_geometry.size() < 2)
{
return;
}
input_geometry.front().necessary = true;
input_geometry.back().necessary = true;
{
BOOST_ASSERT_MSG(zoom_level < 19, "unsupported zoom level");
unsigned left_border = 0;
unsigned right_border = 1;
// Sweep over array and identify those ranges that need to be checked
do
{
// traverse list until new border element found
if (input_geometry[right_border].necessary)
{
// sanity checks
BOOST_ASSERT(input_geometry[left_border].necessary);
BOOST_ASSERT(input_geometry[right_border].necessary);
recursion_stack.emplace(left_border, right_border);
left_border = right_border;
}
++right_border;
} while (right_border < input_geometry.size());
}
// mark locations as 'necessary' by divide-and-conquer
while (!recursion_stack.empty())
{
// pop next element
const GeometryRange pair = recursion_stack.top();
recursion_stack.pop();
// sanity checks
BOOST_ASSERT_MSG(input_geometry[pair.first].necessary, "left border mus be necessary");
BOOST_ASSERT_MSG(input_geometry[pair.second].necessary, "right border must be necessary");
BOOST_ASSERT_MSG(pair.second < input_geometry.size(), "right border outside of geometry");
BOOST_ASSERT_MSG(pair.first < pair.second, "left border on the wrong side");
int max_int_distance = 0;
unsigned farthest_entry_index = pair.second;
const CoordinatePairCalculator DistCalc(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)
{
const int distance = DistCalc(input_geometry[i].location);
// found new feasible maximum?
if (distance > max_int_distance && distance > douglas_peucker_thresholds[zoom_level])
{
farthest_entry_index = i;
max_int_distance = distance;
}
}
// check if maximum violates a zoom level dependent threshold
if (max_int_distance > douglas_peucker_thresholds[zoom_level])
{
// mark idx as necessary
input_geometry[farthest_entry_index].necessary = true;
if (1 < (farthest_entry_index - pair.first))
{
recursion_stack.emplace(pair.first, farthest_entry_index);
}
if (1 < (pair.second - farthest_entry_index))
{
recursion_stack.emplace(farthest_entry_index, pair.second);
}
}
}
}
+39 -110
View File
@@ -1,129 +1,58 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 DOUGLASPEUCKER_H_
#define DOUGLASPEUCKER_H_
#include <cassert>
#include <cmath>
#include <cfloat>
#include <stack>
#include <utility>
#include <vector>
#include "../DataStructures/Coordinate.h"
/*This class object computes the bitvector of indicating generalized input points
* according to the (Ramer-)Douglas-Peucker algorithm.
/* This class object computes the bitvector of indicating generalized input
* points according to the (Ramer-)Douglas-Peucker algorithm.
*
* Input is vector of pairs. Each pair consists of the point information and a bit
* indicating if the points is present in the generalization.
* Input is vector of pairs. Each pair consists of the point information and a
* bit indicating if the points is present in the generalization.
* Note: points may also be pre-selected*/
//These thresholds are more or less heuristically chosen.
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
static double DouglasPeuckerThresholds[19] = { 32000000., 16240000., 80240000., 40240000., 20000000., 10000000., 500000., 240000., 120000., 60000., 30000., 19000., 5000., 2000., 200, 16, 6, 3. , 3. };
struct SegmentInformation;
template<class PointT>
class DouglasPeucker {
private:
typedef std::pair<std::size_t, std::size_t> PairOfPoints;
//Stack to simulate the recursion
std::stack<PairOfPoints > recursionStack;
class DouglasPeucker
{
private:
std::vector<int> douglas_peucker_thresholds;
/**
* This distance computation does integer arithmetic only and is about twice as fast as
* the other distance function. It is an approximation only, but works more or less ok.
*/
template<class CoordT>
inline int fastDistance(const CoordT& point, const CoordT& segA, const CoordT& segB) const {
const int p2x = (segB.lon - segA.lat);
const int p2y = (segB.lon - segA.lat);
const int something = p2x*p2x + p2y*p2y;
int u = (something < FLT_EPSILON ? 0 : ((point.lon - segA.lon) * p2x + (point.lat - segA.lat) * p2y) / something);
typedef std::pair<unsigned, unsigned> GeometryRange;
// Stack to simulate the recursion
std::stack<GeometryRange> recursion_stack;
if (u > 1)
u = 1;
else if (u < 0)
u = 0;
const int x = segA.lon + u * p2x;
const int y = segA.lat + u * p2y;
const int dx = x - point.lon;
const int dy = y - point.lat;
const int dist = (dx*dx + dy*dy);
return dist;
}
public:
void Run(std::vector<PointT> & inputVector, const unsigned zoomLevel) {
{
assert(zoomLevel < 19);
assert(1 < inputVector.size());
std::size_t leftBorderOfRange = 0;
std::size_t rightBorderOfRange = 1;
//Sweep linerarily over array and identify those ranges that need to be checked
// recursionStack.hint(inputVector.size());
do {
assert(inputVector[leftBorderOfRange].necessary);
assert(inputVector.back().necessary);
if(inputVector[rightBorderOfRange].necessary) {
recursionStack.push(std::make_pair(leftBorderOfRange, rightBorderOfRange));
leftBorderOfRange = rightBorderOfRange;
}
++rightBorderOfRange;
} while( rightBorderOfRange < inputVector.size());
}
while(!recursionStack.empty()) {
//pop next element
const PairOfPoints pair = recursionStack.top();
recursionStack.pop();
assert(inputVector[pair.first].necessary);
assert(inputVector[pair.second].necessary);
assert(pair.second < inputVector.size());
assert(pair.first < pair.second);
int maxDistance = INT_MIN;
std::size_t indexOfFarthestElement = pair.second;
//find index idx of element with maxDistance
for(std::size_t i = pair.first+1; i < pair.second; ++i){
const double distance = std::fabs(fastDistance(inputVector[i].location, inputVector[pair.first].location, inputVector[pair.second].location));
if(distance > DouglasPeuckerThresholds[zoomLevel] && distance > maxDistance) {
indexOfFarthestElement = i;
maxDistance = distance;
}
}
if (maxDistance > DouglasPeuckerThresholds[zoomLevel]) {
// mark idx as necessary
inputVector[indexOfFarthestElement].necessary = true;
if (1 < indexOfFarthestElement - pair.first) {
recursionStack.push(std::make_pair(pair.first, indexOfFarthestElement) );
}
if (1 < pair.second - indexOfFarthestElement)
recursionStack.push(std::make_pair(indexOfFarthestElement, pair.second) );
}
}
}
public:
DouglasPeucker();
void Run(std::vector<SegmentInformation> &input_geometry, const unsigned zoom_level);
};
#endif /* DOUGLASPEUCKER_H_ */
+169
View File
@@ -0,0 +1,169 @@
/*
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 EXTRACT_ROUTE_NAMES_H
#define EXTRACT_ROUTE_NAMES_H
#include <boost/assert.hpp>
#include <algorithm>
#include <string>
#include <vector>
struct RouteNames
{
std::string shortest_path_name_1;
std::string shortest_path_name_2;
std::string alternative_path_name_1;
std::string alternative_path_name_2;
};
// construct routes names
template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
{
private:
SegmentT PickNextLongestSegment(const std::vector<SegmentT> &segment_list,
const unsigned blocked_name_id) const
{
SegmentT result_segment;
result_segment.length = 0;
for (const SegmentT &segment : segment_list)
{
if (segment.name_id != blocked_name_id && segment.length > result_segment.length)
{
result_segment = segment;
}
}
return result_segment;
}
public:
RouteNames operator()(std::vector<SegmentT> &shortest_path_segments,
std::vector<SegmentT> &alternative_path_segments,
const DataFacadeT *facade) const
{
RouteNames route_names;
SegmentT shortest_segment_1, shortest_segment_2;
SegmentT alternative_segment_1, alternative_segment_2;
auto length_comperator = [](const SegmentT &a, const SegmentT &b)
{ return a.length > b.length; };
auto name_id_comperator = [](const SegmentT &a, const SegmentT &b)
{ return a.name_id < b.name_id; };
if (shortest_path_segments.empty())
{
return route_names;
}
// pick the longest segment for the shortest path.
std::sort(shortest_path_segments.begin(), shortest_path_segments.end(), length_comperator);
shortest_segment_1 = shortest_path_segments[0];
if (!alternative_path_segments.empty())
{
std::sort(alternative_path_segments.begin(),
alternative_path_segments.end(),
length_comperator);
// also pick the longest segment for the alternative path
alternative_segment_1 = alternative_path_segments[0];
}
// compute the set difference (for shortest path) depending on names between shortest and
// alternative
std::vector<SegmentT> shortest_path_set_difference(shortest_path_segments.size());
std::sort(shortest_path_segments.begin(), shortest_path_segments.end(), name_id_comperator);
std::sort(alternative_path_segments.begin(), alternative_path_segments.end(), name_id_comperator);
std::set_difference(shortest_path_segments.begin(),
shortest_path_segments.end(),
alternative_path_segments.begin(),
alternative_path_segments.end(),
shortest_path_set_difference.begin(),
name_id_comperator);
std::sort(shortest_path_set_difference.begin(),
shortest_path_set_difference.end(),
length_comperator);
shortest_segment_2 =
PickNextLongestSegment(shortest_path_set_difference, shortest_path_segments[0].name_id);
// compute the set difference (for alternative path) depending on names between shortest and
// alternative
// vectors are still sorted, no need to do again
BOOST_ASSERT(std::is_sorted(shortest_path_segments.begin(),
shortest_path_segments.end(),
name_id_comperator));
BOOST_ASSERT(std::is_sorted(alternative_path_segments.begin(),
alternative_path_segments.end(),
name_id_comperator));
std::vector<SegmentT> alternative_path_set_difference(alternative_path_segments.size());
std::set_difference(alternative_path_segments.begin(),
alternative_path_segments.end(),
shortest_path_segments.begin(),
shortest_path_segments.end(),
alternative_path_set_difference.begin(),
name_id_comperator);
std::sort(alternative_path_set_difference.begin(),
alternative_path_set_difference.end(),
length_comperator);
if (!alternative_path_segments.empty())
{
alternative_segment_2 = PickNextLongestSegment(alternative_path_set_difference,
alternative_path_segments[0].name_id);
}
// move the segments into the order in which they occur.
if (shortest_segment_1.position > shortest_segment_2.position)
{
std::swap(shortest_segment_1, shortest_segment_2);
}
if (alternative_segment_1.position > alternative_segment_2.position)
{
std::swap(alternative_segment_1, alternative_segment_2);
}
// fetching names for the selected segments
route_names.shortest_path_name_1 =
facade->GetEscapedNameForNameID(shortest_segment_1.name_id);
route_names.shortest_path_name_2 =
facade->GetEscapedNameForNameID(shortest_segment_2.name_id);
route_names.alternative_path_name_1 =
facade->GetEscapedNameForNameID(alternative_segment_1.name_id);
route_names.alternative_path_name_2 =
facade->GetEscapedNameForNameID(alternative_segment_2.name_id);
return route_names;
}
};
#endif // EXTRACT_ROUTE_NAMES_H
+108 -74
View File
@@ -1,110 +1,144 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 ITERATORBASEDCRC32_H_
#define ITERATORBASEDCRC32_H_
*/
#ifndef ITERATOR_BASED_CRC32_H
#define ITERATOR_BASED_CRC32_H
#include "../Util/SimpleLogger.h"
#include <boost/crc.hpp> // for boost::crc_32_type
#include <iostream>
template<class ContainerT>
class IteratorbasedCRC32 {
private:
typedef typename ContainerT::iterator ContainerT_iterator;
#if defined(__x86_64__) && !defined(__MINGW64__)
#include <cpuid.h>
#else
#include <boost/crc.hpp> // for boost::crc_32_type
inline void __get_cpuid(int param, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx)
{
*ecx = 0;
}
#endif
template <class ContainerT> class IteratorbasedCRC32
{
private:
typedef typename ContainerT::iterator IteratorType;
unsigned crc;
unsigned slowcrc_table[1<<8];
typedef boost::crc_optimal<32, 0x1EDC6F41, 0x0, 0x0, true, true> my_crc_32_type;
typedef unsigned (IteratorbasedCRC32::*CRC32CFunctionPtr)(char *str, unsigned len, unsigned crc);
bool use_SSE42_CRC_function;
unsigned SoftwareBasedCRC32(char *str, unsigned len, unsigned ){
boost::crc_optimal<32, 0x1EDC6F41, 0x0, 0x0, true, true> CRC32_Processor;
CRC32_Processor.process_bytes( str, len);
return CRC32_Processor.checksum();
#if !defined(__x86_64__)
boost::crc_optimal<32, 0x1EDC6F41, 0x0, 0x0, true, true> CRC32_processor;
#endif
unsigned SoftwareBasedCRC32(char *str, unsigned len)
{
#if !defined(__x86_64__)
CRC32_processor.process_bytes(str, len);
return CRC32_processor.checksum();
#else
return 0;
#endif
}
unsigned SSEBasedCRC32( char *str, unsigned len, unsigned crc){
unsigned q=len/sizeof(unsigned),
r=len%sizeof(unsigned),
*p=(unsigned*)str/*, crc*/;
//crc=0;
while (q--) {
__asm__ __volatile__(
".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;"
:"=S"(crc)
:"0"(crc), "c"(*p)
);
// adapted from http://byteworm.com/2010/10/13/crc32/
unsigned SSE42BasedCRC32(char *str, unsigned len)
{
#if defined(__x86_64__)
unsigned q = len / sizeof(unsigned);
unsigned r = len % sizeof(unsigned);
unsigned *p = (unsigned *)str;
// crc=0;
while (q--)
{
__asm__ __volatile__(".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;"
: "=S"(crc)
: "0"(crc), "c"(*p));
++p;
}
str=(char*)p;
while (r--) {
__asm__ __volatile__(
".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;"
:"=S"(crc)
:"0"(crc), "c"(*str)
);
str = (char *)p;
while (r--)
{
__asm__ __volatile__(".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;"
: "=S"(crc)
: "0"(crc), "c"(*str));
++str;
}
#endif
return crc;
}
unsigned cpuid(unsigned functionInput){
unsigned eax;
unsigned ebx;
unsigned ecx;
unsigned edx;
asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (functionInput));
inline unsigned cpuid() const
{
unsigned eax = 0, ebx = 0, ecx = 0, edx = 0;
// on X64 this calls hardware cpuid(.) instr. otherwise a dummy impl.
__get_cpuid(1, &eax, &ebx, &ecx, &edx);
return ecx;
}
CRC32CFunctionPtr detectBestCRC32C(){
static const int SSE42_BIT = 20;
unsigned ecx = cpuid(1);
bool hasSSE42 = ecx & (1 << SSE42_BIT);
if (hasSSE42) {
std::cout << "using hardware base sse computation" << std::endl;
return &IteratorbasedCRC32::SSEBasedCRC32; //crc32 hardware accelarated;
} else {
std::cout << "using software base sse computation" << std::endl;
return &IteratorbasedCRC32::SoftwareBasedCRC32; //crc32cSlicingBy8;
bool DetectNativeCRC32Support()
{
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";
}
}
CRC32CFunctionPtr crcFunction;
public:
IteratorbasedCRC32(): crc(0) {
crcFunction = detectBestCRC32C();
else
{
SimpleLogger().Write() << "using software based CRC32 computation";
}
return has_SSE42;
}
virtual ~IteratorbasedCRC32() {};
public:
IteratorbasedCRC32() : crc(0) { use_SSE42_CRC_function = DetectNativeCRC32Support(); }
unsigned operator()( ContainerT_iterator iter, const ContainerT_iterator end) {
unsigned operator()(IteratorType iter, const IteratorType end)
{
unsigned crc = 0;
while(iter != end) {
char * data = reinterpret_cast<char*>(&(*iter) );
crc =((*this).*(crcFunction))(data, sizeof(typename ContainerT::value_type*), crc);
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;
}
};
#endif /* ITERATORBASEDCRC32_H_ */
#endif /* ITERATOR_BASED_CRC32_H */
+66 -34
View File
@@ -1,67 +1,99 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 OBJECTTOBASE64_H_
#define OBJECTTOBASE64_H_
#include "../Util/StringUtil.h"
#include <boost/assert.hpp>
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/foreach.hpp>
#include <algorithm>
#include <string>
#include "../Util/StringUtil.h"
#include <vector>
typedef
boost::archive::iterators::base64_from_binary<
boost::archive::iterators::transform_width<string::const_iterator, 6, 8>
> base64_t;
boost::archive::iterators::transform_width<const char *, 6, 8>
> base64_t;
typedef
boost::archive::iterators::transform_width<
boost::archive::iterators::binary_from_base64<string::const_iterator>, 8, 6
boost::archive::iterators::binary_from_base64<
std::string::const_iterator>, 8, 6
> binary_t;
template<class ToEncodeT>
static void EncodeObjectToBase64(const ToEncodeT & object, std::string& encoded) {
encoded.clear();
char * pointerToOriginalObject = (char *)&object;
encoded = std::string(base64_t(pointerToOriginalObject), base64_t(pointerToOriginalObject+sizeof(ToEncodeT)));
//replace "+" with "-" and "/" with "_"
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()
);
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, "/", "_");
}
template<class ToEncodeT>
static void DecodeObjectFromBase64(ToEncodeT & object, const std::string& _encoded) {
template<class ObjectT>
static void DecodeObjectFromBase64(const std::string& input, ObjectT & object) {
try {
string encoded(_encoded);
std::string encoded(input);
//replace "-" with "+" and "_" with "/"
replaceAll(encoded, "-", "+");
replaceAll(encoded, "_", "/");
char * pointerToDecodedObject = (char *)&object;
std::string dec(binary_t(encoded.begin()), binary_t(encoded.begin() + encoded.length() - 1));
std::copy ( dec.begin(), dec.end(), pointerToDecodedObject );
} catch(...) {}
std::copy (
binary_t( encoded.begin() ),
binary_t( encoded.begin() + encoded.length() - 1),
(char *)&object
);
} catch(...) { }
}
#endif /* OBJECTTOBASE64_H_ */
+118
View File
@@ -0,0 +1,118 @@
/*
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 "PolylineCompressor.h"
#include "../DataStructures/SegmentInformation.h"
#include <osrm/Coordinate.h>
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)
{
numbers[i] <<= 1;
if (numbers[i] < 0)
{
numbers[i] = ~(numbers[i]);
}
}
for (const int number : numbers)
{
encodeNumber(number, output);
}
}
void PolylineCompressor::encodeNumber(int number_to_encode, std::string &output) const
{
while (number_to_encode >= 0x20)
{
const int next_value = (0x20 | (number_to_encode & 0x1f)) + 63;
output += static_cast<char>(next_value);
if (92 == next_value)
{
output += static_cast<char>(next_value);
}
number_to_encode >>= 5;
}
number_to_encode += 63;
output += static_cast<char>(number_to_encode);
if (92 == number_to_encode)
{
output += static_cast<char>(number_to_encode);
}
}
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)
{
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;
delta_numbers.emplace_back(lat_diff);
delta_numbers.emplace_back(lon_diff);
last_coordinate = segment.location;
}
}
encodeVectorSignedNumber(delta_numbers, output);
}
JSON::String return_value(output);
return return_value;
}
JSON::Array
PolylineCompressor::printUnencodedString(const std::vector<SegmentInformation> &polyline) const
{
JSON::Array json_geometry_array;
for (const auto &segment : polyline)
{
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);
}
}
return json_geometry_array;
}
+35 -118
View File
@@ -1,134 +1,51 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 POLYLINECOMPRESSOR_H_
#define POLYLINECOMPRESSOR_H_
struct SegmentInformation;
#include "../DataStructures/JSONContainer.h"
#include <string>
#include <vector>
//#include "../DataStructures/ExtractorStructs.h"
#include "../DataStructures/SegmentInformation.h"
#include "../Util/StringUtil.h"
class PolylineCompressor
{
private:
void encodeVectorSignedNumber(std::vector<int> &numbers, std::string &output) const;
class PolylineCompressor {
private:
inline void encodeVectorSignedNumber(std::vector<int> & numbers, std::string & output) const {
for(unsigned i = 0; i < numbers.size(); ++i) {
numbers[i] <<= 1;
if (numbers[i] < 0) {
numbers[i] = ~(numbers[i]);
}
}
for(unsigned i = 0; i < numbers.size(); ++i) {
encodeNumber(numbers[i], output);
}
}
void encodeNumber(int number_to_encode, std::string &output) const;
inline void encodeNumber(int numberToEncode, std::string & output) const {
while (numberToEncode >= 0x20) {
int nextValue = (0x20 | (numberToEncode & 0x1f)) + 63;
output += (static_cast<char> (nextValue));
if(92 == nextValue)
output += (static_cast<char> (nextValue));
numberToEncode >>= 5;
}
public:
JSON::String printEncodedString(const std::vector<SegmentInformation> &polyline) const;
numberToEncode += 63;
output += (static_cast<char> (numberToEncode));
if(92 == numberToEncode)
output += (static_cast<char> (numberToEncode));
}
public:
inline void printEncodedString(const std::vector<SegmentInformation>& polyline, std::string &output) const {
std::vector<int> deltaNumbers;
output += "\"";
if(!polyline.empty()) {
_Coordinate lastCoordinate = polyline[0].location;
deltaNumbers.push_back( lastCoordinate.lat );
deltaNumbers.push_back( lastCoordinate.lon );
for(unsigned i = 1; i < polyline.size(); ++i) {
if(!polyline[i].necessary)
continue;
deltaNumbers.push_back(polyline[i].location.lat - lastCoordinate.lat);
deltaNumbers.push_back(polyline[i].location.lon - lastCoordinate.lon);
lastCoordinate = polyline[i].location;
}
encodeVectorSignedNumber(deltaNumbers, output);
}
output += "\"";
}
inline void printEncodedString(const std::vector<_Coordinate>& polyline, std::string &output) const {
std::vector<int> deltaNumbers(2*polyline.size());
output += "\"";
if(!polyline.empty()) {
deltaNumbers[0] = polyline[0].lat;
deltaNumbers[1] = polyline[0].lon;
for(unsigned i = 1; i < polyline.size(); ++i) {
deltaNumbers[(2*i)] = (polyline[i].lat - polyline[i-1].lat);
deltaNumbers[(2*i)+1] = (polyline[i].lon - polyline[i-1].lon);
}
encodeVectorSignedNumber(deltaNumbers, output);
}
output += "\"";
}
inline void printUnencodedString(std::vector<_Coordinate> & polyline, std::string & output) const {
output += "[";
std::string tmp;
for(unsigned i = 0; i < polyline.size(); i++) {
convertInternalLatLonToString(polyline[i].lat, tmp);
output += "[";
output += tmp;
convertInternalLatLonToString(polyline[i].lon, tmp);
output += ", ";
output += tmp;
output += "]";
if( i < polyline.size()-1 ) {
output += ",";
}
}
output += "]";
}
inline void printUnencodedString(std::vector<SegmentInformation> & polyline, std::string & output) const {
output += "[";
std::string tmp;
for(unsigned i = 0; i < polyline.size(); i++) {
if(!polyline[i].necessary)
continue;
convertInternalLatLonToString(polyline[i].location.lat, tmp);
output += "[";
output += tmp;
convertInternalLatLonToString(polyline[i].location.lon, tmp);
output += ", ";
output += tmp;
output += "]";
if( i < polyline.size()-1 ) {
output += ",";
}
}
output += "]";
}
JSON::Array printUnencodedString(const std::vector<SegmentInformation> &polyline) const;
};
#endif /* POLYLINECOMPRESSOR_H_ */
+358 -293
View File
@@ -1,382 +1,447 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 STRONGLYCONNECTEDCOMPONENTS_H_
#define STRONGLYCONNECTEDCOMPONENTS_H_
#include <cassert>
#include <stack>
#include <vector>
#include <boost/foreach.hpp>
#include <boost/make_shared.hpp>
#include <boost/unordered_map.hpp>
#include <gdal/gdal.h>
#include <gdal/ogrsf_frmts.h>
#include "../typedefs.h"
#include "../DataStructures/DeallocatingVector.h"
#include "../DataStructures/DynamicGraph.h"
#include "../DataStructures/ImportEdge.h"
#include "../DataStructures/NodeCoords.h"
#include "../DataStructures/QueryNode.h"
#include "../DataStructures/Percent.h"
#include "../DataStructures/Restriction.h"
#include "../DataStructures/TurnInstructions.h"
// Strongly connected components using Tarjan's Algorithm
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../Util/StdHashExtensions.h"
class TarjanSCC {
private:
struct _NodeBasedEdgeData {
int distance;
unsigned edgeBasedNodeID;
unsigned nameID:31;
bool shortcut:1;
bool forward:1;
bool backward:1;
bool roundabout:1;
bool ignoreInGrid:1;
short type;
bool isAccessRestricted;
};
#include <osrm/Coordinate.h>
struct _EdgeBasedEdgeData {
int distance;
unsigned via;
unsigned nameID;
bool forward;
bool backward;
TurnInstruction turnInstruction;
};
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph;
typedef _NodeBasedDynamicGraph::InputEdge _NodeBasedEdge;
std::vector<NodeInfo> inputNodeInfoList;
unsigned numberOfTurnRestrictions;
boost::shared_ptr<_NodeBasedDynamicGraph> _nodeBasedGraph;
boost::unordered_map<NodeID, bool> _barrierNodes;
boost::unordered_map<NodeID, bool> _trafficLights;
#ifdef __APPLE__
#include <gdal.h>
#include <ogrsf_frmts.h>
#else
#include <gdal/gdal.h>
#include <gdal/ogrsf_frmts.h>
#endif
typedef std::pair<NodeID, NodeID> RestrictionSource;
typedef std::pair<NodeID, bool> RestrictionTarget;
typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector;
typedef boost::unordered_map<RestrictionSource, unsigned > RestrictionMap;
std::vector<EmanatingRestrictionsVector> _restrictionBucketVector;
RestrictionMap _restrictionMap;
#include <cstdint>
#include <memory>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <vector>
public:
struct EdgeBasedNode {
bool operator<(const EdgeBasedNode & other) const {
return other.id < id;
}
bool operator==(const EdgeBasedNode & other) const {
return id == other.id;
}
NodeID id;
int lat1;
int lat2;
int lon1;
int lon2:31;
bool belongsToTinyComponent:1;
NodeID nameID;
unsigned weight:31;
bool ignoreInGrid:1;
};
private:
DeallocatingVector<EdgeBasedNode> edgeBasedNodes;
struct TarjanNode {
TarjanNode() : index(UINT_MAX), lowlink(UINT_MAX), onStack(false) {}
class TarjanSCC
{
private:
struct TarjanNode
{
TarjanNode() : index(UINT_MAX), low_link(UINT_MAX), on_stack(false) {}
unsigned index;
unsigned lowlink;
bool onStack;
unsigned low_link;
bool on_stack;
};
struct TarjanStackFrame {
explicit TarjanStackFrame(NodeID _v, NodeID p) : v(_v), parent(p) {}
struct TarjanEdgeData
{
int distance;
unsigned name_id : 31;
bool shortcut : 1;
short type;
bool forward : 1;
bool backward : 1;
bool reversedEdge : 1;
};
struct TarjanStackFrame
{
explicit TarjanStackFrame(NodeID v, NodeID parent) : v(v), parent(parent) {}
NodeID v;
NodeID parent;
};
public:
TarjanSCC(int nodes, std::vector<NodeBasedEdge> & inputEdges, std::vector<NodeID> & bn, std::vector<NodeID> & tl, std::vector<_Restriction> & irs, std::vector<NodeInfo> & nI) : inputNodeInfoList(nI), numberOfTurnRestrictions(irs.size()) {
BOOST_FOREACH(_Restriction & restriction, irs) {
std::pair<NodeID, NodeID> restrictionSource = std::make_pair(restriction.fromNode, restriction.viaNode);
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;
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;
unsigned m_restriction_counter;
RestrictionMap m_restriction_map;
public:
TarjanSCC(int number_of_nodes,
std::vector<NodeBasedEdge> &input_edges,
std::vector<NodeID> &bn,
std::vector<NodeID> &tl,
std::vector<TurnRestriction> &irs,
std::vector<NodeInfo> &nI)
: m_coordinate_list(nI), m_restriction_counter(irs.size())
{
for (const TurnRestriction &restriction : irs)
{
std::pair<NodeID, NodeID> restrictionSource = {restriction.fromNode,
restriction.viaNode};
unsigned index;
RestrictionMap::iterator restrIter = _restrictionMap.find(restrictionSource);
if(restrIter == _restrictionMap.end()) {
index = _restrictionBucketVector.size();
_restrictionBucketVector.resize(index+1);
_restrictionMap[restrictionSource] = index;
} else {
index = restrIter->second;
//Map already contains an is_only_*-restriction
if(_restrictionBucketVector.at(index).begin()->second)
RestrictionMap::iterator restriction_iterator =
m_restriction_map.find(restrictionSource);
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);
}
else
{
index = restriction_iterator->second;
// Map already contains an is_only_*-restriction
if (m_restriction_bucket_list.at(index).begin()->second)
{
continue;
else if(restriction.flags.isOnly){
//We are going to insert an is_only_*-restriction. There can be only one.
_restrictionBucketVector.at(index).clear();
}
else if (restriction.flags.isOnly)
{
// We are going to insert an is_only_*-restriction. There can be only one.
m_restriction_bucket_list.at(index).clear();
}
}
_restrictionBucketVector.at(index).push_back(std::make_pair(restriction.toNode, restriction.flags.isOnly));
m_restriction_bucket_list.at(index)
.emplace_back(restriction.toNode, restriction.flags.isOnly);
}
BOOST_FOREACH(NodeID id, bn) {
_barrierNodes[id] = true;
}
BOOST_FOREACH(NodeID id, tl) {
_trafficLights[id] = true;
}
m_barrier_node_list.insert(bn.begin(), bn.end());
m_traffic_light_list.insert(tl.begin(), tl.end());
DeallocatingVector< _NodeBasedEdge > edges;
for ( std::vector< NodeBasedEdge >::const_iterator i = inputEdges.begin(); i != inputEdges.end(); ++i ) {
_NodeBasedEdge edge;
if(!i->isForward()) {
edge.source = i->target();
edge.target = i->source();
edge.data.backward = i->isForward();
edge.data.forward = i->isBackward();
} else {
edge.source = i->source();
edge.target = i->target();
edge.data.forward = i->isForward();
edge.data.backward = i->isBackward();
}
if(edge.source == edge.target)
DeallocatingVector<TarjanEdge> edge_list;
for (const NodeBasedEdge &input_edge : input_edges)
{
if (input_edge.source == input_edge.target)
{
continue;
}
edge.data.distance = (std::max)((int)i->weight(), 1 );
assert( edge.data.distance > 0 );
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;
}
else
{
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.roundabout = i->isRoundabout();
edge.data.ignoreInGrid = i->ignoreInGrid();
edge.data.nameID = i->name();
edge.data.type = i->type();
edge.data.isAccessRestricted = i->isAccessRestricted();
edge.data.edgeBasedNodeID = edges.size();
edges.push_back( edge );
if( edge.data.backward ) {
std::swap( edge.source, edge.target );
edge.data.forward = i->isBackward();
edge.data.backward = i->isForward();
edge.data.edgeBasedNodeID = edges.size();
edges.push_back( edge );
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);
}
}
std::vector<NodeBasedEdge>().swap(inputEdges);
std::sort( edges.begin(), edges.end() );
_nodeBasedGraph = boost::make_shared<_NodeBasedDynamicGraph>( nodes, edges );
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());
m_node_based_graph = std::make_shared<TarjanDynamicGraph>(number_of_nodes, edge_list);
}
void Run() {
Percent p(_nodeBasedGraph->GetNumberOfNodes());
~TarjanSCC() { m_node_based_graph.reset(); }
const char *pszDriverName = "ESRI Shapefile";
OGRSFDriver *poDriver;
void Run()
{
// remove files from previous run if exist
DeleteFileIfExists("component.dbf");
DeleteFileIfExists("component.shx");
DeleteFileIfExists("component.shp");
Percent p(m_node_based_graph->GetNumberOfNodes());
OGRRegisterAll();
poDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(
pszDriverName );
if( poDriver == NULL )
const char *pszDriverName = "ESRI Shapefile";
OGRSFDriver *poDriver =
OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(pszDriverName);
if (nullptr == poDriver)
{
printf( "%s driver not available.\n", pszDriverName );
exit( 1 );
throw OSRMException("ESRI Shapefile driver not available");
}
OGRDataSource *poDS;
OGRDataSource *poDS = poDriver->CreateDataSource("component.shp", nullptr);
poDS = poDriver->CreateDataSource( "component.shp", NULL );
if( poDS == NULL ) {
printf( "Creation of output file failed.\n" );
exit( 1 );
if (nullptr == poDS)
{
throw OSRMException("Creation of output file failed");
}
OGRLayer *poLayer;
OGRLayer *poLayer = poDS->CreateLayer("component", nullptr, wkbLineString, nullptr);
poLayer = poDS->CreateLayer( "component", NULL, wkbLineString, NULL );
if( poLayer == NULL ) {
printf( "Layer creation failed.\n" );
exit( 1 );
if (nullptr == poLayer)
{
throw OSRMException("Layer creation failed.");
}
//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> > recursionStack; //true = stuff before, false = stuff after call
std::stack<NodeID> tarjanStack;
std::vector<unsigned> componentsIndex(_nodeBasedGraph->GetNumberOfNodes(), UINT_MAX);
std::vector<NodeID> vectorOfComponentSizes;
std::vector<TarjanNode> tarjanNodes(_nodeBasedGraph->GetNumberOfNodes());
unsigned currentComponent = 0, sizeOfCurrentComponent = 0;
// 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;
// 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<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;
for(NodeID node = 0, endNodes = _nodeBasedGraph->GetNumberOfNodes(); node < endNodes; ++node) {
if(UINT_MAX == componentsIndex[node]) {
recursionStack.push(std::make_pair(true, TarjanStackFrame(node,node)) );
NodeID last_node = m_node_based_graph->GetNumberOfNodes();
for (NodeID node = 0; node < last_node; ++node)
{
if (UINT_MAX == components_index[node])
{
recursion_stack.emplace(true, TarjanStackFrame(node, node));
}
while(!recursionStack.empty()) {
bool beforeRecursion = recursionStack.top().first;
TarjanStackFrame currentFrame = recursionStack.top().second;
while (!recursion_stack.empty())
{
const bool before_recursion = recursion_stack.top().first;
TarjanStackFrame currentFrame = recursion_stack.top().second;
NodeID v = currentFrame.v;
// INFO("popping node " << v << (beforeRecursion ? " before " : " after ") << "recursion");
recursionStack.pop();
recursion_stack.pop();
if(beforeRecursion) {
//Mark frame to handle tail of recursion
recursionStack.push(std::make_pair(false, currentFrame));
if (before_recursion)
{
// Mark frame to handle tail of recursion
recursion_stack.emplace(false, currentFrame);
//Mark essential information for SCC
tarjanNodes[v].index = index;
tarjanNodes[v].lowlink = index;
tarjanStack.push(v);
tarjanNodes[v].onStack = true;
// Mark essential information for SCC
tarjan_node_list[v].index = index;
tarjan_node_list[v].low_link = index;
tarjan_stack.push(v);
tarjan_node_list[v].on_stack = true;
++index;
// INFO("pushing " << v << " onto tarjan stack, idx[" << v << "]=" << tarjanNodes[v].index << ", lowlink["<< v << "]=" << tarjanNodes[v].lowlink);
//Traverse outgoing edges
for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) {
_NodeBasedDynamicGraph::NodeIterator vprime = _nodeBasedGraph->GetTarget(e2);
// INFO("traversing edge (" << v << "," << vprime << ")");
if(UINT_MAX == tarjanNodes[vprime].index) {
recursionStack.push(std::make_pair(true,TarjanStackFrame(vprime, v)));
} else {
// INFO("Node " << vprime << " is already explored");
if(tarjanNodes[vprime].onStack) {
unsigned newLowlink = std::min(tarjanNodes[v].lowlink, tarjanNodes[vprime].index);
// INFO("Setting lowlink[" << v << "] from " << tarjanNodes[v].lowlink << " to " << newLowlink);
tarjanNodes[v].lowlink = newLowlink;
// } else {
// INFO("But node " << vprime << " is not on stack");
// Traverse outgoing edges
for (auto e2 : m_node_based_graph->GetAdjacentEdgeRange(v))
{
const TarjanDynamicGraph::NodeIterator vprime =
m_node_based_graph->GetTarget(e2);
if (UINT_MAX == tarjan_node_list[vprime].index)
{
recursion_stack.emplace(true, TarjanStackFrame(vprime, v));
}
else
{
if (tarjan_node_list[vprime].on_stack &&
tarjan_node_list[vprime].index < tarjan_node_list[v].low_link)
{
tarjan_node_list[v].low_link = tarjan_node_list[vprime].index;
}
}
}
} else {
// INFO("we are at the end of recursion and checking node " << v);
{ // setting lowlink in its own scope so it does not pollute namespace
// NodeID parent = (UINT_MAX == tarjanNodes[v].parent ? v : tarjanNodes[v].parent );
// INFO("parent=" << currentFrame.parent);
// INFO("tarjanNodes[" << v << "].lowlink=" << tarjanNodes[v].lowlink << ", tarjanNodes[" << currentFrame.parent << "].lowlink=" << tarjanNodes[currentFrame.parent].lowlink);
//Note the index shift by 1 compared to the recursive version
tarjanNodes[currentFrame.parent].lowlink = std::min(tarjanNodes[currentFrame.parent].lowlink, tarjanNodes[v].lowlink);
// INFO("Setting tarjanNodes[" << currentFrame.parent <<"].lowlink=" << tarjanNodes[currentFrame.parent].lowlink);
}
// INFO("tarjanNodes[" << v << "].lowlink=" << tarjanNodes[v].lowlink << ", tarjanNodes[" << v << "].index=" << tarjanNodes[v].index);
//after recursion, lets do cycle checking
//Check if we found a cycle. This is the bottom part of the recursion
if(tarjanNodes[v].lowlink == tarjanNodes[v].index) {
}
else
{
tarjan_node_list[currentFrame.parent].low_link =
std::min(tarjan_node_list[currentFrame.parent].low_link,
tarjan_node_list[v].low_link);
// after recursion, lets do cycle checking
// Check if we found a cycle. This is the bottom part of the recursion
if (tarjan_node_list[v].low_link == tarjan_node_list[v].index)
{
NodeID vprime;
do {
// INFO("identified component " << currentComponent << ": " << tarjanStack.top());
vprime = tarjanStack.top(); tarjanStack.pop();
tarjanNodes[vprime].onStack = false;
componentsIndex[vprime] = currentComponent;
++sizeOfCurrentComponent;
} while( v != vprime);
vectorOfComponentSizes.push_back(sizeOfCurrentComponent);
if(sizeOfCurrentComponent > 1000)
INFO("large component [" << currentComponent << "]=" << sizeOfCurrentComponent);
++currentComponent;
sizeOfCurrentComponent = 0;
}
}
}
}
INFO("identified: " << vectorOfComponentSizes.size() << " many components, marking small components");
int singleCounter = 0;
for(unsigned i = 0; i < vectorOfComponentSizes.size(); ++i){
if(1 == vectorOfComponentSizes[i])
++singleCounter;
}
INFO("identified " << singleCounter << " SCCs of size 1");
p.reinit(_nodeBasedGraph->GetNumberOfNodes());
for(_NodeBasedDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) {
for(_NodeBasedDynamicGraph::EdgeIterator e1 = _nodeBasedGraph->BeginEdges(u); e1 < _nodeBasedGraph->EndEdges(u); ++e1) {
_NodeBasedDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1);
if(_nodeBasedGraph->GetEdgeData(e1).type != SHRT_MAX) {
assert(e1 != UINT_MAX);
assert(u != UINT_MAX);
assert(v != UINT_MAX);
//edges that end on bollard nodes may actually be in two distinct components
if(std::min(vectorOfComponentSizes[componentsIndex[u]], vectorOfComponentSizes[componentsIndex[v]]) < 10) {
//INFO("(" << inputNodeInfoList[u].lat/100000. << ";" << inputNodeInfoList[u].lon/100000. << ") -> (" << inputNodeInfoList[v].lat/100000. << ";" << inputNodeInfoList[v].lon/100000. << ")");
OGRLineString lineString;
lineString.addPoint(inputNodeInfoList[u].lon/100000., inputNodeInfoList[u].lat/100000.);
lineString.addPoint(inputNodeInfoList[v].lon/100000., inputNodeInfoList[v].lat/100000.);
OGRFeature *poFeature;
poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() );
poFeature->SetGeometry( &lineString );
if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE )
do
{
ERR( "Failed to create feature in shapefile.\n" );
vprime = tarjan_stack.top();
tarjan_stack.pop();
tarjan_node_list[vprime].on_stack = false;
components_index[vprime] = component_index;
++size_of_current_component;
} while (v != vprime);
component_size_vector.emplace_back(size_of_current_component);
if (size_of_current_component > 1000)
{
SimpleLogger().Write() << "large component [" << component_index
<< "]=" << size_of_current_component;
}
OGRFeature::DestroyFeature( poFeature );
++component_index;
size_of_current_component = 0;
}
}
}
}
OGRDataSource::DestroyDataSource( poDS );
std::vector<NodeID>().swap(vectorOfComponentSizes);
std::vector<NodeID>().swap(componentsIndex);
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;});
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)
{
p.printIncrement();
for (auto e1 : m_node_based_graph->GetAdjacentEdgeRange(u))
{
if (!m_node_based_graph->GetEdgeData(e1).reversedEdge)
{
continue;
}
const TarjanDynamicGraph::NodeIterator v = m_node_based_graph->GetTarget(e1);
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)
{
BOOST_ASSERT(e1 != UINT_MAX);
BOOST_ASSERT(u != UINT_MAX);
BOOST_ASSERT(v != UINT_MAX);
const unsigned size_of_containing_component =
std::min(component_size_vector[components_index[u]],
component_size_vector[components_index[v]]);
// 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);
OGRFeature *poFeature = OGRFeature::CreateFeature(poLayer->GetLayerDefn());
poFeature->SetGeometry(&lineString);
if (OGRERR_NONE != poLayer->CreateFeature(poFeature))
{
throw OSRMException("Failed to create feature in shapefile.");
}
OGRFeature::DestroyFeature(poFeature);
}
}
}
}
OGRDataSource::DestroyDataSource(poDS);
std::vector<NodeID>().swap(component_size_vector);
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);
BOOST_ASSERT_MSG(0 == components_index.size() && 0 == components_index.capacity(),
"icomponents_index not properly deallocated");
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 > restrictionSource = std::make_pair(u, v);
RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource);
if (restrIter != _restrictionMap.end()) {
unsigned index = restrIter->second;
BOOST_FOREACH(RestrictionSource restrictionTarget, _restrictionBucketVector.at(index)) {
if(restrictionTarget.second) {
return restrictionTarget.first;
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);
if (restriction_iterator != m_restriction_map.end())
{
const unsigned index = restriction_iterator->second;
for (const RestrictionSource &restriction_target : m_restriction_bucket_list.at(index))
{
if (restriction_target.second)
{
return restriction_target.first;
}
}
}
return UINT_MAX;
}
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 > restrictionSource = std::make_pair(u, v);
RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource);
if (restrIter != _restrictionMap.end()) {
unsigned index = restrIter->second;
BOOST_FOREACH(RestrictionTarget restrictionTarget, _restrictionBucketVector.at(index)) {
if(w == restrictionTarget.first)
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);
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))
{
if (w == restriction_target.first)
{
return true;
}
}
}
return false;
}
void DeleteFileIfExists(const std::string &file_name) const
{
if (boost::filesystem::exists(file_name))
{
boost::filesystem::remove(file_name);
}
}
};
#endif /* STRONGLYCONNECTEDCOMPONENTS_H_ */
+307
View File
@@ -0,0 +1,307 @@
cmake_minimum_required(VERSION 2.8)
project(OSRM)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include(CheckCXXCompilerFlag)
include(FindPackageHandleStandardArgs)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
include(GetGitRevisionDescription)
git_describe(GIT_DESCRIPTION)
set(bitness 32)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(bitness 64)
message(STATUS "Building on a 64 bit system")
else()
message(WARNING "Building on a 32 bit system is unsupported")
endif()
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)
include_directories(${CMAKE_SOURCE_DIR}/Include/)
add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/Util/FingerPrint.cpp FingerPrint.cpp.alwaysbuild
COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_SOURCE_DIR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/FingerPrint-Config.cmake
DEPENDS
${CMAKE_SOURCE_DIR}/Util/FingerPrint.cpp.in
COMMENT "Configuring FingerPrint.cpp"
VERBATIM)
add_custom_target(FingerPrintConfigure DEPENDS ${CMAKE_SOURCE_DIR}/Util/FingerPrint.cpp)
set(BOOST_COMPONENTS date_time filesystem iostreams program_options regex system thread)
configure_file(
${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp.in
${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp
)
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})
file(GLOB PrepareGlob Contractor/*.cpp DataStructures/HilbertValue.cpp DataStructures/RestrictionMap.cpp)
set(PrepareSources prepare.cpp ${PrepareGlob})
add_executable(osrm-prepare ${PrepareSources})
file(GLOB ServerGlob Server/*.cpp)
file(GLOB DescriptorGlob Descriptors/*.cpp)
file(GLOB DatastructureGlob DataStructures/SearchEngineData.cpp DataStructures/RouteParameters.cpp)
file(GLOB CoordinateGlob DataStructures/Coordinate.cpp)
file(GLOB AlgorithmGlob Algorithms/*.cpp)
file(GLOB HttpGlob Server/Http/*.cpp)
file(GLOB LibOSRMGlob Library/*.cpp)
set(
OSRMSources
${LibOSRMGlob}
${DescriptorGlob}
${DatastructureGlob}
${CoordinateGlob}
${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_dependencies(FINGERPRINT FingerPrintConfigure)
add_executable(osrm-routed routed.cpp ${ServerGlob})
add_executable(osrm-datastore datastore.cpp)
# Check the release mode
if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
set(CMAKE_BUILD_TYPE Release)
endif()
if(CMAKE_BUILD_TYPE MATCHES Debug)
message(STATUS "Configuring OSRM in debug mode")
if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
message(STATUS "adding profiling flags")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage -fno-inline")
set(CMAKE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage -fno-inline")
endif()
endif()
if(CMAKE_BUILD_TYPE MATCHES Release)
message(STATUS "Configuring OSRM in release mode")
# Check if LTO is available
set(LTO_FLAGS "")
CHECK_CXX_COMPILER_FLAG("-flto" HAS_LTO_FLAG)
if (HAS_LTO_FLAG)
set(LTO_FLAGS "${LTO_FLAGS} -flto")
# 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")
message(STATUS "Using gcc specific binutils for LTO.")
set(CMAKE_AR "/usr/bin/gcc-ar")
set(CMAKE_RANLIB "/usr/bin/gcc-ranlib")
endif()
endif (HAS_LTO_FLAG)
endif()
# Configuring compilers
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# using Clang
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wunreachable-code -pedantic -fPIC")
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(-DWIN32)
SET(OPTIONAL_SOCKET_LIBS ws2_32 wsock32)
SET(OPTIONAL_OMP_LIB gomp)
endif()
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
# using Intel C++
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-intel -wd10237 -Wall -ipo -fPIC")
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# using Visual Studio C++
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} date_time chrono zlib)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
add_definitions(-DNOMINMAX) # avoid min and max macros that can break compilation
add_definitions(-D_USE_MATH_DEFINES) # define M_PI
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)
endif()
# Configuring other platform dependencies
if(APPLE)
set(CMAKE_OSX_ARCHITECTURES "x86_64")
message(STATUS "Set Architecture to x64 on OS X")
exec_program(uname ARGS -v OUTPUT_VARIABLE DARWIN_VERSION)
string(REGEX MATCH "[0-9]+" DARWIN_VERSION ${DARWIN_VERSION})
if(OSXLIBSTD)
message(STATUS "linking against ${OSXLIBSTD}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=${OSXLIBSTD}")
elseif(DARWIN_VERSION GREATER 12)
message(STATUS "linking against libc++")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
endif()
endif()
if(UNIX AND NOT APPLE)
target_link_libraries(osrm-prepare rt)
target_link_libraries(osrm-datastore rt)
target_link_libraries(OSRM rt)
endif()
#Check Boost
set(BOOST_MIN_VERSION "1.49.0")
find_package(Boost ${BOOST_MIN_VERSION} COMPONENTS ${BOOST_COMPONENTS} REQUIRED)
if(NOT Boost_FOUND)
message(FATAL_ERROR "Fatal error: Boost (version >= 1.49.0) required.\n")
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)
find_package(Threads REQUIRED)
target_link_libraries(osrm-extract ${CMAKE_THREAD_LIBS_INIT} ${OPTIONAL_OMP_LIB})
target_link_libraries(osrm-datastore ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(OSRM ${CMAKE_THREAD_LIBS_INIT})
find_package(TBB REQUIRED)
if(WIN32 AND CMAKE_BUILD_TYPE MATCHES Debug)
set(TBB_LIBRARIES ${TBB_DEBUG_LIBRARIES})
endif()
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})
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_directories(${LUABIND_INCLUDE_DIR})
target_link_libraries(osrm-extract ${LUABIND_LIBRARY})
target_link_libraries(osrm-prepare ${LUABIND_LIBRARY})
if( LUAJIT_FOUND )
target_link_libraries(osrm-extract ${LUAJIT_LIBRARIES})
target_link_libraries(osrm-prepare ${LUAJIT_LIBRARIES})
else()
target_link_libraries(osrm-extract ${LUA_LIBRARY})
target_link_libraries(osrm-prepare ${LUA_LIBRARY})
endif()
include_directories(${LUA_INCLUDE_DIR})
find_package(LibXml2 REQUIRED)
include_directories(${LIBXML2_INCLUDE_DIR})
target_link_libraries(osrm-extract ${LIBXML2_LIBRARIES})
find_package( STXXL REQUIRED )
include_directories(${STXXL_INCLUDE_DIR})
target_link_libraries(OSRM ${STXXL_LIBRARY})
target_link_libraries(osrm-extract ${STXXL_LIBRARY})
target_link_libraries(osrm-prepare ${STXXL_LIBRARY})
find_package( OSMPBF REQUIRED )
include_directories(${OSMPBF_INCLUDE_DIR})
target_link_libraries(osrm-extract ${OSMPBF_LIBRARY})
target_link_libraries(osrm-prepare ${OSMPBF_LIBRARY})
find_package(Protobuf REQUIRED)
include_directories(${PROTOBUF_INCLUDE_DIRS})
target_link_libraries(osrm-extract ${PROTOBUF_LIBRARY})
target_link_libraries(osrm-prepare ${PROTOBUF_LIBRARY})
find_package(BZip2 REQUIRED)
include_directories(${BZIP_INCLUDE_DIRS})
target_link_libraries(osrm-extract ${BZIP2_LIBRARIES})
find_package(ZLIB REQUIRED)
include_directories(${ZLIB_INCLUDE_DIRS})
target_link_libraries(osrm-extract ${ZLIB_LIBRARY})
target_link_libraries(osrm-routed ${ZLIB_LIBRARY})
if(WITH_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)
include_directories(${GDAL_INCLUDE_DIR})
target_link_libraries(
osrm-components
${GDAL_LIBRARIES} ${Boost_LIBRARIES} FINGERPRINT GITDESCRIPTION COORDLIB)
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)
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)
if(UNIX AND NOT APPLE)
target_link_libraries(osrm-unlock-all rt)
endif()
endif()
file(GLOB InstallGlob Include/osrm/*.h Library/OSRM.h)
# Add RPATH info to executables so that when they are run after being installed
# (i.e., from /usr/local/bin/) the linker can find library dependencies. For
# more info see http://www.cmake.org/Wiki/CMake_RPATH_handling
set_property(TARGET osrm-extract PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
set_property(TARGET osrm-prepare PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
set_property(TARGET osrm-datastore PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
set_property(TARGET osrm-routed PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
install(FILES ${InstallGlob} DESTINATION include/osrm)
install(TARGETS osrm-extract DESTINATION bin)
install(TARGETS osrm-prepare DESTINATION bin)
install(TARGETS osrm-datastore DESTINATION bin)
install(TARGETS osrm-routed DESTINATION bin)
install(TARGETS OSRM DESTINATION lib)
list(GET Boost_LIBRARIES 1 BOOST_LIBRARY_FIRST)
get_filename_component(BOOST_LIBRARY_LISTING "${BOOST_LIBRARY_FIRST}" PATH)
set(BOOST_LIBRARY_LISTING "-L${BOOST_LIBRARY_LISTING}")
foreach (lib ${Boost_LIBRARIES})
get_filename_component(BOOST_LIBRARY_NAME "${lib}" NAME_WE)
string(REPLACE "lib" "" BOOST_LIBRARY_NAME ${BOOST_LIBRARY_NAME})
set(BOOST_LIBRARY_LISTING "${BOOST_LIBRARY_LISTING} -l${BOOST_LIBRARY_NAME}")
endforeach ()
configure_file(${CMAKE_SOURCE_DIR}/cmake/pkgconfig.in libosrm.pc @ONLY)
install(FILES ${PROJECT_BINARY_DIR}/libosrm.pc DESTINATION lib/pkgconfig)
-261
View File
@@ -1,261 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef CONTRACTIONCLEANUP_H_INCLUDED
#define CONTRACTIONCLEANUP_H_INCLUDED
#include <algorithm>
#ifndef _WIN32
#include <sys/time.h>
#endif
#include "Contractor.h"
class ContractionCleanup {
private:
struct _CleanupHeapData {
NodeID parent;
_CleanupHeapData( NodeID p ) {
parent = p;
}
};
typedef BinaryHeap< NodeID, NodeID, int, _CleanupHeapData > _Heap;
struct _ThreadData {
_Heap* _heapForward;
_Heap* _heapBackward;
_ThreadData( NodeID nodes ) {
_heapBackward = new _Heap(nodes);
_heapForward = new _Heap(nodes);
}
~_ThreadData() {
delete _heapBackward;
delete _heapForward;
}
};
public:
struct Edge {
NodeID source;
NodeID target;
struct EdgeData {
NodeID via;
unsigned nameID;
int distance;
TurnInstruction turnInstruction;
bool shortcut:1;
bool forward:1;
bool backward:1;
} data;
bool operator<( const Edge& right ) const {
if ( source != right.source )
return source < right.source;
return target < right.target;
}
//sorts by source and other attributes
static bool CompareBySource( const Edge& left, const Edge& right ) {
if ( left.source != right.source )
return left.source < right.source;
int l = ( left.data.forward ? -1 : 0 ) + ( left.data.backward ? -1 : 0 );
int r = ( right.data.forward ? -1 : 0 ) + ( right.data.backward ? -1 : 0 );
if ( l != r )
return l < r;
if ( left.target != right.target )
return left.target < right.target;
return left.data.distance < right.data.distance;
}
bool operator== ( const Edge& right ) const {
return ( source == right.source && target == right.target && data.distance == right.data.distance &&
data.shortcut == right.data.shortcut && data.forward == right.data.forward && data.backward == right.data.backward
&& data.via == right.data.via && data.nameID == right.data.nameID
);
}
};
ContractionCleanup( int numNodes, const std::vector< Edge >& edges ) {
_graph = edges;
_numNodes = numNodes;
}
~ContractionCleanup() {
}
void Run() {
RemoveUselessShortcuts();
}
template< class EdgeT >
void GetData( std::vector< EdgeT >& edges ) {
for ( int edge = 0, endEdges = ( int ) _graph.size(); edge != endEdges; ++edge ) {
if(_graph[edge].data.forward || _graph[edge].data.backward) {
EdgeT newEdge;
newEdge.source = _graph[edge].source;
newEdge.target = _graph[edge].target;
newEdge.data = _graph[edge].data;
edges.push_back( newEdge );
}
}
sort( edges.begin(), edges.end() );
}
private:
double _Timestamp() {
struct timeval tp;
gettimeofday(&tp, NULL);
return double(tp.tv_sec) + tp.tv_usec / 1000000.;
}
void BuildOutgoingGraph() {
//sort edges by source
sort( _graph.begin(), _graph.end(), Edge::CompareBySource );
try {
_firstEdge.resize( _numNodes + 1 );
} catch(...) {
ERR("Not enough RAM on machine");
return;
}
_firstEdge[0] = 0;
for ( NodeID i = 0, node = 0; i < ( NodeID ) _graph.size(); i++ ) {
while ( _graph[i].source != node )
_firstEdge[++node] = i;
if ( i == ( NodeID ) _graph.size() - 1 )
while ( node < _numNodes )
_firstEdge[++node] = ( int ) _graph.size();
}
}
void RemoveUselessShortcuts() {
int maxThreads = omp_get_max_threads();
std::vector < _ThreadData* > threadData;
for ( int threadNum = 0; threadNum < maxThreads; ++threadNum ) {
threadData.push_back( new _ThreadData( _numNodes ) );
}
INFO("Scanning for useless shortcuts");
BuildOutgoingGraph();
/*
#pragma omp parallel for
for ( int i = 0; i < ( int ) _graph.size(); i++ ) {
//only remove shortcuts
if ( !_graph[i].data.shortcut )
continue;
if ( _graph[i].data.forward ) {
int result = _ComputeDistance( _graph[i].source, _graph[i].target, threadData[omp_get_thread_num()] );
if ( result < _graph[i].data.distance ) {
_graph[i].data.forward = false;
}
}
if ( _graph[i].data.backward ) {
int result = _ComputeDistance( _graph[i].target, _graph[i].source, threadData[omp_get_thread_num()] );
if ( result < _graph[i].data.distance ) {
_graph[i].data.backward = false;
}
}
}
*/
INFO("Removing edges");
int useful = 0;
for ( int i = 0; i < ( int ) _graph.size(); i++ ) {
if ( !_graph[i].data.forward && !_graph[i].data.backward && _graph[i].data.shortcut ) {
continue;
}
_graph[useful] = _graph[i];
useful++;
}
INFO("Removed " << _graph.size() - useful << " useless shortcuts");
_graph.resize( useful );
for ( int threadNum = 0; threadNum < maxThreads; ++threadNum ) {
delete threadData[threadNum];
}
}
void _ComputeStep( _Heap* heapForward, _Heap* heapBackward, bool forwardDirection, NodeID* middle, int* targetDistance ) {
const NodeID node = heapForward->DeleteMin();
const int distance = heapForward->GetKey( node );
if ( distance > *targetDistance ) {
heapForward->DeleteAll();
return;
}
if ( heapBackward->WasInserted( node ) ) {
const int newDistance = heapBackward->GetKey( node ) + distance;
if ( newDistance < *targetDistance ) {
*middle = node;
*targetDistance = newDistance;
}
}
for ( int edge = _firstEdge[node], endEdges = _firstEdge[node + 1]; edge != endEdges; ++edge ) {
const NodeID to = _graph[edge].target;
const int edgeWeight = _graph[edge].data.distance;
assert( edgeWeight > 0 );
const int toDistance = distance + edgeWeight;
if ( (forwardDirection ? _graph[edge].data.forward : _graph[edge].data.backward ) ) {
//New Node discovered -> Add to Heap + Node Info Storage
if ( !heapForward->WasInserted( to ) )
heapForward->Insert( to, toDistance, node );
//Found a shorter Path -> Update distance
else if ( toDistance < heapForward->GetKey( to ) ) {
heapForward->DecreaseKey( to, toDistance );
//new parent
heapForward->GetData( to ) = node;
}
}
}
}
int _ComputeDistance( NodeID source, NodeID target, _ThreadData * data ) {
data->_heapForward->Clear();
data->_heapBackward->Clear();
//insert source into heap
data->_heapForward->Insert( source, 0, source );
data->_heapBackward->Insert( target, 0, target );
int targetDistance = std::numeric_limits< int >::max();
NodeID middle = std::numeric_limits<NodeID>::max();
while ( data->_heapForward->Size() + data->_heapBackward->Size() > 0 ) {
if ( data->_heapForward->Size() > 0 ) {
_ComputeStep( data->_heapForward, data->_heapBackward, true, &middle, &targetDistance );
}
if ( data->_heapBackward->Size() > 0 ) {
_ComputeStep( data->_heapBackward, data->_heapForward, false, &middle, &targetDistance );
}
}
return targetDistance;
}
NodeID _numNodes;
std::vector< Edge > _graph;
std::vector< unsigned > _firstEdge;
};
#endif // CONTRACTIONCLEANUP_H_INCLUDED
+785 -539
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+97 -116
View File
@@ -1,145 +1,126 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 class constructs the edge base representation of a graph from a given node based edge list
*/
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.
*/
// This class constructs the edge-expanded routing graph
#ifndef EDGEBASEDGRAPHFACTORY_H_
#define EDGEBASEDGRAPHFACTORY_H_
#include <algorithm>
#include <queue>
#include <vector>
#include <stxxl.h>
#include <cstdlib>
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include "../typedefs.h"
#include "../DataStructures/DeallocatingVector.h"
#include "../DataStructures/DynamicGraph.h"
#include "../Extractor/ExtractorStructs.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportEdge.h"
#include "../DataStructures/QueryEdge.h"
#include "../DataStructures/Percent.h"
#include "../DataStructures/EdgeBasedNode.h"
#include "../DataStructures/OriginalEdgeData.h"
#include "../DataStructures/QueryNode.h"
#include "../DataStructures/TurnInstructions.h"
#include "../Util/BaseConfiguration.h"
#include "../DataStructures/NodeBasedGraph.h"
#include "../DataStructures/RestrictionMap.h"
#include "GeometryCompressor.h"
class EdgeBasedGraphFactory {
private:
struct _NodeBasedEdgeData {
int distance;
unsigned edgeBasedNodeID;
unsigned nameID:31;
bool shortcut:1;
bool forward:1;
bool backward:1;
bool roundabout:1;
bool ignoreInGrid:1;
short type;
bool isAccessRestricted;
};
#include <algorithm>
#include <iosfwd>
#include <memory>
#include <queue>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
struct _EdgeBasedEdgeData {
int distance;
unsigned via;
unsigned nameID;
bool forward;
bool backward;
TurnInstruction turnInstruction;
};
struct lua_State;
typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph;
typedef _NodeBasedDynamicGraph::InputEdge _NodeBasedEdge;
std::vector<NodeInfo> inputNodeInfoList;
unsigned numberOfTurnRestrictions;
public:
struct EdgeBasedNode {
bool operator<(const EdgeBasedNode & other) const {
return other.id < id;
class EdgeBasedGraphFactory
{
public:
EdgeBasedGraphFactory() = delete;
EdgeBasedGraphFactory(const EdgeBasedGraphFactory &) = delete;
struct SpeedProfileProperties;
explicit EdgeBasedGraphFactory(const std::shared_ptr<NodeBasedDynamicGraph> &node_based_graph,
std::unique_ptr<RestrictionMap> restricion_map,
std::vector<NodeID> &barrier_node_list,
std::vector<NodeID> &traffic_light_node_list,
std::vector<NodeInfo> &m_node_info_list,
SpeedProfileProperties &speed_profile);
void Run(const std::string &original_edge_data_filename,
const std::string &geometry_filename,
lua_State *lua_state);
void GetEdgeBasedEdges(DeallocatingVector<EdgeBasedEdge> &edges);
void GetEdgeBasedNodes(std::vector<EdgeBasedNode> &nodes);
TurnInstruction AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w, double angle) const;
int GetTurnPenalty(double angle, lua_State *lua_state) const;
unsigned GetNumberOfEdgeBasedNodes() const;
struct SpeedProfileProperties
{
SpeedProfileProperties()
: trafficSignalPenalty(0), uTurnPenalty(0), has_turn_penalty_function(false)
{
}
bool operator==(const EdgeBasedNode & other) const {
return id == other.id;
}
NodeID id;
int lat1;
int lat2;
int lon1;
int lon2:31;
bool belongsToTinyComponent:1;
NodeID nameID;
unsigned weight:31;
bool ignoreInGrid:1;
};
struct SpeedProfileProperties{
SpeedProfileProperties() : trafficSignalPenalty(0), uTurnPenalty(0) {}
int trafficSignalPenalty;
int uTurnPenalty;
} speedProfile;
private:
boost::shared_ptr<_NodeBasedDynamicGraph> _nodeBasedGraph;
boost::unordered_map<NodeID, bool> _barrierNodes;
boost::unordered_map<NodeID, bool> _trafficLights;
bool has_turn_penalty_function;
} speed_profile;
typedef std::pair<NodeID, NodeID> RestrictionSource;
typedef std::pair<NodeID, bool> RestrictionTarget;
typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector;
typedef boost::unordered_map<RestrictionSource, unsigned > RestrictionMap;
std::vector<EmanatingRestrictionsVector> _restrictionBucketVector;
RestrictionMap _restrictionMap;
private:
typedef NodeBasedDynamicGraph::EdgeData EdgeData;
unsigned m_number_of_edge_based_nodes;
DeallocatingVector<EdgeBasedEdge> edgeBasedEdges;
DeallocatingVector<EdgeBasedNode> edgeBasedNodes;
std::vector<OriginalEdgeData> originalEdgeData;
std::vector<NodeInfo> m_node_info_list;
std::vector<EdgeBasedNode> m_edge_based_node_list;
DeallocatingVector<EdgeBasedEdge> m_edge_based_edge_list;
NodeID CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const;
bool CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const;
void InsertEdgeBasedNode(
_NodeBasedDynamicGraph::EdgeIterator e1,
_NodeBasedDynamicGraph::NodeIterator u,
_NodeBasedDynamicGraph::NodeIterator v,
bool belongsToTinyComponent);
template<class CoordinateT>
double GetAngleBetweenTwoEdges(const CoordinateT& A, const CoordinateT& C, const CoordinateT& B) const;
// SRTMLookup srtmLookup;
std::shared_ptr<NodeBasedDynamicGraph> m_node_based_graph;
std::unordered_set<NodeID> m_barrier_nodes;
std::unordered_set<NodeID> m_traffic_lights;
std::unique_ptr<RestrictionMap> m_restriction_map;
public:
template< class InputEdgeT >
explicit EdgeBasedGraphFactory(int nodes, std::vector<InputEdgeT> & inputEdges, std::vector<NodeID> & _bollardNodes, std::vector<NodeID> & trafficLights, std::vector<_Restriction> & inputRestrictions, std::vector<NodeInfo> & nI, SpeedProfileProperties speedProfile);
GeometryCompressor m_geometry_compressor;
void Run(const char * originalEdgeDataFilename);
void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges );
void GetEdgeBasedNodes( DeallocatingVector< EdgeBasedNode> & nodes);
void GetOriginalEdgeData( std::vector< OriginalEdgeData> & originalEdgeData);
TurnInstruction AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w) const;
unsigned GetNumberOfNodes() const;
void CompressGeometry();
void RenumberEdges();
void GenerateEdgeExpandedNodes();
void GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename,
lua_State *lua_state);
void InsertEdgeBasedNode(NodeID u, NodeID v, EdgeID e1, bool belongsToTinyComponent);
void FlushVectorToStream(std::ofstream &edge_data_file,
std::vector<OriginalEdgeData> &original_edge_data_vector) const;
unsigned max_id;
};
#endif /* EDGEBASEDGRAPHFACTORY_H_ */
+227
View File
@@ -0,0 +1,227 @@
/*
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 "GeometryCompressor.h"
#include "../Util/SimpleLogger.h"
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <limits>
#include <string>
int free_list_maximum = 0;
int UniqueNumber() { return ++free_list_maximum; }
GeometryCompressor::GeometryCompressor()
{
m_free_list.reserve(100);
IncreaseFreeList();
}
void GeometryCompressor::IncreaseFreeList()
{
m_compressed_geometries.resize(m_compressed_geometries.size() + 100);
for (unsigned i = 100; i > 0; --i)
{
m_free_list.emplace_back(free_list_maximum);
++free_list_maximum;
}
}
bool GeometryCompressor::HasEntryForID(const EdgeID edge_id) const
{
auto iter = m_edge_id_to_list_index_map.find(edge_id);
return iter != m_edge_id_to_list_index_map.end();
}
unsigned GeometryCompressor::GetPositionForID(const EdgeID edge_id) const
{
auto map_iterator = m_edge_id_to_list_index_map.find(edge_id);
BOOST_ASSERT(map_iterator != m_edge_id_to_list_index_map.end());
BOOST_ASSERT(map_iterator->second < m_compressed_geometries.size());
return map_iterator->second;
}
void GeometryCompressor::SerializeInternalVector(const std::string &path) const
{
boost::filesystem::fstream geometry_out_stream(path, std::ios::binary | std::ios::out);
const unsigned compressed_geometries = m_compressed_geometries.size() + 1;
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != compressed_geometries);
geometry_out_stream.write((char *)&compressed_geometries, sizeof(unsigned));
// write indices array
unsigned prefix_sum_of_list_indices = 0;
for (const auto &elem : m_compressed_geometries)
{
geometry_out_stream.write((char *)&prefix_sum_of_list_indices, sizeof(unsigned));
const std::vector<CompressedNode> &current_vector = elem;
const unsigned unpacked_size = current_vector.size();
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != unpacked_size);
prefix_sum_of_list_indices += unpacked_size;
}
// sentinel element
geometry_out_stream.write((char *)&prefix_sum_of_list_indices, sizeof(unsigned));
// number of geometry entries to follow, it is the (inclusive) prefix sum
geometry_out_stream.write((char *)&prefix_sum_of_list_indices, sizeof(unsigned));
unsigned control_sum = 0;
// write compressed geometries
for (auto &elem : m_compressed_geometries)
{
const std::vector<CompressedNode> &current_vector = elem;
const unsigned unpacked_size = current_vector.size();
control_sum += unpacked_size;
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != unpacked_size);
for (const CompressedNode current_node : current_vector)
{
geometry_out_stream.write((char *)&(current_node.first), sizeof(NodeID));
}
}
BOOST_ASSERT(control_sum == prefix_sum_of_list_indices);
// all done, let's close the resource
geometry_out_stream.close();
}
void GeometryCompressor::CompressEdge(const EdgeID edge_id_1,
const EdgeID edge_id_2,
const NodeID via_node_id,
const NodeID target_node_id,
const EdgeWeight weight1,
const EdgeWeight weight2)
{
// remove super-trivial geometries
BOOST_ASSERT(SPECIAL_EDGEID != edge_id_1);
BOOST_ASSERT(SPECIAL_EDGEID != edge_id_2);
BOOST_ASSERT(SPECIAL_NODEID != via_node_id);
BOOST_ASSERT(SPECIAL_NODEID != target_node_id);
BOOST_ASSERT(INVALID_EDGE_WEIGHT != weight1);
BOOST_ASSERT(INVALID_EDGE_WEIGHT != weight2);
// append list of removed edge_id plus via node to surviving edge id:
// <surv_1, .. , surv_n, via_node_id, rem_1, .. rem_n
//
// General scheme:
// 1. append via node id to list of edge_id_1
// 2. find list for edge_id_2, if yes add all elements and delete it
// Add via node id. List is created if it does not exist
if (!HasEntryForID(edge_id_1))
{
// create a new entry in the map
if (0 == m_free_list.size())
{
// make sure there is a place to put the entries
IncreaseFreeList();
}
BOOST_ASSERT(!m_free_list.empty());
m_edge_id_to_list_index_map[edge_id_1] = m_free_list.back();
m_free_list.pop_back();
}
// find bucket index
const auto iter = m_edge_id_to_list_index_map.find(edge_id_1);
BOOST_ASSERT(iter != m_edge_id_to_list_index_map.end());
const unsigned edge_bucket_id1 = iter->second;
BOOST_ASSERT(edge_bucket_id1 == GetPositionForID(edge_id_1));
BOOST_ASSERT(edge_bucket_id1 < m_compressed_geometries.size());
std::vector<CompressedNode> &edge_bucket_list1 = m_compressed_geometries[edge_bucket_id1];
if (edge_bucket_list1.empty())
{
edge_bucket_list1.emplace_back(via_node_id, weight1);
}
BOOST_ASSERT(0 < edge_bucket_list1.size());
BOOST_ASSERT(!edge_bucket_list1.empty());
if (HasEntryForID(edge_id_2))
{
// second edge is not atomic anymore
const unsigned list_to_remove_index = GetPositionForID(edge_id_2);
BOOST_ASSERT(list_to_remove_index < m_compressed_geometries.size());
std::vector<CompressedNode> &edge_bucket_list2 =
m_compressed_geometries[list_to_remove_index];
// found an existing list, append it to the list of edge_id_1
edge_bucket_list1.insert(
edge_bucket_list1.end(), edge_bucket_list2.begin(), edge_bucket_list2.end());
// remove the list of edge_id_2
m_edge_id_to_list_index_map.erase(edge_id_2);
BOOST_ASSERT(m_edge_id_to_list_index_map.end() ==
m_edge_id_to_list_index_map.find(edge_id_2));
edge_bucket_list2.clear();
BOOST_ASSERT(0 == edge_bucket_list2.size());
m_free_list.emplace_back(list_to_remove_index);
BOOST_ASSERT(list_to_remove_index == m_free_list.back());
}
else
{
// we are certain that the second edge is atomic.
edge_bucket_list1.emplace_back(target_node_id, weight2);
}
}
void GeometryCompressor::PrintStatistics() const
{
const uint64_t compressed_edges = m_compressed_geometries.size();
BOOST_ASSERT(0 == compressed_edges % 2);
BOOST_ASSERT(m_compressed_geometries.size() + m_free_list.size() > 0);
uint64_t compressed_geometries = 0;
uint64_t longest_chain_length = 0;
for (const std::vector<CompressedNode> &current_vector : m_compressed_geometries)
{
compressed_geometries += current_vector.size();
longest_chain_length = std::max(longest_chain_length, (uint64_t)current_vector.size());
}
SimpleLogger().Write() << "Geometry successfully removed:"
"\n compressed edges: " << compressed_edges
<< "\n compressed geometries: " << compressed_geometries
<< "\n longest chain length: " << longest_chain_length
<< "\n cmpr ratio: "
<< ((float)compressed_edges /
std::max(compressed_geometries, (uint64_t)1))
<< "\n avg chain length: "
<< (float)compressed_geometries /
std::max((uint64_t)1, compressed_edges);
}
const std::vector<GeometryCompressor::CompressedNode> &
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);
}
+65
View File
@@ -0,0 +1,65 @@
/*
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 "../typedefs.h"
#include <unordered_map>
#include <string>
#include <vector>
#ifndef GEOMETRY_COMPRESSOR_H
#define GEOMETRY_COMPRESSOR_H
class GeometryCompressor
{
public:
typedef std::pair<NodeID, EdgeWeight> CompressedNode;
GeometryCompressor();
void CompressEdge(const EdgeID surviving_edge_id,
const EdgeID removed_edge_id,
const NodeID via_node_id,
const NodeID target_node,
const EdgeWeight weight1,
const EdgeWeight weight2);
bool HasEntryForID(const EdgeID edge_id) const;
void PrintStatistics() const;
void SerializeInternalVector(const std::string &path) const;
unsigned GetPositionForID(const EdgeID edge_id) const;
const std::vector<GeometryCompressor::CompressedNode> &
GetBucketReference(const EdgeID edge_id) const;
private:
void IncreaseFreeList();
std::vector<std::vector<CompressedNode>> m_compressed_geometries;
std::vector<unsigned> m_free_list;
std::unordered_map<EdgeID, unsigned> m_edge_id_to_list_index_map;
};
#endif // GEOMETRY_COMPRESSOR_H
+138 -110
View File
@@ -1,144 +1,172 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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.
#include <boost/foreach.hpp>
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"
TemporaryStorage::TemporaryStorage() {
try {
tempDirectory = boost::filesystem::temp_directory_path();
} catch(boost::filesystem::filesystem_error & e) {
ERR("could not retrieve location of temporary path: " << e.what());
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::GetInstance(){
static TemporaryStorage runningInstance;
return runningInstance;
TemporaryStorage::TemporaryStorage() { temp_directory = boost::filesystem::temp_directory_path(); }
TemporaryStorage &TemporaryStorage::GetInstance()
{
static TemporaryStorage static_instance;
return static_instance;
}
TemporaryStorage::~TemporaryStorage() {
removeAll();
}
TemporaryStorage::~TemporaryStorage() { RemoveAll(); }
void TemporaryStorage::removeAll() {
void TemporaryStorage::RemoveAll()
{
boost::mutex::scoped_lock lock(mutex);
try {
for(unsigned slotID = 0; slotID < vectorOfStreamDatas.size(); ++slotID)
deallocateSlot(slotID);
} catch(boost::filesystem::filesystem_error & e) {
ERR("could not retrieve location of temporary path: " << e.what());
for (unsigned slot_id = 0; slot_id < stream_data_list.size(); ++slot_id)
{
DeallocateSlot(slot_id);
}
vectorOfStreamDatas.clear();
stream_data_list.clear();
}
int TemporaryStorage::allocateSlot() {
int TemporaryStorage::AllocateSlot()
{
boost::mutex::scoped_lock lock(mutex);
try {
vectorOfStreamDatas.push_back(StreamData());
//INFO("created new temporary file: " << vectorOfStreamDatas.back().pathToTemporaryFile);
} catch(boost::filesystem::filesystem_error & e) {
abort(e);
}
return vectorOfStreamDatas.size() - 1;
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(int slotID) {
try {
StreamData & data = vectorOfStreamDatas[slotID];
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.pathToTemporaryFile)) {
if (!boost::filesystem::exists(data.temp_path))
{
return;
}
if(data.streamToTemporaryFile->is_open())
data.streamToTemporaryFile->close();
//INFO("deallocating slot " << slotID << " and its file: " << data.pathToTemporaryFile);
boost::filesystem::remove(data.pathToTemporaryFile);
} catch(boost::filesystem::filesystem_error & e) {
abort(e);
}
}
void TemporaryStorage::writeToSlot(int slotID, char * pointer, std::streamsize size) {
try {
StreamData & data = vectorOfStreamDatas[slotID];
boost::mutex::scoped_lock lock(*data.readWriteMutex);
if(!data.writeMode)
ERR("Writing after first read is not allowed");
data.streamToTemporaryFile->write(pointer, size);
} catch(boost::filesystem::filesystem_error & e) {
abort(e);
}
}
void TemporaryStorage::readFromSlot(int slotID, char * pointer, std::streamsize size) {
try {
StreamData & data = vectorOfStreamDatas[slotID];
boost::mutex::scoped_lock lock(*data.readWriteMutex);
if(data.writeMode) {
data.writeMode = false;
data.streamToTemporaryFile->seekg(0, data.streamToTemporaryFile->beg);
if (data.temp_file->is_open())
{
data.temp_file->close();
}
data.streamToTemporaryFile->read(pointer, size);
} catch(boost::filesystem::filesystem_error & e) {
abort(e);
boost::filesystem::remove(data.temp_path);
}
catch (boost::filesystem::filesystem_error &e) { Abort(e); }
}
unsigned TemporaryStorage::getFreeBytesOnTemporaryDevice() {
boost::filesystem::space_info tempSpaceInfo;
try {
tempSpaceInfo = boost::filesystem::space(tempDirectory);
} catch(boost::filesystem::filesystem_error & e) {
abort(e);
}
return tempSpaceInfo.available;
}
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::filesystem::fstream::pos_type TemporaryStorage::tell(int slotID) {
boost::filesystem::fstream::pos_type position;
try {
StreamData & data = vectorOfStreamDatas[slotID];
boost::mutex::scoped_lock lock(*data.readWriteMutex);
position = data.streamToTemporaryFile->tellp();
} catch(boost::filesystem::filesystem_error & e) {
abort(e);
}
// INFO("telling position: " << position);
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(boost::filesystem::filesystem_error& ) {
removeAll();
// ERR("I/O Error occured: " << e.what());
}
void TemporaryStorage::seek(int slotID, boost::filesystem::fstream::pos_type position) {
try {
StreamData & data = vectorOfStreamDatas[slotID];
boost::mutex::scoped_lock lock(*data.readWriteMutex);
data.streamToTemporaryFile->seekg(position);
// INFO("seeking to position: " << position);
} catch(boost::filesystem::filesystem_error & e) {
abort(e);
}
void TemporaryStorage::Abort(const boost::filesystem::filesystem_error &error)
{
RemoveAll();
throw OSRMException(error.what());
}
+70 -88
View File
@@ -1,114 +1,96 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 <vector>
#include <fstream>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread/mutex.hpp>
#include "../Util/BoostFileSystemFix.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
//This is one big workaround for latest boost renaming woes.
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/thread/mutex.hpp>
#ifndef BOOST_FILESYSTEM_VERSION
#warning Boost Installation with Filesystem3 (>=1.44) is required, activating workaround
#include <cstdio>
namespace boost {
namespace filesystem {
inline path temp_directory_path() {
char * buffer;
buffer = tmpnam (NULL);
#include <cstdint>
return path(buffer);
}
#include <vector>
#include <fstream>
#include <memory>
inline path unique_path(const path&) {
return temp_directory_path();
}
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();
};
#endif
// 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.
#define BOOST_FILESYSTEM_VERSION 3
/**
* 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 tempDirectory;
static boost::filesystem::path temp_directory;
static std::string TemporaryFilePattern("OSRM-%%%%-%%%%-%%%%");
class TemporaryStorage {
public:
static TemporaryStorage & GetInstance();
class TemporaryStorage
{
public:
static TemporaryStorage &GetInstance();
virtual ~TemporaryStorage();
int allocateSlot();
void deallocateSlot(int slotID);
void writeToSlot(int slotID, char * pointer, std::streamsize size);
void readFromSlot(int slotID, char * pointer, std::streamsize size);
//returns the number of free bytes
unsigned getFreeBytesOnTemporaryDevice();
boost::filesystem::fstream::pos_type tell(int slotID);
void seek(int slotID, boost::filesystem::fstream::pos_type);
void removeAll();
private:
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(boost::filesystem::filesystem_error& e);
TemporaryStorage(TemporaryStorage const &) {};
;
TemporaryStorage &operator=(TemporaryStorage const &) { return *this; }
struct StreamData {
bool writeMode;
boost::filesystem::path pathToTemporaryFile;
boost::shared_ptr<boost::filesystem::fstream> streamToTemporaryFile;
boost::shared_ptr<boost::mutex> readWriteMutex;
StreamData() :
writeMode(true),
pathToTemporaryFile (boost::filesystem::unique_path(tempDirectory.append(TemporaryFilePattern.begin(), TemporaryFilePattern.end()))),
streamToTemporaryFile(new boost::filesystem::fstream(pathToTemporaryFile, std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary)),
readWriteMutex(new boost::mutex)
{
if(streamToTemporaryFile->fail())
ERR("Aborting, because temporary file at " << pathToTemporaryFile << " could not be created");
}
};
//vector of file streams that is used to store temporary data
std::vector<StreamData> vectorOfStreamDatas;
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_ */
+180 -155
View File
@@ -1,264 +1,289 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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.
#ifndef BINARYHEAP_H_INCLUDED
#define BINARYHEAP_H_INCLUDED
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.
//Not compatible with non contiguous node ids
*/
#ifndef BINARY_HEAP_H
#define BINARY_HEAP_H
#include <boost/assert.hpp>
#include <cassert>
#include <limits>
#include <vector>
#include <algorithm>
#include <limits>
#include <map>
#include <boost/unordered_map.hpp>
#include <type_traits>
#include <unordered_map>
#include <vector>
template< typename NodeID, typename Key >
class ArrayStorage {
public:
ArrayStorage( size_t size ) : positions( new Key[size] ) {
memset(positions, 0, size*sizeof(Key));
template <typename NodeID, typename Key> class ArrayStorage
{
public:
explicit ArrayStorage(size_t size) : positions(new Key[size])
{
memset(positions, 0, size * sizeof(Key));
}
~ArrayStorage() {
delete[] positions;
}
~ArrayStorage() { delete[] positions; }
Key &operator[]( NodeID node ) {
return positions[node];
}
Key &operator[](NodeID node) { return positions[node]; }
void Clear() {}
private:
Key* positions;
private:
Key *positions;
};
template< typename NodeID, typename Key >
class MapStorage {
public:
template <typename NodeID, typename Key> class MapStorage
{
public:
explicit MapStorage(size_t) {}
MapStorage( size_t ) {}
Key &operator[](NodeID node) { return nodes[node]; }
Key &operator[]( NodeID node ) {
return nodes[node];
}
void Clear() {
nodes.clear();
}
private:
std::map< NodeID, Key > nodes;
void Clear() { nodes.clear(); }
private:
std::map<NodeID, Key> nodes;
};
template< typename NodeID, typename Key >
class UnorderedMapStorage {
public:
template <typename NodeID, typename Key> class UnorderedMapStorage
{
public:
explicit UnorderedMapStorage(size_t) { nodes.rehash(1000); }
UnorderedMapStorage( size_t ) { }
Key &operator[](const NodeID node) { return nodes[node]; }
Key &operator[]( NodeID node ) {
return nodes[node];
Key const &operator[](const NodeID node) const
{
auto iter = nodes.find(node);
return iter->second;
}
void Clear() {
nodes.clear();
}
void Clear() { nodes.clear(); }
private:
boost::unordered_map< NodeID, Key > nodes;
private:
std::unordered_map<NodeID, Key> nodes;
};
template<typename NodeID = unsigned>
struct _SimpleHeapData {
NodeID parent;
_SimpleHeapData( NodeID p ) : parent(p) { }
};
template <typename NodeID,
typename Key,
typename Weight,
typename Data,
typename IndexStorage = ArrayStorage<NodeID, NodeID>>
class BinaryHeap
{
private:
BinaryHeap(const BinaryHeap &right);
void operator=(const BinaryHeap &right);
template < typename NodeID, typename Key, typename Weight, typename Data, typename IndexStorage = ArrayStorage<NodeID, NodeID> >
class BinaryHeap {
private:
BinaryHeap( const BinaryHeap& right );
void operator=( const BinaryHeap& right );
public:
public:
typedef Weight WeightType;
typedef Data DataType;
BinaryHeap( size_t maxID )
: nodeIndex( maxID ) {
Clear();
explicit BinaryHeap(size_t maxID) : node_index(maxID) { Clear(); }
void Clear()
{
heap.resize(1);
inserted_nodes.clear();
heap[0].weight = std::numeric_limits<Weight>::min();
node_index.Clear();
}
void Clear() {
heap.resize( 1 );
insertedNodes.clear();
heap[0].weight = std::numeric_limits< Weight >::min();
nodeIndex.Clear();
}
std::size_t Size() const { return (heap.size() - 1); }
Key Size() const {
return static_cast<Key>( heap.size() - 1 );
}
bool Empty() const { return 0 == Size(); }
void Insert( NodeID node, Weight weight, const Data &data ) {
void Insert(NodeID node, Weight weight, const Data &data)
{
HeapElement element;
element.index = static_cast<NodeID>(insertedNodes.size());
element.index = static_cast<NodeID>(inserted_nodes.size());
element.weight = weight;
const Key key = static_cast<Key>(heap.size());
heap.push_back( element );
insertedNodes.push_back( HeapNode( node, key, weight, data ) );
nodeIndex[node] = element.index;
Upheap( key );
heap.emplace_back(element);
inserted_nodes.emplace_back(node, key, weight, data);
node_index[node] = element.index;
Upheap(key);
CheckHeap();
}
Data& GetData( NodeID node ) {
const Key index = nodeIndex[node];
return insertedNodes[index].data;
Data &GetData(NodeID node)
{
const Key index = node_index[node];
return inserted_nodes[index].data;
}
Weight& GetKey( NodeID node ) {
const Key index = nodeIndex[node];
return insertedNodes[index].weight;
Data const &GetData(NodeID node) const
{
const Key index = node_index[node];
return inserted_nodes[index].data;
}
bool WasRemoved( NodeID node ) {
assert( WasInserted( node ) );
const Key index = nodeIndex[node];
return insertedNodes[index].key == 0;
Weight &GetKey(NodeID node)
{
const Key index = node_index[node];
return inserted_nodes[index].weight;
}
bool WasInserted( NodeID node ) {
const Key index = nodeIndex[node];
if ( index >= static_cast<Key> (insertedNodes.size()) )
bool WasRemoved(const NodeID node)
{
BOOST_ASSERT(WasInserted(node));
const Key index = node_index[node];
return inserted_nodes[index].key == 0;
}
bool WasInserted(const NodeID node)
{
const Key index = node_index[node];
if (index >= static_cast<Key>(inserted_nodes.size()))
{
return false;
return insertedNodes[index].node == node;
}
return inserted_nodes[index].node == node;
}
NodeID Min() const {
assert( heap.size() > 1 );
return insertedNodes[heap[1].index].node;
NodeID Min() const
{
BOOST_ASSERT(heap.size() > 1);
return inserted_nodes[heap[1].index].node;
}
NodeID DeleteMin() {
assert( heap.size() > 1 );
NodeID DeleteMin()
{
BOOST_ASSERT(heap.size() > 1);
const Key removedIndex = heap[1].index;
heap[1] = heap[heap.size()-1];
heap[1] = heap[heap.size() - 1];
heap.pop_back();
if ( heap.size() > 1 )
Downheap( 1 );
insertedNodes[removedIndex].key = 0;
if (heap.size() > 1)
{
Downheap(1);
}
inserted_nodes[removedIndex].key = 0;
CheckHeap();
return insertedNodes[removedIndex].node;
return inserted_nodes[removedIndex].node;
}
void DeleteAll() {
for ( typename std::vector< HeapElement >::iterator i = heap.begin() + 1, iend = heap.end(); i != iend; ++i )
insertedNodes[i->index].key = 0;
heap.resize( 1 );
heap[0].weight = (std::numeric_limits< Weight >::min)();
void DeleteAll()
{
auto iend = heap.end();
for (typename std::vector<HeapElement>::iterator i = heap.begin() + 1; i != iend; ++i)
{
inserted_nodes[i->index].key = 0;
}
heap.resize(1);
heap[0].weight = (std::numeric_limits<Weight>::min)();
}
void DecreaseKey( NodeID node, Weight weight ) {
assert( UINT_MAX != node );
const Key index = nodeIndex[node];
Key key = insertedNodes[index].key;
assert ( key >= 0 );
void DecreaseKey(NodeID node, Weight weight)
{
BOOST_ASSERT(std::numeric_limits<NodeID>::max() != node);
const Key &index = node_index[node];
Key &key = inserted_nodes[index].key;
BOOST_ASSERT(key >= 0);
insertedNodes[index].weight = weight;
inserted_nodes[index].weight = weight;
heap[key].weight = weight;
Upheap( key );
Upheap(key);
CheckHeap();
}
private:
class HeapNode {
public:
HeapNode() {
}
HeapNode( NodeID n, Key k, Weight w, Data d )
: node( n ), key( k ), weight( w ), data( d ) {
}
private:
class HeapNode
{
public:
HeapNode(NodeID n, Key k, Weight w, Data d) : node(n), key(k), weight(w), data(d) {}
NodeID node;
Key key;
Weight weight;
Data data;
};
struct HeapElement {
struct HeapElement
{
Key index;
Weight weight;
};
std::vector< HeapNode > insertedNodes;
std::vector< HeapElement > heap;
IndexStorage nodeIndex;
std::vector<HeapNode> inserted_nodes;
std::vector<HeapElement> heap;
IndexStorage node_index;
void Downheap( Key key ) {
void Downheap(Key key)
{
const Key droppingIndex = heap[key].index;
const Weight weight = heap[key].weight;
Key nextKey = key << 1;
while ( nextKey < static_cast<Key>( heap.size() ) ) {
while (nextKey < static_cast<Key>(heap.size()))
{
const Key nextKeyOther = nextKey + 1;
if ( ( nextKeyOther < static_cast<Key> ( heap.size() ) )&& ( heap[nextKey].weight > heap[nextKeyOther].weight) )
if ((nextKeyOther < static_cast<Key>(heap.size())) &&
(heap[nextKey].weight > heap[nextKeyOther].weight))
{
nextKey = nextKeyOther;
if ( weight <= heap[nextKey].weight )
}
if (weight <= heap[nextKey].weight)
{
break;
}
heap[key] = heap[nextKey];
insertedNodes[heap[key].index].key = key;
inserted_nodes[heap[key].index].key = key;
key = nextKey;
nextKey <<= 1;
}
heap[key].index = droppingIndex;
heap[key].weight = weight;
insertedNodes[droppingIndex].key = key;
inserted_nodes[droppingIndex].key = key;
}
void Upheap( Key key ) {
void Upheap(Key key)
{
const Key risingIndex = heap[key].index;
const Weight weight = heap[key].weight;
Key nextKey = key >> 1;
while ( heap[nextKey].weight > weight ) {
assert( nextKey != 0 );
while (heap[nextKey].weight > weight)
{
BOOST_ASSERT(nextKey != 0);
heap[key] = heap[nextKey];
insertedNodes[heap[key].index].key = key;
inserted_nodes[heap[key].index].key = key;
key = nextKey;
nextKey >>= 1;
}
heap[key].index = risingIndex;
heap[key].weight = weight;
insertedNodes[risingIndex].key = key;
inserted_nodes[risingIndex].key = key;
}
void CheckHeap() {
void CheckHeap()
{
#ifndef NDEBUG
for ( Key i = 2; i < (Key) heap.size(); ++i ) {
assert( heap[i].weight >= heap[i >> 1].weight );
for (Key i = 2; i < (Key)heap.size(); ++i)
{
BOOST_ASSERT(heap[i].weight >= heap[i >> 1].weight);
}
#endif
}
};
#endif //#ifndef BINARYHEAP_H_INCLUDED
#endif // BINARY_HEAP_H
+59 -57
View File
@@ -1,83 +1,85 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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.
#ifndef CONCURRENTQUEUE_H_INCLUDED
#define CONCURRENTQUEUE_H_INCLUDED
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 <boost/bind.hpp>
#include <boost/circular_buffer.hpp>
#include <boost/thread/condition.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
*/
#ifndef CONCURRENT_QUEUE_H
#define CONCURRENT_QUEUE_H
#include "../typedefs.h"
template<typename Data>
class ConcurrentQueue {
#include <boost/circular_buffer.hpp>
#include <condition_variable>
#include <mutex>
typedef typename boost::circular_buffer<Data>::size_type size_t;
template <typename Data> class ConcurrentQueue
{
public:
explicit ConcurrentQueue(const size_t max_size) : m_internal_queue(max_size) {}
public:
ConcurrentQueue(const size_t max_size) : internal_queue(max_size) { }
inline void push(Data const& data) {
boost::mutex::scoped_lock lock(m_mutex);
m_not_full.wait(lock, boost::bind(&ConcurrentQueue<Data>::is_not_full, this));
internal_queue.push_back(data);
lock.unlock();
inline void push(const Data &data)
{
std::unique_lock<std::mutex> lock(m_mutex);
m_not_full.wait(lock,
[this]
{ return m_internal_queue.size() < m_internal_queue.capacity(); });
m_internal_queue.push_back(data);
m_not_empty.notify_one();
}
inline bool empty() const {
return internal_queue.empty();
}
inline bool empty() const { return m_internal_queue.empty(); }
inline void wait_and_pop(Data& popped_value) {
boost::mutex::scoped_lock lock(m_mutex);
m_not_empty.wait(lock, boost::bind(&ConcurrentQueue<Data>::is_not_empty, this));
popped_value=internal_queue.front();
internal_queue.pop_front();
lock.unlock();
inline void wait_and_pop(Data &popped_value)
{
std::unique_lock<std::mutex> lock(m_mutex);
m_not_empty.wait(lock,
[this]
{ return !m_internal_queue.empty(); });
popped_value = m_internal_queue.front();
m_internal_queue.pop_front();
m_not_full.notify_one();
}
inline bool try_pop(Data& popped_value) {
boost::mutex::scoped_lock lock(m_mutex);
if(internal_queue.empty()) {
inline bool try_pop(Data &popped_value)
{
std::unique_lock<std::mutex> lock(m_mutex);
if (m_internal_queue.empty())
{
return false;
}
popped_value=internal_queue.front();
internal_queue.pop_front();
lock.unlock();
popped_value = m_internal_queue.front();
m_internal_queue.pop_front();
m_not_full.notify_one();
return true;
}
private:
boost::circular_buffer<Data> internal_queue;
boost::mutex m_mutex;
boost::condition m_not_empty;
boost::condition m_not_full;
inline bool is_not_empty() const { return internal_queue.size() > 0; }
inline bool is_not_full() const { return internal_queue.size() < internal_queue.capacity(); }
private:
boost::circular_buffer<Data> m_internal_queue;
std::mutex m_mutex;
std::condition_variable m_not_empty;
std::condition_variable m_not_full;
};
#endif //#ifndef CONCURRENTQUEUE_H_INCLUDED
#endif // CONCURRENT_QUEUE_H
+446
View File
@@ -0,0 +1,446 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <osrm/Coordinate.h>
#include "../Util/MercatorUtil.h"
#include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h"
#include <boost/assert.hpp>
#ifndef NDEBUG
#include <bitset>
#endif
#include <iostream>
#include <limits>
FixedPointCoordinate::FixedPointCoordinate()
: lat(std::numeric_limits<int>::min()), lon(std::numeric_limits<int>::min())
{
}
FixedPointCoordinate::FixedPointCoordinate(int lat, int lon) : lat(lat), lon(lon)
{
#ifndef NDEBUG
if (0 != (std::abs(lat) >> 30))
{
std::bitset<32> y_coordinate_vector(lat);
SimpleLogger().Write(logDEBUG) << "broken lat: " << lat
<< ", bits: " << y_coordinate_vector;
}
if (0 != (std::abs(lon) >> 30))
{
std::bitset<32> x_coordinate_vector(lon);
SimpleLogger().Write(logDEBUG) << "broken lon: " << lon
<< ", bits: " << x_coordinate_vector;
}
#endif
}
void FixedPointCoordinate::Reset()
{
lat = std::numeric_limits<int>::min();
lon = std::numeric_limits<int>::min();
}
bool FixedPointCoordinate::isSet() const
{
return (std::numeric_limits<int>::min() != lat) && (std::numeric_limits<int>::min() != lon);
}
bool FixedPointCoordinate::isValid() const
{
if (lat > 90 * COORDINATE_PRECISION || lat < -90 * COORDINATE_PRECISION ||
lon > 180 * COORDINATE_PRECISION || lon < -180 * COORDINATE_PRECISION)
{
return false;
}
return true;
}
bool FixedPointCoordinate::operator==(const FixedPointCoordinate &other) const
{
return lat == other.lat && lon == other.lon;
}
double FixedPointCoordinate::ApproximateDistance(const int lat1,
const int lon1,
const int lat2,
const int lon2)
{
BOOST_ASSERT(lat1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lat2 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon2 != std::numeric_limits<int>::min());
double RAD = 0.017453292519943295769236907684886;
double lt1 = lat1 / COORDINATE_PRECISION;
double ln1 = lon1 / COORDINATE_PRECISION;
double lt2 = lat2 / COORDINATE_PRECISION;
double ln2 = lon2 / COORDINATE_PRECISION;
double dlat1 = lt1 * (RAD);
double dlong1 = ln1 * (RAD);
double dlat2 = lt2 * (RAD);
double dlong2 = ln2 * (RAD);
double dLong = dlong1 - dlong2;
double dLat = dlat1 - dlat2;
double aHarv = pow(sin(dLat / 2.0), 2.0) + cos(dlat1) * cos(dlat2) * pow(sin(dLong / 2.), 2);
double cHarv = 2. * atan2(sqrt(aHarv), sqrt(1.0 - aHarv));
// earth radius varies between 6,356.750-6,378.135 km (3,949.901-3,963.189mi)
// The IUGG value for the equatorial radius is 6378.137 km (3963.19 miles)
const double earth = 6372797.560856;
return earth * cHarv;
}
double FixedPointCoordinate::ApproximateDistance(const FixedPointCoordinate &coordinate_1,
const FixedPointCoordinate &coordinate_2)
{
return ApproximateDistance(
coordinate_1.lat, coordinate_1.lon, coordinate_2.lat, coordinate_2.lon);
}
float FixedPointCoordinate::ApproximateEuclideanDistance(const FixedPointCoordinate &coordinate_1,
const FixedPointCoordinate &coordinate_2)
{
return ApproximateEuclideanDistance(
coordinate_1.lat, coordinate_1.lon, coordinate_2.lat, coordinate_2.lon);
}
float FixedPointCoordinate::ApproximateEuclideanDistance(const int lat1,
const int lon1,
const int lat2,
const int lon2)
{
BOOST_ASSERT(lat1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lat2 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon2 != std::numeric_limits<int>::min());
const float RAD = 0.017453292519943295769236907684886f;
const float float_lat1 = (lat1 / COORDINATE_PRECISION) * RAD;
const float float_lon1 = (lon1 / COORDINATE_PRECISION) * RAD;
const float float_lat2 = (lat2 / COORDINATE_PRECISION) * RAD;
const float float_lon2 = (lon2 / COORDINATE_PRECISION) * RAD;
const float x_value = (float_lon2 - float_lon1) * cos((float_lat1 + float_lat2) / 2.f);
const float y_value = float_lat2 - float_lat1;
const float earth_radius = 6372797.560856f;
return sqrt(x_value * x_value + y_value * y_value) * earth_radius;
}
float
FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &source_coordinate,
const FixedPointCoordinate &target_coordinate,
const FixedPointCoordinate &point)
{
// initialize values
const float x_value = 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 p, q;
if (std::abs(a - c) > std::numeric_limits<float>::epsilon())
{
const float slope = (d - b) / (c - a); // slope
// Projection of (x,y) on line joining (a,b) and (c,d)
p = ((x_value + (slope * y_value)) + (slope * slope * a - slope * b)) /
(1.f + slope * slope);
q = b + slope * (p - a);
}
else
{
p = c;
q = y_value;
}
float 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
float ratio = (p - nY * a) / c;
if (std::isnan(ratio))
{
ratio = (target_coordinate == point ? 1.f : 0.f);
}
else if (std::abs(ratio) <= std::numeric_limits<float>::epsilon())
{
ratio = 0.f;
}
else if (std::abs(ratio - 1.f) <= std::numeric_limits<float>::epsilon())
{
ratio = 1.f;
}
//compute the nearest location
FixedPointCoordinate nearest_location;
BOOST_ASSERT(!std::isnan(ratio));
if (ratio <= 0.f)
{ // point is "left" of edge
nearest_location = source_coordinate;
}
else if (ratio >= 1.f)
{ // point is "right" of edge
nearest_location = target_coordinate;
}
else
{ // point lies in between
nearest_location.lat = static_cast<int>(y2lat(p) * COORDINATE_PRECISION);
nearest_location.lon = static_cast<int>(q * COORDINATE_PRECISION);
}
BOOST_ASSERT(nearest_location.isValid());
return FixedPointCoordinate::ApproximateEuclideanDistance(point, nearest_location);
}
float FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location,
FixedPointCoordinate &nearest_location,
float &ratio)
{
BOOST_ASSERT(query_location.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 float m = (d - b) / (c - a); // slope
// Projection of (x,y) on line joining (a,b) and (c,d)
p = ((x + (m * y)) + (m * m * a - m * b)) / (1.f + m * m);
q = b + m * (p - a);
}
else
{
p = c;
q = y;
}
nY = (d * p - c * q) / (a * d - b * c);
// discretize the result to coordinate precision. it's a hack!
if (std::abs(nY) < (1.f / COORDINATE_PRECISION))
{
nY = 0.f;
}
// compute ratio
ratio = (p - nY * a) / c; // These values are actually n/m+n and m/m+n , we need
// not calculate the explicit values of m an n as we
// are just interested in the ratio
if (std::isnan(ratio))
{
ratio = (segment_target == query_location ? 1.f : 0.f);
}
else if (std::abs(ratio) <= std::numeric_limits<float>::epsilon())
{
ratio = 0.;
}
else if (std::abs(ratio - 1.f) <= std::numeric_limits<float>::epsilon())
{
ratio = 1.f;
}
// compute nearest location
BOOST_ASSERT(!std::isnan(ratio));
if (ratio <= 0.f)
{
nearest_location = segment_source;
}
else if (ratio >= 1.)
{
nearest_location = segment_target;
}
else
{
// point lies in between
nearest_location.lat = static_cast<int>(y2lat(p) * COORDINATE_PRECISION);
nearest_location.lon = static_cast<int>(q * COORDINATE_PRECISION);
}
BOOST_ASSERT(nearest_location.isValid());
const float approximate_distance =
FixedPointCoordinate::ApproximateEuclideanDistance(query_location, nearest_location);
BOOST_ASSERT(0. <= approximate_distance);
return approximate_distance;
}
void FixedPointCoordinate::convertInternalLatLonToString(const int value, std::string &output)
{
char buffer[12];
buffer[11] = 0; // zero termination
output = printInt<11, 6>(buffer, value);
}
void FixedPointCoordinate::convertInternalCoordinateToString(const FixedPointCoordinate &coord,
std::string &output)
{
std::string tmp;
tmp.reserve(23);
convertInternalLatLonToString(coord.lon, tmp);
output = tmp;
output += ",";
convertInternalLatLonToString(coord.lat, tmp);
output += tmp;
}
void
FixedPointCoordinate::convertInternalReversedCoordinateToString(const FixedPointCoordinate &coord,
std::string &output)
{
std::string tmp;
tmp.reserve(23);
convertInternalLatLonToString(coord.lat, tmp);
output = tmp;
output += ",";
convertInternalLatLonToString(coord.lon, tmp);
output += tmp;
}
void FixedPointCoordinate::Output(std::ostream &out) const
{
out << "(" << lat / COORDINATE_PRECISION << "," << lon / COORDINATE_PRECISION << ")";
}
float FixedPointCoordinate::GetBearing(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate)
{
const float lon_diff = second_coordinate.lon / COORDINATE_PRECISION - first_coordinate.lon / COORDINATE_PRECISION;
const float lon_delta = DegreeToRadian(lon_diff);
const float lat1 = DegreeToRadian(first_coordinate.lat / COORDINATE_PRECISION);
const float lat2 = DegreeToRadian(second_coordinate.lat / COORDINATE_PRECISION);
const float y = sin(lon_delta) * cos(lat2);
const float x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lon_delta);
float result = RadianToDegree(std::atan2(y, x));
while (result < 0.f)
{
result += 360.f;
}
while (result >= 360.f)
{
result -= 360.f;
}
return result;
}
float FixedPointCoordinate::GetBearing(const FixedPointCoordinate &other) const
{
const float lon_delta =
DegreeToRadian(lon / COORDINATE_PRECISION - other.lon / COORDINATE_PRECISION);
const float lat1 = DegreeToRadian(other.lat / COORDINATE_PRECISION);
const float lat2 = DegreeToRadian(lat / COORDINATE_PRECISION);
const float y_value = std::sin(lon_delta) * std::cos(lat2);
const float x_value =
std::cos(lat1) * std::sin(lat2) - std::sin(lat1) * std::cos(lat2) * std::cos(lon_delta);
float result = RadianToDegree(std::atan2(y_value, x_value));
while (result < 0.f)
{
result += 360.f;
}
while (result >= 360.f)
{
result -= 360.f;
}
return result;
}
float FixedPointCoordinate::DegreeToRadian(const float degree) { return degree * (static_cast<float>(M_PI) / 180.f); }
float FixedPointCoordinate::RadianToDegree(const float radian) { return radian * (180.f * static_cast<float>(M_1_PI)); }
// This distance computation does integer arithmetic only and is a lot faster than
// the other distance function which are numerically correct('ish).
// It preserves some order among the elements that make it useful for certain purposes
int FixedPointCoordinate::OrderedPerpendicularDistanceApproximation(
const FixedPointCoordinate &input_point,
const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target)
{
// initialize values
const float x = 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 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;
if (a == c)
{
p = c;
q = y;
}
else
{
const float m = (d - b) / (c - a); // slope
// Projection of (x,y) on line joining (a,b) and (c,d)
p = ((x + (m * y)) + (m * m * a - m * b)) / (1.f + m * m);
q = b + m * (p - a);
}
const float nY = (d * p - c * q) / (a * d - b * c);
float ratio = (p - nY * a) / c; // These values are actually n/m+n and m/m+n , we need
// not calculate the explicit values of m an n as we
// are just interested in the ratio
if (std::isnan(ratio))
{
ratio = (segment_target == input_point) ? 1.f : 0.f;
}
// compute target quasi-location
int dx, dy;
if (ratio < 0.f)
{
dx = input_point.lon - segment_source.lon;
dy = input_point.lat - segment_source.lat;
}
else if (ratio > 1.f)
{
dx = input_point.lon - segment_target.lon;
dy = input_point.lat - segment_target.lat;
}
else
{
// point lies in between
dx = input_point.lon - static_cast<int>(q * COORDINATE_PRECISION);
dy = input_point.lat - static_cast<int>(y2lat(p) * COORDINATE_PRECISION);
}
// return an approximation in the plane
return static_cast<int>(sqrt(dx * dx + dy * dy));
}
-106
View File
@@ -1,106 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef COORDINATE_H_
#define COORDINATE_H_
#include <climits>
#include <iostream>
struct _Coordinate {
int lat;
int lon;
_Coordinate () : lat(INT_MIN), lon(INT_MIN) {}
_Coordinate (int t, int n) : lat(t) , lon(n) {}
void Reset() {
lat = INT_MIN;
lon = INT_MIN;
}
bool isSet() const {
return (INT_MIN != lat) && (INT_MIN != lon);
}
inline bool isValid() const {
if(lat > 90*100000 || lat < -90*100000 || lon > 180*100000 || lon <-180*100000) {
return false;
}
return true;
}
bool operator==(const _Coordinate & other) const {
return lat == other.lat && lon == other.lon;
}
};
inline std::ostream & operator<<(std::ostream & out, const _Coordinate & c){
out << "(" << c.lat << "," << c.lon << ")";
return out;
}
inline double ApproximateDistance( const int lat1, const int lon1, const int lat2, const int lon2 ) {
assert(lat1 != INT_MIN);
assert(lon1 != INT_MIN);
assert(lat2 != INT_MIN);
assert(lon2 != INT_MIN);
double RAD = 0.017453292519943295769236907684886;
double lt1 = lat1/100000.;
double ln1 = lon1/100000.;
double lt2 = lat2/100000.;
double ln2 = lon2/100000.;
double dlat1=lt1*(RAD);
double dlong1=ln1*(RAD);
double dlat2=lt2*(RAD);
double dlong2=ln2*(RAD);
double dLong=dlong1-dlong2;
double dLat=dlat1-dlat2;
double aHarv= pow(sin(dLat/2.0),2.0)+cos(dlat1)*cos(dlat2)*pow(sin(dLong/2.),2);
double cHarv=2.*atan2(sqrt(aHarv),sqrt(1.0-aHarv));
//earth's radius from wikipedia varies between 6,356.750 km — 6,378.135 km (˜3,949.901 — 3,963.189 miles)
//The IUGG value for the equatorial radius of the Earth is 6378.137 km (3963.19 mile)
const double earth=6372797.560856;//I am doing miles, just change this to radius in kilometers to get distances in km
double distance=earth*cHarv;
return distance;
}
inline double ApproximateDistance(const _Coordinate &c1, const _Coordinate &c2) {
return ApproximateDistance( c1.lat, c1.lon, c2.lat, c2.lon );
}
inline double ApproximateDistanceByEuclid(const _Coordinate &c1, const _Coordinate &c2) {
assert(c1.lat != INT_MIN);
assert(c1.lon != INT_MIN);
assert(c2.lat != INT_MIN);
assert(c2.lon != INT_MIN);
const double RAD = 0.017453292519943295769236907684886;
const double lat1 = (c1.lat/100000.)*RAD;
const double lon1 = (c1.lon/100000.)*RAD;
const double lat2 = (c2.lat/100000.)*RAD;
const double lon2 = (c2.lon/100000.)*RAD;
const double x = (lon2-lon1) * cos((lat1+lat2)/2.);
const double y = (lat2-lat1);
const double earthRadius = 6372797.560856;
const double d = sqrt(x*x + y*y) * earthRadius;
return d;
}
#endif /* COORDINATE_H_ */
+302 -208
View File
@@ -1,306 +1,400 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 DEALLOCATINGVECTOR_H_
#define DEALLOCATINGVECTOR_H_
#include <cassert>
#include <cstdlib>
#include <boost/assert.hpp>
#include <cstring>
#include <vector>
#if __cplusplus > 199711L
#define DEALLOCATION_VECTOR_NULL_PTR nullptr
#else
#define DEALLOCATION_VECTOR_NULL_PTR NULL
#endif
template<typename ElementT, size_t bucketSizeC = 10485760/sizeof(ElementT), bool DeallocateC = false>
class DeallocatingVectorIterator : public std::iterator<std::random_access_iterator_tag, ElementT> {
protected:
class DeallocatingVectorIteratorState {
private:
//make constructors explicit, so we do not mix random access and deallocation iterators.
template <typename ElementT,
std::size_t bucketSizeC = 8388608 / sizeof(ElementT),
bool DeallocateC = false>
class DeallocatingVectorIterator : public std::iterator<std::random_access_iterator_tag, ElementT>
{
protected:
class DeallocatingVectorIteratorState
{
private:
// make constructors explicit, so we do not mix random access and deallocation iterators.
DeallocatingVectorIteratorState();
public:
explicit DeallocatingVectorIteratorState(const DeallocatingVectorIteratorState &r) : mData(r.mData), mIndex(r.mIndex), mBucketList(r.mBucketList) {}
//explicit DeallocatingVectorIteratorState(const ElementT * ptr, const size_t idx, const std::vector<ElementT *> & input_list) : mData(ptr), mIndex(idx), mBucketList(input_list) {}
explicit DeallocatingVectorIteratorState(const size_t idx, std::vector<ElementT *> & input_list) : mData(DEALLOCATION_VECTOR_NULL_PTR), mIndex(idx), mBucketList(input_list) {
setPointerForIndex();
public:
explicit DeallocatingVectorIteratorState(const DeallocatingVectorIteratorState &r)
: index(r.index), bucket_list(r.bucket_list)
{
}
ElementT * mData;
size_t mIndex;
std::vector<ElementT *> & mBucketList;
inline void setPointerForIndex() {
if(bucketSizeC*mBucketList.size() <= mIndex) {
mData = DEALLOCATION_VECTOR_NULL_PTR;
return;
}
size_t _bucket = mIndex/bucketSizeC;
size_t _index = mIndex%bucketSizeC;
mData = &(mBucketList[_bucket][_index]);
if(DeallocateC) {
//if we hopped over the border of the previous bucket, then delete that bucket.
if(0 == _index && _bucket) {
delete[] mBucketList[_bucket-1];
mBucketList[_bucket-1] = DEALLOCATION_VECTOR_NULL_PTR;
}
}
explicit DeallocatingVectorIteratorState(const std::size_t idx,
std::vector<ElementT *> &input_list)
: index(idx), bucket_list(input_list)
{
}
inline bool operator!=(const DeallocatingVectorIteratorState &other) {
return (mData != other.mData) || (mIndex != other.mIndex) || (mBucketList != other.mBucketList);
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 (mData == other.mData) && (mIndex == other.mIndex) && (mBucketList == other.mBucketList);
inline bool operator==(const DeallocatingVectorIteratorState &other)
{
return index == other.index;
}
inline bool operator<(const DeallocatingVectorIteratorState &other) {
return mIndex < other.mIndex;
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
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 mState;
DeallocatingVectorIteratorState current_state;
public:
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>::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>
DeallocatingVectorIterator(const DeallocatingVectorIterator<T2> & r) : mState(r.mState) {}
DeallocatingVectorIterator(size_t idx, std::vector<ElementT *> & input_list) : mState(idx, input_list) {}
//DeallocatingVectorIterator(size_t idx, const std::vector<ElementT *> & input_list) : mState(idx, input_list) {}
DeallocatingVectorIterator(const DeallocatingVectorIteratorState & r) : mState(r) {}
template<typename T2>
DeallocatingVectorIterator& operator=(const DeallocatingVectorIterator<T2> &r) {
if(DeallocateC) assert(false);
mState = r.mState; return *this;
template <typename T2>
explicit DeallocatingVectorIterator(const DeallocatingVectorIterator<T2> &r)
: current_state(r.current_state)
{
}
inline DeallocatingVectorIterator& operator++() { //prefix
// if(DeallocateC) assert(false);
++mState.mIndex; mState.setPointerForIndex(); return *this;
DeallocatingVectorIterator(std::size_t idx, std::vector<ElementT *> &input_list)
: current_state(idx, input_list)
{
}
explicit DeallocatingVectorIterator(const DeallocatingVectorIteratorState &r) : current_state(r) {}
template <typename T2>
DeallocatingVectorIterator &operator=(const DeallocatingVectorIterator<T2> &r)
{
if (DeallocateC)
{
BOOST_ASSERT(false);
}
current_state = r.current_state;
return *this;
}
inline DeallocatingVectorIterator& operator--() { //prefix
if(DeallocateC) assert(false);
--mState.mIndex; mState.setPointerForIndex(); return *this;
inline DeallocatingVectorIterator &operator++()
{ // prefix
++current_state.index;
return *this;
}
inline DeallocatingVectorIterator operator++(int) { //postfix
DeallocatingVectorIteratorState _myState(mState);
mState.mIndex++; mState.setPointerForIndex();
return DeallocatingVectorIterator(_myState);
}
inline DeallocatingVectorIterator operator --(int) { //postfix
if(DeallocateC) assert(false);
DeallocatingVectorIteratorState _myState(mState);
mState.mIndex--; mState.setPointerForIndex();
return DeallocatingVectorIterator(_myState);
inline DeallocatingVectorIterator &operator--()
{ // prefix
if (DeallocateC)
{
BOOST_ASSERT(false);
}
--current_state.index;
return *this;
}
inline DeallocatingVectorIterator operator+(const difference_type& n) const {
DeallocatingVectorIteratorState _myState(mState);
_myState.mIndex+=n; _myState.setPointerForIndex();
return DeallocatingVectorIterator(_myState);
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 {
mState.mIndex+=n; return *this;
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) const {
if(DeallocateC) assert(false);
DeallocatingVectorIteratorState _myState(mState);
_myState.mIndex-=n; _myState.setPointerForIndex();
return DeallocatingVectorIterator(_myState);
inline DeallocatingVectorIterator &operator+=(const difference_type &n)
{
current_state.index += n;
return *this;
}
inline DeallocatingVectorIterator& operator-=(const difference_type &n) const {
if(DeallocateC) assert(false);
mState.mIndex-=n; return *this;
}
inline reference operator*() const { return *mState.mData; }
inline pointer operator->() const { return mState.mData; }
inline reference operator[](const difference_type &n) const {
if(DeallocateC) assert(false);
DeallocatingVectorIteratorState _myState(mState);
_myState.mIndex += n;
_myState.setPointerForIndex;
return _myState.mData;
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 bool operator!=(const DeallocatingVectorIterator & other) {
return mState != other.mState;
inline DeallocatingVectorIterator &operator-=(const difference_type &n) const
{
if (DeallocateC)
{
BOOST_ASSERT(false);
}
current_state.index -= n;
return *this;
}
inline bool operator==(const DeallocatingVectorIterator & other) {
return mState == other.mState;
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]);
}
bool operator<(const DeallocatingVectorIterator & other) {
return mState < other.mState;
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]);
}
difference_type operator-(const DeallocatingVectorIterator & other) {
if(DeallocateC) assert(false);
return mState.mIndex-other.mState.mIndex;
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, size_t bucketSizeC = 10485760/sizeof(ElementT) >
class DeallocatingVector {
private:
size_t mCurrentSize;
std::vector<ElementT *> mBucketList;
template <typename ElementT, std::size_t bucketSizeC = 8388608 / sizeof(ElementT)>
class DeallocatingVector
{
private:
std::size_t current_size;
std::vector<ElementT *> bucket_list;
public:
public:
typedef ElementT value_type;
typedef DeallocatingVectorIterator<ElementT, bucketSizeC, false> iterator;
typedef DeallocatingVectorIterator<ElementT, bucketSizeC, false> const_iterator;
//this iterator deallocates all buckets that have been visited. Iterators to visited objects become invalid.
// this iterator deallocates all buckets that have been visited. Iterators to visited objects
// become invalid.
typedef DeallocatingVectorIterator<ElementT, bucketSizeC, true> deallocation_iterator;
DeallocatingVector() : mCurrentSize(0) {
//initial bucket
mBucketList.push_back(new ElementT[bucketSizeC]);
DeallocatingVector() : current_size(0)
{
// initial bucket
bucket_list.emplace_back(new ElementT[bucketSizeC]);
}
~DeallocatingVector() {
clear();
~DeallocatingVector() { clear(); }
inline void swap(DeallocatingVector<ElementT, bucketSizeC> &other)
{
std::swap(current_size, other.current_size);
bucket_list.swap(other.bucket_list);
}
inline void swap(DeallocatingVector<ElementT, bucketSizeC> & other) {
std::swap(mCurrentSize, other.mCurrentSize);
mBucketList.swap(other.mBucketList);
}
inline void clear() {
//Delete[]'ing ptr's to all Buckets
for(unsigned i = 0; i < mBucketList.size(); ++i) {
if(DEALLOCATION_VECTOR_NULL_PTR != mBucketList[i]) {
delete[] mBucketList[i];
mBucketList[i] = DEALLOCATION_VECTOR_NULL_PTR;
inline void clear()
{
// Delete[]'ing ptr's to all Buckets
for (unsigned i = 0; i < bucket_list.size(); ++i)
{
if (nullptr != bucket_list[i])
{
delete[] bucket_list[i];
bucket_list[i] = nullptr;
}
}
//Removing all ptrs from vector
std::vector<ElementT *>().swap(mBucketList);
mCurrentSize = 0;
// Removing all ptrs from vector
std::vector<ElementT *>().swap(bucket_list);
current_size = 0;
}
inline void push_back(const ElementT & element) {
size_t _capacity = capacity();
if(mCurrentSize == _capacity) {
mBucketList.push_back(new ElementT[bucketSizeC]);
inline void push_back(const ElementT &element)
{
const std::size_t current_capacity = capacity();
if (current_size == current_capacity)
{
bucket_list.push_back(new ElementT[bucketSizeC]);
}
size_t _index = size()%bucketSizeC;
mBucketList.back()[_index] = element;
++mCurrentSize;
std::size_t current_index = size() % bucketSizeC;
bucket_list.back()[current_index] = element;
++current_size;
}
inline void reserve(const size_t) const {
//don't do anything
inline void emplace_back(const ElementT &&element)
{
const std::size_t current_capacity = capacity();
if (current_size == current_capacity)
{
bucket_list.push_back(new ElementT[bucketSizeC]);
}
const std::size_t current_index = size() % bucketSizeC;
bucket_list.back()[current_index] = element;
++current_size;
}
inline void resize(const size_t new_size) {
if(new_size > mCurrentSize) {
while(capacity() < new_size) {
mBucketList.push_back(new ElementT[bucketSizeC]);
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)
{
while (capacity() < new_size)
{
bucket_list.push_back(new ElementT[bucketSizeC]);
}
mCurrentSize = new_size;
current_size = new_size;
}
if(new_size < mCurrentSize) {
size_t number_of_necessary_buckets = 1+(new_size / bucketSizeC);
if (new_size < current_size)
{
const std::size_t number_of_necessary_buckets = 1 + (new_size / bucketSizeC);
for(unsigned i = number_of_necessary_buckets; i < mBucketList.size(); ++i) {
delete[] mBucketList[i];
for (std::size_t i = number_of_necessary_buckets; i < bucket_list.size(); ++i)
{
delete[] bucket_list[i];
}
mBucketList.resize(number_of_necessary_buckets);
mCurrentSize = new_size;
bucket_list.resize(number_of_necessary_buckets);
current_size = new_size;
}
}
inline size_t size() const {
return mCurrentSize;
inline std::size_t size() const { return current_size; }
inline std::size_t capacity() const { return bucket_list.size() * bucketSizeC; }
inline iterator begin() { return iterator(static_cast<std::size_t>(0), 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);
}
inline size_t capacity() const {
return mBucketList.size() * bucketSizeC;
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);
}
inline iterator begin() {
return iterator(static_cast<size_t>(0), mBucketList);
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;
return (bucket_list[_bucket][_index]);
}
inline iterator end() {
return iterator(size(), mBucketList);
const inline ElementT &operator[](const std::size_t index) const
{
std::size_t _bucket = index / bucketSizeC;
std::size_t _index = index % bucketSizeC;
return (bucket_list[_bucket][_index]);
}
inline deallocation_iterator dbegin() {
return deallocation_iterator(static_cast<size_t>(0), mBucketList);
inline ElementT &back()
{
std::size_t _bucket = current_size / bucketSizeC;
std::size_t _index = current_size % bucketSizeC;
return (bucket_list[_bucket][_index]);
}
inline deallocation_iterator dend() {
return deallocation_iterator(size(), mBucketList);
}
inline const_iterator begin() const {
return const_iterator(static_cast<size_t>(0), mBucketList);
}
inline const_iterator end() const {
return const_iterator(size(), mBucketList);
}
inline ElementT & operator[](const size_t index) {
size_t _bucket = index / bucketSizeC;
size_t _index = index % bucketSizeC;
return (mBucketList[_bucket][_index]);
}
const inline ElementT & operator[](const size_t index) const {
size_t _bucket = index / bucketSizeC;
size_t _index = index % bucketSizeC;
return (mBucketList[_bucket][_index]);
const inline ElementT &back() const
{
std::size_t _bucket = current_size / bucketSizeC;
std::size_t _index = current_size % bucketSizeC;
return (bucket_list[_bucket][_index]);
}
};
+249 -210
View File
@@ -1,241 +1,280 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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.
#ifndef DYNAMICGRAPH_H_INCLUDED
#define DYNAMICGRAPH_H_INCLUDED
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 <vector>
#include <algorithm>
#include <limits>
*/
#ifndef DYNAMICGRAPH_H
#define DYNAMICGRAPH_H
#include "../DataStructures/DeallocatingVector.h"
template< typename EdgeDataT>
class DynamicGraph {
public:
typedef EdgeDataT EdgeData;
typedef unsigned NodeIterator;
typedef unsigned EdgeIterator;
#include <boost/assert.hpp>
#include <boost/range/irange.hpp>
class InputEdge {
public:
NodeIterator source;
NodeIterator target;
EdgeDataT data;
bool operator<( const InputEdge& right ) const {
if ( source != right.source )
return source < right.source;
return target < right.target;
}
};
#include <cstdint>
//Constructs an empty graph with a given number of nodes.
DynamicGraph( int nodes ) : m_numNodes(nodes), m_numEdges(0) {
m_nodes.reserve( m_numNodes );
m_nodes.resize( m_numNodes );
#include <algorithm>
#include <limits>
#include <vector>
#include <atomic>
m_edges.reserve( m_numNodes * 1.1 );
m_edges.resize( m_numNodes );
}
template<class ContainerT>
DynamicGraph( const int nodes, const ContainerT &graph )
template <typename EdgeDataT> class DynamicGraph
{
public:
typedef decltype(boost::irange(0u,0u)) EdgeRange;
typedef EdgeDataT EdgeData;
typedef unsigned NodeIterator;
typedef unsigned EdgeIterator;
class InputEdge
{
public:
NodeIterator source;
NodeIterator target;
EdgeDataT data;
bool operator<(const InputEdge &right) const
{
m_numNodes = nodes;
m_numEdges = ( EdgeIterator ) graph.size();
m_nodes.reserve( m_numNodes );
m_nodes.resize( m_numNodes );
EdgeIterator edge = 0;
EdgeIterator position = 0;
for ( NodeIterator node = 0; node < m_numNodes; ++node ) {
EdgeIterator lastEdge = edge;
while ( edge < m_numEdges && graph[edge].source == node ) {
++edge;
}
m_nodes[node].firstEdge = position;
m_nodes[node].edges = edge - lastEdge;
position += m_nodes[node].edges;
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)
{
m_nodes.reserve(m_numNodes);
m_nodes.resize(m_numNodes);
m_edges.reserve(m_numNodes * 1.1);
m_edges.resize(m_numNodes);
}
template <class ContainerT> DynamicGraph(const int32_t nodes, const ContainerT &graph)
{
m_numNodes = nodes;
m_numEdges = (EdgeIterator)graph.size();
m_nodes.reserve(m_numNodes + 1);
m_nodes.resize(m_numNodes + 1);
EdgeIterator edge = 0;
EdgeIterator position = 0;
for (NodeIterator node = 0; node < m_numNodes; ++node)
{
EdgeIterator lastEdge = edge;
while (edge < m_numEdges && graph[edge].source == node)
{
++edge;
}
m_edges.reserve( position * 1.1 );
m_edges.resize( position );
edge = 0;
for ( NodeIterator node = 0; node < m_numNodes; ++node ) {
for ( EdgeIterator i = m_nodes[node].firstEdge, e = m_nodes[node].firstEdge + m_nodes[node].edges; i != e; ++i ) {
m_edges[i].target = graph[edge].target;
m_edges[i].data = graph[edge].data;
GUARANTEE(graph[edge].data.distance > 0, "edge: " << edge << "(" << graph[edge].source << "," << graph[edge].target << ")=" << graph[edge].data.distance);
++edge;
m_nodes[node].firstEdge = position;
m_nodes[node].edges = edge - lastEdge;
position += m_nodes[node].edges;
}
m_nodes.back().firstEdge = position;
m_edges.reserve(static_cast<std::size_t>(position * 1.1));
m_edges.resize(position);
edge = 0;
for (NodeIterator node = 0; node < m_numNodes; ++node)
{
for (EdgeIterator i = m_nodes[node].firstEdge,
e = m_nodes[node].firstEdge + m_nodes[node].edges;
i != e;
++i)
{
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;
}
}
}
~DynamicGraph() {}
unsigned GetNumberOfNodes() const { return m_numNodes; }
unsigned GetNumberOfEdges() const { return m_numEdges; }
unsigned GetOutDegree(const NodeIterator n) const { return m_nodes[n].edges; }
unsigned GetDirectedOutDegree(const NodeIterator n) const
{
unsigned degree = 0;
for(EdgeIterator edge = BeginEdges(n); edge < EndEdges(n); ++edge)
{
if (GetEdgeData(edge).forward)
{
++degree;
}
}
return degree;
}
NodeIterator GetTarget(const EdgeIterator e) const { return NodeIterator(m_edges[e].target); }
void SetTarget(const EdgeIterator e, const NodeIterator n) { m_edges[e].target = n; }
EdgeDataT &GetEdgeData(const EdgeIterator e) { return m_edges[e].data; }
const EdgeDataT &GetEdgeData(const EdgeIterator e) const { return m_edges[e].data; }
EdgeIterator BeginEdges(const NodeIterator n) const
{
return EdgeIterator(m_nodes[n].firstEdge);
}
EdgeIterator EndEdges(const NodeIterator n) const
{
return EdgeIterator(m_nodes[n].firstEdge + m_nodes[n].edges);
}
EdgeRange GetAdjacentEdgeRange(const NodeIterator node) const
{
return boost::irange(BeginEdges(node), EndEdges(node));
}
// 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];
EdgeIterator newFirstEdge = node.edges + node.firstEdge;
if (newFirstEdge >= m_edges.size() || !isDummy(newFirstEdge))
{
if (node.firstEdge != 0 && isDummy(node.firstEdge - 1))
{
node.firstEdge--;
m_edges[node.firstEdge] = m_edges[node.firstEdge + node.edges];
}
else
{
EdgeIterator newFirstEdge = (EdgeIterator)m_edges.size();
unsigned newSize = node.edges * 1.1 + 2;
EdgeIterator requiredCapacity = newSize + m_edges.size();
EdgeIterator oldCapacity = m_edges.capacity();
if (requiredCapacity >= oldCapacity)
{
m_edges.reserve(requiredCapacity * 1.1);
}
m_edges.resize(m_edges.size() + newSize);
for (EdgeIterator i = 0; i < node.edges; ++i)
{
m_edges[newFirstEdge + i] = m_edges[node.firstEdge + i];
makeDummy(node.firstEdge + i);
}
for (EdgeIterator i = node.edges + 1; i < newSize; ++i)
makeDummy(newFirstEdge + i);
node.firstEdge = newFirstEdge;
}
}
Edge &edge = m_edges[node.firstEdge + node.edges];
edge.target = to;
edge.data = data;
++m_numEdges;
++node.edges;
return EdgeIterator(node.firstEdge + node.edges);
}
// 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.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];
makeDummy(last);
}
// removes all edges (source,target)
int32_t DeleteEdgesTo(const NodeIterator source, const NodeIterator target)
{
int32_t deleted = 0;
for (EdgeIterator i = BeginEdges(source), iend = EndEdges(source); i < iend - deleted; ++i)
{
if (m_edges[i].target == target)
{
do
{
deleted++;
m_edges[i] = m_edges[iend - deleted];
makeDummy(iend - deleted);
} while (i < iend - deleted && m_edges[i].target == target);
}
}
~DynamicGraph(){ }
m_numEdges -= deleted;
m_nodes[source].edges -= deleted;
unsigned GetNumberOfNodes() const
{
return m_numNodes;
}
return deleted;
}
unsigned GetNumberOfEdges() const
// 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)
{
return m_numEdges;
}
unsigned GetOutDegree( const NodeIterator &n ) const
{
return m_nodes[n].edges;
}
NodeIterator GetTarget( const EdgeIterator &e ) const
{
return NodeIterator( m_edges[e].target );
}
EdgeDataT &GetEdgeData( const EdgeIterator &e )
{
return m_edges[e].data;
}
const EdgeDataT &GetEdgeData( const EdgeIterator &e ) const
{
return m_edges[e].data;
}
EdgeIterator BeginEdges( const NodeIterator &n ) const
{
//assert( EndEdges( n ) - EdgeIterator( _nodes[n].firstEdge ) <= 100 );
return EdgeIterator( m_nodes[n].firstEdge );
}
EdgeIterator EndEdges( const NodeIterator &n ) const
{
return EdgeIterator( m_nodes[n].firstEdge + m_nodes[n].edges );
}
//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];
EdgeIterator newFirstEdge = node.edges + node.firstEdge;
if ( newFirstEdge >= m_edges.size() || !isDummy( newFirstEdge ) ) {
if ( node.firstEdge != 0 && isDummy( node.firstEdge - 1 ) ) {
node.firstEdge--;
m_edges[node.firstEdge] = m_edges[node.firstEdge + node.edges];
} else {
EdgeIterator newFirstEdge = ( EdgeIterator ) m_edges.size();
unsigned newSize = node.edges * 1.1 + 2;
EdgeIterator requiredCapacity = newSize + m_edges.size();
EdgeIterator oldCapacity = m_edges.capacity();
if ( requiredCapacity >= oldCapacity ) {
m_edges.reserve( requiredCapacity * 1.1 );
}
m_edges.resize( m_edges.size() + newSize );
for ( EdgeIterator i = 0; i < node.edges; ++i ) {
m_edges[newFirstEdge + i ] = m_edges[node.firstEdge + i];
makeDummy( node.firstEdge + i );
}
for ( EdgeIterator i = node.edges + 1; i < newSize; ++i )
makeDummy( newFirstEdge + i );
node.firstEdge = newFirstEdge;
}
if (to == m_edges[i].target)
{
return i;
}
Edge &edge = m_edges[node.firstEdge + node.edges];
edge.target = to;
edge.data = data;
++m_numEdges;
++node.edges;
return EdgeIterator( node.firstEdge + node.edges );
}
return EndEdges(from);
}
//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.edges;
const unsigned last = node.firstEdge + node.edges;
//swap with last edge
m_edges[e] = m_edges[last];
makeDummy( last );
}
protected:
bool isDummy(const EdgeIterator edge) const
{
return m_edges[edge].target == (std::numeric_limits<NodeIterator>::max)();
}
//removes all edges (source,target)
int DeleteEdgesTo( const NodeIterator source, const NodeIterator target )
{
int deleted = 0;
for ( EdgeIterator i = BeginEdges( source ), iend = EndEdges( source ); i < iend - deleted; ++i ) {
if ( m_edges[i].target == target ) {
do {
deleted++;
m_edges[i] = m_edges[iend - deleted];
makeDummy( iend - deleted );
} while ( i < iend - deleted && m_edges[i].target == target );
}
}
void makeDummy(const EdgeIterator edge)
{
m_edges[edge].target = (std::numeric_limits<NodeIterator>::max)();
}
#pragma omp atomic
m_numEdges -= deleted;
m_nodes[source].edges -= deleted;
struct Node
{
// index of the first edge
EdgeIterator firstEdge;
// amount of edges
unsigned edges;
};
return deleted;
}
struct Edge
{
NodeIterator target;
EdgeDataT data;
};
//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 ) {
if ( m_edges[i].target == to ) {
return i;
}
}
return EndEdges( from );
}
protected:
bool isDummy( EdgeIterator edge ) const
{
return m_edges[edge].target == (std::numeric_limits< NodeIterator >::max)();
}
void makeDummy( EdgeIterator edge )
{
m_edges[edge].target = (std::numeric_limits< NodeIterator >::max)();
}
struct Node {
//index of the first edge
EdgeIterator firstEdge;
//amount of edges
unsigned edges;
};
struct Edge {
NodeIterator target;
EdgeDataT data;
};
NodeIterator m_numNodes;
EdgeIterator m_numEdges;
DeallocatingVector< Node > m_nodes;
DeallocatingVector< Edge > m_edges;
NodeIterator m_numNodes;
std::atomic_uint m_numEdges;
std::vector<Node> m_nodes;
DeallocatingVector<Edge> m_edges;
};
#endif // DYNAMICGRAPH_H_INCLUDED
#endif // DYNAMICGRAPH_H
+90
View File
@@ -0,0 +1,90 @@
#ifndef EDGE_BASED_NODE_H
#define EDGE_BASED_NODE_H
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
#include <limits>
struct EdgeBasedNode
{
EdgeBasedNode() :
forward_edge_based_node_id(SPECIAL_NODEID),
reverse_edge_based_node_id(SPECIAL_NODEID),
u(SPECIAL_NODEID),
v(SPECIAL_NODEID),
name_id(0),
forward_weight(INVALID_EDGE_WEIGHT >> 1),
reverse_weight(INVALID_EDGE_WEIGHT >> 1),
forward_offset(0),
reverse_offset(0),
packed_geometry_id(SPECIAL_EDGEID),
fwd_segment_position( std::numeric_limits<unsigned short>::max() ),
is_in_tiny_cc(false)
{ }
explicit EdgeBasedNode(
NodeID forward_edge_based_node_id,
NodeID reverse_edge_based_node_id,
NodeID u,
NodeID v,
unsigned name_id,
int forward_weight,
int reverse_weight,
int forward_offset,
int reverse_offset,
unsigned packed_geometry_id,
unsigned short fwd_segment_position,
bool belongs_to_tiny_component
) :
forward_edge_based_node_id(forward_edge_based_node_id),
reverse_edge_based_node_id(reverse_edge_based_node_id),
u(u),
v(v),
name_id(name_id),
forward_weight(forward_weight),
reverse_weight(reverse_weight),
forward_offset(forward_offset),
reverse_offset(reverse_offset),
packed_geometry_id(packed_geometry_id),
fwd_segment_position(fwd_segment_position),
is_in_tiny_cc(belongs_to_tiny_component)
{
BOOST_ASSERT((forward_edge_based_node_id != SPECIAL_NODEID) ||
(reverse_edge_based_node_id != SPECIAL_NODEID));
}
static inline FixedPointCoordinate Centroid(const FixedPointCoordinate & a, const FixedPointCoordinate & b)
{
FixedPointCoordinate centroid;
//The coordinates of the midpoint are given by:
centroid.lat = (a.lat + b.lat)/2;
centroid.lon = (a.lon + b.lon)/2;
return centroid;
}
bool IsCompressed() const
{
return packed_geometry_id != SPECIAL_EDGEID;
}
NodeID forward_edge_based_node_id; // needed for edge-expanded graph
NodeID reverse_edge_based_node_id; // needed for edge-expanded graph
NodeID u; // indices into the coordinates array
NodeID v; // indices into the coordinates array
unsigned name_id; // id of the edge name
int forward_weight; // weight of the edge
int reverse_weight; // weight in the other direction (may be different)
int forward_offset; // prefix sum of the weight up the edge TODO: short must suffice
int reverse_offset; // prefix sum of the weight from the edge TODO: short must suffice
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;
};
#endif //EDGE_BASED_NODE_H
-82
View File
@@ -1,82 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef GRIDEDGE_H_
#define GRIDEDGE_H_
#include "Coordinate.h"
struct _GridEdge {
_GridEdge(NodeID n, NodeID na, int w, _Coordinate sc, _Coordinate tc, bool bttc) : edgeBasedNode(n), nameID(na), weight(w), startCoord(sc), targetCoord(tc), belongsToTinyComponent(bttc) {}
_GridEdge() : edgeBasedNode(UINT_MAX), nameID(UINT_MAX), weight(INT_MAX), belongsToTinyComponent(false) {}
NodeID edgeBasedNode;
NodeID nameID;
int weight;
_Coordinate startCoord;
_Coordinate targetCoord;
bool belongsToTinyComponent;
bool operator< ( const _GridEdge& right) const {
return edgeBasedNode < right.edgeBasedNode;
}
bool operator== ( const _GridEdge& right) const {
return edgeBasedNode == right.edgeBasedNode;
}
};
struct GridEntry {
GridEntry() : fileIndex(UINT_MAX), ramIndex(UINT_MAX){}
GridEntry(_GridEdge e, unsigned f, unsigned r) : edge(e), fileIndex(f), ramIndex(r) {}
_GridEdge edge;
unsigned fileIndex;
unsigned ramIndex;
bool operator< ( const GridEntry& right ) const {
return (edge.edgeBasedNode < right.edge.edgeBasedNode);
}
bool operator==( const GridEntry& right ) const {
return right.edge.edgeBasedNode == edge.edgeBasedNode;
}
};
struct CompareGridEdgeDataByFileIndex {
bool operator () (const GridEntry & a, const GridEntry & b) const {
return a.fileIndex < b.fileIndex;
}
};
struct CompareGridEdgeDataByRamIndex {
typedef GridEntry value_type;
bool operator () (const GridEntry & a, const GridEntry & b) const {
return a.ramIndex < b.ramIndex;
}
value_type max_value() {
GridEntry e;
e.ramIndex = (1024*1024) - 1;
return e;
}
value_type min_value() {
GridEntry e;
e.ramIndex = 0;
return e;
}
};
#endif /* GRIDEDGE_H_ */
+62 -63
View File
@@ -1,79 +1,78 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
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.
Created on: 18.11.2010
Author: dennis
*/
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 HASHTABLE_H_
#define HASHTABLE_H_
*/
#include <boost/unordered_map.hpp>
#ifndef HASH_TABLE_H
#define HASH_TABLE_H
template<typename keyT, typename valueT>
class HashTable {
typedef boost::unordered_map<keyT, valueT> MyHashTable;
public:
typedef typename boost::unordered_map<keyT, valueT>::const_iterator MyIterator;
typedef MyIterator iterator;
HashTable() { }
HashTable(const unsigned size) {
table.resize(size);
}
inline void Add(const keyT& key, const valueT& value){
table[key] = value;
}
inline void Set(const keyT& key, const valueT& value){
table[key] = value;
}
inline valueT Find(const keyT& key) const {
if(table.find(key) == table.end())
return valueT();
return table.find(key)->second;
#include <vector>
template <typename Key, typename Value>
class HashTable
{
private:
typedef std::pair<Key, Value> KeyValPair;
std::vector<KeyValPair> table;
public:
HashTable() {}
inline void Add(Key const &key, Value const &value)
{
table.emplace_back(std::move(key), std::move(value));
}
inline bool Holds(const keyT& key) const {
if(table.find(key) == table.end())
return false;
return true;
}
void EraseAll() {
if(table.size() > 0)
table.clear();
inline void Clear()
{
table.clear();
}
inline valueT operator[] (keyT key) const {
if(table.find(key) == table.end())
return valueT();
return table.find(key)->second;
inline const Value Find(Key const &key) const
{
for (const auto &key_val_pair : table)
{
if (key_val_pair.first == key)
{
return key_val_pair.second;
}
}
return Value();
}
inline unsigned Size() const {
return table.size();
inline const bool Holds(Key const &key) const
{
for (const auto &key_val_pair : table)
{
if (key_val_pair.first == key)
{
return true;
}
}
return false;
}
MyIterator begin() const {
return table.begin();
}
MyIterator end() const {
return table.end();
}
private:
MyHashTable table;
};
#endif /* HASHTABLE_H_ */
#endif /* HASH_TABLE_H */
+100
View File
@@ -0,0 +1,100 @@
/*
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 "HilbertValue.h"
#include <osrm/Coordinate.h>
uint64_t HilbertCode::operator()(const FixedPointCoordinate &current_coordinate) const
{
unsigned location[2];
location[0] = current_coordinate.lat + static_cast<int>(90 * COORDINATE_PRECISION);
location[1] = current_coordinate.lon + static_cast<int>(180 * COORDINATE_PRECISION);
TransposeCoordinate(location);
return BitInterleaving(location[0], location[1]);
}
uint64_t HilbertCode::BitInterleaving(const uint32_t latitude, const uint32_t longitude) const
{
uint64_t result = 0;
for (int8_t index = 31; index >= 0; --index)
{
result |= (latitude >> index) & 1;
result <<= 1;
result |= (longitude >> index) & 1;
if (0 != index)
{
result <<= 1;
}
}
return result;
}
void HilbertCode::TransposeCoordinate(uint32_t *X) const
{
uint32_t M = 1 << (32 - 1), P, Q, t;
int i;
// Inverse undo
for (Q = M; Q > 1; Q >>= 1)
{
P = Q - 1;
for (i = 0; i < 2; ++i)
{
const bool condition = (X[i] & Q);
if (condition)
{
X[0] ^= P; // invert
}
else
{
t = (X[0] ^ X[i]) & P;
X[0] ^= t;
X[i] ^= t;
}
} // exchange
}
// Gray encode
for (i = 1; i < 2; ++i)
{
X[i] ^= X[i - 1];
}
t = 0;
for (Q = M; Q > 1; Q >>= 1)
{
const bool condition = (X[2 - 1] & Q);
if (condition)
{
t ^= Q - 1;
}
} // check if this for loop is wrong
for (i = 0; i < 2; ++i)
{
X[i] ^= t;
}
}
+49
View File
@@ -0,0 +1,49 @@
/*
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 HILBERTVALUE_H_
#define HILBERTVALUE_H_
#include <cstdint>
// computes a 64 bit value that corresponds to the hilbert space filling curve
struct FixedPointCoordinate;
class HilbertCode
{
public:
uint64_t operator()(const FixedPointCoordinate &current_coordinate) const;
HilbertCode() {}
HilbertCode(const HilbertCode &) = delete;
private:
inline uint64_t BitInterleaving(const uint32_t a, const uint32_t b) const;
inline void TransposeCoordinate(uint32_t *X) const;
};
#endif /* HILBERTVALUE_H_ */
+107
View File
@@ -0,0 +1,107 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ImportEdge.h"
#include <boost/assert.hpp>
bool NodeBasedEdge::operator<(const NodeBasedEdge &other) const
{
if (source == other.source)
{
if (target == other.target)
{
if (weight == other.weight)
{
return forward && backward && ((!other.forward) || (!other.backward));
}
return weight < other.weight;
}
return target < other.target;
}
return source < other.source;
}
NodeBasedEdge::NodeBasedEdge(NodeID source,
NodeID target,
NodeID name_id,
EdgeWeight weight,
bool forward,
bool backward,
short type,
bool roundabout,
bool in_tiny_cc,
bool access_restricted,
bool contra_flow,
bool is_split)
: source(source), target(target), name_id(name_id), weight(weight), type(type),
forward(forward), backward(backward), roundabout(roundabout), in_tiny_cc(in_tiny_cc),
access_restricted(access_restricted), contra_flow(contra_flow), is_split(is_split)
{
BOOST_ASSERT_MSG(type > 0, "negative edge type");
}
bool EdgeBasedEdge::operator<(const EdgeBasedEdge &other) const
{
if (source == other.source)
{
if (target == other.target)
{
if (weight == other.weight)
{
return forward && backward && ((!other.forward) || (!other.backward));
}
return weight < other.weight;
}
return target < other.target;
}
return source < other.source;
}
template <class EdgeT>
EdgeBasedEdge::EdgeBasedEdge(const EdgeT &other)
: source(other.source), target(other.target), edge_id(other.data.via),
weight(other.data.distance), forward(other.data.forward), backward(other.data.backward)
{
}
/** Default constructor. target and weight are set to 0.*/
EdgeBasedEdge::EdgeBasedEdge()
: source(0), target(0), edge_id(0), weight(0), forward(false), backward(false)
{
}
EdgeBasedEdge::EdgeBasedEdge(const NodeID source,
const NodeID target,
const NodeID edge_id,
const EdgeWeight weight,
const bool forward,
const bool backward)
: source(source), target(target), edge_id(edge_id), weight(weight), forward(forward),
backward(backward)
{
}
+71 -114
View File
@@ -1,135 +1,92 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef EDGE_H
#define EDGE_H
#ifndef IMPORT_EDGE_H
#define IMPORT_EDGE_H
#include <cassert>
#include "../typedefs.h"
class NodeBasedEdge {
public:
struct NodeBasedEdge
{
bool operator<(const NodeBasedEdge &e) const;
bool operator< (const NodeBasedEdge& e) const {
if (source() == e.source()) {
if (target() == e.target()) {
if (weight() == e.weight()) {
return (isForward() && isBackward() &&
((! e.isForward()) || (! e.isBackward())));
}
return (weight() < e.weight());
}
return (target() < e.target());
}
return (source() < e.source());
}
explicit NodeBasedEdge(NodeID source,
NodeID target,
NodeID name_id,
EdgeWeight weight,
bool forward,
bool backward,
short type,
bool roundabout,
bool in_tiny_cc,
bool access_restricted,
bool contra_flow,
bool is_split);
/** Default constructor. target and weight are set to 0.*/
NodeBasedEdge() :
_source(0), _target(0), _name(0), _weight(0), forward(0), backward(0), _type(0), _roundabout(false), _ignoreInGrid(false), _accessRestricted(false) { assert(false); } //shall not be used.
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;
explicit NodeBasedEdge(NodeID s, NodeID t, NodeID n, EdgeWeight w, bool f, bool b, short ty, bool ra, bool ig, bool ar) :
_source(s), _target(t), _name(n), _weight(w), forward(f), backward(b), _type(ty), _roundabout(ra), _ignoreInGrid(ig), _accessRestricted(ar) { if(ty < 0) {ERR("Type: " << ty);}; }
NodeID target() const {return _target; }
NodeID source() const {return _source; }
NodeID name() const { return _name; }
EdgeWeight weight() const {return _weight; }
short type() const { assert(_type >= 0); return _type; }
bool isBackward() const { return backward; }
bool isForward() const { return forward; }
bool isLocatable() const { return _type != 14; }
bool isRoundabout() const { return _roundabout; }
bool ignoreInGrid() const { return _ignoreInGrid; }
bool isAccessRestricted() const { return _accessRestricted; }
NodeID _source;
NodeID _target;
NodeID _name;
EdgeWeight _weight;
bool forward;
bool backward;
short _type;
bool _roundabout;
bool _ignoreInGrid;
bool _accessRestricted;
NodeBasedEdge() = delete;
};
class EdgeBasedEdge {
public:
struct EdgeBasedEdge
{
bool operator< (const EdgeBasedEdge& e) const {
if (source() == e.source()) {
if (target() == e.target()) {
if (weight() == e.weight()) {
return (isForward() && isBackward() &&
((! e.isForward()) || (! e.isBackward())));
}
return (weight() < e.weight());
}
return (target() < e.target());
}
return (source() < e.source());
}
public:
bool operator<(const EdgeBasedEdge &e) const;
template<class EdgeT>
EdgeBasedEdge(const EdgeT & myEdge ) :
_source(myEdge.source),
_target(myEdge.target),
_edgeID(myEdge.data.via),
// _nameID1(myEdge.data.nameID),
_weight(myEdge.data.distance),
_forward(myEdge.data.forward),
_backward(myEdge.data.backward)//,
// _turnInstruction(myEdge.data.turnInstruction)
{ }
template <class EdgeT> explicit EdgeBasedEdge(const EdgeT &myEdge);
/** Default constructor. target and weight are set to 0.*/
EdgeBasedEdge() :
_source(0), _target(0), _edgeID(0), _weight(0), _forward(false), _backward(false) { }
EdgeBasedEdge();
explicit EdgeBasedEdge(NodeID s, NodeID t, NodeID v, EdgeWeight w, bool f, bool b) :
_source(s), _target(t), _edgeID(v), _weight(w), _forward(f), _backward(b){}
NodeID target() const {return _target; }
NodeID source() const {return _source; }
EdgeWeight weight() const {return _weight; }
NodeID id() const { return _edgeID; }
bool isBackward() const { return _backward; }
bool isForward() const { return _forward; }
NodeID _source;
NodeID _target;
NodeID _edgeID;
EdgeWeight _weight:30;
bool _forward:1;
bool _backward:1;
};
struct MinimalEdgeData {
public:
EdgeWeight distance;
bool forward;
bool backward;
explicit EdgeBasedEdge(const NodeID source,
const NodeID target,
const NodeID edge_id,
const EdgeWeight weight,
const bool forward,
const bool backward);
NodeID source;
NodeID target;
NodeID edge_id;
EdgeWeight weight : 30;
bool forward : 1;
bool backward : 1;
};
typedef NodeBasedEdge ImportEdge;
#endif // EDGE_H
#endif /* IMPORT_EDGE_H */
+64
View File
@@ -0,0 +1,64 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ImportNode.h"
#include <limits>
ExternalMemoryNode::ExternalMemoryNode(
int lat, int lon, unsigned int node_id, bool bollard, bool traffic_light)
: NodeInfo(lat, lon, node_id), bollard(bollard), trafficLight(traffic_light)
{
}
ExternalMemoryNode::ExternalMemoryNode() : bollard(false), trafficLight(false)
{
}
ExternalMemoryNode ExternalMemoryNode::min_value()
{
return ExternalMemoryNode(0, 0, 0, false, false);
}
ExternalMemoryNode ExternalMemoryNode::max_value()
{
return ExternalMemoryNode(std::numeric_limits<int>::max(),
std::numeric_limits<int>::max(),
std::numeric_limits<unsigned>::max(),
false,
false);
}
void ImportNode::Clear()
{
keyVals.Clear();
lat = 0;
lon = 0;
node_id = 0;
bollard = false;
trafficLight = false;
}
+37 -34
View File
@@ -1,54 +1,57 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 IMPORTNODE_H_
#define IMPORTNODE_H_
#include "NodeCoords.h"
#include "QueryNode.h"
#include "../DataStructures/HashTable.h"
#include <string>
struct _Node : NodeInfo{
_Node(int _lat, int _lon, unsigned int _id, bool _bollard, bool _trafficLight) : NodeInfo(_lat, _lon, _id), bollard(_bollard), trafficLight(_trafficLight) {}
_Node() : bollard(false), trafficLight(false) {}
struct ExternalMemoryNode : NodeInfo
{
ExternalMemoryNode(int lat, int lon, unsigned int id, bool bollard, bool traffic_light);
ExternalMemoryNode();
static ExternalMemoryNode min_value();
static ExternalMemoryNode max_value();
static _Node min_value() {
return _Node(0,0,0, false, false);
}
static _Node max_value() {
return _Node((std::numeric_limits<int>::max)(), (std::numeric_limits<int>::max)(), (std::numeric_limits<unsigned int>::max)(), false, false);
}
NodeID key() const {
return id;
}
bool bollard;
bool trafficLight;
};
struct ImportNode : public _Node {
struct ImportNode : public ExternalMemoryNode
{
HashTable<std::string, std::string> keyVals;
inline void Clear() {
keyVals.EraseAll();
lat = 0; lon = 0; id = 0; bollard = false; trafficLight = false;
}
inline void Clear();
};
#endif /* IMPORTNODE_H_ */
+78 -49
View File
@@ -1,94 +1,123 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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.
#ifndef INPUTREADERFACTORY_H
#define INPUTREADERFACTORY_H
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef INPUT_READER_FACTORY_H
#define INPUT_READER_FACTORY_H
#include <boost/assert.hpp>
#include <bzlib.h>
#include <libxml/xmlreader.h>
struct BZ2Context {
FILE* file;
BZFILE* bz2;
struct BZ2Context
{
FILE *file;
BZFILE *bz2;
int error;
int nUnused;
char unused[BZ_MAX_UNUSED];
};
int readFromBz2Stream( void* pointer, char* buffer, int len ) {
void *unusedTmpVoid=NULL;
char *unusedTmp=NULL;
BZ2Context* context = (BZ2Context*) pointer;
int readFromBz2Stream(void *pointer, char *buffer, int len)
{
void *unusedTmpVoid = nullptr;
char *unusedTmp = nullptr;
BZ2Context *context = (BZ2Context *)pointer;
int read = 0;
while(0 == read && !(BZ_STREAM_END == context->error && 0 == context->nUnused && feof(context->file))) {
while (0 == read &&
!(BZ_STREAM_END == context->error && 0 == context->nUnused && feof(context->file)))
{
read = BZ2_bzRead(&context->error, context->bz2, buffer, len);
if(BZ_OK == context->error) {
if (BZ_OK == context->error)
{
return read;
} else if(BZ_STREAM_END == context->error) {
}
else if (BZ_STREAM_END == context->error)
{
BZ2_bzReadGetUnused(&context->error, context->bz2, &unusedTmpVoid, &context->nUnused);
if(BZ_OK != context->error) { cerr << "Could not BZ2_bzReadGetUnused" << endl; exit(-1);};
unusedTmp = (char*)unusedTmpVoid;
for(int i=0;i<context->nUnused;i++) {
BOOST_ASSERT_MSG(BZ_OK == context->error, "Could not BZ2_bzReadGetUnused");
unusedTmp = (char *)unusedTmpVoid;
for (int i = 0; i < context->nUnused; i++)
{
context->unused[i] = unusedTmp[i];
}
BZ2_bzReadClose(&context->error, context->bz2);
if(BZ_OK != context->error) { cerr << "Could not BZ2_bzReadClose" << endl; exit(-1);};
BOOST_ASSERT_MSG(BZ_OK == context->error, "Could not BZ2_bzReadClose");
context->error = BZ_STREAM_END; // set to the stream end for next call to this function
if(0 == context->nUnused && feof(context->file)) {
if (0 == context->nUnused && feof(context->file))
{
return read;
} else {
context->bz2 = BZ2_bzReadOpen(&context->error, context->file, 0, 0, context->unused, context->nUnused);
if(NULL == context->bz2){ cerr << "Could not open file" << endl; exit(-1);};
}
} else { cerr << "Could not read bz2 file" << endl; exit(-1); }
else
{
context->bz2 = BZ2_bzReadOpen(
&context->error, context->file, 0, 0, context->unused, context->nUnused);
BOOST_ASSERT_MSG(nullptr != context->bz2, "Could not open file");
}
}
else
{
BOOST_ASSERT_MSG(false, "Could not read bz2 file");
}
}
return read;
}
int closeBz2Stream( void *pointer )
int closeBz2Stream(void *pointer)
{
BZ2Context* context = (BZ2Context*) pointer;
fclose( context->file );
BZ2Context *context = (BZ2Context *)pointer;
fclose(context->file);
delete context;
return 0;
}
xmlTextReaderPtr inputReaderFactory( const char* name )
xmlTextReaderPtr inputReaderFactory(const char *name)
{
std::string inputName(name);
if(inputName.find(".osm.bz2")!=string::npos)
if (inputName.find(".osm.bz2") != std::string::npos)
{
BZ2Context* context = new BZ2Context();
BZ2Context *context = new BZ2Context();
context->error = false;
context->file = fopen( name, "r" );
context->file = fopen(name, "r");
int error;
context->bz2 = BZ2_bzReadOpen( &error, context->file, 0, 0, context->unused, context->nUnused );
if ( context->bz2 == NULL || context->file == NULL ) {
context->bz2 =
BZ2_bzReadOpen(&error, context->file, 0, 0, context->unused, context->nUnused);
if (context->bz2 == nullptr || context->file == nullptr)
{
delete context;
return NULL;
return nullptr;
}
return xmlReaderForIO( readFromBz2Stream, closeBz2Stream, (void*) context, NULL, NULL, 0 );
} else {
return xmlReaderForIO(readFromBz2Stream, closeBz2Stream, (void *)context, nullptr, nullptr, 0);
}
else
{
return xmlNewTextReaderFilename(name);
}
}
#endif // INPUTREADERFACTORY_H
#endif // INPUT_READER_FACTORY_H
+237
View File
@@ -0,0 +1,237 @@
/*
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.
*/
// 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 <iostream>
#include <vector>
#include <string>
#include <unordered_map>
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
{
String() {}
String(const char *value) : value(value) {}
String(const std::string &value) : value(value) {}
std::string value;
};
struct Number
{
Number() {}
Number(double value) : value(value) {}
double value;
};
struct Object
{
std::unordered_map<std::string, Value> values;
};
struct Array
{
std::vector<Value> values;
};
struct True
{
};
struct False
{
};
struct Null
{
};
struct Renderer : boost::static_visitor<>
{
Renderer(std::ostream &_out) : out(_out) {}
void operator()(const String &string) const { out << "\"" << string.value << "\""; }
void operator()(const Number &number) const
{
out.precision(10);
out << number.value;
}
void operator()(const Object &object) const
{
out << "{";
auto iterator = object.values.begin();
while (iterator != object.values.end())
{
out << "\"" << (*iterator).first << "\":";
boost::apply_visitor(Renderer(out), (*iterator).second);
if (++iterator != object.values.end())
{
out << ",";
}
}
out << "}";
}
void operator()(const Array &array) const
{
out << "[";
std::vector<Value>::const_iterator iterator;
iterator = array.values.begin();
while (iterator != array.values.end())
{
boost::apply_visitor(Renderer(out), *iterator);
if (++iterator != array.values.end())
{
out << ",";
}
}
out << "]";
}
void operator()(const True &) const { out << "true"; }
void operator()(const False &) const { out << "false"; }
void operator()(const Null &) const { out << "null"; }
private:
std::ostream &out;
};
struct ArrayRenderer : boost::static_visitor<>
{
ArrayRenderer(std::vector<char> &_out) : out(_out) {}
void operator()(const String &string) const {
out.push_back('\"');
out.insert(out.end(), string.value.begin(), string.value.end());
out.push_back('\"');
}
void operator()(const Number &number) const
{
const std::string number_string = FixedDoubleToString(number.value);
out.insert(out.end(), number_string.begin(), number_string.end());
}
void operator()(const Object &object) const
{
out.push_back('{');
auto iterator = object.values.begin();
while (iterator != object.values.end())
{
out.push_back('\"');
out.insert(out.end(), (*iterator).first.begin(), (*iterator).first.end());
out.push_back('\"');
out.push_back(':');
boost::apply_visitor(ArrayRenderer(out), (*iterator).second);
if (++iterator != object.values.end())
{
out.push_back(',');
}
}
out.push_back('}');
}
void operator()(const Array &array) const
{
out.push_back('[');
std::vector<Value>::const_iterator iterator;
iterator = array.values.begin();
while (iterator != array.values.end())
{
boost::apply_visitor(ArrayRenderer(out), *iterator);
if (++iterator != array.values.end())
{
out.push_back(',');
}
}
out.push_back(']');
}
void operator()(const True &) const {
const std::string temp("true");
out.insert(out.end(), temp.begin(), temp.end());
}
void operator()(const False &) const {
const std::string temp("false");
out.insert(out.end(), temp.begin(), temp.end());
}
void operator()(const Null &) const {
const std::string temp("null");
out.insert(out.end(), temp.begin(), temp.end());
}
private:
std::vector<char> &out;
};
inline void render(std::ostream &out, const Object &object)
{
Value value = object;
boost::apply_visitor(Renderer(out), value);
}
inline void render(std::vector<char> &out, const Object &object)
{
Value value = object;
boost::apply_visitor(ArrayRenderer(out), value);
}
} // namespace JSON
#endif // JSON_CONTAINER_H
+51 -36
View File
@@ -1,82 +1,97 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 LRUCACHE_H
#define LRUCACHE_H
#include <list>
#include <boost/unordered_map.hpp>
#include <unordered_map>
template<typename KeyT, typename ValueT>
class LRUCache {
private:
struct CacheEntry {
template <typename KeyT, typename ValueT> class LRUCache
{
private:
struct CacheEntry
{
CacheEntry(KeyT k, ValueT v) : key(k), value(v) {}
KeyT key;
ValueT value;
};
unsigned capacity;
std::list<CacheEntry> itemsInCache;
boost::unordered_map<KeyT, typename std::list<CacheEntry>::iterator > positionMap;
public:
LRUCache(unsigned c) : capacity(c) {}
std::unordered_map<KeyT, typename std::list<CacheEntry>::iterator> positionMap;
bool Holds(KeyT key) {
if(positionMap.find(key) != positionMap.end()) {
public:
explicit LRUCache(unsigned c) : capacity(c) {}
bool Holds(KeyT key)
{
if (positionMap.find(key) != positionMap.end())
{
return true;
}
return false;
}
void Insert(const KeyT key, ValueT &value) {
void Insert(const KeyT key, ValueT &value)
{
itemsInCache.push_front(CacheEntry(key, value));
positionMap.insert(std::make_pair(key, itemsInCache.begin()));
if(itemsInCache.size() > capacity) {
if (itemsInCache.size() > capacity)
{
positionMap.erase(itemsInCache.back().key);
itemsInCache.pop_back();
}
}
void Insert(const KeyT key, ValueT value) {
void Insert(const KeyT key, ValueT value)
{
itemsInCache.push_front(CacheEntry(key, value));
positionMap.insert(std::make_pair(key, itemsInCache.begin()));
if(itemsInCache.size() > capacity) {
if (itemsInCache.size() > capacity)
{
positionMap.erase(itemsInCache.back().key);
itemsInCache.pop_back();
}
}
bool Fetch(const KeyT key, ValueT& result) {
if(Holds(key)) {
bool Fetch(const KeyT key, ValueT &result)
{
if (Holds(key))
{
CacheEntry e = *(positionMap.find(key)->second);
result = e.value;
//move to front
// move to front
itemsInCache.splice(positionMap.find(key)->second, itemsInCache, itemsInCache.begin());
positionMap.find(key)->second = itemsInCache.begin();
return true;
}
return false;
}
unsigned Size() const {
return itemsInCache.size();
}
unsigned Size() const { return itemsInCache.size(); }
};
#endif //LRUCACHE_H
#endif // LRUCACHE_H
-594
View File
@@ -1,594 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef NNGRID_H_
#define NNGRID_H_
#include <algorithm>
#include <cassert>
#include <cfloat>
#include <cmath>
#include <fstream>
#include <limits>
#include <vector>
#ifndef ROUTED
#include <stxxl.h>
#endif
#ifdef _WIN32
#include <math.h>
#endif
#include <boost/thread.hpp>
#include <boost/foreach.hpp>
#include <boost/unordered_map.hpp>
#include "DeallocatingVector.h"
//#include "ExtractorStructs.h"
#include "GridEdge.h"
#include "Percent.h"
#include "PhantomNodes.h"
#include "Util.h"
#include "StaticGraph.h"
#include "../Algorithms/Bresenham.h"
namespace NNGrid{
static boost::thread_specific_ptr<std::ifstream> localStream;
template<bool WriteAccess = false>
class NNGrid {
public:
NNGrid() /*: cellCache(500), fileCache(500)*/ {
ramIndexTable.resize((1024*1024), ULONG_MAX);
}
NNGrid(const char* rif, const char* _i) {
if(WriteAccess) {
ERR("Not available in Write mode");
}
iif = std::string(_i);
ramIndexTable.resize((1024*1024), ULONG_MAX);
ramInFile.open(rif, std::ios::in | std::ios::binary);
if(!ramInFile) { ERR(rif << " not found"); }
}
~NNGrid() {
if(ramInFile.is_open()) ramInFile.close();
#ifndef ROUTED
if (WriteAccess) {
entries.clear();
}
#endif
if(localStream.get() && localStream->is_open()) {
localStream->close();
}
}
void OpenIndexFiles() {
assert(ramInFile.is_open());
ramInFile.read(static_cast<char*>(static_cast<void*>(&ramIndexTable[0]) ), sizeof(unsigned long)*1024*1024);
ramInFile.close();
}
#ifndef ROUTED
template<typename EdgeT>
inline void ConstructGrid(DeallocatingVector<EdgeT> & edgeList, char * ramIndexOut, char * fileIndexOut) {
//TODO: Implement this using STXXL-Streams
Percent p(edgeList.size());
BOOST_FOREACH(EdgeT & edge, edgeList) {
p.printIncrement();
if(edge.ignoreInGrid)
continue;
int slat = 100000*lat2y(edge.lat1/100000.);
int slon = edge.lon1;
int tlat = 100000*lat2y(edge.lat2/100000.);
int tlon = edge.lon2;
AddEdge( _GridEdge( edge.id, edge.nameID, edge.weight, _Coordinate(slat, slon), _Coordinate(tlat, tlon), edge.belongsToTinyComponent ) );
}
double timestamp = get_timestamp();
//create index file on disk, old one is over written
indexOutFile.open(fileIndexOut, std::ios::out | std::ios::binary | std::ios::trunc);
//sort entries
stxxl::sort(entries.begin(), entries.end(), CompareGridEdgeDataByRamIndex(), 1024*1024*1024);
INFO("finished sorting after " << (get_timestamp() - timestamp) << "s");
std::vector<GridEntry> entriesInFileWithRAMSameIndex;
unsigned indexInRamTable = entries.begin()->ramIndex;
unsigned long lastPositionInIndexFile = 0;
cout << "writing data ..." << flush;
p.reinit(entries.size());
boost::unordered_map< unsigned, unsigned > cellMap(1024);
BOOST_FOREACH(GridEntry & gridEntry, entries) {
p.printIncrement();
if(gridEntry.ramIndex != indexInRamTable) {
cellMap.clear();
BuildCellIndexToFileIndexMap(indexInRamTable, cellMap);
unsigned numberOfBytesInCell = FillCell(entriesInFileWithRAMSameIndex, lastPositionInIndexFile, cellMap);
ramIndexTable[indexInRamTable] = lastPositionInIndexFile;
lastPositionInIndexFile += numberOfBytesInCell;
entriesInFileWithRAMSameIndex.clear();
indexInRamTable = gridEntry.ramIndex;
}
entriesInFileWithRAMSameIndex.push_back(gridEntry);
}
cellMap.clear();
BuildCellIndexToFileIndexMap(indexInRamTable, cellMap);
/*unsigned numberOfBytesInCell = */FillCell(entriesInFileWithRAMSameIndex, lastPositionInIndexFile, cellMap);
ramIndexTable[indexInRamTable] = lastPositionInIndexFile;
entriesInFileWithRAMSameIndex.clear();
std::vector<GridEntry>().swap(entriesInFileWithRAMSameIndex);
assert(entriesInFileWithRAMSameIndex.size() == 0);
//close index file
indexOutFile.close();
//Serialize RAM Index
ofstream ramFile(ramIndexOut, std::ios::out | std::ios::binary | std::ios::trunc);
//write 4 MB of index Table in RAM
ramFile.write((char *)&ramIndexTable[0], sizeof(unsigned long)*1024*1024 );
//close ram index file
ramFile.close();
}
#endif
inline bool CoordinatesAreEquivalent(const _Coordinate & a, const _Coordinate & b, const _Coordinate & c, const _Coordinate & d) const {
return (a == b && c == d) || (a == c && b == d) || (a == d && b == c);
}
bool FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode, const unsigned zoomLevel) {
bool ignoreTinyComponents = (zoomLevel <= 14);
// INFO("Coordinate: " << location << ", zoomLevel: " << zoomLevel << ", ignoring tinyComponentents: " << (ignoreTinyComponents ? "yes" : "no"));
// double time1 = get_timestamp();
bool foundNode = false;
const _Coordinate startCoord(100000*(lat2y(static_cast<double>(location.lat)/100000.)), location.lon);
/** search for point on edge close to source */
const unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.lon);
std::vector<_GridEdge> candidates;
const int lowerBoundForLoop = (fileIndex < 32768 ? 0 : -32768);
for(int j = lowerBoundForLoop; (j < (32768+1)) && (fileIndex != UINT_MAX); j+=32768) {
for(int i = -1; i < 2; ++i){
// unsigned oldSize = candidates.size();
GetContentsOfFileBucketEnumerated(fileIndex+i+j, candidates);
// INFO("Getting fileIndex=" << fileIndex+i+j << " with " << candidates.size() - oldSize << " candidates");
}
}
// INFO("looked up " << candidates.size());
_GridEdge smallestEdge;
_Coordinate tmp, edgeStartCoord, edgeEndCoord;
double dist = numeric_limits<double>::max();
double r, tmpDist;
BOOST_FOREACH(_GridEdge candidate, candidates) {
if(candidate.belongsToTinyComponent && ignoreTinyComponents)
continue;
r = 0.;
tmpDist = ComputeDistance(startCoord, candidate.startCoord, candidate.targetCoord, tmp, &r);
// INFO("dist " << startCoord << "->[" << candidate.startCoord << "-" << candidate.targetCoord << "]=" << tmpDist );
// INFO("Looking at edge " << candidate.edgeBasedNode << " at distance " << tmpDist);
if(tmpDist < dist && !DoubleEpsilonCompare(dist, tmpDist)) {
// INFO("a) " << candidate.edgeBasedNode << ", dist: " << tmpDist << ", tinyCC: " << (candidate.belongsToTinyComponent ? "yes" : "no"));
dist = tmpDist;
resultNode.edgeBasedNode = candidate.edgeBasedNode;
resultNode.nodeBasedEdgeNameID = candidate.nameID;
resultNode.weight1 = candidate.weight;
resultNode.weight2 = INT_MAX;
resultNode.location.lat = tmp.lat;
resultNode.location.lon = tmp.lon;
edgeStartCoord = candidate.startCoord;
edgeEndCoord = candidate.targetCoord;
foundNode = true;
smallestEdge = candidate;
//} else if(tmpDist < dist) {
//INFO("a) ignored " << candidate.edgeBasedNode << " at distance " << std::fabs(dist - tmpDist));
} else if(DoubleEpsilonCompare(dist, tmpDist) && 1 == std::abs(static_cast<int>(candidate.edgeBasedNode)-static_cast<int>(resultNode.edgeBasedNode) ) && CoordinatesAreEquivalent(edgeStartCoord, candidate.startCoord, edgeEndCoord, candidate.targetCoord)) {
resultNode.edgeBasedNode = std::min(candidate.edgeBasedNode, resultNode.edgeBasedNode);
resultNode.weight2 = candidate.weight;
//INFO("b) " << candidate.edgeBasedNode << ", dist: " << tmpDist);
}
}
// INFO("startcoord: " << smallestEdge.startCoord << ", tgtcoord" << smallestEdge.targetCoord << "result: " << newEndpoint);
// INFO("length of old edge: " << ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord));
// INFO("Length of new edge: " << ApproximateDistance(smallestEdge.startCoord, newEndpoint));
// assert(!resultNode.isBidirected() || (resultNode.weight1 == resultNode.weight2));
// if(resultNode.weight1 != resultNode.weight2) {
// INFO("-> Weight1: " << resultNode.weight1 << ", weight2: " << resultNode.weight2);
// INFO("-> node: " << resultNode.edgeBasedNode << ", bidir: " << (resultNode.isBidirected() ? "yes" : "no"));
// }
// INFO("startCoord: " << smallestEdge.startCoord << "; targetCoord: " << smallestEdge.targetCoord << "; newEndpoint: " << resultNode.location);
double ratio = (foundNode ? std::min(1., ApproximateDistance(smallestEdge.startCoord, resultNode.location)/ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord)) : 0);
resultNode.location.lat = round(100000.*(y2lat(static_cast<double>(resultNode.location.lat)/100000.)));
// INFO("Length of vector: " << ApproximateDistance(smallestEdge.startCoord, resultNode.location)/ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord));
//Hack to fix rounding errors and wandering via nodes.
if(std::abs(location.lon - resultNode.location.lon) == 1)
resultNode.location.lon = location.lon;
if(std::abs(location.lat - resultNode.location.lat) == 1)
resultNode.location.lat = location.lat;
resultNode.weight1 *= ratio;
if(INT_MAX != resultNode.weight2) {
resultNode.weight2 -= resultNode.weight1;
}
resultNode.ratio = ratio;
// INFO("New weight1: " << resultNode.weight1 << ", new weight2: " << resultNode.weight2 << ", ratio: " << ratio);
// INFO("start: " << edgeStartCoord << ", end: " << edgeEndCoord);
// INFO("selected node: " << resultNode.edgeBasedNode << ", bidirected: " << (resultNode.isBidirected() ? "yes" : "no") << "\n--");
// double time2 = get_timestamp();
// INFO("NN-Lookup in " << 1000*(time2-time1) << "ms");
return foundNode;
}
bool FindRoutingStarts(const _Coordinate& start, const _Coordinate& target, PhantomNodes & routingStarts, unsigned zoomLevel) {
routingStarts.Reset();
return (FindPhantomNodeForCoordinate( start, routingStarts.startPhantom, zoomLevel) &&
FindPhantomNodeForCoordinate( target, routingStarts.targetPhantom, zoomLevel) );
}
bool FindNearestCoordinateOnEdgeInNodeBasedGraph(const _Coordinate& inputCoordinate, _Coordinate& outputCoordinate, unsigned zoomLevel = 18) {
PhantomNode resultNode;
bool foundNode = FindPhantomNodeForCoordinate(inputCoordinate, resultNode, zoomLevel);
outputCoordinate = resultNode.location;
return foundNode;
}
void FindNearestPointOnEdge(const _Coordinate& inputCoordinate, _Coordinate& outputCoordinate) {
_Coordinate startCoord(100000*(lat2y(static_cast<double>(inputCoordinate.lat)/100000.)), inputCoordinate.lon);
unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.lon);
std::vector<_GridEdge> candidates;
boost::unordered_map< unsigned, unsigned > cellMap;
for(int j = -32768; j < (32768+1); j+=32768) {
for(int i = -1; i < 2; ++i) {
GetContentsOfFileBucket(fileIndex+i+j, candidates, cellMap);
}
}
_Coordinate tmp;
double dist = (std::numeric_limits<double>::max)();
BOOST_FOREACH(_GridEdge candidate, candidates) {
double r = 0.;
double tmpDist = ComputeDistance(startCoord, candidate.startCoord, candidate.targetCoord, tmp, &r);
if(tmpDist < dist) {
dist = tmpDist;
outputCoordinate.lat = round(100000*(y2lat(static_cast<double>(tmp.lat)/100000.)));
outputCoordinate.lon = tmp.lon;
}
}
}
private:
inline unsigned GetCellIndexFromRAMAndFileIndex(const unsigned ramIndex, const unsigned fileIndex) const {
unsigned lineBase = ramIndex/1024;
lineBase = lineBase*32*32768;
unsigned columnBase = ramIndex%1024;
columnBase=columnBase*32;
for (int i = 0;i < 32;++i) {
for (int j = 0;j < 32;++j) {
const unsigned localFileIndex = lineBase + i * 32768 + columnBase + j;
if(localFileIndex == fileIndex) {
unsigned cellIndex = i * 32 + j;
return cellIndex;
}
}
}
return UINT_MAX;
}
inline void BuildCellIndexToFileIndexMap(const unsigned ramIndex, boost::unordered_map<unsigned, unsigned >& cellMap){
unsigned lineBase = ramIndex/1024;
lineBase = lineBase*32*32768;
unsigned columnBase = ramIndex%1024;
columnBase=columnBase*32;
std::vector<std::pair<unsigned, unsigned> >insertionVector(1024);
for (int i = 0;i < 32;++i) {
for (int j = 0;j < 32;++j) {
unsigned fileIndex = lineBase + i * 32768 + columnBase + j;
unsigned cellIndex = i * 32 + j;
insertionVector[i * 32 + j] = std::make_pair(fileIndex, cellIndex);
}
}
cellMap.insert(insertionVector.begin(), insertionVector.end());
}
inline bool DoubleEpsilonCompare(const double d1, const double d2) {
return (std::fabs(d1 - d2) < FLT_EPSILON);
}
inline unsigned FillCell(std::vector<GridEntry>& entriesWithSameRAMIndex, const unsigned long fileOffset, boost::unordered_map< unsigned, unsigned > & cellMap ) {
std::vector<char> tmpBuffer(32*32*4096,0);
unsigned long indexIntoTmpBuffer = 0;
unsigned numberOfWrittenBytes = 0;
assert(indexOutFile.is_open());
std::vector<unsigned long> cellIndex(32*32,ULONG_MAX);
for(unsigned i = 0; i < entriesWithSameRAMIndex.size() -1; ++i) {
assert(entriesWithSameRAMIndex[i].ramIndex== entriesWithSameRAMIndex[i+1].ramIndex);
}
//sort & unique
std::sort(entriesWithSameRAMIndex.begin(), entriesWithSameRAMIndex.end(), CompareGridEdgeDataByFileIndex());
// entriesWithSameRAMIndex.erase(std::unique(entriesWithSameRAMIndex.begin(), entriesWithSameRAMIndex.end()), entriesWithSameRAMIndex.end());
//traverse each file bucket and write its contents to disk
std::vector<GridEntry> entriesWithSameFileIndex;
unsigned fileIndex = entriesWithSameRAMIndex.begin()->fileIndex;
BOOST_FOREACH(GridEntry & gridEntry, entriesWithSameRAMIndex) {
assert(cellMap.find(gridEntry.fileIndex) != cellMap.end() ); //asserting that file index belongs to cell index
if(gridEntry.fileIndex != fileIndex) {
// start in cellIndex vermerken
int localFileIndex = entriesWithSameFileIndex.begin()->fileIndex;
int localCellIndex = cellMap.find(localFileIndex)->second;
assert(cellMap.find(entriesWithSameFileIndex.begin()->fileIndex) != cellMap.end());
cellIndex[localCellIndex] = indexIntoTmpBuffer + fileOffset;
indexIntoTmpBuffer += FlushEntriesWithSameFileIndexToBuffer(entriesWithSameFileIndex, tmpBuffer, indexIntoTmpBuffer);
fileIndex = gridEntry.fileIndex;
}
entriesWithSameFileIndex.push_back(gridEntry);
}
assert(cellMap.find(entriesWithSameFileIndex.begin()->fileIndex) != cellMap.end());
int localFileIndex = entriesWithSameFileIndex.begin()->fileIndex;
int localCellIndex = cellMap.find(localFileIndex)->second;
cellIndex[localCellIndex] = indexIntoTmpBuffer + fileOffset;
indexIntoTmpBuffer += FlushEntriesWithSameFileIndexToBuffer(entriesWithSameFileIndex, tmpBuffer, indexIntoTmpBuffer);
assert(entriesWithSameFileIndex.size() == 0);
indexOutFile.write(static_cast<char*>(static_cast<void*>(&cellIndex[0])),32*32*sizeof(unsigned long));
numberOfWrittenBytes += 32*32*sizeof(unsigned long);
//write contents of tmpbuffer to disk
indexOutFile.write(&tmpBuffer[0], indexIntoTmpBuffer*sizeof(char));
numberOfWrittenBytes += indexIntoTmpBuffer*sizeof(char);
return numberOfWrittenBytes;
}
inline unsigned FlushEntriesWithSameFileIndexToBuffer( std::vector<GridEntry> &vectorWithSameFileIndex, std::vector<char> & tmpBuffer, const unsigned long index) const {
sort( vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end() );
vectorWithSameFileIndex.erase(unique(vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end()), vectorWithSameFileIndex.end());
const unsigned lengthOfBucket = vectorWithSameFileIndex.size();
tmpBuffer.resize(tmpBuffer.size()+(sizeof(_GridEdge)*lengthOfBucket) + sizeof(unsigned) );
unsigned counter = 0;
for(unsigned i = 0; i < vectorWithSameFileIndex.size()-1; ++i) {
assert( vectorWithSameFileIndex[i].fileIndex == vectorWithSameFileIndex[i+1].fileIndex );
assert( vectorWithSameFileIndex[i].ramIndex == vectorWithSameFileIndex[i+1].ramIndex );
}
//write length of bucket
memcpy((char*)&(tmpBuffer[index+counter]), (char*)&lengthOfBucket, sizeof(lengthOfBucket));
counter += sizeof(lengthOfBucket);
BOOST_FOREACH(const GridEntry & entry, vectorWithSameFileIndex) {
char * data = (char*)&(entry.edge);
memcpy(static_cast<char*>(static_cast<void*>(&(tmpBuffer[index+counter]) )), data, sizeof(entry.edge));
counter += sizeof(entry.edge);
}
//Freeing data
vectorWithSameFileIndex.clear();
return counter;
}
inline void GetContentsOfFileBucketEnumerated(const unsigned fileIndex, std::vector<_GridEdge>& result) const {
unsigned ramIndex = GetRAMIndexFromFileIndex(fileIndex);
unsigned long startIndexInFile = ramIndexTable[ramIndex];
if(startIndexInFile == ULONG_MAX) {
return;
}
unsigned enumeratedIndex = GetCellIndexFromRAMAndFileIndex(ramIndex, fileIndex);
if(!localStream.get() || !localStream->is_open()) {
localStream.reset(new std::ifstream(iif.c_str(), std::ios::in | std::ios::binary));
}
if(!localStream->good()) {
localStream->clear(std::ios::goodbit);
DEBUG("Resetting stale filestream");
}
//only read the single necessary cell index
localStream->seekg(startIndexInFile+(enumeratedIndex*sizeof(unsigned long)));
unsigned long fetchedIndex = 0;
localStream->read(static_cast<char*>( static_cast<void*>(&fetchedIndex)), sizeof(unsigned long));
if(fetchedIndex == ULONG_MAX) {
return;
}
const unsigned long position = fetchedIndex + 32*32*sizeof(unsigned long) ;
unsigned lengthOfBucket;
unsigned currentSizeOfResult = result.size();
localStream->seekg(position);
localStream->read(static_cast<char*>( static_cast<void*>(&(lengthOfBucket))), sizeof(unsigned));
result.resize(currentSizeOfResult+lengthOfBucket);
localStream->read(static_cast<char*>( static_cast<void*>(&result[currentSizeOfResult])), lengthOfBucket*sizeof(_GridEdge));
}
inline void GetContentsOfFileBucket(const unsigned fileIndex, std::vector<_GridEdge>& result, boost::unordered_map< unsigned, unsigned> & cellMap) {
unsigned ramIndex = GetRAMIndexFromFileIndex(fileIndex);
unsigned long startIndexInFile = ramIndexTable[ramIndex];
if(startIndexInFile == ULONG_MAX) {
return;
}
unsigned long cellIndex[32*32];
cellMap.clear();
BuildCellIndexToFileIndexMap(ramIndex, cellMap);
if(!localStream.get() || !localStream->is_open()) {
localStream.reset(new std::ifstream(iif.c_str(), std::ios::in | std::ios::binary));
}
if(!localStream->good()) {
localStream->clear(std::ios::goodbit);
DEBUG("Resetting stale filestream");
}
localStream->seekg(startIndexInFile);
localStream->read(static_cast<char*>(static_cast<void*>( cellIndex)), 32*32*sizeof(unsigned long));
assert(cellMap.find(fileIndex) != cellMap.end());
if(cellIndex[cellMap[fileIndex]] == ULONG_MAX) {
return;
}
const unsigned long position = cellIndex[cellMap[fileIndex]] + 32*32*sizeof(unsigned long) ;
unsigned lengthOfBucket;
unsigned currentSizeOfResult = result.size();
localStream->seekg(position);
localStream->read(static_cast<char*>(static_cast<void*>(&(lengthOfBucket))), sizeof(unsigned));
result.resize(currentSizeOfResult+lengthOfBucket);
localStream->read(static_cast<char*>(static_cast<void*>(&result[currentSizeOfResult])), lengthOfBucket*sizeof(_GridEdge));
}
#ifndef ROUTED
inline void AddEdge(const _GridEdge & edge) {
std::vector<BresenhamPixel> indexList;
GetListOfIndexesForEdgeAndGridSize(edge.startCoord, edge.targetCoord, indexList);
for(unsigned i = 0; i < indexList.size(); ++i) {
entries.push_back(GridEntry(edge, indexList[i].first, indexList[i].second));
}
}
#endif
inline double ComputeDistance(const _Coordinate& inputPoint, const _Coordinate& source, const _Coordinate& target, _Coordinate& nearest, double *r) {
// INFO("comparing point " << inputPoint << " to edge [" << source << "-" << target << "]");
const double x = static_cast<double>(inputPoint.lat);
const double y = static_cast<double>(inputPoint.lon);
const double a = static_cast<double>(source.lat);
const double b = static_cast<double>(source.lon);
const double c = static_cast<double>(target.lat);
const double d = static_cast<double>(target.lon);
double p,q,mX,nY;
// INFO("x=" << x << ", y=" << y << ", a=" << a << ", b=" << b << ", c=" << c << ", d=" << d);
if(fabs(a-c) > FLT_EPSILON){
const double m = (d-b)/(c-a); // slope
// Projection of (x,y) on line joining (a,b) and (c,d)
p = ((x + (m*y)) + (m*m*a - m*b))/(1. + m*m);
q = b + m*(p - a);
}
else{
p = c;
q = y;
}
nY = (d*p - c*q)/(a*d - b*c);
mX = (p - nY*a)/c;// These values are actually n/m+n and m/m+n , we neednot calculate the values of m an n as we are just interested in the ratio
// INFO("p=" << p << ", q=" << q << ", nY=" << nY << ", mX=" << mX);
if(std::isnan(mX)) {
*r = (target == inputPoint) ? 1. : 0.;
} else {
*r = mX;
}
// INFO("r=" << *r);
if(*r<=0.){
nearest.lat = source.lat;
nearest.lon = source.lon;
// INFO("a returning distance " << ((b - y)*(b - y) + (a - x)*(a - x)))
return ((b - y)*(b - y) + (a - x)*(a - x));
}
else if(*r >= 1.){
nearest.lat = target.lat;
nearest.lon = target.lon;
// INFO("b returning distance " << ((d - y)*(d - y) + (c - x)*(c - x)))
return ((d - y)*(d - y) + (c - x)*(c - x));
}
// point lies in between
nearest.lat = p;
nearest.lon = q;
// INFO("c returning distance " << (p-x)*(p-x) + (q-y)*(q-y))
return (p-x)*(p-x) + (q-y)*(q-y);
}
inline void GetListOfIndexesForEdgeAndGridSize(const _Coordinate& start, const _Coordinate& target, std::vector<BresenhamPixel> &indexList) const {
double lat1 = start.lat/100000.;
double lon1 = start.lon/100000.;
double x1 = ( lon1 + 180.0 ) / 360.0;
double y1 = ( lat1 + 180.0 ) / 360.0;
double lat2 = target.lat/100000.;
double lon2 = target.lon/100000.;
double x2 = ( lon2 + 180.0 ) / 360.0;
double y2 = ( lat2 + 180.0 ) / 360.0;
Bresenham(x1*32768, y1*32768, x2*32768, y2*32768, indexList);
BOOST_FOREACH(BresenhamPixel & pixel, indexList) {
int fileIndex = (pixel.second-1)*32768 + pixel.first;
int ramIndex = GetRAMIndexFromFileIndex(fileIndex);
pixel.first = fileIndex;
pixel.second = ramIndex;
}
}
inline unsigned GetFileIndexForLatLon(const int lt, const int ln) {
double lat = lt/100000.;
double lon = ln/100000.;
double x = ( lon + 180.0 ) / 360.0;
double y = ( lat + 180.0 ) / 360.0;
if( x>1.0 || x < 0.)
return UINT_MAX;
if( y>1.0 || y < 0.)
return UINT_MAX;
unsigned line = (32768 * (32768-1))*y;
line = line - (line % 32768);
assert(line % 32768 == 0);
unsigned column = 32768.*x;
unsigned fileIndex = line+column;
return fileIndex;
}
inline unsigned GetRAMIndexFromFileIndex(const int fileIndex) const {
unsigned fileLine = fileIndex / 32768;
fileLine = fileLine / 32;
fileLine = fileLine * 1024;
unsigned fileColumn = (fileIndex % 32768);
fileColumn = fileColumn / 32;
unsigned ramIndex = fileLine + fileColumn;
assert(ramIndex < 1024*1024);
return ramIndex;
}
const static unsigned long END_OF_BUCKET_DELIMITER = UINT_MAX;
std::ofstream indexOutFile;
std::ifstream ramInFile;
#ifndef ROUTED
stxxl::vector<GridEntry> entries;
#endif
std::vector<unsigned long> ramIndexTable; //8 MB for first level index in RAM
std::string iif;
// LRUCache<int,std::vector<unsigned> > cellCache;
// LRUCache<int,std::vector<_Edge> > fileCache;
};
}
typedef NNGrid::NNGrid<false> ReadOnlyGrid;
typedef NNGrid::NNGrid<true > WritableGrid;
#endif /* NNGRID_H_ */
+166
View File
@@ -0,0 +1,166 @@
#ifndef __NODE_BASED_GRAPH_H__
#define __NODE_BASED_GRAPH_H__
#include "DynamicGraph.h"
#include "ImportEdge.h"
#include "../Util/SimpleLogger.h"
#include <tbb/parallel_sort.h>
#include <memory>
struct NodeBasedEdgeData
{
NodeBasedEdgeData()
: distance(INVALID_EDGE_WEIGHT), edgeBasedNodeID(SPECIAL_NODEID),
nameID(std::numeric_limits<unsigned>::max()), type(std::numeric_limits<short>::max()),
isAccessRestricted(false), shortcut(false), forward(false), backward(false),
roundabout(false), ignore_in_grid(false), contraFlow(false)
{
}
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;
void SwapDirectionFlags()
{
bool temp_flag = forward;
forward = backward;
backward = temp_flag;
}
bool IsEqualTo(const NodeBasedEdgeData &other) const
{
return (forward == other.forward) && (backward == other.backward) &&
(nameID == other.nameID) && (ignore_in_grid == other.ignore_in_grid) &&
(contraFlow == other.contraFlow);
}
};
typedef DynamicGraph<NodeBasedEdgeData> NodeBasedDynamicGraph;
// 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;
for (const ImportEdge &import_edge : input_edge_list)
{
if (import_edge.forward)
{
edge.source = import_edge.source;
edge.target = import_edge.target;
edge.data.forward = import_edge.forward;
edge.data.backward = import_edge.backward;
}
else
{
edge.source = import_edge.target;
edge.target = import_edge.source;
edge.data.backward = import_edge.forward;
edge.data.forward = import_edge.backward;
}
if (edge.source == edge.target)
{
continue;
}
edge.data.distance = (std::max)((int)import_edge.weight, 1);
BOOST_ASSERT(edge.data.distance > 0);
edge.data.shortcut = false;
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;
edges_list.push_back(edge);
if (!import_edge.is_split)
{
using std::swap; // enable ADL
swap(edge.source, edge.target);
edge.data.SwapDirectionFlags();
edges_list.push_back(edge);
}
}
// remove duplicate edges
std::sort(edges_list.begin(), edges_list.end());
NodeID edge_count = 0;
for (NodeID i = 0; i < edges_list.size(); )
{
const NodeID source = edges_list[i].source;
const NodeID target = edges_list[i].target;
// remove eigenloops
if (source == target)
{
i++;
continue;
}
NodeBasedDynamicGraph::InputEdge forward_edge;
NodeBasedDynamicGraph::InputEdge reverse_edge;
forward_edge = reverse_edge = edges_list[i];
forward_edge.data.forward = reverse_edge.data.backward = true;
forward_edge.data.backward = reverse_edge.data.forward = false;
forward_edge.data.shortcut = reverse_edge.data.shortcut = false;
forward_edge.data.distance = reverse_edge.data.distance =
std::numeric_limits<int>::max();
// remove parallel edges
while (i < edges_list.size() && edges_list[i].source == source && edges_list[i].target == target)
{
if (edges_list[i].data.forward)
{
forward_edge.data.distance =
std::min(edges_list[i].data.distance, forward_edge.data.distance);
}
if (edges_list[i].data.backward)
{
reverse_edge.data.distance =
std::min(edges_list[i].data.distance, reverse_edge.data.distance);
}
++i;
}
// merge edges (s,t) and (t,s) into bidirectional edge
if (forward_edge.data.distance == reverse_edge.data.distance)
{
if ((int)forward_edge.data.distance != std::numeric_limits<int>::max())
{
forward_edge.data.backward = true;
edges_list[edge_count++] = forward_edge;
}
}
else
{ // insert seperate edges
if (((int)forward_edge.data.distance) != std::numeric_limits<int>::max())
{
edges_list[edge_count++] = forward_edge;
}
if ((int)reverse_edge.data.distance != std::numeric_limits<int>::max())
{
edges_list[edge_count++] = reverse_edge;
}
}
}
edges_list.resize(edge_count);
SimpleLogger().Write() << "merged " << edges_list.size() - edge_count << " edges out of " << edges_list.size();
auto graph = std::make_shared<NodeBasedDynamicGraph>(number_of_nodes, edges_list);
return graph;
}
#endif // __NODE_BASED_GRAPH_H__
-69
View File
@@ -1,69 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef _NODE_COORDS_H
#define _NODE_COORDS_H
#include <cassert>
#include <cstddef>
#include <climits>
#include <limits>
#include "../typedefs.h"
template<typename NodeT>
struct NodeCoords {
typedef unsigned key_type; //type of NodeID
typedef int value_type; //type of lat,lons
NodeCoords(int _lat, int _lon, NodeT _id) : lat(_lat), lon(_lon), id(_id) {}
NodeCoords() : lat(INT_MAX), lon(INT_MAX), id(UINT_MAX) {}
int lat;
int lon;
NodeT id;
static NodeCoords<NodeT> min_value() {
return NodeCoords<NodeT>(-90*100000,-180*100000,std::numeric_limits<NodeT>::min());
}
static NodeCoords<NodeT> max_value() {
return NodeCoords<NodeT>(90*100000, 180*100000, std::numeric_limits<NodeT>::max());
}
value_type operator[](std::size_t n) const {
switch(n) {
case 1:
return lat;
break;
case 0:
return lon;
break;
default:
assert(false);
return UINT_MAX;
break;
}
assert(false);
return UINT_MAX;
}
};
typedef NodeCoords<NodeID> NodeInfo;
#endif //_NODE_COORDS_H
-124
View File
@@ -1,124 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef NODEINFORMATIONHELPDESK_H_
#define NODEINFORMATIONHELPDESK_H_
#include <fstream>
#include <iostream>
#include <vector>
#include "../typedefs.h"
#include "../DataStructures/QueryEdge.h"
#include "NNGrid.h"
#include "PhantomNodes.h"
#include "NodeCoords.h"
class NodeInformationHelpDesk{
public:
NodeInformationHelpDesk(const char* ramIndexInput, const char* fileIndexInput, const unsigned _numberOfNodes, const unsigned crc) : numberOfNodes(_numberOfNodes), checkSum(crc) {
readOnlyGrid = new ReadOnlyGrid(ramIndexInput,fileIndexInput);
assert(0 == coordinateVector.size());
}
//Todo: Shared memory mechanism
// NodeInformationHelpDesk(const char* ramIndexInput, const char* fileIndexInput, const unsigned crc) : checkSum(crc) {
// readOnlyGrid = new ReadOnlyGrid(ramIndexInput,fileIndexInput);
// }
~NodeInformationHelpDesk() {
delete readOnlyGrid;
}
void initNNGrid(std::ifstream& nodesInstream, std::ifstream& edgesInStream) {
DEBUG("Loading node data");
NodeInfo b;
while(!nodesInstream.eof()) {
nodesInstream.read((char *)&b, sizeof(NodeInfo));
coordinateVector.push_back(_Coordinate(b.lat, b.lon));
}
std::vector<_Coordinate>(coordinateVector).swap(coordinateVector);
nodesInstream.close();
DEBUG("Loading edge data");
unsigned numberOfOrigEdges(0);
edgesInStream.read((char*)&numberOfOrigEdges, sizeof(unsigned));
origEdgeData.resize(numberOfOrigEdges);
edgesInStream.read((char*)&(origEdgeData[0]), numberOfOrigEdges*sizeof(OriginalEdgeData));
edgesInStream.close();
DEBUG("Loaded " << numberOfOrigEdges << " orig edges");
DEBUG("Opening NN indices");
readOnlyGrid->OpenIndexFiles();
}
void initNNGrid() {
readOnlyGrid->OpenIndexFiles();
}
inline int getLatitudeOfNode(const unsigned id) const {
const NodeID node = origEdgeData.at(id).viaNode;
return coordinateVector.at(node).lat;
}
inline int getLongitudeOfNode(const unsigned id) const {
const NodeID node = origEdgeData.at(id).viaNode;
return coordinateVector.at(node).lon;
}
inline unsigned getNameIndexFromEdgeID(const unsigned id) const {
return origEdgeData.at(id).nameID;
}
inline TurnInstruction getTurnInstructionFromEdgeID(const unsigned id) const {
return origEdgeData.at(id).turnInstruction;
}
inline NodeID getNumberOfNodes() const { return numberOfNodes; }
inline NodeID getNumberOfNodes2() const { return coordinateVector.size(); }
inline bool FindNearestNodeCoordForLatLon(const _Coordinate& coord, _Coordinate& result) const {
return readOnlyGrid->FindNearestCoordinateOnEdgeInNodeBasedGraph(coord, result);
}
inline bool FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode, const unsigned zoomLevel) const {
return readOnlyGrid->FindPhantomNodeForCoordinate(location, resultNode, zoomLevel);
}
inline void FindRoutingStarts(const _Coordinate &start, const _Coordinate &target, PhantomNodes & phantomNodes, const unsigned zoomLevel) const {
readOnlyGrid->FindRoutingStarts(start, target, phantomNodes, zoomLevel);
}
inline void FindNearestPointOnEdge(const _Coordinate & input, _Coordinate& output){
readOnlyGrid->FindNearestPointOnEdge(input, output);
}
inline unsigned GetCheckSum() const {
return checkSum;
}
private:
std::vector<_Coordinate> coordinateVector;
std::vector<OriginalEdgeData> origEdgeData;
ReadOnlyGrid * readOnlyGrid;
const unsigned numberOfNodes;
const unsigned checkSum;
};
#endif /*NODEINFORMATIONHELPDESK_H_*/
+60
View File
@@ -0,0 +1,60 @@
/*
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 ORIGINAL_EDGE_DATA_H
#define ORIGINAL_EDGE_DATA_H
#include "TurnInstructions.h"
#include "../typedefs.h"
#include <limits>
struct OriginalEdgeData
{
explicit OriginalEdgeData(NodeID via_node,
unsigned name_id,
TurnInstruction turn_instruction,
bool compressed_geometry)
: via_node(via_node), name_id(name_id), turn_instruction(turn_instruction),
compressed_geometry(compressed_geometry)
{
}
OriginalEdgeData()
: via_node(std::numeric_limits<unsigned>::max()),
name_id(std::numeric_limits<unsigned>::max()),
turn_instruction(TurnInstruction::NoTurn), compressed_geometry(false)
{
}
NodeID via_node;
unsigned name_id;
TurnInstruction turn_instruction;
bool compressed_geometry;
};
#endif // ORIGINAL_EDGE_DATA_H
+68 -61
View File
@@ -1,89 +1,96 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 PERCENT_H
#define PERCENT_H
#include <iostream>
#include <atomic>
class Percent
{
public:
/**
* Constructor.
* @param maxValue the value that corresponds to 100%
* @param step the progress is shown in steps of 'step' percent
*/
Percent(unsigned maxValue, unsigned step = 5) {
reinit(maxValue, step);
public:
explicit Percent(unsigned max_value, unsigned step = 5) { reinit(max_value, step); }
// Reinitializes
void reinit(unsigned max_value, unsigned step = 5)
{
m_max_value = max_value;
m_current_value = 0;
m_percent_interval = m_max_value / 100;
m_next_threshold = m_percent_interval;
m_last_percent = 0;
m_step = step;
}
/** Reinitializes this object. */
void reinit(unsigned maxValue, unsigned step = 5) {
_maxValue = maxValue;
_current_value = 0;
_intervalPercent = _maxValue / 100;
_nextThreshold = _intervalPercent;
_lastPercent = 0;
_step = step;
}
/** If there has been significant progress, display it. */
void printStatus(unsigned currentValue) {
if (currentValue >= _nextThreshold) {
_nextThreshold += _intervalPercent;
printPercent( currentValue / (double)_maxValue * 100 );
// If there has been significant progress, display it.
void printStatus(unsigned current_value)
{
if (current_value >= m_next_threshold)
{
m_next_threshold += m_percent_interval;
printPercent(current_value / (double)m_max_value * 100);
}
if (currentValue + 1 == _maxValue)
if (current_value + 1 == m_max_value)
std::cout << " 100%" << std::endl;
}
void printIncrement()
{
#pragma omp atomic
++_current_value;
printStatus(_current_value);
++m_current_value;
printStatus(m_current_value);
}
void printAddition(const unsigned addition) {
#pragma omp atomic
_current_value += addition;
printStatus(_current_value);
void printAddition(const unsigned addition)
{
m_current_value += addition;
printStatus(m_current_value);
}
private:
unsigned _current_value;
unsigned _maxValue;
unsigned _intervalPercent;
unsigned _nextThreshold;
unsigned _lastPercent;
unsigned _step;
/** Displays the new progress. */
void printPercent(double percent) {
while (percent >= _lastPercent+_step) {
_lastPercent+=_step;
if (_lastPercent % 10 == 0) {
std::cout << " " << _lastPercent << "% ";
private:
std::atomic_uint m_current_value;
unsigned m_max_value;
unsigned m_percent_interval;
unsigned m_next_threshold;
unsigned m_last_percent;
unsigned m_step;
// Displays progress.
void printPercent(double percent)
{
while (percent >= m_last_percent + m_step)
{
m_last_percent += m_step;
if (m_last_percent % 10 == 0)
{
std::cout << " " << m_last_percent << "% ";
}
else {
else
{
std::cout << ".";
}
std::cout.flush();
+151 -72
View File
@@ -1,94 +1,173 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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.
#ifndef PHANTOMNODES_H_
#define PHANTOMNODES_H_
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Coordinate.h"
*/
struct PhantomNode {
PhantomNode() : edgeBasedNode(UINT_MAX), nodeBasedEdgeNameID(UINT_MAX), weight1(INT_MAX), weight2(INT_MAX), ratio(0.) {}
NodeID edgeBasedNode;
unsigned nodeBasedEdgeNameID;
int weight1;
int weight2;
double ratio;
_Coordinate location;
void Reset() {
edgeBasedNode = UINT_MAX;
nodeBasedEdgeNameID = UINT_MAX;
weight1 = INT_MAX;
weight2 = INT_MAX;
ratio = 0.;
location.Reset();
}
bool isBidirected() const {
return weight2 != INT_MAX;
}
bool isValid(const unsigned numberOfNodes) const {
return location.isValid() && (edgeBasedNode < numberOfNodes) && (weight1 != INT_MAX) && (ratio >= 0.) && (ratio <= 1.) && (nodeBasedEdgeNameID != UINT_MAX);
#ifndef PHANTOM_NODES_H
#define PHANTOM_NODES_H
#include <osrm/Coordinate.h>
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
#include <vector>
struct PhantomNode
{
PhantomNode(NodeID forward_node_id, NodeID reverse_node_id, unsigned name_id,
int forward_weight, int reverse_weight, int forward_offset, int reverse_offset,
unsigned packed_geometry_id, FixedPointCoordinate &location,
unsigned short fwd_segment_position) :
forward_node_id(forward_node_id),
reverse_node_id(reverse_node_id),
name_id(name_id),
forward_weight(forward_weight),
reverse_weight(reverse_weight),
forward_offset(forward_offset),
reverse_offset(reverse_offset),
packed_geometry_id(packed_geometry_id),
location(location),
fwd_segment_position(fwd_segment_position)
{ }
PhantomNode() :
forward_node_id(SPECIAL_NODEID),
reverse_node_id(SPECIAL_NODEID),
name_id(std::numeric_limits<unsigned>::max()),
forward_weight(INVALID_EDGE_WEIGHT),
reverse_weight(INVALID_EDGE_WEIGHT),
forward_offset(0),
reverse_offset(0),
packed_geometry_id(SPECIAL_EDGEID),
fwd_segment_position(0)
{ }
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;
int GetForwardWeightPlusOffset() const
{
if (SPECIAL_NODEID == forward_node_id)
{
return 0;
}
const int result = (forward_offset + forward_weight);
return result;
}
bool operator==(const PhantomNode & other) const {
int GetReverseWeightPlusOffset() const
{
if (SPECIAL_NODEID == reverse_node_id)
{
return 0;
}
const int result = (reverse_offset + reverse_weight);
return result;
}
bool isBidirected() const
{
return (forward_node_id != SPECIAL_NODEID) &&
(reverse_node_id != SPECIAL_NODEID);
}
bool IsCompressed() const
{
return (forward_offset != 0) || (reverse_offset != 0);
}
bool isValid(const unsigned numberOfNodes) const
{
return
location.isValid() &&
(
(forward_node_id < numberOfNodes) ||
(reverse_node_id < numberOfNodes)
) &&
(
(forward_weight != INVALID_EDGE_WEIGHT) ||
(reverse_weight != INVALID_EDGE_WEIGHT)
) &&
(name_id != std::numeric_limits<unsigned>::max()
);
}
bool isValid() const
{
return location.isValid() &&
(name_id != std::numeric_limits<unsigned>::max());
}
bool operator==(const PhantomNode & other) const
{
return location == other.location;
}
};
struct PhantomNodes {
PhantomNode startPhantom;
PhantomNode targetPhantom;
void Reset() {
startPhantom.Reset();
targetPhantom.Reset();
}
typedef std::vector<std::vector<PhantomNode>> PhantomNodeArray;
bool PhantomsAreOnSameNodeBasedEdge() const {
return (startPhantom.edgeBasedNode == targetPhantom.edgeBasedNode);
}
bool AtLeastOnePhantomNodeIsUINTMAX() const {
return !(startPhantom.edgeBasedNode == UINT_MAX || targetPhantom.edgeBasedNode == UINT_MAX);
}
bool PhantomNodesHaveEqualLocation() const {
return startPhantom == targetPhantom;
}
struct PhantomNodeLists
{
std::vector<PhantomNode> source_phantom_list;
std::vector<PhantomNode> target_phantom_list;
};
inline std::ostream& operator<<(std::ostream &out, const PhantomNodes & pn){
out << "Node1: " << pn.startPhantom.edgeBasedNode << std::endl;
out << "Node2: " << pn.targetPhantom.edgeBasedNode << std::endl;
out << "startCoord: " << pn.startPhantom.location << std::endl;
out << "targetCoord: " << pn.targetPhantom.location << std::endl;
struct PhantomNodes
{
PhantomNode source_phantom;
PhantomNode target_phantom;
};
inline std::ostream& operator<<(std::ostream &out, const PhantomNodes & pn)
{
out << "source_coord: " << pn.source_phantom.location << "\n";
out << "target_coord: " << pn.target_phantom.location << std::endl;
return out;
}
inline std::ostream& operator<<(std::ostream &out, const PhantomNode & pn){
out << "node: " << pn.edgeBasedNode << ", name: " << pn.nodeBasedEdgeNameID << ", w1: " << pn.weight1 << ", w2: " << pn.weight2 << ", ratio: " << pn.ratio << ", loc: " << pn.location;
inline std::ostream& operator<<(std::ostream &out, const PhantomNode & pn)
{
out << "node1: " << pn.forward_node_id << ", " <<
"node2: " << pn.reverse_node_id << ", " <<
"name: " << pn.name_id << ", " <<
"fwd-w: " << pn.forward_weight << ", " <<
"rev-w: " << pn.reverse_weight << ", " <<
"fwd-o: " << pn.forward_offset << ", " <<
"rev-o: " << pn.reverse_offset << ", " <<
"geom: " << pn.packed_geometry_id << ", " <<
"pos: " << pn.fwd_segment_position << ", " <<
"loc: " << pn.location;
return out;
}
struct NodesOfEdge {
NodeID edgeBasedNode;
double ratio;
_Coordinate projectedPoint;
};
#endif /* PHANTOMNODES_H_ */
#endif // PHANTOM_NODES_H
+41 -53
View File
@@ -1,75 +1,63 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 QUERYEDGE_H_
#define QUERYEDGE_H_
#include "TurnInstructions.h"
#include "../typedefs.h"
#include <climits>
struct OriginalEdgeData{
explicit OriginalEdgeData(NodeID v, unsigned n, TurnInstruction t) : viaNode(v), nameID(n), turnInstruction(t) {}
OriginalEdgeData() : viaNode(UINT_MAX), nameID(UINT_MAX), turnInstruction(UCHAR_MAX) {}
NodeID viaNode;
unsigned nameID;
TurnInstruction turnInstruction;
};
struct QueryEdge {
struct QueryEdge
{
NodeID source;
NodeID target;
struct EdgeData {
NodeID id:31;
int distance:30;
bool shortcut:1;
bool forward:1;
bool backward:1;
struct EdgeData
{
NodeID id : 31;
bool shortcut : 1;
int distance : 30;
bool forward : 1;
bool backward : 1;
} data;
bool operator<( const QueryEdge& right ) const {
if ( source != right.source )
bool operator<(const QueryEdge &right) const
{
if (source != right.source)
{
return source < right.source;
}
return target < right.target;
}
//sorts by source and other attributes
static bool CompareBySource( const QueryEdge& left, const QueryEdge& right ) {
if ( left.source != right.source )
return left.source < right.source;
int l = ( left.data.forward ? -1 : 0 ) + ( left.data.backward ? -1 : 0 );
int r = ( right.data.forward ? -1 : 0 ) + ( right.data.backward ? -1 : 0 );
if ( l != r )
return l < r;
if ( left.target != right.target )
return left.target < right.target;
return left.data.distance < right.data.distance;
}
bool operator== ( const QueryEdge& right ) const {
return ( source == right.source && target == right.target && data.distance == right.data.distance &&
data.shortcut == right.data.shortcut && data.forward == right.data.forward && data.backward == right.data.backward
&& data.id == right.data.id
);
bool operator==(const QueryEdge &right) const
{
return (source == right.source && target == right.target &&
data.distance == right.data.distance && data.shortcut == right.data.shortcut &&
data.forward == right.data.forward && data.backward == right.data.backward &&
data.id == right.data.id);
}
};
+85
View File
@@ -0,0 +1,85 @@
/*
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 QUERY_NODE_H
#define QUERY_NODE_H
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
#include <limits>
struct NodeInfo
{
typedef NodeID key_type; // type of NodeID
typedef int value_type; // type of lat,lons
explicit NodeInfo(int lat, int lon, NodeID node_id) : lat(lat), lon(lon), node_id(node_id) {}
NodeInfo()
: lat(std::numeric_limits<int>::max()), lon(std::numeric_limits<int>::max()),
node_id(std::numeric_limits<unsigned>::max())
{
}
int lat;
int lon;
NodeID node_id;
static NodeInfo min_value()
{
return NodeInfo(static_cast<int>(-90 * COORDINATE_PRECISION),
static_cast<int>(-180 * COORDINATE_PRECISION),
std::numeric_limits<NodeID>::min());
}
static NodeInfo max_value()
{
return NodeInfo(static_cast<int>(90 * COORDINATE_PRECISION),
static_cast<int>(180 * COORDINATE_PRECISION),
std::numeric_limits<NodeID>::max());
}
value_type operator[](const std::size_t n) const
{
switch (n)
{
case 1:
return lat;
case 0:
return lon;
default:
break;
}
BOOST_ASSERT_MSG(false, "should not happen");
return std::numeric_limits<unsigned>::max();
}
};
#endif // QUERY_NODE_H
+231
View File
@@ -0,0 +1,231 @@
#ifndef __RANGE_TABLE_H__
#define __RANGE_TABLE_H__
#include "SharedMemoryFactory.h"
#include "SharedMemoryVectorWrapper.h"
#include <boost/range/irange.hpp>
#include <fstream>
#include <vector>
#include <array>
/*
* These pre-declarations are needed because parsing C++ is hard
* and otherwise the compiler gets confused.
*/
template<unsigned BLOCK_SIZE=16, bool USE_SHARED_MEMORY = false> class RangeTable;
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::ostream& operator<<(std::ostream &out, const RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table);
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::istream& operator>>(std::istream &in, RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table);
/**
* Stores adjacent ranges in a compressed format.
*
* Maximum supported length of a range is 255.
*
* Note: BLOCK_SIZE is the number of differential encodoed values.
* But each block consists of an absolute value and BLOCK_SIZE differential values.
* So the effective block size is sizeof(unsigned) + BLOCK_SIZE.
*/
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
class RangeTable
{
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;
friend std::ostream& operator<< <>(std::ostream &out, const RangeTable &table);
friend std::istream& operator>> <>(std::istream &in, RangeTable &table);
RangeTable() : sum_lengths(0) {}
// for loading from shared memory
explicit RangeTable(OffsetContainerT& external_offsets, BlockContainerT& external_blocks, const unsigned sum_lengths)
: sum_lengths(sum_lengths)
{
block_offsets.swap(external_offsets);
diff_blocks.swap(external_blocks);
}
// construct table from length vector
explicit RangeTable(const std::vector<unsigned>& lengths)
{
const unsigned number_of_blocks = [&lengths]() {
unsigned num = (lengths.size() + 1) / (BLOCK_SIZE + 1);
if ((lengths.size() + 1) % (BLOCK_SIZE + 1) != 0)
{
num += 1;
}
return num;
}();
block_offsets.reserve(number_of_blocks);
diff_blocks.reserve(number_of_blocks);
unsigned last_length = 0;
unsigned lengths_prefix_sum = 0;
unsigned block_idx = 0;
unsigned block_counter = 0;
BlockT block;
unsigned block_sum = 0;
for (const unsigned l : lengths)
{
// first entry of a block: encode absolute offset
if (block_idx == 0)
{
block_offsets.push_back(lengths_prefix_sum);
block_sum = 0;
}
else
{
block[block_idx - 1] = last_length;
block_sum += last_length;
}
BOOST_ASSERT((block_idx == 0 && block_offsets[block_counter] == lengths_prefix_sum)
|| lengths_prefix_sum == (block_offsets[block_counter]+block_sum));
// block is full
if (BLOCK_SIZE == block_idx)
{
diff_blocks.push_back(block);
block_counter++;
}
// we can only store strings with length 255
BOOST_ASSERT(l <= 255);
lengths_prefix_sum += l;
last_length = l;
block_idx = (block_idx + 1) % (BLOCK_SIZE + 1);
}
// Last block can't be finished because we didn't add the sentinel
BOOST_ASSERT (block_counter == (number_of_blocks - 1));
// one block missing: starts with guard value
if (0 == block_idx)
{
// the last value is used as sentinel
block_offsets.push_back(lengths_prefix_sum);
block_idx = (block_idx + 1) % BLOCK_SIZE;
}
while (0 != block_idx)
{
block[block_idx - 1] = last_length;
last_length = 0;
block_idx = (block_idx + 1) % (BLOCK_SIZE + 1);
}
diff_blocks.push_back(block);
BOOST_ASSERT(diff_blocks.size() == number_of_blocks && block_offsets.size() == number_of_blocks);
sum_lengths = lengths_prefix_sum;
}
inline RangeT GetRange(const unsigned id) const
{
BOOST_ASSERT(id < block_offsets.size() + diff_blocks.size() * BLOCK_SIZE);
// internal_idx 0 is implicitly stored in block_offsets[block_idx]
const unsigned internal_idx = id % (BLOCK_SIZE + 1);
const unsigned block_idx = id / (BLOCK_SIZE + 1);
BOOST_ASSERT(block_idx < diff_blocks.size());
unsigned begin_idx = 0;
unsigned end_idx = 0;
begin_idx = block_offsets[block_idx];
const BlockT& block = diff_blocks[block_idx];
if (internal_idx > 0)
{
begin_idx += PrefixSumAtIndex(internal_idx - 1, block);
}
// next index inside current block
if (internal_idx < BLOCK_SIZE)
{
// note internal_idx - 1 is the *current* index for uint8_blocks
end_idx = begin_idx + block[internal_idx];
}
else
{
BOOST_ASSERT(block_idx < block_offsets.size() - 1);
end_idx = block_offsets[block_idx + 1];
}
BOOST_ASSERT(begin_idx < sum_lengths && end_idx <= sum_lengths);
BOOST_ASSERT(begin_idx <= end_idx);
return boost::irange(begin_idx, end_idx);
}
private:
inline unsigned PrefixSumAtIndex(int index, const BlockT& block) const;
// contains offset for each differential block
OffsetContainerT block_offsets;
// blocks of differential encoded offsets, should be aligned
BlockContainerT diff_blocks;
unsigned sum_lengths;
};
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
unsigned RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY>::PrefixSumAtIndex(int index, const BlockT& block) const
{
// this loop looks inefficent, but a modern compiler
// will emit nice SIMD here, at least for sensible block sizes. (I checked.)
unsigned sum = 0;
for (int i = 0; i <= index; ++i)
{
sum += block[i];
}
return sum;
}
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::ostream& operator<<(std::ostream &out, const RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table)
{
// write number of block
const unsigned number_of_blocks = table.diff_blocks.size();
out.write((char *) &number_of_blocks, sizeof(unsigned));
// write total length
out.write((char *) &table.sum_lengths, sizeof(unsigned));
// write block offsets
out.write((char *) table.block_offsets.data(), sizeof(unsigned) * table.block_offsets.size());
// write blocks
out.write((char *) table.diff_blocks.data(), BLOCK_SIZE * table.diff_blocks.size());
return out;
}
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::istream& operator>>(std::istream &in, RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table)
{
// read number of block
unsigned number_of_blocks;
in.read((char *) &number_of_blocks, sizeof(unsigned));
// read total length
in.read((char *) &table.sum_lengths, sizeof(unsigned));
table.block_offsets.resize(number_of_blocks);
table.diff_blocks.resize(number_of_blocks);
// read block offsets
in.read((char *) table.block_offsets.data(), sizeof(unsigned) * number_of_blocks);
// read blocks
in.read((char *) table.diff_blocks.data(), BLOCK_SIZE * number_of_blocks);
return in;
}
#endif
+80
View File
@@ -0,0 +1,80 @@
/*
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 RAW_ROUTE_DATA_H
#define RAW_ROUTE_DATA_H
#include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/TurnInstructions.h"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <vector>
struct PathData
{
PathData()
: node(SPECIAL_NODEID), name_id(INVALID_EDGE_WEIGHT),
segment_duration(INVALID_EDGE_WEIGHT),
turn_instruction(TurnInstruction::NoTurn)
{
}
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)
{
}
NodeID node;
unsigned name_id;
EdgeWeight segment_duration;
TurnInstruction turn_instruction;
};
struct RawRouteData
{
std::vector<std::vector<PathData>> unpacked_path_segments;
std::vector<PathData> unpacked_alternative;
std::vector<PhantomNodes> segment_end_coordinates;
std::vector<FixedPointCoordinate> raw_via_node_coordinates;
std::vector<bool> source_traversed_in_reverse;
std::vector<bool> target_traversed_in_reverse;
std::vector<bool> alt_source_traversed_in_reverse;
std::vector<bool> alt_target_traversed_in_reverse;
unsigned check_sum;
int shortest_path_length;
int alternative_path_length;
RawRouteData()
: check_sum(SPECIAL_NODEID),
shortest_path_length(INVALID_EDGE_WEIGHT),
alternative_path_length(INVALID_EDGE_WEIGHT)
{
}
};
#endif // RAW_ROUTE_DATA_H
+92 -63
View File
@@ -1,97 +1,126 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 RESTRICTION_H_
#define RESTRICTION_H_
#ifndef RESTRICTION_H
#define RESTRICTION_H
#include <climits>
#include "../typedefs.h"
struct _Restriction {
#include <limits>
struct TurnRestriction
{
NodeID viaNode;
NodeID fromNode;
NodeID toNode;
struct Bits { //mostly unused
Bits() : isOnly(false), unused1(false), unused2(false), unused3(false), unused4(false), unused5(false), unused6(false), unused7(false) {}
char isOnly:1;
char unused1:1;
char unused2:1;
char unused3:1;
char unused4:1;
char unused5:1;
char unused6:1;
char unused7:1;
struct Bits
{ // mostly unused
Bits()
: isOnly(false), unused1(false), unused2(false), unused3(false), unused4(false),
unused5(false), unused6(false), unused7(false)
{
}
bool isOnly : 1;
bool unused1 : 1;
bool unused2 : 1;
bool unused3 : 1;
bool unused4 : 1;
bool unused5 : 1;
bool unused6 : 1;
bool unused7 : 1;
} flags;
_Restriction(NodeID vn) : viaNode(vn), fromNode(UINT_MAX), toNode(UINT_MAX) { }
_Restriction(bool isOnly = false) : viaNode(UINT_MAX), fromNode(UINT_MAX), toNode(UINT_MAX) {
explicit TurnRestriction(NodeID viaNode)
: viaNode(viaNode), fromNode(std::numeric_limits<unsigned>::max()),
toNode(std::numeric_limits<unsigned>::max())
{
}
explicit TurnRestriction(const bool isOnly = false)
: viaNode(std::numeric_limits<unsigned>::max()),
fromNode(std::numeric_limits<unsigned>::max()),
toNode(std::numeric_limits<unsigned>::max())
{
flags.isOnly = isOnly;
}
};
inline bool CmpRestrictionByFrom ( _Restriction a, _Restriction b) { return (a.fromNode < b.fromNode); }
struct _RawRestrictionContainer {
_Restriction restriction;
struct InputRestrictionContainer
{
EdgeID fromWay;
EdgeID toWay;
unsigned viaNode;
TurnRestriction restriction;
_RawRestrictionContainer(EdgeID f, EdgeID t, NodeID vn, unsigned vw) : fromWay(f), toWay(t), viaNode(vw) { restriction.viaNode = vn;}
_RawRestrictionContainer(bool isOnly = false) : fromWay(UINT_MAX), toWay(UINT_MAX), viaNode(UINT_MAX) { restriction.flags.isOnly = isOnly;}
static _RawRestrictionContainer min_value() {
return _RawRestrictionContainer(0, 0, 0, 0);
InputRestrictionContainer(EdgeID fromWay, EdgeID toWay, NodeID vn, unsigned vw)
: fromWay(fromWay), toWay(toWay), viaNode(vw)
{
restriction.viaNode = vn;
}
static _RawRestrictionContainer max_value() {
return _RawRestrictionContainer(UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX);
explicit InputRestrictionContainer(bool isOnly = false)
: fromWay(std::numeric_limits<unsigned>::max()),
toWay(std::numeric_limits<unsigned>::max()), viaNode(std::numeric_limits<unsigned>::max())
{
restriction.flags.isOnly = isOnly;
}
static InputRestrictionContainer min_value() { return InputRestrictionContainer(0, 0, 0, 0); }
static InputRestrictionContainer max_value()
{
return InputRestrictionContainer(std::numeric_limits<unsigned>::max(),
std::numeric_limits<unsigned>::max(),
std::numeric_limits<unsigned>::max(),
std::numeric_limits<unsigned>::max());
}
};
struct CmpRestrictionContainerByFrom: public std::binary_function<_RawRestrictionContainer, _RawRestrictionContainer, bool> {
typedef _RawRestrictionContainer value_type;
bool operator () (const _RawRestrictionContainer & a, const _RawRestrictionContainer & b) const {
struct CmpRestrictionContainerByFrom
{
typedef InputRestrictionContainer value_type;
inline bool operator()(const InputRestrictionContainer &a, const InputRestrictionContainer &b)
const
{
return a.fromWay < b.fromWay;
}
value_type max_value() {
return _RawRestrictionContainer::max_value();
}
value_type min_value() {
return _RawRestrictionContainer::min_value();
}
inline value_type max_value() const { return InputRestrictionContainer::max_value(); }
inline value_type min_value() const { return InputRestrictionContainer::min_value(); }
};
struct CmpRestrictionContainerByTo: public std::binary_function<_RawRestrictionContainer, _RawRestrictionContainer, bool> {
typedef _RawRestrictionContainer value_type;
bool operator () (const _RawRestrictionContainer & a, const _RawRestrictionContainer & b) const {
struct CmpRestrictionContainerByTo
{
typedef InputRestrictionContainer value_type;
inline bool operator()(const InputRestrictionContainer &a, const InputRestrictionContainer &b)
const
{
return a.toWay < b.toWay;
}
value_type max_value() {
return _RawRestrictionContainer::max_value();
}
value_type min_value() {
return _RawRestrictionContainer::min_value();
}
value_type max_value() const { return InputRestrictionContainer::max_value(); }
value_type min_value() const { return InputRestrictionContainer::min_value(); }
};
#endif /* RESTRICTION_H_ */
#endif // RESTRICTION_H
+224
View File
@@ -0,0 +1,224 @@
/*
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 "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();
}
RestrictionMap::RestrictionMap(const std::shared_ptr<NodeBasedDynamicGraph> &graph,
const std::vector<TurnRestriction> &restriction_list)
: m_count(0), m_graph(graph)
{
// decompose restriction consisting of a start, via and end node into a
// a pair of starting edge and a list of all end nodes
for (auto &restriction : restriction_list)
{
m_restriction_start_nodes.insert(restriction.fromNode);
m_no_turn_via_node_set.insert(restriction.viaNode);
RestrictionSource restriction_source = {restriction.fromNode, restriction.viaNode};
unsigned index;
auto restriction_iter = m_restriction_map.find(restriction_source);
if (restriction_iter == m_restriction_map.end())
{
index = m_restriction_bucket_list.size();
m_restriction_bucket_list.resize(index + 1);
m_restriction_map.emplace(restriction_source, index);
}
else
{
index = restriction_iter->second;
// Map already contains an is_only_*-restriction
if (m_restriction_bucket_list.at(index).begin()->is_only)
{
continue;
}
else if (restriction.flags.isOnly)
{
// We are going to insert an is_only_*-restriction. There can be only one.
m_count -= m_restriction_bucket_list.at(index).size();
m_restriction_bucket_list.at(index).clear();
}
}
++m_count;
m_restriction_bucket_list.at(index)
.emplace_back(restriction.toNode, restriction.flags.isOnly);
}
}
// Replace end v with w in each turn restriction containing u as via node
void RestrictionMap::FixupArrivingTurnRestriction(const NodeID node_u,
const NodeID node_v,
const NodeID node_w)
{
BOOST_ASSERT(node_u != SPECIAL_NODEID);
BOOST_ASSERT(node_v != SPECIAL_NODEID);
BOOST_ASSERT(node_w != SPECIAL_NODEID);
if (!IsViaNode(node_u))
{
return;
}
// find all potential start edges. It is more efficent to get a (small) list
// of potential start edges than iterating over all buckets
std::vector<NodeID> predecessors;
for (const EdgeID current_edge_id : 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))
{
predecessors.push_back(target);
}
}
for (const NodeID node_x : predecessors)
{
const auto restriction_iterator = m_restriction_map.find({node_x, node_u});
if (restriction_iterator == m_restriction_map.end())
{
continue;
}
const unsigned index = restriction_iterator->second;
auto &bucket = m_restriction_bucket_list.at(index);
for (RestrictionTarget &restriction_target : bucket)
{
if (node_v == restriction_target.target_node)
{
restriction_target.target_node = node_w;
}
}
}
}
// Replaces start edge (v, w) with (u, w). Only start node changes.
void RestrictionMap::FixupStartingTurnRestriction(const NodeID node_u,
const NodeID node_v,
const NodeID node_w)
{
BOOST_ASSERT(node_u != SPECIAL_NODEID);
BOOST_ASSERT(node_v != SPECIAL_NODEID);
BOOST_ASSERT(node_w != SPECIAL_NODEID);
if (!IsSourceNode(node_v))
{
return;
}
const auto restriction_iterator = m_restriction_map.find({node_v, node_w});
if (restriction_iterator != m_restriction_map.end())
{
const unsigned index = restriction_iterator->second;
// remove old restriction start (v,w)
m_restriction_map.erase(restriction_iterator);
m_restriction_start_nodes.emplace(node_u);
// insert new restriction start (u,w) (pointing to index)
RestrictionSource new_source = {node_u, node_w};
m_restriction_map.emplace(new_source, index);
}
}
// Check if edge (u, v) is the start of any turn restriction.
// If so returns id of first target node.
NodeID RestrictionMap::CheckForEmanatingIsOnlyTurn(const NodeID node_u, const NodeID node_v) const
{
BOOST_ASSERT(node_u != SPECIAL_NODEID);
BOOST_ASSERT(node_v != SPECIAL_NODEID);
if (!IsSourceNode(node_u))
{
return SPECIAL_NODEID;
}
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);
for (const RestrictionTarget &restriction_target : bucket)
{
if (restriction_target.is_only)
{
return restriction_target.target_node;
}
}
}
return SPECIAL_NODEID;
}
// Checks if turn <u,v,w> is actually a turn restriction.
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);
if (!IsSourceNode(node_u))
{
return false;
}
auto restriction_iter = m_restriction_map.find({node_u, node_v});
if (restriction_iter != m_restriction_map.end())
{
const unsigned index = restriction_iter->second;
const auto &bucket = m_restriction_bucket_list.at(index);
for (const RestrictionTarget &restriction_target : bucket)
{
if ((node_w == restriction_target.target_node) && // target found
(!restriction_target.is_only) // and not an only_-restr.
)
{
return true;
}
}
}
return false;
}
// check of node is the start of any restriction
bool RestrictionMap::IsSourceNode(const NodeID node) const
{
if (m_restriction_start_nodes.find(node) == m_restriction_start_nodes.end())
{
return false;
}
return true;
}
+126
View File
@@ -0,0 +1,126 @@
/*
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 __RESTRICTION_MAP_H__
#define __RESTRICTION_MAP_H__
#include <memory>
#include "DynamicGraph.h"
#include "Restriction.h"
#include "NodeBasedGraph.h"
#include "../Util/StdHashExtensions.h"
#include "../typedefs.h"
#include <unordered_map>
#include <unordered_set>
struct RestrictionSource
{
NodeID start_node;
NodeID via_node;
RestrictionSource(NodeID start, NodeID via) : start_node(start), via_node(via)
{
}
friend inline bool operator==(const RestrictionSource &lhs, const RestrictionSource &rhs)
{
return (lhs.start_node == rhs.start_node && lhs.via_node == rhs.via_node);
}
};
struct RestrictionTarget
{
NodeID target_node;
bool is_only;
explicit RestrictionTarget(NodeID target, bool only) : target_node(target), is_only(only)
{
}
friend inline bool operator==(const RestrictionTarget &lhs, const RestrictionTarget &rhs)
{
return (lhs.target_node == rhs.target_node && lhs.is_only == rhs.is_only);
}
};
namespace std
{
template <> struct hash<RestrictionSource>
{
size_t operator()(const RestrictionSource &r_source) const
{
return hash_val(r_source.start_node, r_source.via_node);
}
};
template <> struct hash<RestrictionTarget>
{
size_t operator()(const RestrictionTarget &r_target) const
{
return hash_val(r_target.target_node, r_target.is_only);
}
};
}
/**
\brief Efficent look up if an edge is the start + via node of a TurnRestriction
EdgeBasedEdgeFactory decides by it if edges are inserted or geometry is compressed
*/
class RestrictionMap
{
public:
RestrictionMap(const std::shared_ptr<NodeBasedDynamicGraph> &graph,
const std::vector<TurnRestriction> &input_restrictions_list);
void FixupArrivingTurnRestriction(const NodeID u, const NodeID v, const NodeID w);
void FixupStartingTurnRestriction(const NodeID u, const NodeID v, const NodeID w);
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()
{
return m_count;
}
private:
bool IsSourceNode(const NodeID node) const;
typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector;
typedef NodeBasedDynamicGraph::EdgeData EdgeData;
unsigned m_count;
std::shared_ptr<NodeBasedDynamicGraph> m_graph;
//! index -> list of (target, isOnly)
std::vector<EmanatingRestrictionsVector> m_restriction_bucket_list;
//! maps (start, via) -> bucket index
std::unordered_map<RestrictionSource, unsigned> m_restriction_map;
std::unordered_set<NodeID> m_restriction_start_nodes;
std::unordered_set<NodeID> m_no_turn_via_node_set;
};
#endif
+89
View File
@@ -0,0 +1,89 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <osrm/RouteParameters.h>
#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/sequence/intrinsic.hpp>
#include <boost/fusion/include/at_c.hpp>
RouteParameters::RouteParameters()
: zoom_level(18), print_instructions(false), alternate_route(true), geometry(true),
compression(true), deprecatedAPI(false), check_sum(-1)
{
}
void RouteParameters::setZoomLevel(const short level)
{
if (18 >= level && 0 <= level)
{
zoom_level = level;
}
}
void RouteParameters::setAlternateRouteFlag(const bool flag) { alternate_route = flag; }
void RouteParameters::setDeprecatedAPIFlag(const std::string &) { deprecatedAPI = true; }
void RouteParameters::setChecksum(const unsigned sum) { check_sum = sum; }
void RouteParameters::setInstructionFlag(const bool flag) { print_instructions = flag; }
void RouteParameters::setService(const std::string &service_string) { service = service_string; }
void RouteParameters::setOutputFormat(const std::string &format) { output_format = format; }
void RouteParameters::setJSONpParameter(const std::string &parameter)
{
jsonp_parameter = parameter;
}
void RouteParameters::addHint(const std::string &hint)
{
hints.resize(coordinates.size());
if (!hints.empty())
{
hints.back() = hint;
}
}
void RouteParameters::setLanguage(const std::string &language_string)
{
language = language_string;
}
void RouteParameters::setGeometryFlag(const bool flag) { geometry = flag; }
void RouteParameters::setCompressionFlag(const bool flag) { compression = flag; }
void
RouteParameters::addCoordinate(const boost::fusion::vector<double, double> &transmitted_coordinates)
{
coordinates.emplace_back(
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<0>(transmitted_coordinates)),
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<1>(transmitted_coordinates)));
}
+42 -153
View File
@@ -1,171 +1,60 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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.
#ifndef SEARCHENGINE_H_
#define SEARCHENGINE_H_
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 <climits>
#include <deque>
#include "SimpleStack.h"
*/
#include <boost/thread.hpp>
#ifndef SEARCHENGINE_H
#define SEARCHENGINE_H
#include "BinaryHeap.h"
#include "NodeInformationHelpDesk.h"
#include "PhantomNodes.h"
#include "SearchEngineData.h"
#include "../RoutingAlgorithms/AlternativePathRouting.h"
#include "../RoutingAlgorithms/BasicRoutingInterface.h"
#include "../RoutingAlgorithms/ManyToManyRouting.h"
#include "../RoutingAlgorithms/ShortestPathRouting.h"
#include "../Util/StringUtil.h"
#include "../typedefs.h"
#include <type_traits>
struct _HeapData {
NodeID parent;
_HeapData( NodeID p ) : parent(p) { }
};
template <class DataFacadeT> class SearchEngine
{
private:
DataFacadeT *facade;
SearchEngineData engine_working_data;
typedef boost::thread_specific_ptr<BinaryHeap< NodeID, NodeID, int, _HeapData, UnorderedMapStorage<NodeID, int> > > SearchEngineHeapPtr;
public:
ShortestPathRouting<DataFacadeT> shortest_path;
AlternativeRouting<DataFacadeT> alternative_path;
ManyToManyRouting<DataFacadeT> distance_table;
template<class EdgeData, class GraphT>
struct SearchEngineData {
typedef SearchEngineHeapPtr HeapPtr;
typedef GraphT Graph;
SearchEngineData(GraphT * g, NodeInformationHelpDesk * nh, std::vector<string> & n) :graph(g), nodeHelpDesk(nh), names(n) {}
const GraphT * graph;
NodeInformationHelpDesk * nodeHelpDesk;
std::vector<string> & names;
static HeapPtr forwardHeap;
static HeapPtr backwardHeap;
static HeapPtr forwardHeap2;
static HeapPtr backwardHeap2;
static HeapPtr forwardHeap3;
static HeapPtr backwardHeap3;
inline void InitializeOrClearFirstThreadLocalStorage() {
if(!forwardHeap.get()) {
forwardHeap.reset(new BinaryHeap< NodeID, NodeID, int, _HeapData, UnorderedMapStorage<NodeID, int> >(nodeHelpDesk->getNumberOfNodes()));
}
else
forwardHeap->Clear();
if(!backwardHeap.get()) {
backwardHeap.reset(new BinaryHeap< NodeID, NodeID, int, _HeapData, UnorderedMapStorage<NodeID, int> >(nodeHelpDesk->getNumberOfNodes()));
}
else
backwardHeap->Clear();
explicit SearchEngine(DataFacadeT *facade)
: facade(facade), shortest_path(facade, engine_working_data),
alternative_path(facade, engine_working_data), distance_table(facade, engine_working_data)
{
static_assert(!std::is_pointer<DataFacadeT>::value, "don't instantiate with ptr type");
static_assert(std::is_object<DataFacadeT>::value, "don't instantiate with void, function, or reference");
}
inline void InitializeOrClearSecondThreadLocalStorage() {
if(!forwardHeap2.get()) {
forwardHeap2.reset(new BinaryHeap< NodeID, NodeID, int, _HeapData, UnorderedMapStorage<NodeID, int> >(nodeHelpDesk->getNumberOfNodes()));
}
else
forwardHeap2->Clear();
if(!backwardHeap2.get()) {
backwardHeap2.reset(new BinaryHeap< NodeID, NodeID, int, _HeapData, UnorderedMapStorage<NodeID, int> >(nodeHelpDesk->getNumberOfNodes()));
}
else
backwardHeap2->Clear();
}
inline void InitializeOrClearThirdThreadLocalStorage() {
if(!forwardHeap3.get()) {
forwardHeap3.reset(new BinaryHeap< NodeID, NodeID, int, _HeapData, UnorderedMapStorage<NodeID, int> >(nodeHelpDesk->getNumberOfNodes()));
}
else
forwardHeap3->Clear();
if(!backwardHeap3.get()) {
backwardHeap3.reset(new BinaryHeap< NodeID, NodeID, int, _HeapData, UnorderedMapStorage<NodeID, int> >(nodeHelpDesk->getNumberOfNodes()));
}
else
backwardHeap3->Clear();
}
~SearchEngine() {}
};
template<class EdgeData, class GraphT>
class SearchEngine {
private:
typedef SearchEngineData<EdgeData, GraphT> SearchEngineDataT;
SearchEngineDataT _queryData;
inline double absDouble(double input) { if(input < 0) return input*(-1); else return input;}
public:
ShortestPathRouting<SearchEngineDataT> shortestPath;
AlternativeRouting<SearchEngineDataT> alternativePaths;
SearchEngine(GraphT * g, NodeInformationHelpDesk * nh, std::vector<string> & n) :
_queryData(g, nh, n),
shortestPath(_queryData),
alternativePaths(_queryData)
{}
~SearchEngine() {}
inline void GetCoordinatesForNodeID(NodeID id, _Coordinate& result) const {
result.lat = _queryData.nodeHelpDesk->getLatitudeOfNode(id);
result.lon = _queryData.nodeHelpDesk->getLongitudeOfNode(id);
}
inline void FindRoutingStarts(const _Coordinate & start, const _Coordinate & target, PhantomNodes & routingStarts) const {
_queryData.nodeHelpDesk->FindRoutingStarts(start, target, routingStarts);
}
inline void FindPhantomNodeForCoordinate(const _Coordinate & location, PhantomNode & result, unsigned zoomLevel) const {
_queryData.nodeHelpDesk->FindPhantomNodeForCoordinate(location, result, zoomLevel);
}
inline NodeID GetNameIDForOriginDestinationNodeID(const NodeID s, const NodeID t) const {
if(s == t)
return 0;
EdgeID e = _queryData.graph->FindEdge(s, t);
if(e == UINT_MAX)
e = _queryData.graph->FindEdge( t, s );
if(UINT_MAX == e) {
return 0;
}
assert(e != UINT_MAX);
const EdgeData ed = _queryData.graph->GetEdgeData(e);
return ed.via;
}
inline std::string GetEscapedNameForNameID(const unsigned nameID) const {
return ((nameID >= _queryData.names.size() || nameID == 0) ? std::string("") : HTMLEntitize(_queryData.names.at(nameID)));
}
inline std::string GetEscapedNameForEdgeBasedEdgeID(const unsigned edgeID) const {
const unsigned nameID = _queryData.graph->GetEdgeData(edgeID).nameID1;
return GetEscapedNameForNameID(nameID);
}
};
template<class EdgeData, class GraphT> SearchEngineHeapPtr SearchEngineData<EdgeData, GraphT>::forwardHeap;
template<class EdgeData, class GraphT> SearchEngineHeapPtr SearchEngineData<EdgeData, GraphT>::backwardHeap;
template<class EdgeData, class GraphT> SearchEngineHeapPtr SearchEngineData<EdgeData, GraphT>::forwardHeap2;
template<class EdgeData, class GraphT> SearchEngineHeapPtr SearchEngineData<EdgeData, GraphT>::backwardHeap2;
template<class EdgeData, class GraphT> SearchEngineHeapPtr SearchEngineData<EdgeData, GraphT>::forwardHeap3;
template<class EdgeData, class GraphT> SearchEngineHeapPtr SearchEngineData<EdgeData, GraphT>::backwardHeap3;
#endif /* SEARCHENGINE_H_ */
#endif // SEARCHENGINE_H
+93
View File
@@ -0,0 +1,93 @@
/*
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 "SearchEngineData.h"
#include "BinaryHeap.h"
void SearchEngineData::InitializeOrClearFirstThreadLocalStorage(const unsigned number_of_nodes)
{
if (forwardHeap.get())
{
forwardHeap->Clear();
}
else
{
forwardHeap.reset(new QueryHeap(number_of_nodes));
}
if (backwardHeap.get())
{
backwardHeap->Clear();
}
else
{
backwardHeap.reset(new QueryHeap(number_of_nodes));
}
}
void SearchEngineData::InitializeOrClearSecondThreadLocalStorage(const unsigned number_of_nodes)
{
if (forwardHeap2.get())
{
forwardHeap2->Clear();
}
else
{
forwardHeap2.reset(new QueryHeap(number_of_nodes));
}
if (backwardHeap2.get())
{
backwardHeap2->Clear();
}
else
{
backwardHeap2.reset(new QueryHeap(number_of_nodes));
}
}
void SearchEngineData::InitializeOrClearThirdThreadLocalStorage(const unsigned number_of_nodes)
{
if (forwardHeap3.get())
{
forwardHeap3->Clear();
}
else
{
forwardHeap3.reset(new QueryHeap(number_of_nodes));
}
if (backwardHeap3.get())
{
backwardHeap3->Clear();
}
else
{
backwardHeap3.reset(new QueryHeap(number_of_nodes));
}
}
+61
View File
@@ -0,0 +1,61 @@
/*
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 SEARCH_ENGINE_DATA_H
#define SEARCH_ENGINE_DATA_H
#include <boost/thread/tss.hpp>
#include "../typedefs.h"
#include "BinaryHeap.h"
struct HeapData
{
NodeID parent;
/* explicit */ HeapData(NodeID p) : parent(p) {}
};
struct SearchEngineData
{
typedef BinaryHeap<NodeID, NodeID, int, HeapData, UnorderedMapStorage<NodeID, int>> QueryHeap;
typedef boost::thread_specific_ptr<QueryHeap> SearchEngineHeapPtr;
static SearchEngineHeapPtr forwardHeap;
static SearchEngineHeapPtr backwardHeap;
static SearchEngineHeapPtr forwardHeap2;
static SearchEngineHeapPtr backwardHeap2;
static SearchEngineHeapPtr forwardHeap3;
static SearchEngineHeapPtr backwardHeap3;
void InitializeOrClearFirstThreadLocalStorage(const unsigned number_of_nodes);
void InitializeOrClearSecondThreadLocalStorage(const unsigned number_of_nodes);
void InitializeOrClearThirdThreadLocalStorage(const unsigned number_of_nodes);
};
#endif // SEARCH_ENGINE_DATA_H
+61 -31
View File
@@ -1,42 +1,72 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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.
#ifndef SEGMENTINFORMATION_H_
#define SEGMENTINFORMATION_H_
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 <climits>
*/
#ifndef SEGMENT_INFORMATION_H
#define SEGMENT_INFORMATION_H
#include "TurnInstructions.h"
struct SegmentInformation {
_Coordinate location;
NodeID nameID;
double length;
unsigned duration;
double bearing;
TurnInstruction turnInstruction;
bool necessary;
SegmentInformation(const _Coordinate & loc, const NodeID nam, const double len, const unsigned dur, const TurnInstruction tInstr, const bool nec) :
location(loc), nameID(nam), length(len), duration(dur), bearing(0.), turnInstruction(tInstr), necessary(nec) {}
SegmentInformation(const _Coordinate & loc, const NodeID nam, const double len, const unsigned dur, const TurnInstruction tInstr) :
location(loc), nameID(nam), length(len), duration(dur), bearing(0.), turnInstruction(tInstr), necessary(tInstr != 0) {}
#include "../typedefs.h"
#include <osrm/Coordinate.h>
// Struct fits everything in one cache line
struct SegmentInformation
{
FixedPointCoordinate location;
NodeID name_id;
EdgeWeight duration;
float length;
short bearing; // more than enough [0..3600] fits into 12 bits
TurnInstruction turn_instruction;
bool necessary:1;
bool is_via_location:1;
explicit SegmentInformation(const FixedPointCoordinate &location,
const NodeID name_id,
const EdgeWeight duration,
const float length,
const TurnInstruction turn_instruction,
const bool necessary,
const bool is_via_location)
: location(location), name_id(name_id), duration(duration), length(length), bearing(0),
turn_instruction(turn_instruction), necessary(necessary), is_via_location(is_via_location)
{
}
explicit SegmentInformation(const FixedPointCoordinate &location,
const NodeID name_id,
const EdgeWeight duration,
const float length,
const TurnInstruction turn_instruction)
: 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)
{
}
};
#endif /* SEGMENTINFORMATION_H_ */
#endif /* SEGMENT_INFORMATION_H */
+370
View File
@@ -0,0 +1,370 @@
/*
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 SHARED_MEMORY_FACTORY_H
#define SHARED_MEMORY_FACTORY_H
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/interprocess/mapped_region.hpp>
#ifndef WIN32
#include <boost/interprocess/xsi_shared_memory.hpp>
#else
#include <boost/interprocess/shared_memory_object.hpp>
#endif
#ifdef __linux__
#include <sys/ipc.h>
#include <sys/shm.h>
#endif
// #include <cstring>
#include <cstdint>
#include <algorithm>
#include <exception>
struct OSRMLockFile
{
boost::filesystem::path operator()()
{
boost::filesystem::path temp_dir = boost::filesystem::temp_directory_path();
boost::filesystem::path lock_file = temp_dir / "osrm.lock";
return lock_file;
}
};
#ifndef WIN32
class SharedMemory
{
// Remove shared memory on destruction
class shm_remove
{
private:
int m_shmid;
bool m_initialized;
public:
void SetID(int shmid)
{
m_shmid = shmid;
m_initialized = true;
}
shm_remove() : m_shmid(INT_MIN), m_initialized(false) {}
shm_remove(const shm_remove &) = delete;
~shm_remove()
{
if (m_initialized)
{
SimpleLogger().Write(logDEBUG) << "automatic memory deallocation";
if (!boost::interprocess::xsi_shared_memory::remove(m_shmid))
{
SimpleLogger().Write(logDEBUG) << "could not deallocate id " << m_shmid;
}
}
}
};
public:
void *Ptr() const { return region.get_address(); }
SharedMemory() = delete;
SharedMemory(const SharedMemory &) = delete;
template <typename IdentifierT>
SharedMemory(const boost::filesystem::path &lock_file,
const IdentifierT id,
const uint64_t size = 0,
bool read_write = false,
bool remove_prev = true)
: key(lock_file.string().c_str(), id)
{
if (0 == size)
{ // read_only
shm = boost::interprocess::xsi_shared_memory(boost::interprocess::open_only, key);
region = boost::interprocess::mapped_region(
shm,
(read_write ? boost::interprocess::read_write : boost::interprocess::read_only));
}
else
{ // writeable pointer
// remove previously allocated mem
if (remove_prev)
{
Remove(key);
}
shm = boost::interprocess::xsi_shared_memory(
boost::interprocess::open_or_create, key, size);
#ifdef __linux__
if (-1 == shmctl(shm.get_shmid(), SHM_LOCK, 0))
{
if (ENOMEM == errno)
{
SimpleLogger().Write(logWARNING) << "could not lock shared memory to RAM";
}
}
#endif
region = boost::interprocess::mapped_region(shm, boost::interprocess::read_write);
remover.SetID(shm.get_shmid());
SimpleLogger().Write(logDEBUG) << "writeable memory allocated " << size << " bytes";
}
}
template <typename IdentifierT> static bool RegionExists(const IdentifierT id)
{
bool result = true;
try
{
OSRMLockFile lock_file;
boost::interprocess::xsi_key key(lock_file().string().c_str(), id);
result = RegionExists(key);
}
catch (...) { result = false; }
return result;
}
template <typename IdentifierT> static bool Remove(const IdentifierT id)
{
OSRMLockFile lock_file;
boost::interprocess::xsi_key key(lock_file().string().c_str(), id);
return Remove(key);
}
private:
static bool RegionExists(const boost::interprocess::xsi_key &key)
{
bool result = true;
try { boost::interprocess::xsi_shared_memory shm(boost::interprocess::open_only, key); }
catch (...) { result = false; }
return result;
}
static bool Remove(const boost::interprocess::xsi_key &key)
{
bool ret = false;
try
{
SimpleLogger().Write(logDEBUG) << "deallocating prev memory";
boost::interprocess::xsi_shared_memory xsi(boost::interprocess::open_only, key);
ret = boost::interprocess::xsi_shared_memory::remove(xsi.get_shmid());
}
catch (const boost::interprocess::interprocess_exception &e)
{
if (e.get_error_code() != boost::interprocess::not_found_error)
{
throw;
}
}
return ret;
}
boost::interprocess::xsi_key key;
boost::interprocess::xsi_shared_memory shm;
boost::interprocess::mapped_region region;
shm_remove remover;
};
#else
// Windows - specific code
class SharedMemory : boost::noncopyable
{
// Remove shared memory on destruction
class shm_remove : boost::noncopyable
{
private:
char *m_shmid;
bool m_initialized;
public:
void SetID(char *shmid)
{
m_shmid = shmid;
m_initialized = true;
}
shm_remove() : m_shmid("undefined"), m_initialized(false) {}
~shm_remove()
{
if (m_initialized)
{
SimpleLogger().Write(logDEBUG) << "automatic memory deallocation";
if (!boost::interprocess::shared_memory_object::remove(m_shmid))
{
SimpleLogger().Write(logDEBUG) << "could not deallocate id " << m_shmid;
}
}
}
};
public:
void *Ptr() const { return region.get_address(); }
SharedMemory(const boost::filesystem::path &lock_file,
const int id,
const uint64_t size = 0,
bool read_write = false,
bool remove_prev = true)
{
sprintf(key, "%s.%d", "osrm.lock", id);
if (0 == size)
{ // read_only
shm = boost::interprocess::shared_memory_object(
boost::interprocess::open_only,
key,
read_write ? boost::interprocess::read_write : boost::interprocess::read_only);
region = boost::interprocess::mapped_region(
shm, read_write ? boost::interprocess::read_write : boost::interprocess::read_only);
}
else
{ // writeable pointer
// remove previously allocated mem
if (remove_prev)
{
Remove(key);
}
shm = boost::interprocess::shared_memory_object(
boost::interprocess::open_or_create, key, boost::interprocess::read_write);
shm.truncate(size);
region = boost::interprocess::mapped_region(shm, boost::interprocess::read_write);
remover.SetID(key);
SimpleLogger().Write(logDEBUG) << "writeable memory allocated " << size << " bytes";
}
}
static bool RegionExists(const int id)
{
bool result = true;
try
{
char k[500];
build_key(id, k);
result = RegionExists(k);
}
catch (...) { result = false; }
return result;
}
static bool Remove(const int id)
{
char k[500];
build_key(id, k);
return Remove(k);
}
private:
static void build_key(int id, char *key)
{
OSRMLockFile lock_file;
sprintf(key, "%s.%d", "osrm.lock", id);
}
static bool RegionExists(const char *key)
{
bool result = true;
try
{
boost::interprocess::shared_memory_object shm(
boost::interprocess::open_only, key, boost::interprocess::read_write);
}
catch (...) { result = false; }
return result;
}
static bool Remove(char *key)
{
bool ret = false;
try
{
SimpleLogger().Write(logDEBUG) << "deallocating prev memory";
ret = boost::interprocess::shared_memory_object::remove(key);
}
catch (const boost::interprocess::interprocess_exception &e)
{
if (e.get_error_code() != boost::interprocess::not_found_error)
{
throw;
}
}
return ret;
}
char key[500];
boost::interprocess::shared_memory_object shm;
boost::interprocess::mapped_region region;
shm_remove remover;
};
#endif
template <class LockFileT = OSRMLockFile> class SharedMemoryFactory_tmpl
{
public:
template <typename IdentifierT>
static SharedMemory *Get(const IdentifierT &id,
const uint64_t size = 0,
bool read_write = false,
bool remove_prev = true)
{
try
{
LockFileT lock_file;
if (!boost::filesystem::exists(lock_file()))
{
if (0 == size)
{
throw OSRMException("lock file does not exist, exiting");
}
else
{
boost::filesystem::ofstream ofs(lock_file());
ofs.close();
}
}
return new SharedMemory(lock_file(), id, size, read_write, remove_prev);
}
catch (const boost::interprocess::interprocess_exception &e)
{
SimpleLogger().Write(logWARNING) << "caught exception: " << e.what() << ", code "
<< e.get_error_code();
throw OSRMException(e.what());
}
}
SharedMemoryFactory_tmpl() = delete;
SharedMemoryFactory_tmpl(const SharedMemoryFactory_tmpl &) = delete;
};
typedef SharedMemoryFactory_tmpl<> SharedMemoryFactory;
#endif /* SHARED_MEMORY_POINTER_FACTORY_H */
+156
View File
@@ -0,0 +1,156 @@
/*
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 SHARED_MEMORY_VECTOR_WRAPPER_H
#define SHARED_MEMORY_VECTOR_WRAPPER_H
#include "../Util/SimpleLogger.h"
#include <boost/assert.hpp>
#include <algorithm>
#include <iterator>
#include <type_traits>
#include <vector>
template <typename DataT> class ShMemIterator : public std::iterator<std::input_iterator_tag, DataT>
{
DataT *p;
public:
explicit ShMemIterator(DataT *x) : p(x) {}
ShMemIterator(const ShMemIterator &mit) : p(mit.p) {}
ShMemIterator &operator++()
{
++p;
return *this;
}
ShMemIterator operator++(int)
{
ShMemIterator tmp(*this);
operator++();
return tmp;
}
ShMemIterator operator+(std::ptrdiff_t diff)
{
ShMemIterator tmp(p + diff);
return tmp;
}
bool operator==(const ShMemIterator &rhs) { return p == rhs.p; }
bool operator!=(const ShMemIterator &rhs) { return p != rhs.p; }
DataT &operator*() { return *p; }
};
template <typename DataT> class SharedMemoryWrapper
{
private:
DataT *m_ptr;
std::size_t m_size;
public:
SharedMemoryWrapper() : m_ptr(nullptr), m_size(0) {}
SharedMemoryWrapper(DataT *ptr, std::size_t size) : m_ptr(ptr), m_size(size) {}
void swap(SharedMemoryWrapper<DataT> &other)
{
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);
}
DataT &at(const std::size_t index) { return m_ptr[index]; }
const DataT &at(const std::size_t index) const { return m_ptr[index]; }
ShMemIterator<DataT> begin() const { return ShMemIterator<DataT>(m_ptr); }
ShMemIterator<DataT> end() const { return ShMemIterator<DataT>(m_ptr + m_size); }
std::size_t size() const { return m_size; }
bool empty() const { return 0 == size(); }
DataT &operator[](const unsigned index)
{
BOOST_ASSERT_MSG(index < m_size, "invalid size");
return m_ptr[index];
}
const DataT &operator[](const unsigned index) const
{
BOOST_ASSERT_MSG(index < m_size, "invalid size");
return m_ptr[index];
}
};
template <> class SharedMemoryWrapper<bool>
{
private:
unsigned *m_ptr;
std::size_t m_size;
public:
SharedMemoryWrapper() : m_ptr(nullptr), m_size(0) {}
SharedMemoryWrapper(unsigned *ptr, std::size_t size) : m_ptr(ptr), m_size(size) {}
void swap(SharedMemoryWrapper<bool> &other)
{
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);
}
bool at(const std::size_t index) const
{
const std::size_t bucket = index / 32;
const unsigned offset = static_cast<unsigned>(index % 32);
return m_ptr[bucket] & (1 << offset);
}
std::size_t size() const { return m_size; }
bool empty() const { return 0 == size(); }
bool operator[](const unsigned index)
{
BOOST_ASSERT_MSG(index < m_size, "invalid size");
const unsigned bucket = index / 32;
const unsigned offset = index % 32;
return m_ptr[bucket] & (1 << offset);
}
};
template <typename DataT, bool UseSharedMemory> struct ShM
{
typedef typename std::conditional<UseSharedMemory,
SharedMemoryWrapper<DataT>,
std::vector<DataT>>::type vector;
};
#endif // SHARED_MEMORY_VECTOR_WRAPPER_H
-71
View File
@@ -1,71 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef SIMPLESTACK_H_
#define SIMPLESTACK_H_
#include <cassert>
#include <vector>
template<typename StackItemT, class ContainerT = std::vector<StackItemT> >
class SimpleStack {
private:
int last;
ContainerT arr;
public:
SimpleStack() : last(-1) {
}
SimpleStack(std::size_t size_hint) : last(-1) {
hint(size_hint);
}
inline void hint(std::size_t size_hint) {
arr.reserve(size_hint);
}
inline void push(StackItemT t) {
++last;
arr.push_back(t);
}
inline void pop() {
arr.pop_back();
--last;
}
inline StackItemT top() {
assert (last >= 0);
return arr[last];
}
inline int size() {
return last+1;
}
inline bool empty() {
return (-1 == last);
}
};
#endif /* SIMPLESTACK_H_ */
+165 -120
View File
@@ -1,113 +1,156 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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.
#ifndef STATICGRAPH_H_INCLUDED
#define STATICGRAPH_H_INCLUDED
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 <vector>
#include <algorithm>
*/
#ifndef STATIC_GRAPH_H
#define STATIC_GRAPH_H
#include "../DataStructures/Percent.h"
#include "../DataStructures/SharedMemoryVectorWrapper.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
#include "ImportEdge.h"
template< typename EdgeDataT>
class StaticGraph {
public:
#include <boost/assert.hpp>
#include <boost/range/irange.hpp>
#include <tbb/parallel_sort.h>
#include <algorithm>
#include <limits>
#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;
class InputEdge {
public:
class InputEdge
{
public:
EdgeDataT data;
NodeIterator source;
NodeIterator target;
bool operator<( const InputEdge& right ) const {
if ( source != right.source )
bool operator<(const InputEdge &right) const
{
if (source != right.source)
{
return source < right.source;
}
return target < right.target;
}
};
struct _StrNode {
//index of the first edge
EdgeIterator firstEdge;
struct NodeArrayEntry
{
// index of the first edge
EdgeIterator first_edge;
};
struct _StrEdge {
struct EdgeArrayEntry
{
NodeID target;
EdgeDataT data;
};
StaticGraph( const int nodes, std::vector< InputEdge > &graph ) {
std::sort( graph.begin(), graph.end() );
_numNodes = nodes;
_numEdges = ( EdgeIterator ) graph.size();
_nodes.resize( _numNodes + 1);
EdgeRange GetAdjacentEdgeRange(const NodeID node) const
{
return boost::irange(BeginEdges(node), EndEdges(node));
}
StaticGraph(const int nodes, std::vector<InputEdge> &graph)
{
tbb::parallel_sort(graph.begin(), graph.end());
number_of_nodes = nodes;
number_of_edges = (EdgeIterator)graph.size();
node_array.resize(number_of_nodes + 1);
EdgeIterator edge = 0;
EdgeIterator position = 0;
for ( NodeIterator node = 0; node <= _numNodes; ++node ) {
EdgeIterator lastEdge = edge;
while ( edge < _numEdges && graph[edge].source == node )
for (NodeIterator node = 0; node <= number_of_nodes; ++node)
{
EdgeIterator last_edge = edge;
while (edge < number_of_edges && graph[edge].source == node)
{
++edge;
_nodes[node].firstEdge = position; //=edge
position += edge - lastEdge; //remove
}
node_array[node].first_edge = position; //=edge
position += edge - last_edge; // remove
}
_edges.resize( position ); //(edge)
edge_array.resize(position); //(edge)
edge = 0;
for ( NodeIterator node = 0; node < _numNodes; ++node ) {
for ( EdgeIterator i = _nodes[node].firstEdge, e = _nodes[node+1].firstEdge; i != e; ++i ) {
_edges[i].target = graph[edge].target;
_edges[i].data = graph[edge].data;
assert(_edges[i].data.distance > 0);
for (NodeIterator node = 0; node < number_of_nodes; ++node)
{
EdgeIterator e = node_array[node + 1].first_edge;
for (EdgeIterator i = node_array[node].first_edge; i != e; ++i)
{
edge_array[i].target = graph[edge].target;
edge_array[i].data = graph[edge].data;
BOOST_ASSERT(edge_array[i].data.distance > 0);
edge++;
}
}
}
StaticGraph( std::vector<_StrNode> & nodes, std::vector<_StrEdge> & edges) {
_numNodes = nodes.size();
_numEdges = edges.size();
StaticGraph(typename ShM<NodeArrayEntry, UseSharedMemory>::vector &nodes,
typename ShM<EdgeArrayEntry, UseSharedMemory>::vector &edges)
{
number_of_nodes = nodes.size() - 1;
number_of_edges = edges.size();
_nodes.swap(nodes);
_edges.swap(edges);
//Add dummy node to end of _nodes array;
_nodes.push_back(_nodes.back());
node_array.swap(nodes);
edge_array.swap(edges);
#ifndef NDEBUG
Percent p(GetNumberOfNodes());
for(unsigned u = 0; u < GetNumberOfNodes(); ++u) {
for(unsigned eid = BeginEdges(u); eid < EndEdges(u); ++eid) {
unsigned v = GetTarget(eid);
EdgeData & data = GetEdgeData(eid);
if(data.shortcut) {
unsigned eid2 = FindEdgeInEitherDirection(u, data.id);
if(eid2 == UINT_MAX) {
DEBUG("cannot find first segment of edge (" << u << "," << data.id << "," << v << ")");
data.shortcut = false;
}
eid2 = FindEdgeInEitherDirection(data.id, v);
if(eid2 == UINT_MAX) {
DEBUG("cannot find second segment of edge (" << u << "," << data.id << "," << v << ")");
data.shortcut = false;
}
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();
@@ -115,74 +158,76 @@ public:
#endif
}
unsigned GetNumberOfNodes() const {
return _numNodes;
unsigned GetNumberOfNodes() const { return number_of_nodes -1; }
unsigned GetNumberOfEdges() const { return number_of_edges; }
unsigned GetOutDegree(const NodeIterator n) const { return BeginEdges(n) - EndEdges(n) - 1; }
inline NodeIterator GetTarget(const EdgeIterator e) const
{
return NodeIterator(edge_array[e].target);
}
unsigned GetNumberOfEdges() const {
return _numEdges;
inline EdgeDataT &GetEdgeData(const EdgeIterator e) { return edge_array[e].data; }
const EdgeDataT &GetEdgeData(const EdgeIterator e) const { return edge_array[e].data; }
EdgeIterator BeginEdges(const NodeIterator n) const
{
return EdgeIterator(node_array.at(n).first_edge);
}
unsigned GetOutDegree( const NodeIterator &n ) const {
return BeginEdges(n)-EndEdges(n) - 1;
EdgeIterator EndEdges(const NodeIterator n) const
{
return EdgeIterator(node_array.at(n + 1).first_edge);
}
inline NodeIterator GetTarget( const EdgeIterator &e ) const {
return NodeIterator( _edges[e].target );
}
inline EdgeDataT &GetEdgeData( const EdgeIterator &e ) {
return _edges[e].data;
}
const EdgeDataT &GetEdgeData( const EdgeIterator &e ) const {
return _edges[e].data;
}
EdgeIterator BeginEdges( const NodeIterator &n ) const {
return EdgeIterator( _nodes[n].firstEdge );
}
EdgeIterator EndEdges( const NodeIterator &n ) const {
return EdgeIterator( _nodes[n+1].firstEdge );
}
//searches for a specific edge
EdgeIterator FindEdge( const NodeIterator &from, const NodeIterator &to ) const {
EdgeIterator smallestEdge = SPECIAL_EDGEID;
EdgeWeight smallestWeight = UINT_MAX;
for ( EdgeIterator edge = BeginEdges( from ); edge < EndEdges(from); edge++ ) {
// searches for a specific edge
EdgeIterator FindEdge(const NodeIterator from, const NodeIterator to) const
{
EdgeIterator smallest_edge = SPECIAL_EDGEID;
EdgeWeight smallest_weight = INVALID_EDGE_WEIGHT;
for (auto edge : GetAdjacentEdgeRange(from))
{
const NodeID target = GetTarget(edge);
const EdgeWeight weight = GetEdgeData(edge).distance;
if(target == to && weight < smallestWeight) {
smallestEdge = edge; smallestWeight = weight;
if (target == to && weight < smallest_weight)
{
smallest_edge = edge;
smallest_weight = weight;
}
}
return smallestEdge;
return smallest_edge;
}
EdgeIterator FindEdgeInEitherDirection( const NodeIterator &from, const NodeIterator &to ) const {
EdgeIterator tmp = FindEdge( from, to );
return (UINT_MAX != tmp ? tmp : FindEdge( to, from ));
EdgeIterator FindEdgeInEitherDirection(const NodeIterator from, const NodeIterator to) const
{
EdgeIterator tmp = FindEdge(from, to);
return (SPECIAL_NODEID != tmp ? tmp : FindEdge(to, from));
}
EdgeIterator FindEdgeIndicateIfReverse( const NodeIterator &from, const NodeIterator &to, bool & result ) const {
EdgeIterator tmp = FindEdge( from, to );
if(UINT_MAX == tmp) {
tmp = FindEdge( to, from );
if(UINT_MAX != tmp)
EdgeIterator
FindEdgeIndicateIfReverse(const NodeIterator from, const NodeIterator to, bool &result) const
{
EdgeIterator current_iterator = FindEdge(from, to);
if (SPECIAL_NODEID == current_iterator)
{
current_iterator = FindEdge(to, from);
if (SPECIAL_NODEID != current_iterator)
{
result = true;
}
}
return tmp;
return current_iterator;
}
private:
private:
NodeIterator number_of_nodes;
EdgeIterator number_of_edges;
NodeIterator _numNodes;
EdgeIterator _numEdges;
std::vector< _StrNode > _nodes;
std::vector< _StrEdge > _edges;
typename ShM<NodeArrayEntry, UseSharedMemory>::vector node_array;
typename ShM<EdgeArrayEntry, UseSharedMemory>::vector edge_array;
};
#endif // STATICGRAPH_H_INCLUDED
#endif // STATIC_GRAPH_H
+141 -104
View File
@@ -1,45 +1,55 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
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.
KD Tree coded by Christian Vetter, Monav Project
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.
*/
// KD Tree coded by Christian Vetter, Monav Project
*/
#ifndef STATICKDTREE_H_INCLUDED
#define STATICKDTREE_H_INCLUDED
#include <cassert>
#include <boost/assert.hpp>
#include <vector>
#include <algorithm>
#include <stack>
#include <limits>
namespace KDTree {
namespace KDTree
{
#define KDTREE_BASESIZE (8)
template< unsigned k, typename T >
class BoundingBox {
public:
BoundingBox() {
for ( unsigned dim = 0; dim < k; ++dim ) {
min[dim] = std::numeric_limits< T >::min();
max[dim] = std::numeric_limits< T >::max();
template <unsigned k, typename T> class BoundingBox
{
public:
BoundingBox()
{
for (unsigned dim = 0; dim < k; ++dim)
{
min[dim] = std::numeric_limits<T>::min();
max[dim] = std::numeric_limits<T>::max();
}
}
@@ -47,102 +57,118 @@ public:
T max[k];
};
struct NoData {};
struct NoData
{
};
template< unsigned k, typename T >
class EuclidianMetric {
public:
double operator() ( const T left[k], const T right[k] ) {
template <unsigned k, typename T> class EuclidianMetric
{
public:
double operator()(const T left[k], const T right[k])
{
double result = 0;
for ( unsigned i = 0; i < k; ++i ) {
for (unsigned i = 0; i < k; ++i)
{
double temp = (double)left[i] - (double)right[i];
result += temp * temp;
}
return result;
}
double operator() ( const BoundingBox< k, T > &box, const T point[k] ) {
double operator()(const BoundingBox<k, T> &box, const T point[k])
{
T nearest[k];
for ( unsigned dim = 0; dim < k; ++dim ) {
if ( point[dim] < box.min[dim] )
for (unsigned dim = 0; dim < k; ++dim)
{
if (point[dim] < box.min[dim])
nearest[dim] = box.min[dim];
else if ( point[dim] > box.max[dim] )
else if (point[dim] > box.max[dim])
nearest[dim] = box.max[dim];
else
nearest[dim] = point[dim];
}
return operator() ( point, nearest );
return operator()(point, nearest);
}
};
template < unsigned k, typename T, typename Data = NoData, typename Metric = EuclidianMetric< k, T > >
class StaticKDTree {
public:
struct InputPoint {
template <unsigned k, typename T, typename Data = NoData, typename Metric = EuclidianMetric<k, T>>
class StaticKDTree
{
public:
struct InputPoint
{
T coordinates[k];
Data data;
bool operator==( const InputPoint& right )
{
for ( int i = 0; i < k; i++ ) {
if ( coordinates[i] != right.coordinates[i] )
bool operator==(const InputPoint &right)
{
for (int i = 0; i < k; i++)
{
if (coordinates[i] != right.coordinates[i])
return false;
}
return true;
}
}
};
StaticKDTree( std::vector< InputPoint > * points ){
assert( k > 0 );
assert ( points->size() > 0 );
explicit StaticKDTree(std::vector<InputPoint> *points)
{
BOOST_ASSERT(k > 0);
BOOST_ASSERT(points->size() > 0);
size = points->size();
kdtree = new InputPoint[size];
for ( Iterator i = 0; i != size; ++i ) {
for (Iterator i = 0; i != size; ++i)
{
kdtree[i] = points->at(i);
for ( unsigned dim = 0; dim < k; ++dim ) {
if ( kdtree[i].coordinates[dim] < boundingBox.min[dim] )
for (unsigned dim = 0; dim < k; ++dim)
{
if (kdtree[i].coordinates[dim] < boundingBox.min[dim])
boundingBox.min[dim] = kdtree[i].coordinates[dim];
if ( kdtree[i].coordinates[dim] > boundingBox.max[dim] )
if (kdtree[i].coordinates[dim] > boundingBox.max[dim])
boundingBox.max[dim] = kdtree[i].coordinates[dim];
}
}
std::stack< Tree > s;
s.push ( Tree ( 0, size, 0 ) );
while ( !s.empty() ) {
std::stack<Tree> s;
s.push(Tree(0, size, 0));
while (!s.empty())
{
Tree tree = s.top();
s.pop();
if ( tree.right - tree.left < KDTREE_BASESIZE )
if (tree.right - tree.left < KDTREE_BASESIZE)
continue;
Iterator middle = tree.left + ( tree.right - tree.left ) / 2;
std::nth_element( kdtree + tree.left, kdtree + middle, kdtree + tree.right, Less( tree.dimension ) );
s.push( Tree( tree.left, middle, ( tree.dimension + 1 ) % k ) );
s.push( Tree( middle + 1, tree.right, ( tree.dimension + 1 ) % k ) );
Iterator middle = tree.left + (tree.right - tree.left) / 2;
std::nth_element(
kdtree + tree.left, kdtree + middle, kdtree + tree.right, Less(tree.dimension));
s.push(Tree(tree.left, middle, (tree.dimension + 1) % k));
s.push(Tree(middle + 1, tree.right, (tree.dimension + 1) % k));
}
}
~StaticKDTree(){
delete[] kdtree;
}
~StaticKDTree() { delete[] kdtree; }
bool NearestNeighbor( InputPoint* result, const InputPoint& point ) {
bool NearestNeighbor(InputPoint *result, const InputPoint &point)
{
Metric distance;
bool found = false;
double nearestDistance = std::numeric_limits< T >::max();
std::stack< NNTree > s;
s.push ( NNTree ( 0, size, 0, boundingBox ) );
while ( !s.empty() ) {
double nearestDistance = std::numeric_limits<T>::max();
std::stack<NNTree> s;
s.push(NNTree(0, size, 0, boundingBox));
while (!s.empty())
{
NNTree tree = s.top();
s.pop();
if ( distance( tree.box, point.coordinates ) >= nearestDistance )
if (distance(tree.box, point.coordinates) >= nearestDistance)
continue;
if ( tree.right - tree.left < KDTREE_BASESIZE ) {
for ( unsigned i = tree.left; i < tree.right; i++ ) {
double newDistance = distance( kdtree[i].coordinates, point.coordinates );
if ( newDistance < nearestDistance ) {
if (tree.right - tree.left < KDTREE_BASESIZE)
{
for (unsigned i = tree.left; i < tree.right; i++)
{
double newDistance = distance(kdtree[i].coordinates, point.coordinates);
if (newDistance < nearestDistance)
{
nearestDistance = newDistance;
*result = kdtree[i];
found = true;
@@ -151,73 +177,84 @@ public:
continue;
}
Iterator middle = tree.left + ( tree.right - tree.left ) / 2;
Iterator middle = tree.left + (tree.right - tree.left) / 2;
double newDistance = distance( kdtree[middle].coordinates, point.coordinates );
if ( newDistance < nearestDistance ) {
double newDistance = distance(kdtree[middle].coordinates, point.coordinates);
if (newDistance < nearestDistance)
{
nearestDistance = newDistance;
*result = kdtree[middle];
found = true;
}
Less comperator( tree.dimension );
if ( !comperator( point, kdtree[middle] ) ) {
NNTree first( middle + 1, tree.right, ( tree.dimension + 1 ) % k, tree.box );
NNTree second( tree.left, middle, ( tree.dimension + 1 ) % k, tree.box );
Less comperator(tree.dimension);
if (!comperator(point, kdtree[middle]))
{
NNTree first(middle + 1, tree.right, (tree.dimension + 1) % k, tree.box);
NNTree second(tree.left, middle, (tree.dimension + 1) % k, tree.box);
first.box.min[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
second.box.max[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
s.push( second );
s.push( first );
s.push(second);
s.push(first);
}
else {
NNTree first( middle + 1, tree.right, ( tree.dimension + 1 ) % k, tree.box );
NNTree second( tree.left, middle, ( tree.dimension + 1 ) % k, tree.box );
else
{
NNTree first(middle + 1, tree.right, (tree.dimension + 1) % k, tree.box);
NNTree second(tree.left, middle, (tree.dimension + 1) % k, tree.box);
first.box.min[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
second.box.max[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
s.push( first );
s.push( second );
s.push(first);
s.push(second);
}
}
return found;
}
private:
private:
typedef unsigned Iterator;
struct Tree {
struct Tree
{
Iterator left;
Iterator right;
unsigned dimension;
Tree() {}
Tree( Iterator l, Iterator r, unsigned d ): left( l ), right( r ), dimension( d ) {}
Tree(Iterator l, Iterator r, unsigned d) : left(l), right(r), dimension(d) {}
};
struct NNTree {
struct NNTree
{
Iterator left;
Iterator right;
unsigned dimension;
BoundingBox< k, T > box;
BoundingBox<k, T> box;
NNTree() {}
NNTree( Iterator l, Iterator r, unsigned d, const BoundingBox< k, T >& b ): left( l ), right( r ), dimension( d ), box ( b ) {}
NNTree(Iterator l, Iterator r, unsigned d, const BoundingBox<k, T> &b)
: left(l), right(r), dimension(d), box(b)
{
}
};
class Less {
public:
Less( unsigned d ) {
class Less
{
public:
explicit Less(unsigned d)
{
dimension = d;
assert( dimension < k );
BOOST_ASSERT(dimension < k);
}
bool operator() ( const InputPoint& left, const InputPoint& right ) {
assert( dimension < k );
bool operator()(const InputPoint &left, const InputPoint &right)
{
BOOST_ASSERT(dimension < k);
return left.coordinates[dimension] < right.coordinates[dimension];
}
private:
private:
unsigned dimension;
};
BoundingBox< k, T > boundingBox;
InputPoint* kdtree;
BoundingBox<k, T> boundingBox;
InputPoint *kdtree;
Iterator size;
};
}
#endif // STATICKDTREE_H_INCLUDED
File diff suppressed because it is too large Load Diff
+79 -113
View File
@@ -1,124 +1,90 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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.
#ifndef TURNINSTRUCTIONS_H_
#define TURNINSTRUCTIONS_H_
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 <string>
*/
typedef unsigned char TurnInstruction;
//This is a hack until c++0x is available enough to use scoped enums
struct TurnInstructionsClass {
const static TurnInstruction NoTurn = 0; //Give no instruction at all
const static TurnInstruction GoStraight = 1; //Tell user to go straight!
const static TurnInstruction TurnSlightRight = 2;
const static TurnInstruction TurnRight = 3;
const static TurnInstruction TurnSharpRight = 4;
const static TurnInstruction UTurn = 5;
const static TurnInstruction TurnSharpLeft = 6;
const static TurnInstruction TurnLeft = 7;
const static TurnInstruction TurnSlightLeft = 8;
const static TurnInstruction ReachViaPoint = 9;
const static TurnInstruction HeadOn = 10;
const static TurnInstruction EnterRoundAbout = 11;
const static TurnInstruction LeaveRoundAbout = 12;
const static TurnInstruction StayOnRoundAbout = 13;
const static TurnInstruction StartAtEndOfStreet = 14;
const static TurnInstruction ReachedYourDestination = 15;
const static TurnInstruction AccessRestrictionFlag = 128;
const static TurnInstruction InverseAccessRestrictionFlag = 0x7f; // ~128 does not work without a warning.
const static int AccessRestrictionPenalty = 1 << 15; //unrelated to the bit set in the restriction flag
// std::string TurnStrings[16];
// std::string Ordinals[12];
//This is a hack until c++0x is available enough to use initializer lists.
// TurnInstructionsClass(){
// TurnStrings [0] = "";
// TurnStrings [1] = "Continue";
// TurnStrings [2] = "Turn slight right";
// TurnStrings [3] = "Turn right";
// TurnStrings [4] = "Turn sharp right";
// TurnStrings [5] = "U-Turn";
// TurnStrings [6] = "Turn sharp left";
// TurnStrings [7] = "Turn left";
// TurnStrings [8] = "Turn slight left";
// TurnStrings [9] = "Reach via point";
// TurnStrings[10] = "Head";
// TurnStrings[11] = "Enter roundabout";
// TurnStrings[12] = "Leave roundabout";
// TurnStrings[13] = "Stay on roundabout";
// TurnStrings[14] = "Start";
// TurnStrings[15] = "You have reached your destination";
//
// Ordinals[0] = "zeroth";
// Ordinals[1] = "first";
// Ordinals[2] = "second";
// Ordinals[3] = "third";
// Ordinals[4] = "fourth";
// Ordinals[5] = "fifth";
// Ordinals[6] = "sixth";
// Ordinals[7] = "seventh";
// Ordinals[8] = "eighth";
// Ordinals[9] = "nineth";
// Ordinals[10] = "tenth";
// Ordinals[11] = "one of the too many";
// };
static inline TurnInstruction GetTurnDirectionOfInstruction( const double angle ) {
if(angle >= 23 && angle < 67) {
return TurnSharpRight;
}
if (angle >= 67 && angle < 113) {
return TurnRight;
}
if (angle >= 113 && angle < 158) {
return TurnSlightRight;
}
if (angle >= 158 && angle < 202) {
return GoStraight;
}
if (angle >= 202 && angle < 248) {
return TurnSlightLeft;
}
if (angle >= 248 && angle < 292) {
return TurnLeft;
}
if (angle >= 292 && angle < 336) {
return TurnSharpLeft;
}
return UTurn;
}
static inline bool TurnIsNecessary ( const short turnInstruction ) {
if(NoTurn == turnInstruction || StayOnRoundAbout == turnInstruction)
return false;
return true;
}
#ifndef TURN_INSTRUCTIONS_H
#define TURN_INSTRUCTIONS_H
enum class TurnInstruction : unsigned char
{
NoTurn = 0, GoStraight, TurnSlightRight, TurnRight, TurnSharpRight, UTurn,
TurnSharpLeft, TurnLeft, TurnSlightLeft, ReachViaPoint, HeadOn, EnterRoundAbout,
LeaveRoundAbout, StayOnRoundAbout, StartAtEndOfStreet, ReachedYourDestination,
EnterAgainstAllowedDirection, LeaveAgainstAllowedDirection,
InverseAccessRestrictionFlag = 127,
AccessRestrictionFlag = 128,
AccessRestrictionPenalty = 129
};
static TurnInstructionsClass TurnInstructions;
struct TurnInstructionsClass
{
TurnInstructionsClass() = delete;
TurnInstructionsClass(const TurnInstructionsClass&) = delete;
#endif /* TURNINSTRUCTIONS_H_ */
static inline TurnInstruction GetTurnDirectionOfInstruction(const double angle)
{
if (angle >= 23 && angle < 67)
{
return TurnInstruction::TurnSharpRight;
}
if (angle >= 67 && angle < 113)
{
return TurnInstruction::TurnRight;
}
if (angle >= 113 && angle < 158)
{
return TurnInstruction::TurnSlightRight;
}
if (angle >= 158 && angle < 202)
{
return TurnInstruction::GoStraight;
}
if (angle >= 202 && angle < 248)
{
return TurnInstruction::TurnSlightLeft;
}
if (angle >= 248 && angle < 292)
{
return TurnInstruction::TurnLeft;
}
if (angle >= 292 && angle < 336)
{
return TurnInstruction::TurnSharpLeft;
}
return TurnInstruction::UTurn;
}
static inline bool TurnIsNecessary(const TurnInstruction turn_instruction)
{
if (TurnInstruction::NoTurn == turn_instruction || TurnInstruction::StayOnRoundAbout == turn_instruction)
{
return false;
}
return true;
}
};
#endif /* TURN_INSTRUCTIONS_H */
-70
View File
@@ -1,70 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef TIMEUTIL_H_
#define TIMEUTIL_H_
#include <climits>
#include <cmath>
#include <cstdlib>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifdef _WIN32
#include <sys/timeb.h>
#include <sys/types.h>
#include <winsock.h>
void gettimeofday(struct timeval* t,void* timezone)
{ struct _timeb timebuffer;
_ftime( &timebuffer );
t->tv_sec=timebuffer.time;
t->tv_usec=1000*timebuffer.millitm;
}
#else
#include <sys/time.h>
#endif
#ifdef _WIN32
#include <boost/functional/hash.hpp>
#else
#include <tr1/functional_hash.h>
#endif
#include <boost/thread.hpp>
/** Returns a timestamp (now) in seconds (incl. a fractional part). */
static inline double get_timestamp() {
struct timeval tp;
gettimeofday(&tp, NULL);
return double(tp.tv_sec) + tp.tv_usec / 1000000.;
}
static inline double y2lat(double a) { return 180/M_PI * (2 * atan(exp(a*M_PI/180)) - M_PI/2); }
static inline double lat2y(double a) { return 180/M_PI * log(tan(M_PI/4+a*(M_PI/180)/2)); }
static inline unsigned boost_thread_id_hash(boost::thread::id const& id) {
std::stringstream ostr;
ostr << id;
std::tr1::hash<std::string> h;
return h(ostr.str());
}
#endif /* TIMEUTIL_H_ */
+52 -32
View File
@@ -1,31 +1,39 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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.
#ifndef FASTXORHASH_H_
#define FASTXORHASH_H_
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 XOR_FAST_HASH_H
#define XOR_FAST_HASH_H
#include <algorithm>
#include <vector>
/*
This is an implementation of Tabulation hashing, which has suprising properties like universality.
This is an implementation of Tabulation hashing, which has suprising properties like
universality.
The space requirement is 2*2^16 = 256 kb of memory, which fits into L2 cache.
Evaluation boils down to 10 or less assembly instruction on any recent X86 CPU:
@@ -41,49 +49,61 @@ or see http://www.gnu.org/licenses/agpl.txt.
10: ret
*/
class XORFastHash { //65k entries
class XORFastHash
{ // 65k entries
std::vector<unsigned short> table1;
std::vector<unsigned short> table2;
public:
XORFastHash() {
public:
XORFastHash()
{
table1.resize(2 << 16);
table2.resize(2 << 16);
for(unsigned i = 0; i < (2 << 16); ++i) {
table1[i] = i; table2[i];
for (unsigned i = 0; i < (2 << 16); ++i)
{
table1[i] = i;
table2[i] = i;
}
std::random_shuffle(table1.begin(), table1.end());
std::random_shuffle(table2.begin(), table2.end());
}
inline unsigned short operator()(const unsigned originalValue) const {
inline unsigned short operator()(const unsigned originalValue) const
{
unsigned short lsb = ((originalValue) & 0xffff);
unsigned short msb = (((originalValue) >> 16) & 0xffff);
return table1[lsb] ^ table2[msb];
}
};
class XORMiniHash { //256 entries
class XORMiniHash
{ // 256 entries
std::vector<unsigned char> table1;
std::vector<unsigned char> table2;
std::vector<unsigned char> table3;
std::vector<unsigned char> table4;
public:
XORMiniHash() {
public:
XORMiniHash()
{
table1.resize(1 << 8);
table2.resize(1 << 8);
table3.resize(1 << 8);
table4.resize(1 << 8);
for(unsigned i = 0; i < (1 << 8); ++i) {
table1[i] = i; table2[i];
table3[i] = i; table4[i];
for (unsigned i = 0; i < (1 << 8); ++i)
{
table1[i] = i;
table2[i] = i;
table3[i] = i;
table4[i] = i;
}
std::random_shuffle(table1.begin(), table1.end());
std::random_shuffle(table2.begin(), table2.end());
std::random_shuffle(table3.begin(), table3.end());
std::random_shuffle(table4.begin(), table4.end());
}
unsigned char operator()(const unsigned originalValue) const {
unsigned char operator()(const unsigned originalValue) const
{
unsigned char byte1 = ((originalValue) & 0xff);
unsigned char byte2 = ((originalValue >> 8) & 0xff);
unsigned char byte3 = ((originalValue >> 16) & 0xff);
@@ -92,4 +112,4 @@ public:
}
};
#endif /* FASTXORHASH_H_ */
#endif // XOR_FAST_HASH_H
+59 -50
View File
@@ -1,80 +1,89 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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.
#ifndef XORFASTHASHSTORAGE_H_
#define XORFASTHASHSTORAGE_H_
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 <climits>
#include <vector>
#include <bitset>
*/
#ifndef XOR_FAST_HASH_STORAGE_H
#define XOR_FAST_HASH_STORAGE_H
#include "XORFastHash.h"
template< typename NodeID, typename Key >
class XORFastHashStorage {
public:
struct HashCell{
#include <limits>
#include <vector>
template <typename NodeID, typename Key> class XORFastHashStorage
{
public:
struct HashCell
{
Key key;
NodeID id;
unsigned time;
HashCell() : key(UINT_MAX), id(UINT_MAX), time(UINT_MAX) {}
HashCell(const HashCell & other) : key(other.key), id(other.id), time(other.time) { }
inline operator Key() const {
return key;
HashCell()
: key(std::numeric_limits<unsigned>::max()), id(std::numeric_limits<unsigned>::max()),
time(std::numeric_limits<unsigned>::max())
{
}
inline void operator=(const Key & keyToInsert) {
key = keyToInsert;
}
HashCell(const HashCell &other) : key(other.key), id(other.id), time(other.time) {}
inline operator Key() const { return key; }
inline void operator=(const Key &key_to_insert) { key = key_to_insert; }
};
XORFastHashStorage( size_t ) : positions(2<<16), currentTimestamp(0) { }
explicit XORFastHashStorage(size_t) : positions(2 << 16), current_timestamp(0) {}
inline HashCell& operator[]( const NodeID node ) {
unsigned short position = fastHash(node);
while((positions[position].time == currentTimestamp) && (positions[position].id != node)){
++position %= (2<<16);
inline HashCell &operator[](const NodeID node)
{
unsigned short position = fast_hasher(node);
while ((positions[position].time == current_timestamp) && (positions[position].id != node))
{
++position %= (2 << 16);
}
positions[position].id = node;
positions[position].time = currentTimestamp;
positions[position].time = current_timestamp;
return positions[position];
}
inline void Clear() {
++currentTimestamp;
if(UINT_MAX == currentTimestamp) {
inline void Clear()
{
++current_timestamp;
if (std::numeric_limits<unsigned>::max() == current_timestamp)
{
positions.clear();
positions.resize((2<<16));
positions.resize((2 << 16));
}
}
private:
XORFastHashStorage() : positions(2<<16), currentTimestamp(0) {}
private:
XORFastHashStorage() : positions(2 << 16), current_timestamp(0) {}
std::vector<HashCell> positions;
XORFastHash fastHash;
unsigned currentTimestamp;
XORFastHash fast_hasher;
unsigned current_timestamp;
};
#endif /* XORFASTHASHSTORAGE_H_ */
#endif // XOR_FAST_HASH_STORAGE_H
+46 -40
View File
@@ -1,55 +1,61 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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.
#ifndef BASE_DESCRIPTOR_H_
#define BASE_DESCRIPTOR_H_
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 BASE_DESCRIPTOR_H
#define BASE_DESCRIPTOR_H
#include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/RawRouteData.h"
#include "../typedefs.h"
#include <osrm/Reply.h>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <string>
#include <vector>
#include "../typedefs.h"
#include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/HashTable.h"
#include "../Util/StringUtil.h"
#include "../Plugins/RawRouteData.h"
struct _DescriptorConfig {
_DescriptorConfig() : instructions(true), geometry(true), encodeGeometry(true), z(18) {}
struct DescriptorConfig
{
DescriptorConfig() : instructions(true), geometry(true), encode_geometry(true), zoom_level(18)
{
}
bool instructions;
bool geometry;
bool encodeGeometry;
unsigned short z;
bool encode_geometry;
unsigned short zoom_level;
};
template<class SearchEngineT>
class BaseDescriptor {
public:
BaseDescriptor() { }
//Maybe someone can explain the pure virtual destructor thing to me (dennis)
virtual ~BaseDescriptor() { }
virtual void Run(http::Reply & reply, const RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine) = 0;
virtual void SetConfig(const _DescriptorConfig & config) = 0;
template <class DataFacadeT> class BaseDescriptor
{
public:
BaseDescriptor() {}
// Maybe someone can explain the pure virtual destructor thing to me (dennis)
virtual ~BaseDescriptor() {}
virtual void Run(const RawRouteData &raw_route, http::Reply &reply) = 0;
virtual void SetConfig(const DescriptorConfig &config) = 0;
};
#endif /* BASE_DESCRIPTOR_H_ */
#endif // BASE_DESCRIPTOR_H
+73 -190
View File
@@ -1,210 +1,93 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 "DescriptionFactory.h"
DescriptionFactory::DescriptionFactory() : entireLength(0) { }
#include <osrm/Coordinate.h>
DescriptionFactory::~DescriptionFactory() { }
#include "../typedefs.h"
#include "../Algorithms/PolylineCompressor.h"
#include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/RawRouteData.h"
#include "../DataStructures/SegmentInformation.h"
#include "../DataStructures/TurnInstructions.h"
inline double DescriptionFactory::DegreeToRadian(const double degree) const {
return degree * (M_PI/180);
DescriptionFactory::DescriptionFactory() : entireLength(0) { via_indices.push_back(0); }
std::vector<unsigned> const &DescriptionFactory::GetViaIndices() const { return via_indices; }
void DescriptionFactory::SetStartSegment(const PhantomNode &source, const bool traversed_in_reverse)
{
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));
BOOST_ASSERT(path_description.back().duration == segment_duration);
}
inline double DescriptionFactory::RadianToDegree(const double radian) const {
return radian * (180/M_PI);
void DescriptionFactory::SetEndSegment(const PhantomNode &target, const bool traversed_in_reverse)
{
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);
BOOST_ASSERT(path_description.back().duration == segment_duration);
}
double DescriptionFactory::GetBearing(const _Coordinate& A, const _Coordinate& B) const {
double deltaLong = DegreeToRadian(B.lon/100000. - A.lon/100000.);
double lat1 = DegreeToRadian(A.lat/100000.);
double lat2 = DegreeToRadian(B.lat/100000.);
double y = sin(deltaLong) * cos(lat2);
double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(deltaLong);
double result = RadianToDegree(atan2(y, x));
while(result <= 0.)
result += 360.;
while(result >= 360.)
result -= 360.;
return result;
}
void DescriptionFactory::SetStartSegment(const PhantomNode & _startPhantom) {
startPhantom = _startPhantom;
AppendSegment(_startPhantom.location, _PathData(0, _startPhantom.nodeBasedEdgeNameID, 10, _startPhantom.weight1));
}
void DescriptionFactory::SetEndSegment(const PhantomNode & _targetPhantom) {
targetPhantom = _targetPhantom;
pathDescription.push_back(SegmentInformation(_targetPhantom.location, _targetPhantom.nodeBasedEdgeNameID, 0, _targetPhantom.weight1, 0, true) );
}
void DescriptionFactory::AppendSegment(const _Coordinate & coordinate, const _PathData & data ) {
if(1 == pathDescription.size() && pathDescription.back().location == coordinate) {
pathDescription.back().nameID = data.nameID;
} else {
pathDescription.push_back(SegmentInformation(coordinate, data.nameID, 0, data.durationOfSegment, data.turnInstruction) );
}
}
void DescriptionFactory::AppendEncodedPolylineString(std::string & output, bool isEncoded) {
if(isEncoded)
pc.printEncodedString(pathDescription, output);
else
pc.printUnencodedString(pathDescription, output);
}
void DescriptionFactory::AppendEncodedPolylineString(std::string &output) {
pc.printEncodedString(pathDescription, output);
}
void DescriptionFactory::AppendUnencodedPolylineString(std::string &output) {
pc.printUnencodedString(pathDescription, output);
}
void DescriptionFactory::Run(const SearchEngineT &sEngine, const unsigned zoomLevel) {
if(0 == pathDescription.size())
void DescriptionFactory::AppendSegment(const FixedPointCoordinate &coordinate,
const PathData &path_point)
{
if ((1 == path_description.size()) && (path_description.back().location == coordinate))
{
path_description.back().name_id = path_point.name_id;
return;
// unsigned entireLength = 0;
/** starts at index 1 */
pathDescription[0].length = 0;
for(unsigned i = 1; i < pathDescription.size(); ++i) {
pathDescription[i].length = ApproximateDistanceByEuclid(pathDescription[i-1].location, pathDescription[i].location);
}
double lengthOfSegment = 0;
unsigned durationOfSegment = 0;
unsigned indexOfSegmentBegin = 0;
std::string string0 = sEngine.GetEscapedNameForNameID(pathDescription[0].nameID);
std::string string1;
/*Simplify turn instructions
Input :
10. Turn left on B 36 for 20 km
11. Continue on B 35; B 36 for 2 km
12. Continue on B 36 for 13 km
becomes:
10. Turn left on B 36 for 35 km
*/
//TODO: rework to check only end and start of string.
// stl string is way to expensive
// unsigned lastTurn = 0;
// for(unsigned i = 1; i < pathDescription.size(); ++i) {
// string1 = sEngine.GetEscapedNameForNameID(pathDescription[i].nameID);
// if(TurnInstructionsClass::GoStraight == pathDescription[i].turnInstruction) {
// if(std::string::npos != string0.find(string1+";")
// || std::string::npos != string0.find(";"+string1)
// || std::string::npos != string0.find(string1+" ;")
// || std::string::npos != string0.find("; "+string1)
// ){
// INFO("->next correct: " << string0 << " contains " << string1);
// for(; lastTurn != i; ++lastTurn)
// pathDescription[lastTurn].nameID = pathDescription[i].nameID;
// pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn;
// } else if(std::string::npos != string1.find(string0+";")
// || std::string::npos != string1.find(";"+string0)
// || std::string::npos != string1.find(string0+" ;")
// || std::string::npos != string1.find("; "+string0)
// ){
// INFO("->prev correct: " << string1 << " contains " << string0);
// pathDescription[i].nameID = pathDescription[i-1].nameID;
// pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn;
// }
// }
// if (TurnInstructionsClass::NoTurn != pathDescription[i].turnInstruction) {
// lastTurn = i;
// }
// string0 = string1;
// }
for(unsigned i = 1; i < pathDescription.size(); ++i) {
entireLength += pathDescription[i].length;
lengthOfSegment += pathDescription[i].length;
durationOfSegment += pathDescription[i].duration;
pathDescription[indexOfSegmentBegin].length = lengthOfSegment;
pathDescription[indexOfSegmentBegin].duration = durationOfSegment;
if(TurnInstructionsClass::NoTurn != pathDescription[i].turnInstruction) {
//INFO("Turn after " << lengthOfSegment << "m into way with name id " << segment.nameID);
assert(pathDescription[i].necessary);
lengthOfSegment = 0;
durationOfSegment = 0;
indexOfSegmentBegin = i;
}
}
// INFO("#segs: " << pathDescription.size());
//Post-processing to remove empty or nearly empty path segments
if(FLT_EPSILON > pathDescription.back().length) {
// INFO("#segs: " << pathDescription.size() << ", last ratio: " << targetPhantom.ratio << ", length: " << pathDescription.back().length);
if(pathDescription.size() > 2){
pathDescription.pop_back();
pathDescription.back().necessary = true;
pathDescription.back().turnInstruction = TurnInstructions.NoTurn;
targetPhantom.nodeBasedEdgeNameID = (pathDescription.end()-2)->nameID;
// INFO("Deleting last turn instruction");
}
} else {
pathDescription[indexOfSegmentBegin].duration *= (1.-targetPhantom.ratio);
}
if(FLT_EPSILON > pathDescription[0].length) {
//TODO: this is never called actually?
if(pathDescription.size() > 2) {
pathDescription.erase(pathDescription.begin());
pathDescription[0].turnInstruction = TurnInstructions.HeadOn;
pathDescription[0].necessary = true;
startPhantom.nodeBasedEdgeNameID = pathDescription[0].nameID;
// INFO("Deleting first turn instruction, ratio: " << startPhantom.ratio << ", length: " << pathDescription[0].length);
}
} else {
pathDescription[0].duration *= startPhantom.ratio;
}
//Generalize poly line
dp.Run(pathDescription, zoomLevel);
//fix what needs to be fixed else
for(unsigned i = 0; i < pathDescription.size()-1 && pathDescription.size() >= 2; ++i){
if(pathDescription[i].necessary) {
double angle = GetBearing(pathDescription[i].location, pathDescription[i+1].location);
pathDescription[i].bearing = angle;
}
}
// BuildRouteSummary(entireLength, duration);
return;
path_description.emplace_back(coordinate,
path_point.name_id,
path_point.segment_duration,
0,
path_point.turn_instruction);
}
void DescriptionFactory::BuildRouteSummary(const double distance, const unsigned time) {
summary.startName = startPhantom.nodeBasedEdgeNameID;
summary.destName = targetPhantom.nodeBasedEdgeNameID;
JSON::Value DescriptionFactory::AppendEncodedPolylineString(const bool return_encoded)
{
if (return_encoded)
{
return polyline_compressor.printEncodedString(path_description);
}
return polyline_compressor.printUnencodedString(path_description);
}
void DescriptionFactory::BuildRouteSummary(const double distance, const unsigned time)
{
summary.source_name_id = start_phantom.name_id;
summary.target_name_id = target_phantom.name_id;
summary.BuildDurationAndLengthStrings(distance, time);
}
+186 -54
View File
@@ -1,83 +1,215 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 DESCRIPTIONFACTORY_H_
#define DESCRIPTIONFACTORY_H_
#include <vector>
#include "../typedefs.h"
#include "../Algorithms/DouglasPeucker.h"
#include "../Algorithms/PolylineCompressor.h"
#include "../DataStructures/Coordinate.h"
#include "../DataStructures/QueryEdge.h"
#include "../DataStructures/SearchEngine.h"
#include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/SegmentInformation.h"
#include "../DataStructures/TurnInstructions.h"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <limits>
#include <vector>
struct PathData;
/* This class is fed with all way segments in consecutive order
* and produces the description plus the encoded polyline */
class DescriptionFactory {
DouglasPeucker<SegmentInformation> dp;
PolylineCompressor pc;
PhantomNode startPhantom, targetPhantom;
typedef SearchEngine<QueryEdge::EdgeData, StaticGraph<QueryEdge::EdgeData> > SearchEngineT;
class DescriptionFactory
{
DouglasPeucker polyline_generalizer;
PolylineCompressor polyline_compressor;
PhantomNode start_phantom, target_phantom;
double DegreeToRadian(const double degree) const;
double RadianToDegree(const double degree) const;
public:
struct _RouteSummary {
std::string lengthString;
std::string durationString;
unsigned startName;
unsigned destName;
_RouteSummary() : lengthString("0"), durationString("0"), startName(0), destName(0) {}
void BuildDurationAndLengthStrings(const double distance, const unsigned time) {
//compute distance/duration for route summary
std::ostringstream s;
s << round(distance);
lengthString = s.str();
int travelTime = time/10 + 1;
s.str("");
s << travelTime;
durationString = s.str();
std::vector<unsigned> via_indices;
public:
struct RouteSummary
{
unsigned distance;
EdgeWeight duration;
unsigned source_name_id;
unsigned target_name_id;
RouteSummary() : distance(0), duration(0), source_name_id(0), target_name_id(0) {}
void BuildDurationAndLengthStrings(const double raw_distance, const unsigned raw_duration)
{
// compute distance/duration for route summary
distance = static_cast<unsigned>(round(raw_distance));
duration = static_cast<unsigned>(round(raw_duration / 10.));
}
} summary;
double entireLength;
//I know, declaring this public is considered bad. I'm lazy
std::vector <SegmentInformation> pathDescription;
// I know, declaring this public is considered bad. I'm lazy
std::vector<SegmentInformation> path_description;
DescriptionFactory();
virtual ~DescriptionFactory();
double GetBearing(const _Coordinate& C, const _Coordinate& B) const;
void AppendEncodedPolylineString(std::string &output);
void AppendUnencodedPolylineString(std::string &output);
void AppendSegment(const _Coordinate & coordinate, const _PathData & data);
void AppendSegment(const FixedPointCoordinate &coordinate, const PathData &data);
void BuildRouteSummary(const double distance, const unsigned time);
void SetStartSegment(const PhantomNode & startPhantom);
void SetEndSegment(const PhantomNode & startPhantom);
void AppendEncodedPolylineString(std::string & output, bool isEncoded);
void Run(const SearchEngineT &sEngine, const unsigned zoomLevel);
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;
template <class DataFacadeT> void Run(const DataFacadeT *facade, const unsigned zoomLevel)
{
if (path_description.empty())
{
return;
}
/** starts at index 1 */
path_description[0].length = 0;
for (unsigned i = 1; i < path_description.size(); ++i)
{
// move down names by one, q&d hack
path_description[i - 1].name_id = path_description[i].name_id;
path_description[i].length = FixedPointCoordinate::ApproximateEuclideanDistance(
path_description[i - 1].location, path_description[i].location);
}
/*Simplify turn instructions
Input :
10. Turn left on B 36 for 20 km
11. Continue on B 35; B 36 for 2 km
12. Continue on B 36 for 13 km
becomes:
10. Turn left on B 36 for 35 km
*/
// TODO: rework to check only end and start of string.
// stl string is way to expensive
// unsigned lastTurn = 0;
// for(unsigned i = 1; i < path_description.size(); ++i) {
// string1 = sEngine.GetEscapedNameForNameID(path_description[i].name_id);
// if(TurnInstruction::GoStraight == path_description[i].turn_instruction) {
// if(std::string::npos != string0.find(string1+";")
// || std::string::npos != string0.find(";"+string1)
// || std::string::npos != string0.find(string1+" ;")
// || std::string::npos != string0.find("; "+string1)
// ){
// SimpleLogger().Write() << "->next correct: " << string0 << " contains " <<
// string1;
// for(; lastTurn != i; ++lastTurn)
// path_description[lastTurn].name_id = path_description[i].name_id;
// path_description[i].turn_instruction = TurnInstruction::NoTurn;
// } else if(std::string::npos != string1.find(string0+";")
// || std::string::npos != string1.find(";"+string0)
// || std::string::npos != string1.find(string0+" ;")
// || std::string::npos != string1.find("; "+string0)
// ){
// SimpleLogger().Write() << "->prev correct: " << string1 << " contains " <<
// string0;
// path_description[i].name_id = path_description[i-1].name_id;
// path_description[i].turn_instruction = TurnInstruction::NoTurn;
// }
// }
// if (TurnInstruction::NoTurn != path_description[i].turn_instruction) {
// lastTurn = i;
// }
// string0 = string1;
// }
float segment_length = 0.;
unsigned segment_duration = 0;
unsigned segment_start_index = 0;
for (unsigned i = 1; i < path_description.size(); ++i)
{
entireLength += path_description[i].length;
segment_length += path_description[i].length;
segment_duration += path_description[i].duration;
path_description[segment_start_index].length = segment_length;
path_description[segment_start_index].duration = segment_duration;
if (TurnInstruction::NoTurn != path_description[i].turn_instruction)
{
BOOST_ASSERT(path_description[i].necessary);
segment_length = 0;
segment_duration = 0;
segment_start_index = i;
}
}
// Post-processing to remove empty or nearly empty path segments
if (std::numeric_limits<double>::epsilon() > path_description.back().length)
{
if (path_description.size() > 2)
{
path_description.pop_back();
path_description.back().necessary = true;
path_description.back().turn_instruction = TurnInstruction::NoTurn;
target_phantom.name_id = (path_description.end() - 2)->name_id;
}
}
if (std::numeric_limits<double>::epsilon() > path_description.front().length)
{
if (path_description.size() > 2)
{
path_description.erase(path_description.begin());
path_description.front().turn_instruction = TurnInstruction::HeadOn;
path_description.front().necessary = true;
start_phantom.name_id = path_description.front().name_id;
}
}
// Generalize poly line
polyline_generalizer.Run(path_description, zoomLevel);
// fix what needs to be fixed else
unsigned necessary_pieces = 0; // a running index that counts the necessary pieces
for (unsigned i = 0; i < path_description.size() - 1 && path_description.size() >= 2; ++i)
{
if (path_description[i].necessary)
{
++necessary_pieces;
if (path_description[i].is_via_location)
{ //mark the end of a leg
via_indices.push_back(necessary_pieces);
}
const double angle = path_description[i+1].location.GetBearing(path_description[i].location);
path_description[i].bearing = static_cast<unsigned>(angle * 10);
}
}
via_indices.push_back(necessary_pieces+1);
BOOST_ASSERT(via_indices.size() >= 2);
// BOOST_ASSERT(0 != necessary_pieces || path_description.empty());
return;
}
};
#endif /* DESCRIPTIONFACTORY_H_ */
+85 -50
View File
@@ -1,65 +1,100 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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.
#ifndef GPX_DESCRIPTOR_H_
#define GPX_DESCRIPTOR_H_
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 GPX_DESCRIPTOR_H
#define GPX_DESCRIPTOR_H
#include <boost/foreach.hpp>
#include "BaseDescriptor.h"
template<class SearchEngineT>
class GPXDescriptor : public BaseDescriptor<SearchEngineT>{
private:
_DescriptorConfig config;
_Coordinate current;
template <class DataFacadeT> class GPXDescriptor : public BaseDescriptor<DataFacadeT>
{
private:
DescriptorConfig config;
FixedPointCoordinate current;
DataFacadeT * facade;
std::string tmp;
public:
void SetConfig(const _DescriptorConfig& c) { config = c; }
void Run(http::Reply & reply, const RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine) {
reply.content += ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
reply.content += "<gpx creator=\"OSRM Routing Engine\" version=\"1.1\" xmlns=\"http://www.topografix.com/GPX/1/1\" "
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
"xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 gpx.xsd"
"\">";
reply.content += "<rte>";
if(rawRoute.lengthOfShortestPath != INT_MAX && rawRoute.computedShortestPath.size()) {
convertInternalLatLonToString(phantomNodes.startPhantom.location.lat, tmp);
reply.content += "<rtept lat=\"" + tmp + "\" ";
convertInternalLatLonToString(phantomNodes.startPhantom.location.lon, tmp);
reply.content += "lon=\"" + tmp + "\"></rtept>";
void AddRoutePoint(const FixedPointCoordinate & coordinate, std::vector<char> & output)
{
const std::string route_point_head = "<rtept lat=\"";
const std::string route_point_middle = " lon=\"";
const std::string route_point_tail = "\"></rtept>";
BOOST_FOREACH(_PathData pathData, rawRoute.computedShortestPath) {
sEngine.GetCoordinatesForNodeID(pathData.node, current);
std::string tmp;
convertInternalLatLonToString(current.lat, tmp);
reply.content += "<rtept lat=\"" + tmp + "\" ";
convertInternalLatLonToString(current.lon, tmp);
reply.content += "lon=\"" + tmp + "\"></rtept>";
FixedPointCoordinate::convertInternalLatLonToString(coordinate.lat, tmp);
output.insert(output.end(), route_point_head.begin(), route_point_head.end());
output.insert(output.end(), tmp.begin(), tmp.end());
output.push_back('\"');
FixedPointCoordinate::convertInternalLatLonToString(coordinate.lon, tmp);
output.insert(output.end(), route_point_middle.begin(), route_point_middle.end());
output.insert(output.end(), tmp.begin(), tmp.end());
output.insert(output.end(), route_point_tail.begin(), route_point_tail.end());
}
public:
GPXDescriptor(DataFacadeT *facade) : facade(facade) {}
void SetConfig(const DescriptorConfig &c) { config = c; }
// TODO: reorder parameters
void Run(const RawRouteData &raw_route, http::Reply &reply)
{
std::string header("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<gpx creator=\"OSRM Routing Engine\" version=\"1.1\" "
"xmlns=\"http://www.topografix.com/GPX/1/1\" "
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
"xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 gpx.xsd"
"\">"
"<metadata><copyright author=\"Project OSRM\"><license>Data (c)"
" OpenStreetMap contributors (ODbL)</license></copyright>"
"</metadata>"
"<rte>");
reply.content.insert(reply.content.end(), header.begin(), header.end());
const bool found_route = (raw_route.shortest_path_length != INVALID_EDGE_WEIGHT) &&
(!raw_route.unpacked_path_segments.front().empty());
if (found_route)
{
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)
{
for (const PathData &path_data : path_data_vector)
{
const FixedPointCoordinate current_coordinate =
facade->GetCoordinateOfNode(path_data.node);
AddRoutePoint(current_coordinate, reply.content);
}
}
convertInternalLatLonToString(phantomNodes.targetPhantom.location.lat, tmp);
reply.content += "<rtept lat=\"" + tmp + "\" ";
convertInternalLatLonToString(phantomNodes.targetPhantom.location.lon, tmp);
reply.content += "lon=\"" + tmp + "\"></rtept>";
AddRoutePoint(raw_route.segment_end_coordinates.back().target_phantom.location, reply.content);
}
reply.content += "</rte></gpx>";
std::string footer("</rte></gpx>");
reply.content.insert(reply.content.end(), footer.begin(), footer.end());
}
};
#endif /* GPX_DESCRIPTOR_H_ */
#endif // GPX_DESCRIPTOR_H
+385 -391
View File
@@ -1,391 +1,385 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef JSON_DESCRIPTOR_H_
#define JSON_DESCRIPTOR_H_
#include <algorithm>
#include <boost/lambda/lambda.hpp>
#include <boost/bind.hpp>
#include "BaseDescriptor.h"
#include "DescriptionFactory.h"
#include "../Algorithms/ObjectToBase64.h"
#include "../DataStructures/SegmentInformation.h"
#include "../DataStructures/TurnInstructions.h"
#include "../Util/Azimuth.h"
#include "../Util/StringUtil.h"
template<class SearchEngineT>
class JSONDescriptor : public BaseDescriptor<SearchEngineT>{
private:
_DescriptorConfig config;
DescriptionFactory descriptionFactory;
DescriptionFactory alternateDescriptionFactory;
_Coordinate current;
unsigned numberOfEnteredRestrictedAreas;
struct {
int startIndex;
int nameID;
int leaveAtExit;
} roundAbout;
struct Segment {
Segment() : nameID(-1), length(-1), position(-1) {}
Segment(int n, int l, int p) : nameID(n), length(l), position(p) {}
int nameID;
int length;
int position;
};
std::vector<Segment> shortestSegments, alternativeSegments;
struct RouteNames {
std::string shortestPathName1;
std::string shortestPathName2;
std::string alternativePathName1;
std::string alternativePathName2;
};
public:
JSONDescriptor() : numberOfEnteredRestrictedAreas(0) {}
void SetConfig(const _DescriptorConfig & c) { config = c; }
void Run(http::Reply & reply, const RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine) {
WriteHeaderToOutput(reply.content);
if(rawRoute.lengthOfShortestPath != INT_MAX) {
descriptionFactory.SetStartSegment(phantomNodes.startPhantom);
reply.content += "0,"
"\"status_message\": \"Found route between points\",";
//Get all the coordinates for the computed route
BOOST_FOREACH(const _PathData & pathData, rawRoute.computedShortestPath) {
sEngine.GetCoordinatesForNodeID(pathData.node, current);
descriptionFactory.AppendSegment(current, pathData );
}
descriptionFactory.SetEndSegment(phantomNodes.targetPhantom);
} else {
//We do not need to do much, if there is no route ;-)
reply.content += "207,"
"\"status_message\": \"Cannot find route between points\",";
}
descriptionFactory.Run(sEngine, config.z);
reply.content += "\"route_geometry\": ";
if(config.geometry) {
descriptionFactory.AppendEncodedPolylineString(reply.content, config.encodeGeometry);
} else {
reply.content += "[]";
}
reply.content += ","
"\"route_instructions\": [";
numberOfEnteredRestrictedAreas = 0;
if(config.instructions) {
BuildTextualDescription(descriptionFactory, reply, rawRoute.lengthOfShortestPath, sEngine, shortestSegments);
} else {
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) {
TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction);
}
}
reply.content += "],";
descriptionFactory.BuildRouteSummary(descriptionFactory.entireLength, rawRoute.lengthOfShortestPath - ( numberOfEnteredRestrictedAreas*TurnInstructions.AccessRestrictionPenalty));
reply.content += "\"route_summary\":";
reply.content += "{";
reply.content += "\"total_distance\":";
reply.content += descriptionFactory.summary.lengthString;
reply.content += ","
"\"total_time\":";
reply.content += descriptionFactory.summary.durationString;
reply.content += ","
"\"start_point\":\"";
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.startName);
reply.content += "\","
"\"end_point\":\"";
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.destName);
reply.content += "\"";
reply.content += "}";
reply.content +=",";
//only one alternative route is computed at this time, so this is hardcoded
if(rawRoute.lengthOfAlternativePath != INT_MAX) {
alternateDescriptionFactory.SetStartSegment(phantomNodes.startPhantom);
//Get all the coordinates for the computed route
BOOST_FOREACH(const _PathData & pathData, rawRoute.computedAlternativePath) {
sEngine.GetCoordinatesForNodeID(pathData.node, current);
alternateDescriptionFactory.AppendSegment(current, pathData );
}
alternateDescriptionFactory.SetEndSegment(phantomNodes.targetPhantom);
}
alternateDescriptionFactory.Run(sEngine, config.z);
//give an array of alternative routes
reply.content += "\"alternative_geometries\": [";
if(config.geometry && INT_MAX != rawRoute.lengthOfAlternativePath) {
//Generate the linestrings for each alternative
alternateDescriptionFactory.AppendEncodedPolylineString(reply.content, config.encodeGeometry);
}
reply.content += "],";
reply.content += "\"alternative_instructions\":[";
numberOfEnteredRestrictedAreas = 0;
if(INT_MAX != rawRoute.lengthOfAlternativePath) {
reply.content += "[";
//Generate instructions for each alternative
if(config.instructions) {
BuildTextualDescription(alternateDescriptionFactory, reply, rawRoute.lengthOfAlternativePath, sEngine, alternativeSegments);
} else {
BOOST_FOREACH(const SegmentInformation & segment, alternateDescriptionFactory.pathDescription) {
TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction);
}
}
reply.content += "]";
}
reply.content += "],";
reply.content += "\"alternative_summaries\":[";
if(INT_MAX != rawRoute.lengthOfAlternativePath) {
//Generate route summary (length, duration) for each alternative
alternateDescriptionFactory.BuildRouteSummary(alternateDescriptionFactory.entireLength, rawRoute.lengthOfAlternativePath - ( numberOfEnteredRestrictedAreas*TurnInstructions.AccessRestrictionPenalty));
reply.content += "{";
reply.content += "\"total_distance\":";
reply.content += alternateDescriptionFactory.summary.lengthString;
reply.content += ","
"\"total_time\":";
reply.content += alternateDescriptionFactory.summary.durationString;
reply.content += ","
"\"start_point\":\"";
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.startName);
reply.content += "\","
"\"end_point\":\"";
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.destName);
reply.content += "\"";
reply.content += "}";
}
reply.content += "],";
//Get Names for both routes
RouteNames routeNames;
GetRouteNames(shortestSegments, alternativeSegments, sEngine, routeNames);
reply.content += "\"route_name\":[\"";
reply.content += routeNames.shortestPathName1;
reply.content += "\",\"";
reply.content += routeNames.shortestPathName2;
reply.content += "\"],"
"\"alternative_names\":[";
reply.content += "[\"";
reply.content += routeNames.alternativePathName1;
reply.content += "\",\"";
reply.content += routeNames.alternativePathName2;
reply.content += "\"]";
reply.content += "],";
//list all viapoints so that the client may display it
reply.content += "\"via_points\":[";
std::string tmp;
if(config.geometry && INT_MAX != rawRoute.lengthOfShortestPath) {
for(unsigned i = 0; i < rawRoute.segmentEndCoordinates.size(); ++i) {
reply.content += "[";
if(rawRoute.segmentEndCoordinates[i].startPhantom.location.isSet())
convertInternalReversedCoordinateToString(rawRoute.segmentEndCoordinates[i].startPhantom.location, tmp);
else
convertInternalReversedCoordinateToString(rawRoute.rawViaNodeCoordinates[i], tmp);
reply.content += tmp;
reply.content += "],";
}
reply.content += "[";
if(rawRoute.segmentEndCoordinates.back().startPhantom.location.isSet())
convertInternalReversedCoordinateToString(rawRoute.segmentEndCoordinates.back().targetPhantom.location, tmp);
else
convertInternalReversedCoordinateToString(rawRoute.rawViaNodeCoordinates.back(), tmp);
reply.content += tmp;
reply.content += "]";
}
reply.content += "],";
reply.content += "\"hint_data\": {";
reply.content += "\"checksum\":";
intToString(rawRoute.checkSum, tmp);
reply.content += tmp;
reply.content += ", \"locations\": [";
std::string hint;
for(unsigned i = 0; i < rawRoute.segmentEndCoordinates.size(); ++i) {
reply.content += "\"";
EncodeObjectToBase64(rawRoute.segmentEndCoordinates[i].startPhantom, hint);
reply.content += hint;
reply.content += "\", ";
}
EncodeObjectToBase64(rawRoute.segmentEndCoordinates.back().targetPhantom, hint);
reply.content += "\"";
reply.content += hint;
reply.content += "\"]";
reply.content += "},";
reply.content += "\"transactionId\": \"OSRM Routing Engine JSON Descriptor (v0.3)\"";
reply.content += "}";
}
void GetRouteNames(std::vector<Segment> & shortestSegments, std::vector<Segment> & alternativeSegments, SearchEngineT &sEngine, RouteNames & routeNames) {
/*** extract names for both alternatives ***/
Segment shortestSegment1, shortestSegment2;
Segment alternativeSegment1, alternativeSegment2;
if(0 < shortestSegments.size()) {
sort(shortestSegments.begin(), shortestSegments.end(), boost::bind(&Segment::length, _1) > boost::bind(&Segment::length, _2) );
shortestSegment1 = shortestSegments[0];
if(0 < alternativeSegments.size()) {
sort(alternativeSegments.begin(), alternativeSegments.end(), boost::bind(&Segment::length, _1) > boost::bind(&Segment::length, _2) );
alternativeSegment1 = alternativeSegments[0];
}
std::vector<Segment> shortestDifference(shortestSegments.size());
std::vector<Segment> alternativeDifference(alternativeSegments.size());
std::set_difference(shortestSegments.begin(), shortestSegments.end(), alternativeSegments.begin(), alternativeSegments.end(), shortestDifference.begin(), boost::bind(&Segment::nameID, _1) < boost::bind(&Segment::nameID, _2) );
if(0 < shortestDifference.size() ) {
unsigned i = 0;
while( i < shortestDifference.size() && shortestDifference[i].nameID == shortestSegments[0].nameID) {
++i;
}
if(i < shortestDifference.size()) {
shortestSegment2 = shortestDifference[i];
}
}
std::set_difference(alternativeSegments.begin(), alternativeSegments.end(), shortestSegments.begin(), shortestSegments.end(), alternativeDifference.begin(), boost::bind(&Segment::nameID, _1) < boost::bind(&Segment::nameID, _2) );
if(0 < alternativeDifference.size() ) {
unsigned i = 0;
while( i < alternativeDifference.size() && alternativeDifference[i].nameID == alternativeSegments[0].nameID) {
++i;
}
if(i < alternativeDifference.size()) {
alternativeSegment2 = alternativeDifference[i];
}
}
if(shortestSegment1.position > shortestSegment2.position)
std::swap(shortestSegment1, shortestSegment2);
if(alternativeSegment1.position > alternativeSegment2.position)
std::swap(alternativeSegment1, alternativeSegment2);
routeNames.shortestPathName1 = sEngine.GetEscapedNameForNameID(shortestSegment1.nameID);
routeNames.shortestPathName2 = sEngine.GetEscapedNameForNameID(shortestSegment2.nameID);
routeNames.alternativePathName1 = sEngine.GetEscapedNameForNameID(alternativeSegment1.nameID);
routeNames.alternativePathName2 += sEngine.GetEscapedNameForNameID(alternativeSegment2.nameID);
}
}
inline void WriteHeaderToOutput(std::string & output) {
output += "{"
"\"version\": 0.3,"
"\"status\":";
}
inline void BuildTextualDescription(DescriptionFactory & descriptionFactory, http::Reply & reply, const int lengthOfRoute, const SearchEngineT &sEngine, std::vector<Segment> & segmentVector) {
//Segment information has following format:
//["instruction","streetname",length,position,time,"length","earth_direction",azimuth]
//Example: ["Turn left","High Street",200,4,10,"200m","NE",22.5]
//See also: http://developers.cloudmade.com/wiki/navengine/JSON_format
unsigned prefixSumOfNecessarySegments = 0;
roundAbout.leaveAtExit = 0;
roundAbout.nameID = 0;
std::string tmpDist, tmpLength, tmpDuration, tmpBearing, tmpInstruction;
//Fetch data from Factory and generate a string from it.
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) {
TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction);
if(TurnInstructions.TurnIsNecessary( currentInstruction) ) {
if(TurnInstructions.EnterRoundAbout == currentInstruction) {
roundAbout.nameID = segment.nameID;
roundAbout.startIndex = prefixSumOfNecessarySegments;
} else {
if(0 != prefixSumOfNecessarySegments){
reply.content += ",";
}
reply.content += "[\"";
if(TurnInstructions.LeaveRoundAbout == currentInstruction) {
intToString(TurnInstructions.EnterRoundAbout, tmpInstruction);
reply.content += tmpInstruction;
reply.content += "-";
intToString(roundAbout.leaveAtExit+1, tmpInstruction);
reply.content += tmpInstruction;
roundAbout.leaveAtExit = 0;
} else {
intToString(currentInstruction, tmpInstruction);
reply.content += tmpInstruction;
}
reply.content += "\",\"";
reply.content += sEngine.GetEscapedNameForNameID(segment.nameID);
reply.content += "\",";
intToString(segment.length, tmpDist);
reply.content += tmpDist;
reply.content += ",";
intToString(prefixSumOfNecessarySegments, tmpLength);
reply.content += tmpLength;
reply.content += ",";
intToString(segment.duration/10, tmpDuration);
reply.content += tmpDuration;
reply.content += ",\"";
intToString(segment.length, tmpLength);
reply.content += tmpLength;
reply.content += "m\",\"";
reply.content += Azimuth::Get(segment.bearing);
reply.content += "\",";
intToString(round(segment.bearing), tmpBearing);
reply.content += tmpBearing;
reply.content += "]";
segmentVector.push_back( Segment(segment.nameID, segment.length, segmentVector.size() ));
}
} else if(TurnInstructions.StayOnRoundAbout == currentInstruction) {
++roundAbout.leaveAtExit;
}
if(segment.necessary)
++prefixSumOfNecessarySegments;
}
if(INT_MAX != lengthOfRoute) {
reply.content += ",[\"";
intToString(TurnInstructions.ReachedYourDestination, tmpInstruction);
reply.content += tmpInstruction;
reply.content += "\",\"";
reply.content += "\",";
reply.content += "0";
reply.content += ",";
intToString(prefixSumOfNecessarySegments-1, tmpLength);
reply.content += tmpLength;
reply.content += ",";
reply.content += "0";
reply.content += ",\"";
reply.content += "\",\"";
reply.content += Azimuth::Get(0.0);
reply.content += "\",";
reply.content += "0.0";
reply.content += "]";
}
}
};
#endif /* JSON_DESCRIPTOR_H_ */
/*
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 JSON_DESCRIPTOR_H_
#define JSON_DESCRIPTOR_H_
#include "BaseDescriptor.h"
#include "DescriptionFactory.h"
#include "../Algorithms/ObjectToBase64.h"
#include "../Algorithms/ExtractRouteNames.h"
#include "../DataStructures/JSONContainer.h"
#include "../DataStructures/SegmentInformation.h"
#include "../DataStructures/TurnInstructions.h"
#include "../Util/Azimuth.h"
#include "../Util/StringUtil.h"
#include "../Util/TimingUtil.h"
#include <algorithm>
template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFacadeT>
{
private:
DataFacadeT *facade;
DescriptorConfig config;
DescriptionFactory description_factory, alternate_description_factory;
FixedPointCoordinate current;
unsigned entered_restricted_area_count;
struct RoundAbout
{
RoundAbout() : start_index(INT_MAX), name_id(INVALID_NAMEID), leave_at_exit(INT_MAX) {}
int start_index;
unsigned name_id;
int leave_at_exit;
} round_about;
struct Segment
{
Segment() : name_id(INVALID_NAMEID), length(-1), position(0) {}
Segment(unsigned n, int l, unsigned p) : name_id(n), length(l), position(p) {}
unsigned name_id;
int length;
unsigned position;
};
std::vector<Segment> shortest_path_segments, alternative_path_segments;
ExtractRouteNames<DataFacadeT, Segment> GenerateRouteNames;
public:
JSONDescriptor(DataFacadeT *facade) : facade(facade), entered_restricted_area_count(0) {}
void SetConfig(const DescriptorConfig &c) { config = c; }
unsigned DescribeLeg(const std::vector<PathData> route_leg,
const PhantomNodes &leg_phantoms,
const bool target_traversed_in_reverse)
{
unsigned added_element_count = 0;
// Get all the coordinates for the computed route
FixedPointCoordinate current_coordinate;
for (const PathData &path_data : route_leg)
{
current_coordinate = facade->GetCoordinateOfNode(path_data.node);
description_factory.AppendSegment(current_coordinate, path_data);
++added_element_count;
}
description_factory.SetEndSegment(leg_phantoms.target_phantom, target_traversed_in_reverse);
++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)
{
JSON::Object json_result;
if (INVALID_EDGE_WEIGHT == raw_route.shortest_path_length)
{
// We do not need to do much, if there is no route ;-)
json_result.values["status"] = 207;
json_result.values["status_message"] = "Cannot find route between points";
JSON::render(reply.content, json_result);
return;
}
// check if first segment is non-zero
std::string road_name = facade->GetEscapedNameForNameID(
raw_route.segment_end_coordinates.front().source_phantom.name_id);
BOOST_ASSERT(raw_route.unpacked_path_segments.size() ==
raw_route.segment_end_coordinates.size());
description_factory.SetStartSegment(
raw_route.segment_end_coordinates.front().source_phantom,
raw_route.source_traversed_in_reverse.front());
json_result.values["status"] = 0;
json_result.values["status_message"] = "Found route between points";
// for each unpacked segment add the leg to the description
for (unsigned i = 0; i < raw_route.unpacked_path_segments.size(); ++i)
{
#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]);
BOOST_ASSERT(0 < added_segments);
}
description_factory.Run(facade, config.zoom_level);
if (config.geometry)
{
JSON::Value route_geometry =
description_factory.AppendEncodedPolylineString(config.encode_geometry);
json_result.values["route_geometry"] = route_geometry;
}
if (config.instructions)
{
JSON::Array json_route_instructions;
BuildTextualDescription(description_factory,
json_route_instructions,
raw_route.shortest_path_length,
shortest_path_segments);
json_result.values["route_instructions"] = json_route_instructions;
}
description_factory.BuildRouteSummary(description_factory.entireLength,
raw_route.shortest_path_length);
JSON::Object json_route_summary;
json_route_summary.values["total_distance"] = description_factory.summary.distance;
json_route_summary.values["total_time"] = description_factory.summary.duration;
json_route_summary.values["start_point"] =
facade->GetEscapedNameForNameID(description_factory.summary.source_name_id);
json_route_summary.values["end_point"] =
facade->GetEscapedNameForNameID(description_factory.summary.target_name_id);
json_result.values["route_summary"] = json_route_summary;
BOOST_ASSERT(!raw_route.segment_end_coordinates.empty());
JSON::Array json_via_points_array;
JSON::Array json_first_coordinate;
json_first_coordinate.values.push_back(
raw_route.segment_end_coordinates.front().source_phantom.location.lat /
COORDINATE_PRECISION);
json_first_coordinate.values.push_back(
raw_route.segment_end_coordinates.front().source_phantom.location.lon /
COORDINATE_PRECISION);
json_via_points_array.values.push_back(json_first_coordinate);
for (const PhantomNodes &nodes : raw_route.segment_end_coordinates)
{
std::string tmp;
JSON::Array json_coordinate;
json_coordinate.values.push_back(nodes.target_phantom.location.lat /
COORDINATE_PRECISION);
json_coordinate.values.push_back(nodes.target_phantom.location.lon /
COORDINATE_PRECISION);
json_via_points_array.values.push_back(json_coordinate);
}
json_result.values["via_points"] = json_via_points_array;
JSON::Array json_via_indices_array;
std::vector<unsigned> const &shortest_leg_end_indices = description_factory.GetViaIndices();
json_via_indices_array.values.insert(json_via_indices_array.values.end(),
shortest_leg_end_indices.begin(),
shortest_leg_end_indices.end());
json_result.values["via_indices"] = json_via_indices_array;
// only one alternative route is computed at this time, so this is hardcoded
if (INVALID_EDGE_WEIGHT != raw_route.alternative_path_length)
{
json_result.values["found_alternative"] = JSON::True();
BOOST_ASSERT(!raw_route.alt_source_traversed_in_reverse.empty());
alternate_description_factory.SetStartSegment(
raw_route.segment_end_coordinates.front().source_phantom,
raw_route.alt_source_traversed_in_reverse.front());
// Get all the coordinates for the computed route
for (const PathData &path_data : raw_route.unpacked_alternative)
{
current = facade->GetCoordinateOfNode(path_data.node);
alternate_description_factory.AppendSegment(current, path_data);
}
alternate_description_factory.Run(facade, config.zoom_level);
if (config.geometry)
{
JSON::Value alternate_geometry_string =
alternate_description_factory.AppendEncodedPolylineString(
config.encode_geometry);
JSON::Array json_alternate_geometries_array;
json_alternate_geometries_array.values.push_back(alternate_geometry_string);
json_result.values["alternative_geometries"] = json_alternate_geometries_array;
}
// Generate instructions for each alternative (simulated here)
JSON::Array json_alt_instructions;
JSON::Array json_current_alt_instructions;
if (config.instructions)
{
BuildTextualDescription(alternate_description_factory,
json_current_alt_instructions,
raw_route.alternative_path_length,
alternative_path_segments);
json_alt_instructions.values.push_back(json_current_alt_instructions);
json_result.values["alternative_instructions"] = json_alt_instructions;
}
alternate_description_factory.BuildRouteSummary(
alternate_description_factory.entireLength, raw_route.alternative_path_length);
JSON::Object json_alternate_route_summary;
JSON::Array json_alternate_route_summary_array;
json_alternate_route_summary.values["total_distance"] =
alternate_description_factory.summary.distance;
json_alternate_route_summary.values["total_time"] =
alternate_description_factory.summary.duration;
json_alternate_route_summary.values["start_point"] = facade->GetEscapedNameForNameID(
alternate_description_factory.summary.source_name_id);
json_alternate_route_summary.values["end_point"] = facade->GetEscapedNameForNameID(
alternate_description_factory.summary.target_name_id);
json_alternate_route_summary_array.values.push_back(json_alternate_route_summary);
json_result.values["alternative_summaries"] = json_alternate_route_summary_array;
std::vector<unsigned> const &alternate_leg_end_indices =
alternate_description_factory.GetViaIndices();
JSON::Array json_altenative_indices_array;
json_altenative_indices_array.values.insert(json_altenative_indices_array.values.end(),
alternate_leg_end_indices.begin(),
alternate_leg_end_indices.end());
json_result.values["alternative_indices"] = json_altenative_indices_array;
}
else
{
json_result.values["found_alternative"] = JSON::False();
}
// Get Names for both routes
RouteNames route_names =
GenerateRouteNames(shortest_path_segments, alternative_path_segments, facade);
JSON::Array json_route_names;
json_route_names.values.push_back(route_names.shortest_path_name_1);
json_route_names.values.push_back(route_names.shortest_path_name_2);
json_result.values["route_name"] = json_route_names;
if (INVALID_EDGE_WEIGHT != raw_route.alternative_path_length)
{
JSON::Array json_alternate_names_array;
JSON::Array json_alternate_names;
json_alternate_names.values.push_back(route_names.alternative_path_name_1);
json_alternate_names.values.push_back(route_names.alternative_path_name_2);
json_alternate_names_array.values.push_back(json_alternate_names);
json_result.values["alternative_names"] = json_alternate_names_array;
}
JSON::Object json_hint_object;
json_hint_object.values["checksum"] = 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)
{
EncodeObjectToBase64(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);
json_location_hint_array.values.push_back(hint);
json_hint_object.values["locations"] = json_location_hint_array;
json_result.values["hint_data"] = json_hint_object;
// render the content to the output array
TIMER_START(route_render);
JSON::render(reply.content, json_result);
TIMER_STOP(route_render);
SimpleLogger().Write(logDEBUG) << "rendering took: " << TIMER_MSEC(route_render);
}
// TODO: reorder parameters
inline void BuildTextualDescription(DescriptionFactory &description_factory,
JSON::Array &json_instruction_array,
const int route_length,
std::vector<Segment> &route_segments_list)
{
// Segment information has following format:
//["instruction id","streetname",length,position,time,"length","earth_direction",azimuth]
unsigned necessary_segments_running_index = 0;
round_about.leave_at_exit = 0;
round_about.name_id = 0;
std::string temp_dist, temp_length, temp_duration, temp_bearing, temp_instruction;
// Fetch data from Factory and generate a string from it.
for (const SegmentInformation &segment : description_factory.path_description)
{
JSON::Array json_instruction_row;
TurnInstruction current_instruction = segment.turn_instruction;
entered_restricted_area_count += (current_instruction != segment.turn_instruction);
if (TurnInstructionsClass::TurnIsNecessary(current_instruction))
{
if (TurnInstruction::EnterRoundAbout == current_instruction)
{
round_about.name_id = segment.name_id;
round_about.start_index = necessary_segments_running_index;
}
else
{
std::string current_turn_instruction;
if (TurnInstruction::LeaveRoundAbout == current_instruction)
{
temp_instruction =
IntToString(as_integer(TurnInstruction::EnterRoundAbout));
current_turn_instruction += temp_instruction;
current_turn_instruction += "-";
temp_instruction = IntToString(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));
current_turn_instruction += temp_instruction;
}
json_instruction_row.values.push_back(current_turn_instruction);
json_instruction_row.values.push_back(
facade->GetEscapedNameForNameID(segment.name_id));
json_instruction_row.values.push_back(std::round(segment.length));
json_instruction_row.values.push_back(necessary_segments_running_index);
json_instruction_row.values.push_back(round(segment.duration / 10));
json_instruction_row.values.push_back(
UintToString(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)));
route_segments_list.emplace_back(
segment.name_id, segment.length, route_segments_list.size());
json_instruction_array.values.push_back(json_instruction_row);
}
}
else if (TurnInstruction::StayOnRoundAbout == current_instruction)
{
++round_about.leave_at_exit;
}
if (segment.necessary)
{
++necessary_segments_running_index;
}
}
// 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);
}
}
};
#endif /* JSON_DESCRIPTOR_H_ */
Submodule Docs deleted from f7150057d5
+3
View File
@@ -0,0 +1,3 @@
The javascript based web client is a seperate project available at
https://github.com/DennisSchiefer/Project-OSRM-Web
+139
View File
@@ -0,0 +1,139 @@
/*
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 "BaseParser.h"
#include "ExtractionWay.h"
#include "ScriptingEnvironment.h"
#include "../DataStructures/ImportNode.h"
#include "../Util/LuaUtil.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/regex.hpp>
#include <boost/ref.hpp>
#include <boost/regex.hpp>
BaseParser::BaseParser(ExtractorCallbacks *extractor_callbacks,
ScriptingEnvironment &scripting_environment)
: extractor_callbacks(extractor_callbacks),
lua_state(scripting_environment.getLuaState()),
scripting_environment(scripting_environment), use_turn_restrictions(true)
{
ReadUseRestrictionsSetting();
ReadRestrictionExceptions();
}
void BaseParser::ReadUseRestrictionsSetting()
{
if (0 != luaL_dostring(lua_state, "return use_turn_restrictions\n"))
{
throw OSRMException("ERROR occured in scripting block");
}
if (lua_isboolean(lua_state, -1))
{
use_turn_restrictions = lua_toboolean(lua_state, -1);
}
if (use_turn_restrictions)
{
SimpleLogger().Write() << "Using turn restrictions";
}
else
{
SimpleLogger().Write() << "Ignoring turn restrictions";
}
}
void BaseParser::ReadRestrictionExceptions()
{
if (lua_function_exists(lua_state, "get_exceptions"))
{
// get list of turn restriction exceptions
luabind::call_function<void>(
lua_state, "get_exceptions", boost::ref(restriction_exceptions));
const unsigned exception_count = restriction_exceptions.size();
SimpleLogger().Write() << "Found " << exception_count
<< " exceptions to turn restrictions:";
for (const std::string &str : restriction_exceptions)
{
SimpleLogger().Write() << " " << str;
}
}
else
{
SimpleLogger().Write() << "Found no exceptions to turn restrictions";
}
}
void BaseParser::report_errors(lua_State *lua_state, const int status) const
{
if (0 != status)
{
std::cerr << "-- " << lua_tostring(lua_state, -1) << std::endl;
lua_pop(lua_state, 1); // remove error message
}
}
void BaseParser::ParseNodeInLua(ImportNode &node, lua_State *local_lua_state)
{
luabind::call_function<void>(local_lua_state, "node_function", boost::ref(node));
}
void BaseParser::ParseWayInLua(ExtractionWay &way, lua_State *local_lua_state)
{
luabind::call_function<void>(local_lua_state, "way_function", boost::ref(way));
}
bool BaseParser::ShouldIgnoreRestriction(const std::string &except_tag_string) const
{
// should this restriction be ignored? yes if there's an overlap between:
// a) the list of modes in the except tag of the restriction
// (except_tag_string), eg: except=bus;bicycle
// b) the lua profile defines a hierachy of modes,
// eg: [access, vehicle, bicycle]
if (except_tag_string.empty())
{
return false;
}
// Be warned, this is quadratic work here, but we assume that
// only a few exceptions are actually defined.
std::vector<std::string> exceptions;
boost::algorithm::split_regex(exceptions, except_tag_string, boost::regex("[;][ ]*"));
for (std::string &current_string : exceptions)
{
const auto string_iterator =
std::find(restriction_exceptions.begin(), restriction_exceptions.end(), current_string);
if (restriction_exceptions.end() != string_iterator)
{
return true;
}
}
return false;
}
+50 -33
View File
@@ -1,50 +1,67 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 BASEPARSER_H_
#define BASEPARSER_H_
extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
#include <string>
#include <vector>
#include "ScriptingEnvironment.h"
struct lua_State;
class ExtractorCallbacks;
class ScriptingEnvironment;
struct ExtractionWay;
struct ImportNode;
template<class ExternalMemoryT, typename NodeT, typename RestrictionT, typename WayT>
class BaseParser {
public:
class BaseParser
{
public:
BaseParser() = delete;
BaseParser(const BaseParser &) = delete;
BaseParser(ExtractorCallbacks *extractor_callbacks,
ScriptingEnvironment &scripting_environment);
virtual ~BaseParser() {}
virtual bool Init() = 0;
virtual void RegisterCallbacks(ExternalMemoryT * externalMemory) = 0;
virtual void RegisterScriptingEnvironment(ScriptingEnvironment & _se) = 0;
virtual bool ReadHeader() = 0;
virtual bool Parse() = 0;
void report_errors(lua_State *L, int status) {
if ( status!=0 ) {
std::cerr << "-- " << lua_tostring(L, -1) << std::endl;
lua_pop(L, 1); // remove error message
}
}
virtual void ParseNodeInLua(ImportNode &node, lua_State *lua_state);
virtual void ParseWayInLua(ExtractionWay &way, lua_State *lua_state);
virtual void report_errors(lua_State *lua_state, const int status) const;
protected:
virtual void ReadUseRestrictionsSetting();
virtual void ReadRestrictionExceptions();
virtual bool ShouldIgnoreRestriction(const std::string &except_tag_string) const;
ExtractorCallbacks *extractor_callbacks;
lua_State *lua_state;
ScriptingEnvironment &scripting_environment;
std::vector<std::string> restriction_exceptions;
bool use_turn_restrictions;
};
#endif /* BASEPARSER_H_ */
+416 -293
View File
@@ -1,305 +1,428 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 "ExtractionContainers.h"
#include "ExtractionWay.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../Util/TimingUtil.h"
#include "../DataStructures/RangeTable.h"
void ExtractionContainers::PrepareData(const std::string & outputFileName, const std::string restrictionsFileName, const unsigned amountOfRAM) {
try {
unsigned usedNodeCounter = 0;
unsigned usedEdgeCounter = 0;
double time = get_timestamp();
boost::uint64_t memory_to_use = static_cast<boost::uint64_t>(amountOfRAM) * 1024 * 1024 * 1024;
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
cout << "[extractor] Sorting used nodes ... " << flush;
stxxl::sort(usedNodeIDs.begin(), usedNodeIDs.end(), Cmp(), memory_to_use);
cout << "ok, after " << get_timestamp() - time << "s" << endl;
#include <stxxl/sort>
time = get_timestamp();
cout << "[extractor] Erasing duplicate nodes ... " << flush;
stxxl::vector<NodeID>::iterator NewEnd = unique ( usedNodeIDs.begin(),usedNodeIDs.end() ) ;
usedNodeIDs.resize ( NewEnd - usedNodeIDs.begin() );
cout << "ok, after " << get_timestamp() - time << "s" << endl;
time = get_timestamp();
#include <chrono>
#include <limits>
cout << "[extractor] Sorting all nodes ... " << flush;
stxxl::sort(allNodes.begin(), allNodes.end(), CmpNodeByID(), memory_to_use);
cout << "ok, after " << get_timestamp() - time << "s" << endl;
time = get_timestamp();
cout << "[extractor] Sorting used ways ... " << flush;
stxxl::sort(wayStartEndVector.begin(), wayStartEndVector.end(), CmpWayByID(), memory_to_use);
cout << "ok, after " << get_timestamp() - time << "s" << endl;
cout << "[extractor] Sorting restrctns. by from... " << flush;
stxxl::sort(restrictionsVector.begin(), restrictionsVector.end(), CmpRestrictionContainerByFrom(), memory_to_use);
cout << "ok, after " << get_timestamp() - time << "s" << endl;
cout << "[extractor] Fixing restriction starts ... " << flush;
STXXLRestrictionsVector::iterator restrictionsIT = restrictionsVector.begin();
STXXLWayIDStartEndVector::iterator wayStartAndEndEdgeIT = wayStartEndVector.begin();
while(wayStartAndEndEdgeIT != wayStartEndVector.end() && restrictionsIT != restrictionsVector.end()) {
if(wayStartAndEndEdgeIT->wayID < restrictionsIT->fromWay){
++wayStartAndEndEdgeIT;
continue;
}
if(wayStartAndEndEdgeIT->wayID > restrictionsIT->fromWay) {
++restrictionsIT;
continue;
}
assert(wayStartAndEndEdgeIT->wayID == restrictionsIT->fromWay);
NodeID viaNode = restrictionsIT->restriction.viaNode;
if(wayStartAndEndEdgeIT->firstStart == viaNode) {
restrictionsIT->restriction.fromNode = wayStartAndEndEdgeIT->firstTarget;
} else if(wayStartAndEndEdgeIT->firstTarget == viaNode) {
restrictionsIT->restriction.fromNode = wayStartAndEndEdgeIT->firstStart;
} else if(wayStartAndEndEdgeIT->lastStart == viaNode) {
restrictionsIT->restriction.fromNode = wayStartAndEndEdgeIT->lastTarget;
} else if(wayStartAndEndEdgeIT->lastTarget == viaNode) {
restrictionsIT->restriction.fromNode = wayStartAndEndEdgeIT->lastStart;
}
++restrictionsIT;
}
cout << "ok, after " << get_timestamp() - time << "s" << endl;
time = get_timestamp();
cout << "[extractor] Sorting restrctns. by to ... " << flush;
stxxl::sort(restrictionsVector.begin(), restrictionsVector.end(), CmpRestrictionContainerByTo(), memory_to_use);
cout << "ok, after " << get_timestamp() - time << "s" << endl;
time = get_timestamp();
unsigned usableRestrictionsCounter(0);
cout << "[extractor] Fixing restriction ends ... " << flush;
restrictionsIT = restrictionsVector.begin();
wayStartAndEndEdgeIT = wayStartEndVector.begin();
while(wayStartAndEndEdgeIT != wayStartEndVector.end() && restrictionsIT != restrictionsVector.end()) {
if(wayStartAndEndEdgeIT->wayID < restrictionsIT->toWay){
++wayStartAndEndEdgeIT;
continue;
}
if(wayStartAndEndEdgeIT->wayID > restrictionsIT->toWay) {
++restrictionsIT;
continue;
}
NodeID viaNode = restrictionsIT->restriction.viaNode;
if(wayStartAndEndEdgeIT->lastStart == viaNode) {
restrictionsIT->restriction.toNode = wayStartAndEndEdgeIT->lastTarget;
} else if(wayStartAndEndEdgeIT->lastTarget == viaNode) {
restrictionsIT->restriction.toNode = wayStartAndEndEdgeIT->lastStart;
} else if(wayStartAndEndEdgeIT->firstStart == viaNode) {
restrictionsIT->restriction.toNode = wayStartAndEndEdgeIT->firstTarget;
} else if(wayStartAndEndEdgeIT->firstTarget == viaNode) {
restrictionsIT->restriction.toNode = wayStartAndEndEdgeIT->firstStart;
}
if(UINT_MAX != restrictionsIT->restriction.fromNode && UINT_MAX != restrictionsIT->restriction.toNode) {
++usableRestrictionsCounter;
}
++restrictionsIT;
}
cout << "ok, after " << get_timestamp() - time << "s" << endl;
INFO("usable restrictions: " << usableRestrictionsCounter );
//serialize restrictions
ofstream restrictionsOutstream;
restrictionsOutstream.open(restrictionsFileName.c_str(), ios::binary);
restrictionsOutstream.write((char*)&usableRestrictionsCounter, sizeof(unsigned));
for(restrictionsIT = restrictionsVector.begin(); restrictionsIT != restrictionsVector.end(); ++restrictionsIT) {
if(UINT_MAX != restrictionsIT->restriction.fromNode && UINT_MAX != restrictionsIT->restriction.toNode) {
restrictionsOutstream.write((char *)&(restrictionsIT->restriction), sizeof(_Restriction));
}
}
restrictionsOutstream.close();
ofstream fout;
fout.open(outputFileName.c_str(), ios::binary);
fout.write((char*)&usedNodeCounter, sizeof(unsigned));
time = get_timestamp();
cout << "[extractor] Confirming/Writing used nodes ... " << flush;
STXXLNodeVector::iterator nodesIT = allNodes.begin();
STXXLNodeIDVector::iterator usedNodeIDsIT = usedNodeIDs.begin();
while(usedNodeIDsIT != usedNodeIDs.end() && nodesIT != allNodes.end()) {
if(*usedNodeIDsIT < nodesIT->id){
++usedNodeIDsIT;
continue;
}
if(*usedNodeIDsIT > nodesIT->id) {
++nodesIT;
continue;
}
if(*usedNodeIDsIT == nodesIT->id) {
fout.write((char*)&(*nodesIT), sizeof(_Node));
++usedNodeCounter;
++usedNodeIDsIT;
++nodesIT;
}
}
cout << "ok, after " << get_timestamp() - time << "s" << endl;
cout << "[extractor] setting number of nodes ... " << flush;
ios::pos_type positionInFile = fout.tellp();
fout.seekp(ios::beg);
fout.write((char*)&usedNodeCounter, sizeof(unsigned));
fout.seekp(positionInFile);
cout << "ok" << endl;
time = get_timestamp();
// Sort edges by start.
cout << "[extractor] Sorting edges by start ... " << flush;
stxxl::sort(allEdges.begin(), allEdges.end(), CmpEdgeByStartID(), memory_to_use);
cout << "ok, after " << get_timestamp() - time << "s" << endl;
time = get_timestamp();
cout << "[extractor] Setting start coords ... " << flush;
fout.write((char*)&usedEdgeCounter, sizeof(unsigned));
// Traverse list of edges and nodes in parallel and set start coord
nodesIT = allNodes.begin();
STXXLEdgeVector::iterator edgeIT = allEdges.begin();
while(edgeIT != allEdges.end() && nodesIT != allNodes.end()) {
if(edgeIT->start < nodesIT->id){
++edgeIT;
continue;
}
if(edgeIT->start > nodesIT->id) {
nodesIT++;
continue;
}
if(edgeIT->start == nodesIT->id) {
edgeIT->startCoord.lat = nodesIT->lat;
edgeIT->startCoord.lon = nodesIT->lon;
++edgeIT;
}
}
cout << "ok, after " << get_timestamp() - time << "s" << endl;
time = get_timestamp();
// Sort Edges by target
cout << "[extractor] Sorting edges by target ... " << flush;
stxxl::sort(allEdges.begin(), allEdges.end(), CmpEdgeByTargetID(), memory_to_use);
cout << "ok, after " << get_timestamp() - time << "s" << endl;
time = get_timestamp();
cout << "[extractor] Setting target coords ... " << flush;
// Traverse list of edges and nodes in parallel and set target coord
nodesIT = allNodes.begin();
edgeIT = allEdges.begin();
while(edgeIT != allEdges.end() && nodesIT != allNodes.end()) {
if(edgeIT->target < nodesIT->id){
++edgeIT;
continue;
}
if(edgeIT->target > nodesIT->id) {
++nodesIT;
continue;
}
if(edgeIT->target == nodesIT->id) {
if(edgeIT->startCoord.lat != INT_MIN && edgeIT->startCoord.lon != INT_MIN) {
edgeIT->targetCoord.lat = nodesIT->lat;
edgeIT->targetCoord.lon = nodesIT->lon;
double distance = ApproximateDistance(edgeIT->startCoord.lat, edgeIT->startCoord.lon, nodesIT->lat, nodesIT->lon);
assert(edgeIT->speed != -1);
double weight = ( distance * 10. ) / (edgeIT->speed / 3.6);
int intWeight = std::max(1, (int)std::floor((edgeIT->isDurationSet ? edgeIT->speed : weight)+.5) );
int intDist = std::max(1, (int)distance);
short zero = 0;
short one = 1;
fout.write((char*)&edgeIT->start, sizeof(unsigned));
fout.write((char*)&edgeIT->target, sizeof(unsigned));
fout.write((char*)&intDist, sizeof(int));
switch(edgeIT->direction) {
case _Way::notSure:
fout.write((char*)&zero, sizeof(short));
break;
case _Way::oneway:
fout.write((char*)&one, sizeof(short));
break;
case _Way::bidirectional:
fout.write((char*)&zero, sizeof(short));
break;
case _Way::opposite:
fout.write((char*)&one, sizeof(short));
break;
default:
cerr << "[error] edge with no direction: " << edgeIT->direction << endl;
assert(false);
break;
}
fout.write((char*)&intWeight, sizeof(int));
assert(edgeIT->type >= 0);
fout.write((char*)&edgeIT->type, sizeof(short));
fout.write((char*)&edgeIT->nameID, sizeof(unsigned));
fout.write((char*)&edgeIT->isRoundabout, sizeof(bool));
fout.write((char*)&edgeIT->ignoreInGrid, sizeof(bool));
fout.write((char*)&edgeIT->isAccessRestricted, sizeof(bool));
}
++usedEdgeCounter;
++edgeIT;
}
}
cout << "ok, after " << get_timestamp() - time << "s" << endl;
cout << "[extractor] setting number of edges ... " << flush;
fout.seekp(positionInFile);
fout.write((char*)&usedEdgeCounter, sizeof(unsigned));
fout.close();
cout << "ok" << endl;
time = get_timestamp();
cout << "[extractor] writing street name index ... " << flush;
std::string nameOutFileName = (outputFileName + ".names");
ofstream nameOutFile(nameOutFileName.c_str(), ios::binary);
unsigned sizeOfNameIndex = nameVector.size();
nameOutFile.write((char *)&(sizeOfNameIndex), sizeof(unsigned));
BOOST_FOREACH(string str, nameVector) {
unsigned lengthOfRawString = strlen(str.c_str());
nameOutFile.write((char *)&(lengthOfRawString), sizeof(unsigned));
nameOutFile.write(str.c_str(), lengthOfRawString);
}
nameOutFile.close();
cout << "ok, after " << get_timestamp() - time << "s" << endl;
// time = get_timestamp();
// cout << "[extractor] writing address list ... " << flush;
//
// adressFileName.append(".address");
// ofstream addressOutFile(adressFileName.c_str());
// for(STXXLAddressVector::iterator it = adressVector.begin(); it != adressVector.end(); it++) {
// addressOutFile << it->node.id << "|" << it->node.lat << "|" << it->node.lon << "|" << it->city << "|" << it->street << "|" << it->housenumber << "|" << it->state << "|" << it->country << "\n";
// }
// addressOutFile.close();
// cout << "ok, after " << get_timestamp() - time << "s" << endl;
INFO("Processed " << usedNodeCounter << " nodes and " << usedEdgeCounter << " edges");
} catch ( const exception& e ) {
cerr << "Caught Execption:" << e.what() << endl;
}
ExtractionContainers::ExtractionContainers()
{
// Check if stxxl can be instantiated
stxxl::vector<unsigned> dummy_vector;
name_list.push_back("");
}
ExtractionContainers::~ExtractionContainers()
{
used_node_id_list.clear();
all_nodes_list.clear();
all_edges_list.clear();
name_list.clear();
restrictions_list.clear();
way_start_end_id_list.clear();
}
void ExtractionContainers::PrepareData(const std::string &output_file_name,
const std::string &restrictions_file_name)
{
try
{
unsigned number_of_used_nodes = 0;
unsigned number_of_used_edges = 0;
std::cout << "[extractor] Sorting used nodes ... " << std::flush;
TIMER_START(sorting_used_nodes);
stxxl::sort(used_node_id_list.begin(), used_node_id_list.end(), Cmp(), stxxl_memory);
TIMER_STOP(sorting_used_nodes);
std::cout << "ok, after " << TIMER_SEC(sorting_used_nodes) << "s" << std::endl;
std::cout << "[extractor] Erasing duplicate nodes ... " << std::flush;
TIMER_START(erasing_dups);
auto new_end = std::unique(used_node_id_list.begin(), used_node_id_list.end());
used_node_id_list.resize(new_end - used_node_id_list.begin());
TIMER_STOP(erasing_dups);
std::cout << "ok, after " << TIMER_SEC(erasing_dups) << "s" << std::endl;
std::cout << "[extractor] Sorting all nodes ... " << std::flush;
TIMER_START(sorting_nodes);
stxxl::sort(all_nodes_list.begin(), all_nodes_list.end(), CmpNodeByID(), stxxl_memory);
TIMER_STOP(sorting_nodes);
std::cout << "ok, after " << TIMER_SEC(sorting_nodes) << "s" << std::endl;
std::cout << "[extractor] Sorting used ways ... " << std::flush;
TIMER_START(sort_ways);
stxxl::sort(
way_start_end_id_list.begin(), way_start_end_id_list.end(), CmpWayByID(), stxxl_memory);
TIMER_STOP(sort_ways);
std::cout << "ok, after " << TIMER_SEC(sort_ways) << "s" << std::endl;
std::cout << "[extractor] Sorting restrictions. by from... " << std::flush;
TIMER_START(sort_restrictions);
stxxl::sort(restrictions_list.begin(),
restrictions_list.end(),
CmpRestrictionContainerByFrom(),
stxxl_memory);
TIMER_STOP(sort_restrictions);
std::cout << "ok, after " << TIMER_SEC(sort_restrictions) << "s" << std::endl;
std::cout << "[extractor] Fixing restriction starts ... " << std::flush;
TIMER_START(fix_restriction_starts);
auto restrictions_iterator = restrictions_list.begin();
auto way_start_and_end_iterator = way_start_end_id_list.begin();
while (way_start_and_end_iterator != way_start_end_id_list.end() &&
restrictions_iterator != restrictions_list.end())
{
if (way_start_and_end_iterator->wayID < restrictions_iterator->fromWay)
{
++way_start_and_end_iterator;
continue;
}
if (way_start_and_end_iterator->wayID > restrictions_iterator->fromWay)
{
++restrictions_iterator;
continue;
}
BOOST_ASSERT(way_start_and_end_iterator->wayID == restrictions_iterator->fromWay);
const NodeID via_node_id = restrictions_iterator->restriction.viaNode;
if (way_start_and_end_iterator->firstStart == via_node_id)
{
restrictions_iterator->restriction.fromNode =
way_start_and_end_iterator->firstTarget;
}
else if (way_start_and_end_iterator->firstTarget == via_node_id)
{
restrictions_iterator->restriction.fromNode =
way_start_and_end_iterator->firstStart;
}
else if (way_start_and_end_iterator->lastStart == via_node_id)
{
restrictions_iterator->restriction.fromNode =
way_start_and_end_iterator->lastTarget;
}
else if (way_start_and_end_iterator->lastTarget == via_node_id)
{
restrictions_iterator->restriction.fromNode = way_start_and_end_iterator->lastStart;
}
++restrictions_iterator;
}
TIMER_STOP(fix_restriction_starts);
std::cout << "ok, after " << TIMER_SEC(fix_restriction_starts) << "s" << std::endl;
std::cout << "[extractor] Sorting restrictions. by to ... " << std::flush;
TIMER_START(sort_restrictions_to);
stxxl::sort(restrictions_list.begin(),
restrictions_list.end(),
CmpRestrictionContainerByTo(),
stxxl_memory);
TIMER_STOP(sort_restrictions_to);
std::cout << "ok, after " << TIMER_SEC(sort_restrictions_to) << "s" << std::endl;
unsigned number_of_useable_restrictions = 0;
std::cout << "[extractor] Fixing restriction ends ... " << std::flush;
TIMER_START(fix_restriction_ends);
restrictions_iterator = restrictions_list.begin();
way_start_and_end_iterator = way_start_end_id_list.begin();
while (way_start_and_end_iterator != way_start_end_id_list.end() &&
restrictions_iterator != restrictions_list.end())
{
if (way_start_and_end_iterator->wayID < restrictions_iterator->toWay)
{
++way_start_and_end_iterator;
continue;
}
if (way_start_and_end_iterator->wayID > restrictions_iterator->toWay)
{
++restrictions_iterator;
continue;
}
NodeID via_node_id = restrictions_iterator->restriction.viaNode;
if (way_start_and_end_iterator->lastStart == via_node_id)
{
restrictions_iterator->restriction.toNode = way_start_and_end_iterator->lastTarget;
}
else if (way_start_and_end_iterator->lastTarget == via_node_id)
{
restrictions_iterator->restriction.toNode = way_start_and_end_iterator->lastStart;
}
else if (way_start_and_end_iterator->firstStart == via_node_id)
{
restrictions_iterator->restriction.toNode = way_start_and_end_iterator->firstTarget;
}
else if (way_start_and_end_iterator->firstTarget == via_node_id)
{
restrictions_iterator->restriction.toNode = way_start_and_end_iterator->firstStart;
}
if (std::numeric_limits<unsigned>::max() != restrictions_iterator->restriction.fromNode &&
std::numeric_limits<unsigned>::max() != restrictions_iterator->restriction.toNode)
{
++number_of_useable_restrictions;
}
++restrictions_iterator;
}
TIMER_STOP(fix_restriction_ends);
std::cout << "ok, after " << TIMER_SEC(fix_restriction_ends) << "s" << std::endl;
SimpleLogger().Write() << "usable restrictions: " << number_of_useable_restrictions;
// serialize restrictions
std::ofstream restrictions_out_stream;
restrictions_out_stream.open(restrictions_file_name.c_str(), std::ios::binary);
restrictions_out_stream.write((char *)&fingerprint, sizeof(FingerPrint));
restrictions_out_stream.write((char *)&number_of_useable_restrictions, sizeof(unsigned));
for(const auto & restriction_container : restrictions_list)
{
if (std::numeric_limits<unsigned>::max() != restriction_container.restriction.fromNode &&
std::numeric_limits<unsigned>::max() != restriction_container.restriction.toNode)
{
restrictions_out_stream.write((char *)&(restriction_container.restriction),
sizeof(TurnRestriction));
}
}
restrictions_out_stream.close();
std::ofstream file_out_stream;
file_out_stream.open(output_file_name.c_str(), std::ios::binary);
file_out_stream.write((char *)&fingerprint, sizeof(FingerPrint));
file_out_stream.write((char *)&number_of_used_nodes, sizeof(unsigned));
std::cout << "[extractor] Confirming/Writing used nodes ... " << std::flush;
TIMER_START(write_nodes);
// identify all used nodes by a merging step of two sorted lists
auto node_iterator = all_nodes_list.begin();
auto node_id_iterator = used_node_id_list.begin();
while (node_id_iterator != used_node_id_list.end() && node_iterator != all_nodes_list.end())
{
if (*node_id_iterator < node_iterator->node_id)
{
++node_id_iterator;
continue;
}
if (*node_id_iterator > node_iterator->node_id)
{
++node_iterator;
continue;
}
BOOST_ASSERT(*node_id_iterator == node_iterator->node_id);
file_out_stream.write((char *)&(*node_iterator), sizeof(ExternalMemoryNode));
++number_of_used_nodes;
++node_id_iterator;
++node_iterator;
}
TIMER_STOP(write_nodes);
std::cout << "ok, after " << TIMER_SEC(write_nodes) << "s" << std::endl;
std::cout << "[extractor] setting number of nodes ... " << std::flush;
std::ios::pos_type previous_file_position = file_out_stream.tellp();
file_out_stream.seekp(std::ios::beg + sizeof(FingerPrint));
file_out_stream.write((char *)&number_of_used_nodes, sizeof(unsigned));
file_out_stream.seekp(previous_file_position);
std::cout << "ok" << std::endl;
// Sort edges by start.
std::cout << "[extractor] Sorting edges by start ... " << std::flush;
TIMER_START(sort_edges_by_start);
stxxl::sort(all_edges_list.begin(), all_edges_list.end(), CmpEdgeByStartID(), stxxl_memory);
TIMER_STOP(sort_edges_by_start);
std::cout << "ok, after " << TIMER_SEC(sort_edges_by_start) << "s" << std::endl;
std::cout << "[extractor] Setting start coords ... " << std::flush;
TIMER_START(set_start_coords);
file_out_stream.write((char *)&number_of_used_edges, sizeof(unsigned));
// Traverse list of edges and nodes in parallel and set start coord
node_iterator = all_nodes_list.begin();
auto edge_iterator = all_edges_list.begin();
while (edge_iterator != all_edges_list.end() && node_iterator != all_nodes_list.end())
{
if (edge_iterator->start < node_iterator->node_id)
{
++edge_iterator;
continue;
}
if (edge_iterator->start > node_iterator->node_id)
{
node_iterator++;
continue;
}
BOOST_ASSERT(edge_iterator->start == node_iterator->node_id);
edge_iterator->source_coordinate.lat = node_iterator->lat;
edge_iterator->source_coordinate.lon = node_iterator->lon;
++edge_iterator;
}
TIMER_STOP(set_start_coords);
std::cout << "ok, after " << TIMER_SEC(set_start_coords) << "s" << std::endl;
// Sort Edges by target
std::cout << "[extractor] Sorting edges by target ... " << std::flush;
TIMER_START(sort_edges_by_target);
stxxl::sort(all_edges_list.begin(), all_edges_list.end(), CmpEdgeByTargetID(), stxxl_memory);
TIMER_STOP(sort_edges_by_target);
std::cout << "ok, after " << TIMER_SEC(sort_edges_by_target) << "s" << std::endl;
std::cout << "[extractor] Setting target coords ... " << std::flush;
TIMER_START(set_target_coords);
// Traverse list of edges and nodes in parallel and set target coord
node_iterator = all_nodes_list.begin();
edge_iterator = all_edges_list.begin();
while (edge_iterator != all_edges_list.end() && node_iterator != all_nodes_list.end())
{
if (edge_iterator->target < node_iterator->node_id)
{
++edge_iterator;
continue;
}
if (edge_iterator->target > node_iterator->node_id)
{
++node_iterator;
continue;
}
BOOST_ASSERT(edge_iterator->target == node_iterator->node_id);
if (edge_iterator->source_coordinate.lat != std::numeric_limits<int>::min() &&
edge_iterator->source_coordinate.lon != std::numeric_limits<int>::min())
{
BOOST_ASSERT(edge_iterator->speed != -1);
BOOST_ASSERT(edge_iterator->type >= 0);
edge_iterator->target_coordinate.lat = node_iterator->lat;
edge_iterator->target_coordinate.lon = node_iterator->lon;
const double distance = FixedPointCoordinate::ApproximateEuclideanDistance(
edge_iterator->source_coordinate.lat,
edge_iterator->source_coordinate.lon,
node_iterator->lat,
node_iterator->lon);
const double weight = (distance * 10.) / (edge_iterator->speed / 3.6);
int integer_weight = std::max(
1,
(int)std::floor(
(edge_iterator->is_duration_set ? edge_iterator->speed : weight) + .5));
int integer_distance = std::max(1, (int)distance);
short zero = 0;
short one = 1;
file_out_stream.write((char *)&edge_iterator->start, sizeof(unsigned));
file_out_stream.write((char *)&edge_iterator->target, sizeof(unsigned));
file_out_stream.write((char *)&integer_distance, sizeof(int));
switch (edge_iterator->direction)
{
case ExtractionWay::notSure:
file_out_stream.write((char *)&zero, sizeof(short));
break;
case ExtractionWay::oneway:
file_out_stream.write((char *)&one, sizeof(short));
break;
case ExtractionWay::bidirectional:
file_out_stream.write((char *)&zero, sizeof(short));
break;
case ExtractionWay::opposite:
file_out_stream.write((char *)&one, sizeof(short));
break;
default:
throw OSRMException("edge has broken direction");
}
file_out_stream.write((char *)&integer_weight, sizeof(int));
file_out_stream.write((char *)&edge_iterator->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));
file_out_stream.write((char *)&edge_iterator->is_split, sizeof(bool));
++number_of_used_edges;
}
++edge_iterator;
}
TIMER_STOP(set_target_coords);
std::cout << "ok, after " << TIMER_SEC(set_target_coords) << "s" << std::endl;
std::cout << "[extractor] setting number of edges ... " << std::flush;
file_out_stream.seekp(previous_file_position);
file_out_stream.write((char *)&number_of_used_edges, sizeof(unsigned));
file_out_stream.close();
std::cout << "ok" << std::endl;
std::cout << "[extractor] writing street name index ... " << std::flush;
TIMER_START(write_name_index);
std::string name_file_streamName = (output_file_name + ".names");
boost::filesystem::ofstream name_file_stream(name_file_streamName, std::ios::binary);
unsigned total_length = 0;
std::vector<unsigned> name_lengths;
for (const std::string &temp_string : name_list)
{
const unsigned string_length = std::min(static_cast<unsigned>(temp_string.length()), 255u);
name_lengths.push_back(string_length);
total_length += string_length;
}
RangeTable<> table(name_lengths);
name_file_stream << table;
name_file_stream.write((char*) &total_length, sizeof(unsigned));
// write all chars consecutively
for (const std::string &temp_string : name_list)
{
const unsigned string_length = std::min(static_cast<unsigned>(temp_string.length()), 255u);
name_file_stream.write(temp_string.c_str(), string_length);
}
name_file_stream.close();
TIMER_STOP(write_name_index);
std::cout << "ok, after " << TIMER_SEC(write_name_index) << "s" << std::endl;
SimpleLogger().Write() << "Processed " << number_of_used_nodes << " nodes and "
<< number_of_used_edges << " edges";
}
catch (const std::exception &e) { std::cerr << "Caught Execption:" << e.what() << std::endl; }
}
+50 -50
View File
@@ -1,69 +1,69 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 EXTRACTIONCONTAINERS_H_
#define EXTRACTIONCONTAINERS_H_
#include <boost/foreach.hpp>
#include <stxxl.h>
#include "InternalExtractorEdge.h"
#include "ExtractorStructs.h"
#include "../DataStructures/Util.h"
#include "../DataStructures/Restriction.h"
#include "../Util/FingerPrint.h"
class ExtractionContainers {
public:
#include <stxxl/vector>
class ExtractionContainers
{
#ifndef _MSC_VER
constexpr static unsigned stxxl_memory = ((sizeof(std::size_t) == 4) ? std::numeric_limits<int>::max() : std::numeric_limits<unsigned>::max());
#else
const static unsigned stxxl_memory = ((sizeof(std::size_t) == 4) ? INT_MAX : UINT_MAX);
#endif
public:
typedef stxxl::vector<NodeID> STXXLNodeIDVector;
typedef stxxl::vector<_Node> STXXLNodeVector;
typedef stxxl::vector<_Edge> STXXLEdgeVector;
typedef stxxl::vector<ExternalMemoryNode> STXXLNodeVector;
typedef stxxl::vector<InternalExtractorEdge> STXXLEdgeVector;
typedef stxxl::vector<std::string> STXXLStringVector;
typedef stxxl::vector<_RawRestrictionContainer> STXXLRestrictionsVector;
typedef stxxl::vector<_WayIDStartAndEndEdge> STXXLWayIDStartEndVector;
typedef stxxl::vector<InputRestrictionContainer> STXXLRestrictionsVector;
typedef stxxl::vector<WayIDStartAndEndEdge> STXXLWayIDStartEndVector;
ExtractionContainers() {
//Check if another instance of stxxl is already running or if there is a general problem
try {
stxxl::vector<unsigned> testForRunningInstance;
} catch(std::exception & e) {
ERR("Could not instantiate STXXL layer." << std::endl << e.what());
}
STXXLNodeIDVector used_node_id_list;
STXXLNodeVector all_nodes_list;
STXXLEdgeVector all_edges_list;
STXXLStringVector name_list;
STXXLRestrictionsVector restrictions_list;
STXXLWayIDStartEndVector way_start_end_id_list;
const FingerPrint fingerprint;
nameVector.push_back("");
}
virtual ~ExtractionContainers() {
usedNodeIDs.clear();
allNodes.clear();
allEdges.clear();
nameVector.clear();
restrictionsVector.clear();
wayStartEndVector.clear();
}
ExtractionContainers();
void PrepareData( const std::string & outputFileName, const std::string restrictionsFileName, const unsigned amountOfRAM);
STXXLNodeIDVector usedNodeIDs;
STXXLNodeVector allNodes;
STXXLEdgeVector allEdges;
STXXLStringVector nameVector;
STXXLRestrictionsVector restrictionsVector;
STXXLWayIDStartEndVector wayStartEndVector;
virtual ~ExtractionContainers();
void PrepareData(const std::string &output_file_name,
const std::string &restrictions_file_name);
};
#endif /* EXTRACTIONCONTAINERS_H_ */
+67 -48
View File
@@ -1,70 +1,89 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 EXTRACTIONHELPERFUNCTIONS_H_
#define EXTRACTIONHELPERFUNCTIONS_H_
#ifndef EXTRACTION_HELPER_FUNCTIONS_H
#define EXTRACTION_HELPER_FUNCTIONS_H
#include "../Util/StringUtil.h"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string_regex.hpp>
#include <boost/regex.hpp>
#include <climits>
#include "../Util/StringUtil.h"
#include <limits>
//TODO: Move into LUA
namespace qi = boost::spirit::qi;
inline bool durationIsValid(const std::string &s) {
boost::regex e ("((\\d|\\d\\d):)*(\\d|\\d\\d)",boost::regex_constants::icase|boost::regex_constants::perl);
// TODO: Move into LUA
std::vector< std::string > result;
boost::algorithm::split_regex( result, s, boost::regex( ":" ) ) ;
bool matched = regex_match(s, e);
inline bool durationIsValid(const std::string &s)
{
boost::regex e(
"((\\d|\\d\\d):(\\d|\\d\\d):(\\d|\\d\\d))|((\\d|\\d\\d):(\\d|\\d\\d))|(\\d|\\d\\d)",
boost::regex_constants::icase | boost::regex_constants::perl);
std::vector<std::string> result;
boost::algorithm::split_regex(result, s, boost::regex(":"));
const bool matched = regex_match(s, e);
return matched;
}
inline unsigned parseDuration(const std::string &s) {
int hours = 0;
int minutes = 0;
boost::regex e ("((\\d|\\d\\d):)*(\\d|\\d\\d)",boost::regex_constants::icase|boost::regex_constants::perl);
inline unsigned parseDuration(const std::string &s)
{
unsigned hours = 0;
unsigned minutes = 0;
unsigned seconds = 0;
boost::regex e(
"((\\d|\\d\\d):(\\d|\\d\\d):(\\d|\\d\\d))|((\\d|\\d\\d):(\\d|\\d\\d))|(\\d|\\d\\d)",
boost::regex_constants::icase | boost::regex_constants::perl);
std::vector< std::string > result;
boost::algorithm::split_regex( result, s, boost::regex( ":" ) ) ;
bool matched = regex_match(s, e);
if(matched) {
hours = (result.size()== 2) ? stringToInt(result[0]) : 0;
minutes = (result.size()== 2) ? stringToInt(result[1]) : stringToInt(result[0]);
return 600*(hours*60+minutes);
std::vector<std::string> result;
boost::algorithm::split_regex(result, s, boost::regex(":"));
const bool matched = regex_match(s, e);
if (matched)
{
if (1 == result.size())
{
minutes = StringToUint(result[0]);
}
if (2 == result.size())
{
minutes = StringToUint(result[1]);
hours = StringToUint(result[0]);
}
if (3 == result.size())
{
seconds = StringToUint(result[2]);
minutes = StringToUint(result[1]);
hours = StringToUint(result[0]);
}
return 10 * (3600 * hours + 60 * minutes + seconds);
}
return UINT_MAX;
return std::numeric_limits<unsigned>::max();
}
inline int parseMaxspeed(std::string input) { //call-by-value on purpose.
boost::algorithm::to_lower(input);
int n = stringToInt(input);
if (input.find("mph") != std::string::npos || input.find("mp/h") != std::string::npos) {
n = (n*1609)/1000;
}
return n;
}
#endif /* EXTRACTIONHELPERFUNCTIONS_H_ */
#endif // EXTRACTION_HELPER_FUNCTIONS_H_
+79
View File
@@ -0,0 +1,79 @@
/*
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 EXTRACTION_WAY_H
#define EXTRACTION_WAY_H
#include "../DataStructures/HashTable.h"
#include "../typedefs.h"
#include <string>
#include <vector>
struct ExtractionWay
{
ExtractionWay() { Clear(); }
inline void Clear()
{
id = SPECIAL_NODEID;
nameID = INVALID_NAMEID;
path.clear();
keyVals.Clear();
direction = ExtractionWay::notSure;
speed = -1;
backward_speed = -1;
duration = -1;
type = -1;
access = true;
roundabout = false;
isAccessRestricted = false;
ignoreInGrid = false;
}
enum Directions
{ notSure = 0,
oneway,
bidirectional,
opposite };
unsigned id;
unsigned nameID;
double 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;
};
#endif // EXTRACTION_WAY_H
+155 -89
View File
@@ -1,105 +1,171 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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.
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 "ExtractorCallbacks.h"
#include "ExtractionHelperFunctions.h"
#include "ExtractionContainers.h"
#include "ExtractionWay.h"
ExtractorCallbacks::ExtractorCallbacks() {externalMemory = NULL; stringMap = NULL; }
ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers * ext, StringMap * strMap) {
externalMemory = ext;
stringMap = strMap;
}
#include "../DataStructures/Restriction.h"
#include "../DataStructures/ImportNode.h"
#include "../Util/SimpleLogger.h"
ExtractorCallbacks::~ExtractorCallbacks() {
#include <osrm/Coordinate.h>
#include <limits>
#include <string>
#include <vector>
ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers &extraction_containers,
std::unordered_map<std::string, NodeID> &string_map)
: string_map(string_map), external_memory(extraction_containers)
{
}
/** warning: caller needs to take care of synchronization! */
bool ExtractorCallbacks::nodeFunction(_Node &n) {
if(n.lat <= 85*100000 && n.lat >= -85*100000)
externalMemory->allNodes.push_back(n);
return true;
}
bool ExtractorCallbacks::restrictionFunction(_RawRestrictionContainer &r) {
externalMemory->restrictionsVector.push_back(r);
return true;
}
/** warning: caller needs to take care of synchronization! */
bool ExtractorCallbacks::wayFunction(_Way &w) {
/*** Store name of way and split it into edge segments ***/
if ( w.speed > 0 ) { //Only true if the way is specified by the speed profile
//Get the unique identifier for the street name
const StringMap::const_iterator strit = stringMap->find(w.name);
if(strit == stringMap->end()) {
w.nameID = externalMemory->nameVector.size();
externalMemory->nameVector.push_back(w.name);
stringMap->insert(StringMap::value_type(w.name, w.nameID));
} else {
w.nameID = strit->second;
}
if(fabs(-1. - w.speed) < FLT_EPSILON){
WARN("found way with bogus speed, id: " << w.id);
return true;
}
if(w.id == UINT_MAX) {
WARN("found way with unknown type: " << w.id);
return true;
}
if ( w.direction == _Way::opposite ){
std::reverse( w.path.begin(), w.path.end() );
}
for(vector< NodeID >::size_type n = 0; n < w.path.size()-1; ++n) {
externalMemory->allEdges.push_back(_Edge(w.path[n], w.path[n+1], w.type, w.direction, w.speed, w.nameID, w.roundabout, w.ignoreInGrid, w.isDurationSet, w.isAccessRestricted));
externalMemory->usedNodeIDs.push_back(w.path[n]);
}
externalMemory->usedNodeIDs.push_back(w.path.back());
//The following information is needed to identify start and end segments of restrictions
externalMemory->wayStartEndVector.push_back(_WayIDStartAndEndEdge(w.id, w.path[0], w.path[1], w.path[w.path.size()-2], w.path[w.path.size()-1]));
void ExtractorCallbacks::ProcessNode(const ExternalMemoryNode &n)
{
if (n.lat <= 85 * COORDINATE_PRECISION && n.lat >= -85 * COORDINATE_PRECISION)
{
external_memory.all_nodes_list.push_back(n);
}
}
bool ExtractorCallbacks::ProcessRestriction(const InputRestrictionContainer &restriction)
{
external_memory.restrictions_list.push_back(restriction);
return true;
}
/** warning: caller needs to take care of synchronization! */
void ExtractorCallbacks::ProcessWay(ExtractionWay &parsed_way)
{
if ((0 >= parsed_way.speed) && (0 >= parsed_way.duration))
{ // Only true if the way is specified by the speed profile
return;
}
if (parsed_way.path.size() <= 1)
{ // safe-guard against broken data
return;
}
if (std::numeric_limits<unsigned>::max() == parsed_way.id)
{
SimpleLogger().Write(logDEBUG) << "found bogus way with id: " << parsed_way.id
<< " of size " << parsed_way.path.size();
return;
}
if (0 < parsed_way.duration)
{
// 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);
}
if (std::numeric_limits<double>::epsilon() >= std::abs(-1. - parsed_way.speed))
{
SimpleLogger().Write(logDEBUG) << "found way with bogus speed, id: " << parsed_way.id;
return;
}
// Get the unique identifier for the street name
const auto &string_map_iterator = string_map.find(parsed_way.name);
if (string_map.end() == string_map_iterator)
{
parsed_way.nameID = external_memory.name_list.size();
external_memory.name_list.push_back(parsed_way.name);
string_map.insert(std::make_pair(parsed_way.name, parsed_way.nameID));
}
else
{
parsed_way.nameID = string_map_iterator->second;
}
if (ExtractionWay::opposite == parsed_way.direction)
{
std::reverse(parsed_way.path.begin(), parsed_way.path.end());
parsed_way.direction = ExtractionWay::oneway;
}
const bool split_edge =
(parsed_way.backward_speed > 0) && (parsed_way.speed != parsed_way.backward_speed);
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,
parsed_way.nameID,
parsed_way.roundabout,
parsed_way.ignoreInGrid,
(0 < parsed_way.duration),
parsed_way.isAccessRestricted,
false,
split_edge));
external_memory.used_node_id_list.push_back(parsed_way.path[n]);
}
external_memory.used_node_id_list.push_back(parsed_way.path.back());
// The following information is needed to identify start and end segments of restrictions
external_memory.way_start_end_id_list.push_back(
WayIDStartAndEndEdge(parsed_way.id,
parsed_way.path[0],
parsed_way.path[1],
parsed_way.path[parsed_way.path.size() - 2],
parsed_way.path.back()));
if (split_edge)
{ // Only true if the way should be split
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,
parsed_way.roundabout,
parsed_way.ignoreInGrid,
(0 < parsed_way.duration),
parsed_way.isAccessRestricted,
(ExtractionWay::oneway == parsed_way.direction),
split_edge));
}
external_memory.way_start_end_id_list.push_back(
WayIDStartAndEndEdge(parsed_way.id,
parsed_way.path[0],
parsed_way.path[1],
parsed_way.path[parsed_way.path.size() - 2],
parsed_way.path.back()));
}
}
+48 -42
View File
@@ -1,57 +1,63 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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.
#ifndef EXTRACTORCALLBACKS_H_
#define EXTRACTORCALLBACKS_H_
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 EXTRACTOR_CALLBACKS_H
#define EXTRACTOR_CALLBACKS_H
#include "../typedefs.h"
#include <unordered_map>
#include <string>
#include <vector>
#include <cfloat>
struct ExternalMemoryNode;
class ExtractionContainers;
struct ExtractionWay;
struct InputRestrictionContainer;
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/regex.hpp>
#include <boost/regex.hpp>
class ExtractorCallbacks
{
private:
std::unordered_map<std::string, NodeID> &string_map;
ExtractionContainers &external_memory;
#include "ExtractionContainers.h"
#include "ExtractorStructs.h"
public:
ExtractorCallbacks() = delete;
ExtractorCallbacks(const ExtractorCallbacks &) = delete;
explicit ExtractorCallbacks(ExtractionContainers &extraction_containers,
std::unordered_map<std::string, NodeID> &string_map);
class ExtractorCallbacks{
private:
StringMap * stringMap;
ExtractionContainers * externalMemory;
// warning: caller needs to take care of synchronization!
void ProcessNode(const ExternalMemoryNode &node);
ExtractorCallbacks();
public:
explicit ExtractorCallbacks(ExtractionContainers * ext, StringMap * strMap);
~ExtractorCallbacks();
/** warning: caller needs to take care of synchronization! */
bool nodeFunction(_Node &n);
bool restrictionFunction(_RawRestrictionContainer &r);
/** warning: caller needs to take care of synchronization! */
bool wayFunction(_Way &w);
// warning: caller needs to take care of synchronization!
bool ProcessRestriction(const InputRestrictionContainer &restriction);
// warning: caller needs to take care of synchronization!
void ProcessWay(ExtractionWay &way);
};
#endif /* EXTRACTORCALLBACKS_H_ */
#endif /* EXTRACTOR_CALLBACKS_H */
+77 -182
View File
@@ -1,219 +1,114 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 EXTRACTORSTRUCTS_H_
#define EXTRACTORSTRUCTS_H_
#include <climits>
#include <string>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/regex.hpp>
#include <boost/regex.hpp>
#include <boost/unordered_map.hpp>
#include "../DataStructures/Coordinate.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportNode.h"
#include "../DataStructures/NodeCoords.h"
#include "../DataStructures/Restriction.h"
#include "../DataStructures/Util.h"
#include "../typedefs.h"
typedef boost::unordered_map<std::string, NodeID > StringMap;
typedef boost::unordered_map<std::string, std::pair<int, short> > StringToIntPairMap;
#include <limits>
#include <string>
struct _Way {
_Way() {
Clear();
}
inline void Clear(){
id = UINT_MAX;
nameID = UINT_MAX;
path.clear();
keyVals.EraseAll();
direction = _Way::notSure;
speed = -1;
type = -1;
access = true;
roundabout = false;
isDurationSet = false;
isAccessRestricted = false;
ignoreInGrid = false;
}
enum {
notSure = 0, oneway, bidirectional, opposite
} direction;
unsigned id;
unsigned nameID;
std::string name;
double speed;
short type;
bool access;
bool roundabout;
bool isDurationSet;
bool isAccessRestricted;
bool ignoreInGrid;
std::vector< NodeID > path;
struct ExtractorRelation
{
ExtractorRelation() : type(unknown) {}
enum
{ unknown = 0,
ferry,
turnRestriction } type;
HashTable<std::string, std::string> keyVals;
};
struct _Relation {
_Relation() : type(unknown){}
enum {
unknown = 0, ferry, turnRestriction
} type;
HashTable<std::string, std::string> keyVals;
};
struct _Edge {
_Edge() : start(0), target(0), type(0), direction(0), speed(0), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(false) {};
_Edge(NodeID s, NodeID t) : start(s), target(t), type(0), direction(0), speed(0), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(false) { }
_Edge(NodeID s, NodeID t, short tp, short d, double sp): start(s), target(t), type(tp), direction(d), speed(sp), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(false) { }
_Edge(NodeID s, NodeID t, short tp, short d, double sp, unsigned nid, bool isra, bool iing, bool ids, bool iar): start(s), target(t), type(tp), direction(d), speed(sp), nameID(nid), isRoundabout(isra), ignoreInGrid(iing), isDurationSet(ids), isAccessRestricted(iar) {
assert(0 <= type);
}
NodeID start;
NodeID target;
short type;
short direction;
double speed;
unsigned nameID;
bool isRoundabout;
bool ignoreInGrid;
bool isDurationSet;
bool isAccessRestricted;
_Coordinate startCoord;
_Coordinate targetCoord;
static _Edge min_value() {
return _Edge(0,0);
}
static _Edge max_value() {
return _Edge((numeric_limits<unsigned>::max)(), (numeric_limits<unsigned>::max)());
}
};
struct _WayIDStartAndEndEdge {
struct WayIDStartAndEndEdge
{
unsigned wayID;
NodeID firstStart;
NodeID firstTarget;
NodeID lastStart;
NodeID lastTarget;
_WayIDStartAndEndEdge() : wayID(UINT_MAX), firstStart(UINT_MAX), firstTarget(UINT_MAX), lastStart(UINT_MAX), lastTarget(UINT_MAX) {}
_WayIDStartAndEndEdge(unsigned w, NodeID fs, NodeID ft, NodeID ls, NodeID lt) : wayID(w), firstStart(fs), firstTarget(ft), lastStart(ls), lastTarget(lt) {}
static _WayIDStartAndEndEdge min_value() {
return _WayIDStartAndEndEdge((numeric_limits<unsigned>::min)(), (numeric_limits<unsigned>::min)(), (numeric_limits<unsigned>::min)(), (numeric_limits<unsigned>::min)(), (numeric_limits<unsigned>::min)());
WayIDStartAndEndEdge()
: wayID(std::numeric_limits<unsigned>::max()), firstStart(std::numeric_limits<unsigned>::max()), firstTarget(std::numeric_limits<unsigned>::max()), lastStart(std::numeric_limits<unsigned>::max()),
lastTarget(std::numeric_limits<unsigned>::max())
{
}
static _WayIDStartAndEndEdge max_value() {
return _WayIDStartAndEndEdge((numeric_limits<unsigned>::max)(), (numeric_limits<unsigned>::max)(), (numeric_limits<unsigned>::max)(), (numeric_limits<unsigned>::max)(), (numeric_limits<unsigned>::max)());
explicit WayIDStartAndEndEdge(unsigned w, NodeID fs, NodeID ft, NodeID ls, NodeID lt)
: wayID(w), firstStart(fs), firstTarget(ft), lastStart(ls), lastTarget(lt)
{
}
static WayIDStartAndEndEdge min_value()
{
return WayIDStartAndEndEdge((std::numeric_limits<unsigned>::min)(),
(std::numeric_limits<unsigned>::min)(),
(std::numeric_limits<unsigned>::min)(),
(std::numeric_limits<unsigned>::min)(),
(std::numeric_limits<unsigned>::min)());
}
static WayIDStartAndEndEdge max_value()
{
return WayIDStartAndEndEdge((std::numeric_limits<unsigned>::max)(),
(std::numeric_limits<unsigned>::max)(),
(std::numeric_limits<unsigned>::max)(),
(std::numeric_limits<unsigned>::max)(),
(std::numeric_limits<unsigned>::max)());
}
};
struct CmpWayByID : public std::binary_function<_WayIDStartAndEndEdge, _WayIDStartAndEndEdge, bool> {
typedef _WayIDStartAndEndEdge value_type;
bool operator () (const _WayIDStartAndEndEdge & a, const _WayIDStartAndEndEdge & b) const {
struct CmpWayByID
{
typedef WayIDStartAndEndEdge value_type;
bool operator()(const WayIDStartAndEndEdge &a, const WayIDStartAndEndEdge &b) const
{
return a.wayID < b.wayID;
}
value_type max_value() {
return _WayIDStartAndEndEdge::max_value();
}
value_type min_value() {
return _WayIDStartAndEndEdge::min_value();
}
value_type max_value() { return WayIDStartAndEndEdge::max_value(); }
value_type min_value() { return WayIDStartAndEndEdge::min_value(); }
};
struct Cmp : public std::binary_function<NodeID, NodeID, bool> {
struct Cmp
{
typedef NodeID value_type;
bool operator () (const NodeID & a, const NodeID & b) const {
return a < b;
}
value_type max_value() {
return 0xffffffff;
}
value_type min_value() {
return 0x0;
}
bool operator()(const NodeID left, const NodeID right) const { return left < right; }
value_type max_value() { return 0xffffffff; }
value_type min_value() { return 0x0; }
};
struct CmpNodeByID : public std::binary_function<_Node, _Node, bool> {
typedef _Node value_type;
bool operator () (const _Node & a, const _Node & b) const {
return a.id < b.id;
}
value_type max_value() {
return _Node::max_value();
}
value_type min_value() {
return _Node::min_value();
}
};
struct CmpEdgeByStartID : public std::binary_function<_Edge, _Edge, bool>
struct CmpNodeByID
{
typedef _Edge value_type;
bool operator () (const _Edge & a, const _Edge & b) const {
return a.start < b.start;
}
value_type max_value() {
return _Edge::max_value();
}
value_type min_value() {
return _Edge::min_value();
typedef ExternalMemoryNode value_type;
bool operator()(const ExternalMemoryNode &left, const ExternalMemoryNode &right) const
{
return left.node_id < right.node_id;
}
value_type max_value() { return ExternalMemoryNode::max_value(); }
value_type min_value() { return ExternalMemoryNode::min_value(); }
};
struct CmpEdgeByTargetID : public std::binary_function<_Edge, _Edge, bool>
{
typedef _Edge value_type;
bool operator () (const _Edge & a, const _Edge & b) const
{
return a.target < b.target;
}
value_type max_value()
{
return _Edge::max_value();
}
value_type min_value()
{
return _Edge::min_value();
}
};
inline string GetRandomString() {
char s[128];
static const char alphanum[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < 127; ++i) {
s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
}
s[127] = 0;
return string(s);
}
#endif /* EXTRACTORSTRUCTS_H_ */
+120
View File
@@ -0,0 +1,120 @@
/*
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 INTERNAL_EXTRACTOR_EDGE_H
#define INTERNAL_EXTRACTOR_EDGE_H
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
struct InternalExtractorEdge
{
InternalExtractorEdge()
: start(0), target(0), type(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)
{
}
explicit InternalExtractorEdge(NodeID start,
NodeID target,
short type,
short direction,
double speed,
unsigned name_id,
bool is_roundabout,
bool is_in_tiny_cc,
bool is_duration_set,
bool is_access_restricted,
bool is_contra_flow,
bool is_split)
: start(start), target(target), type(type), 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)
{
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);
}
static InternalExtractorEdge max_value()
{
return InternalExtractorEdge(
SPECIAL_NODEID, SPECIAL_NODEID, 0, 0, 0, 0, false, false, false, false, false, false);
}
NodeID start;
NodeID target;
short type;
short direction;
double speed;
unsigned name_id;
bool is_roundabout;
bool is_in_tiny_cc;
bool is_duration_set;
bool is_access_restricted;
bool is_contra_flow;
bool is_split;
FixedPointCoordinate source_coordinate;
FixedPointCoordinate target_coordinate;
};
struct CmpEdgeByStartID
{
typedef InternalExtractorEdge value_type;
bool operator()(const InternalExtractorEdge &a, const InternalExtractorEdge &b) const
{
return a.start < b.start;
}
value_type max_value() { return InternalExtractorEdge::max_value(); }
value_type min_value() { return InternalExtractorEdge::min_value(); }
};
struct CmpEdgeByTargetID
{
typedef InternalExtractorEdge value_type;
bool operator()(const InternalExtractorEdge &a, const InternalExtractorEdge &b) const
{
return a.target < b.target;
}
value_type max_value() { return InternalExtractorEdge::max_value(); }
value_type min_value() { return InternalExtractorEdge::min_value(); }
};
#endif // INTERNAL_EXTRACTOR_EDGE_H
-35
View File
@@ -1,35 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef LUAUTIL_H_
#define LUAUTIL_H_
#include <iostream>
template<typename T>
void LUA_print(T number) {
std::cout << "[LUA] " << number << std::endl;
}
#endif /* LUAUTIL_H_ */
+664
View File
@@ -0,0 +1,664 @@
/*
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 "PBFParser.h"
#include "ExtractionWay.h"
#include "ExtractorCallbacks.h"
#include "ScriptingEnvironment.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportNode.h"
#include "../DataStructures/Restriction.h"
#include "../Util/MachineInfo.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
#include <boost/assert.hpp>
#include <tbb/parallel_for.h>
#include <tbb/task_scheduler_init.h>
#include <osrm/Coordinate.h>
#include <zlib.h>
#include <functional>
#include <limits>
#include <thread>
PBFParser::PBFParser(const char *fileName,
ExtractorCallbacks *extractor_callbacks,
ScriptingEnvironment &scripting_environment,
unsigned num_threads)
: BaseParser(extractor_callbacks, scripting_environment)
{
if (0 == num_threads)
{
num_parser_threads = tbb::task_scheduler_init::default_num_threads();
}
else
{
num_parser_threads = num_threads;
}
GOOGLE_PROTOBUF_VERIFY_VERSION;
// TODO: What is the bottleneck here? Filling the queue or reading the stuff from disk?
// NOTE: With Lua scripting, it is parsing the stuff. I/O is virtually for free.
// Max 2500 items in queue, hardcoded.
thread_data_queue = std::make_shared<ConcurrentQueue<ParserThreadData *>>(2500);
input.open(fileName, std::ios::in | std::ios::binary);
if (!input)
{
throw OSRMException("pbf file not found.");
}
block_count = 0;
group_count = 0;
}
PBFParser::~PBFParser()
{
if (input.is_open())
{
input.close();
}
// Clean up any leftover ThreadData objects in the queue
ParserThreadData *thread_data;
while (thread_data_queue->try_pop(thread_data))
{
delete thread_data;
}
google::protobuf::ShutdownProtobufLibrary();
SimpleLogger().Write(logDEBUG) << "parsed " << block_count << " blocks from pbf with "
<< group_count << " groups";
}
inline bool PBFParser::ReadHeader()
{
ParserThreadData init_data;
/** read Header */
if (!readPBFBlobHeader(input, &init_data))
{
return false;
}
if (readBlob(input, &init_data))
{
if (!init_data.PBFHeaderBlock.ParseFromArray(&(init_data.charBuffer[0]),
static_cast<int>(init_data.charBuffer.size())))
{
std::cerr << "[error] Header not parseable!" << std::endl;
return false;
}
const auto feature_size = init_data.PBFHeaderBlock.required_features_size();
for (int i = 0; i < feature_size; ++i)
{
const std::string &feature = init_data.PBFHeaderBlock.required_features(i);
bool supported = false;
if ("OsmSchema-V0.6" == feature)
{
supported = true;
}
else if ("DenseNodes" == feature)
{
supported = true;
}
if (!supported)
{
std::cerr << "[error] required feature not supported: " << feature.data()
<< std::endl;
return false;
}
}
}
else
{
std::cerr << "[error] blob not loaded!" << std::endl;
}
return true;
}
inline void PBFParser::ReadData()
{
bool keep_running = true;
do
{
ParserThreadData *thread_data = new ParserThreadData();
keep_running = readNextBlock(input, thread_data);
if (keep_running)
{
thread_data_queue->push(thread_data);
}
else
{
// No more data to read, parse stops when nullptr encountered
thread_data_queue->push(nullptr);
delete thread_data;
}
} while (keep_running);
}
inline void PBFParser::ParseData()
{
tbb::task_scheduler_init init(num_parser_threads);
while (true)
{
ParserThreadData *thread_data;
thread_data_queue->wait_and_pop(thread_data);
if (nullptr == thread_data)
{
thread_data_queue->push(nullptr); // Signal end of data for other threads
break;
}
loadBlock(thread_data);
int group_size = thread_data->PBFprimitiveBlock.primitivegroup_size();
for (int i = 0; i < group_size; ++i)
{
thread_data->currentGroupID = i;
loadGroup(thread_data);
if (thread_data->entityTypeIndicator == TypeNode)
{
parseNode(thread_data);
}
if (thread_data->entityTypeIndicator == TypeWay)
{
parseWay(thread_data);
}
if (thread_data->entityTypeIndicator == TypeRelation)
{
parseRelation(thread_data);
}
if (thread_data->entityTypeIndicator == TypeDenseNode)
{
parseDenseNode(thread_data);
}
}
delete thread_data;
thread_data = nullptr;
}
}
inline bool PBFParser::Parse()
{
// Start the read and parse threads
std::thread read_thread(std::bind(&PBFParser::ReadData, this));
// Open several parse threads that are synchronized before call to
std::thread parse_thread(std::bind(&PBFParser::ParseData, this));
// Wait for the threads to finish
read_thread.join();
parse_thread.join();
return true;
}
inline void PBFParser::parseDenseNode(ParserThreadData *thread_data)
{
const OSMPBF::DenseNodes &dense =
thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID).dense();
int denseTagIndex = 0;
int64_t m_lastDenseID = 0;
int64_t m_lastDenseLatitude = 0;
int64_t m_lastDenseLongitude = 0;
const int number_of_nodes = dense.id_size();
std::vector<ImportNode> extracted_nodes_vector(number_of_nodes);
for (int i = 0; i < number_of_nodes; ++i)
{
m_lastDenseID += dense.id(i);
m_lastDenseLatitude += dense.lat(i);
m_lastDenseLongitude += dense.lon(i);
extracted_nodes_vector[i].node_id = static_cast<NodeID>(m_lastDenseID);
extracted_nodes_vector[i].lat = static_cast<int>(
COORDINATE_PRECISION *
((double)m_lastDenseLatitude * thread_data->PBFprimitiveBlock.granularity() +
thread_data->PBFprimitiveBlock.lat_offset()) /
NANO);
extracted_nodes_vector[i].lon = static_cast<int>(
COORDINATE_PRECISION *
((double)m_lastDenseLongitude * thread_data->PBFprimitiveBlock.granularity() +
thread_data->PBFprimitiveBlock.lon_offset()) /
NANO);
while (denseTagIndex < dense.keys_vals_size())
{
const int tagValue = dense.keys_vals(denseTagIndex);
if (0 == tagValue)
{
++denseTagIndex;
break;
}
const int keyValue = dense.keys_vals(denseTagIndex + 1);
const std::string &key = thread_data->PBFprimitiveBlock.stringtable().s(tagValue);
const std::string &value = thread_data->PBFprimitiveBlock.stringtable().s(keyValue);
extracted_nodes_vector[i].keyVals.Add(std::move(key), std::move(value));
denseTagIndex += 2;
}
}
tbb::parallel_for(tbb::blocked_range<size_t>(0, extracted_nodes_vector.size()),
[this, &extracted_nodes_vector](const tbb::blocked_range<size_t> &range)
{
lua_State *lua_state = this->scripting_environment.getLuaState();
for (size_t i = range.begin(); i != range.end(); ++i)
{
ImportNode &import_node = extracted_nodes_vector[i];
ParseNodeInLua(import_node, lua_state);
}
});
for (const ImportNode &import_node : extracted_nodes_vector)
{
extractor_callbacks->ProcessNode(import_node);
}
}
inline void PBFParser::parseNode(ParserThreadData *)
{
throw OSRMException("Parsing of simple nodes not supported. PBF should use dense nodes");
}
inline void PBFParser::parseRelation(ParserThreadData *thread_data)
{
// TODO: leave early, if relation is not a restriction
// TODO: reuse rawRestriction container
if (!use_turn_restrictions)
{
return;
}
const OSMPBF::PrimitiveGroup &group =
thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID);
for (int i = 0, relation_size = group.relations_size(); i < relation_size; ++i)
{
std::string except_tag_string;
const OSMPBF::Relation &inputRelation =
thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID).relations(i);
bool is_restriction = false;
bool is_only_restriction = false;
for (int k = 0, endOfKeys = inputRelation.keys_size(); k < endOfKeys; ++k)
{
const std::string &key =
thread_data->PBFprimitiveBlock.stringtable().s(inputRelation.keys(k));
const std::string &val =
thread_data->PBFprimitiveBlock.stringtable().s(inputRelation.vals(k));
if ("type" == key)
{
if ("restriction" == val)
{
is_restriction = true;
}
else
{
break;
}
}
if (("restriction" == key) && (val.find("only_") == 0))
{
is_only_restriction = true;
}
if ("except" == key)
{
except_tag_string = val;
}
}
if (is_restriction && ShouldIgnoreRestriction(except_tag_string))
{
continue;
}
if (is_restriction)
{
int64_t last_ref = 0;
InputRestrictionContainer current_restriction_container(is_only_restriction);
for (int rolesIndex = 0, last_role = inputRelation.roles_sid_size();
rolesIndex < last_role;
++rolesIndex)
{
const std::string &role = thread_data->PBFprimitiveBlock.stringtable().s(
inputRelation.roles_sid(rolesIndex));
last_ref += inputRelation.memids(rolesIndex);
if (!("from" == role || "to" == role || "via" == role))
{
continue;
}
switch (inputRelation.types(rolesIndex))
{
case 0: // node
if ("from" == role || "to" == role)
{ // Only via should be a node
continue;
}
BOOST_ASSERT("via" == role);
if (std::numeric_limits<unsigned>::max() !=
current_restriction_container.viaNode)
{
current_restriction_container.viaNode =
std::numeric_limits<unsigned>::max();
}
BOOST_ASSERT(std::numeric_limits<unsigned>::max() ==
current_restriction_container.viaNode);
current_restriction_container.restriction.viaNode =
static_cast<NodeID>(last_ref);
break;
case 1: // way
BOOST_ASSERT("from" == role || "to" == role || "via" == role);
if ("from" == role)
{
current_restriction_container.fromWay = static_cast<EdgeID>(last_ref);
}
if ("to" == role)
{
current_restriction_container.toWay = static_cast<EdgeID>(last_ref);
}
if ("via" == role)
{
BOOST_ASSERT(current_restriction_container.restriction.toNode ==
std::numeric_limits<unsigned>::max());
current_restriction_container.viaNode = static_cast<NodeID>(last_ref);
}
break;
case 2: // relation, not used. relations relating to relations are evil.
continue;
BOOST_ASSERT(false);
break;
default: // should not happen
BOOST_ASSERT(false);
break;
}
}
if (!extractor_callbacks->ProcessRestriction(current_restriction_container))
{
std::cerr << "[PBFParser] relation not parsed" << std::endl;
}
}
}
}
inline void PBFParser::parseWay(ParserThreadData *thread_data)
{
const int number_of_ways =
thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID).ways_size();
std::vector<ExtractionWay> parsed_way_vector(number_of_ways);
for (int i = 0; i < number_of_ways; ++i)
{
const OSMPBF::Way &input_way =
thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID).ways(i);
parsed_way_vector[i].id = static_cast<EdgeID>(input_way.id());
unsigned node_id_in_path = 0;
const auto number_of_referenced_nodes = input_way.refs_size();
for (auto j = 0; j < number_of_referenced_nodes; ++j)
{
node_id_in_path += static_cast<NodeID>(input_way.refs(j));
parsed_way_vector[i].path.push_back(node_id_in_path);
}
BOOST_ASSERT(input_way.keys_size() == input_way.vals_size());
const auto number_of_keys = input_way.keys_size();
for (auto j = 0; j < number_of_keys; ++j)
{
const std::string &key =
thread_data->PBFprimitiveBlock.stringtable().s(input_way.keys(j));
const std::string &val =
thread_data->PBFprimitiveBlock.stringtable().s(input_way.vals(j));
parsed_way_vector[i].keyVals.Add(std::move(key), std::move(val));
}
}
// TODO: investigate if schedule guided will be handled by tbb automatically
tbb::parallel_for(tbb::blocked_range<size_t>(0, parsed_way_vector.size()),
[this, &parsed_way_vector](const tbb::blocked_range<size_t> &range)
{
lua_State *lua_state = this->scripting_environment.getLuaState();
for (size_t i = range.begin(); i != range.end(); i++)
{
ExtractionWay &extraction_way = parsed_way_vector[i];
if (2 <= extraction_way.path.size())
{
ParseWayInLua(extraction_way, lua_state);
}
}
});
for (ExtractionWay &extraction_way : parsed_way_vector)
{
if (2 <= extraction_way.path.size())
{
extractor_callbacks->ProcessWay(extraction_way);
}
}
}
inline void PBFParser::loadGroup(ParserThreadData *thread_data)
{
#ifndef NDEBUG
++group_count;
#endif
const OSMPBF::PrimitiveGroup &group =
thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID);
thread_data->entityTypeIndicator = TypeDummy;
if (0 != group.nodes_size())
{
thread_data->entityTypeIndicator = TypeNode;
}
if (0 != group.ways_size())
{
thread_data->entityTypeIndicator = TypeWay;
}
if (0 != group.relations_size())
{
thread_data->entityTypeIndicator = TypeRelation;
}
if (group.has_dense())
{
thread_data->entityTypeIndicator = TypeDenseNode;
BOOST_ASSERT(0 != group.dense().id_size());
}
BOOST_ASSERT(thread_data->entityTypeIndicator != TypeDummy);
}
inline void PBFParser::loadBlock(ParserThreadData *thread_data)
{
++block_count;
thread_data->currentGroupID = 0;
thread_data->currentEntityID = 0;
}
inline bool PBFParser::readPBFBlobHeader(std::fstream &stream, ParserThreadData *thread_data)
{
int size(0);
stream.read((char *)&size, sizeof(int));
size = SwapEndian(size);
if (stream.eof())
{
return false;
}
if (size > MAX_BLOB_HEADER_SIZE || size < 0)
{
return false;
}
char *data = new char[size];
stream.read(data, size * sizeof(data[0]));
bool dataSuccessfullyParsed = (thread_data->PBFBlobHeader).ParseFromArray(data, size);
delete[] data;
return dataSuccessfullyParsed;
}
inline bool PBFParser::unpackZLIB(ParserThreadData *thread_data)
{
auto raw_size = thread_data->PBFBlob.raw_size();
char *unpacked_data_array = new char[raw_size];
z_stream compressed_data_stream;
compressed_data_stream.next_in = (unsigned char *)thread_data->PBFBlob.zlib_data().data();
compressed_data_stream.avail_in = thread_data->PBFBlob.zlib_data().size();
compressed_data_stream.next_out = (unsigned char *)unpacked_data_array;
compressed_data_stream.avail_out = raw_size;
compressed_data_stream.zalloc = Z_NULL;
compressed_data_stream.zfree = Z_NULL;
compressed_data_stream.opaque = Z_NULL;
int return_code = inflateInit(&compressed_data_stream);
if (return_code != Z_OK)
{
std::cerr << "[error] failed to init zlib stream" << std::endl;
delete[] unpacked_data_array;
return false;
}
return_code = inflate(&compressed_data_stream, Z_FINISH);
if (return_code != Z_STREAM_END)
{
std::cerr << "[error] failed to inflate zlib stream" << std::endl;
std::cerr << "[error] Error type: " << return_code << std::endl;
delete[] unpacked_data_array;
return false;
}
return_code = inflateEnd(&compressed_data_stream);
if (return_code != Z_OK)
{
std::cerr << "[error] failed to deinit zlib stream" << std::endl;
delete[] unpacked_data_array;
return false;
}
thread_data->charBuffer.clear();
thread_data->charBuffer.resize(raw_size);
std::copy(unpacked_data_array, unpacked_data_array + raw_size, thread_data->charBuffer.begin());
delete[] unpacked_data_array;
return true;
}
inline bool PBFParser::unpackLZMA(ParserThreadData *) { return false; }
inline bool PBFParser::readBlob(std::fstream &stream, ParserThreadData *thread_data)
{
if (stream.eof())
{
return false;
}
const int size = thread_data->PBFBlobHeader.datasize();
if (size < 0 || size > MAX_BLOB_SIZE)
{
std::cerr << "[error] invalid Blob size:" << size << std::endl;
return false;
}
char *data = new char[size];
stream.read(data, sizeof(data[0]) * size);
if (!thread_data->PBFBlob.ParseFromArray(data, size))
{
std::cerr << "[error] failed to parse blob" << std::endl;
delete[] data;
return false;
}
if (thread_data->PBFBlob.has_raw())
{
const std::string &data = thread_data->PBFBlob.raw();
thread_data->charBuffer.clear();
thread_data->charBuffer.resize(data.size());
std::copy(data.begin(), data.end(), thread_data->charBuffer.begin());
}
else if (thread_data->PBFBlob.has_zlib_data())
{
if (!unpackZLIB(thread_data))
{
std::cerr << "[error] zlib data encountered that could not be unpacked" << std::endl;
delete[] data;
return false;
}
}
else if (thread_data->PBFBlob.has_lzma_data())
{
if (!unpackLZMA(thread_data))
{
std::cerr << "[error] lzma data encountered that could not be unpacked" << std::endl;
}
delete[] data;
return false;
}
else
{
std::cerr << "[error] Blob contains no data" << std::endl;
delete[] data;
return false;
}
delete[] data;
return true;
}
bool PBFParser::readNextBlock(std::fstream &stream, ParserThreadData *thread_data)
{
if (stream.eof())
{
return false;
}
if (!readPBFBlobHeader(stream, thread_data))
{
return false;
}
if (thread_data->PBFBlobHeader.type() != "OSMData")
{
return false;
}
if (!readBlob(stream, thread_data))
{
return false;
}
if (!thread_data->PBFprimitiveBlock.ParseFromArray(&(thread_data->charBuffer[0]),
thread_data->charBuffer.size()))
{
std::cerr << "failed to parse PrimitiveBlock" << std::endl;
return false;
}
return true;
}
+64 -561
View File
@@ -1,64 +1,57 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 PBFPARSER_H_
#define PBFPARSER_H_
#include <zlib.h>
#include <boost/make_shared.hpp>
#include <boost/ref.hpp>
#include <boost/shared_ptr.hpp>
#include "BaseParser.h"
#include "../DataStructures/ConcurrentQueue.h"
#include <osmpbf/fileformat.pb.h>
#include <osmpbf/osmformat.pb.h>
#include "../typedefs.h"
#include <fstream>
#include <memory>
#include "BaseParser.h"
#include "ExtractorCallbacks.h"
#include "ExtractorStructs.h"
#include "ScriptingEnvironment.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/ConcurrentQueue.h"
#include "../Util/OpenMPWrapper.h"
class PBFParser : public BaseParser
{
class PBFParser : public BaseParser<ExtractorCallbacks, _Node, _RawRestrictionContainer, _Way> {
enum EntityType
{ TypeDummy = 0,
TypeNode = 1,
TypeWay = 2,
TypeRelation = 4,
TypeDenseNode = 8 };
// typedef BaseParser<ExtractorCallbacks, _Node, _RawRestrictionContainer, _Way> super;
enum EntityType {
TypeNode = 1,
TypeWay = 2,
TypeRelation = 4,
TypeDenseNode = 8
} ;
enum Endianness {
LittleEndian = 1,
BigEndian = 2
};
struct _ThreadData {
struct ParserThreadData
{
int currentGroupID;
int currentEntityID;
short entityTypeIndicator;
EntityType entityTypeIndicator;
OSMPBF::BlobHeader PBFBlobHeader;
OSMPBF::Blob PBFBlob;
@@ -69,532 +62,42 @@ class PBFParser : public BaseParser<ExtractorCallbacks, _Node, _RawRestrictionCo
std::vector<char> charBuffer;
};
public:
PBFParser(const char * fileName) : externalMemory(NULL){
GOOGLE_PROTOBUF_VERIFY_VERSION;
//TODO: What is the bottleneck here? Filling the queue or reading the stuff from disk?
//NOTE: With Lua scripting, it is parsing the stuff. I/O is virtually for free.
threadDataQueue = boost::make_shared<ConcurrentQueue<_ThreadData*> >( 2500 ); /* Max 2500 items in queue, hardcoded. */
input.open(fileName, std::ios::in | std::ios::binary);
public:
PBFParser(const char *file_name,
ExtractorCallbacks *extractor_callbacks,
ScriptingEnvironment &scripting_environment,
unsigned num_parser_threads = 0);
virtual ~PBFParser();
if (!input) {
std::cerr << fileName << ": File not found." << std::endl;
}
inline bool ReadHeader();
inline bool Parse();
#ifndef NDEBUG
blockCount = 0;
groupCount = 0;
#endif
}
private:
inline void ReadData();
inline void ParseData();
inline void parseDenseNode(ParserThreadData *thread_data);
inline void parseNode(ParserThreadData *thread_data);
inline void parseRelation(ParserThreadData *thread_data);
inline void parseWay(ParserThreadData *thread_data);
void RegisterCallbacks(ExtractorCallbacks * em) {
externalMemory = em;
}
//call by value, but who cares. It is done once.
void RegisterScriptingEnvironment(ScriptingEnvironment & _se) {
scriptingEnvironment = _se;
}
~PBFParser() {
if(input.is_open())
input.close();
// Clean up any leftover ThreadData objects in the queue
_ThreadData* td;
while (threadDataQueue->try_pop(td)) {
delete td;
}
google::protobuf::ShutdownProtobufLibrary();
#ifndef NDEBUG
DEBUG("parsed " << blockCount << " blocks from pbf with " << groupCount << " groups");
#endif
}
inline bool Init() {
_ThreadData initData;
/** read Header */
if(!readPBFBlobHeader(input, &initData)) {
return false;
}
if(readBlob(input, &initData)) {
if(!initData.PBFHeaderBlock.ParseFromArray(&(initData.charBuffer[0]), initData.charBuffer.size() ) ) {
std::cerr << "[error] Header not parseable!" << std::endl;
return false;
}
for(int i = 0, featureSize = initData.PBFHeaderBlock.required_features_size(); i < featureSize; ++i) {
const std::string& feature = initData.PBFHeaderBlock.required_features( i );
bool supported = false;
if ( "OsmSchema-V0.6" == feature )
supported = true;
else if ( "DenseNodes" == feature )
supported = true;
if ( !supported ) {
std::cerr << "[error] required feature not supported: " << feature.data() << std::endl;
return false;
}
}
} else {
std::cerr << "[error] blob not loaded!" << std::endl;
}
return true;
}
inline void ReadData() {
bool keepRunning = true;
do {
_ThreadData *threadData = new _ThreadData();
keepRunning = readNextBlock(input, threadData);
if (keepRunning)
threadDataQueue->push(threadData);
else {
threadDataQueue->push(NULL); // No more data to read, parse stops when NULL encountered
delete threadData;
}
} while(keepRunning);
}
inline void ParseData() {
while (1) {
_ThreadData *threadData;
threadDataQueue->wait_and_pop(threadData);
if (threadData == NULL) {
INFO("Parse Data Thread Finished");
threadDataQueue->push(NULL); // Signal end of data for other threads
break;
}
loadBlock(threadData);
for(int i = 0, groupSize = threadData->PBFprimitiveBlock.primitivegroup_size(); i < groupSize; ++i) {
threadData->currentGroupID = i;
loadGroup(threadData);
if(threadData->entityTypeIndicator == TypeNode)
parseNode(threadData);
if(threadData->entityTypeIndicator == TypeWay)
parseWay(threadData);
if(threadData->entityTypeIndicator == TypeRelation)
parseRelation(threadData);
if(threadData->entityTypeIndicator == TypeDenseNode)
parseDenseNode(threadData);
}
delete threadData;
threadData = NULL;
}
}
inline bool Parse() {
// Start the read and parse threads
boost::thread readThread(boost::bind(&PBFParser::ReadData, this));
//Open several parse threads that are synchronized before call to
boost::thread parseThread(boost::bind(&PBFParser::ParseData, this));
// Wait for the threads to finish
readThread.join();
parseThread.join();
return true;
}
private:
inline void parseDenseNode(_ThreadData * threadData) {
const OSMPBF::DenseNodes& dense = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).dense();
int denseTagIndex = 0;
int m_lastDenseID = 0;
int m_lastDenseLatitude = 0;
int m_lastDenseLongitude = 0;
ImportNode n;
std::vector<ImportNode> nodesToParse;
for(int i = 0, idSize = dense.id_size(); i < idSize; ++i) {
n.Clear();
m_lastDenseID += dense.id( i );
m_lastDenseLatitude += dense.lat( i );
m_lastDenseLongitude += dense.lon( i );
n.id = m_lastDenseID;
n.lat = 100000*( ( double ) m_lastDenseLatitude * threadData->PBFprimitiveBlock.granularity() +threadData-> PBFprimitiveBlock.lat_offset() ) / NANO;
n.lon = 100000*( ( double ) m_lastDenseLongitude * threadData->PBFprimitiveBlock.granularity() + threadData->PBFprimitiveBlock.lon_offset() ) / NANO;
while (denseTagIndex < dense.keys_vals_size()) {
const int tagValue = dense.keys_vals( denseTagIndex );
if(tagValue == 0) {
++denseTagIndex;
break;
}
const int keyValue = dense.keys_vals ( denseTagIndex+1 );
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(tagValue).data();
const std::string & value = threadData->PBFprimitiveBlock.stringtable().s(keyValue).data();
n.keyVals.Add(key, value);
denseTagIndex += 2;
}
nodesToParse.push_back(n);
}
unsigned endi_nodes = nodesToParse.size();
#pragma omp parallel for schedule ( guided )
for(unsigned i = 0; i < endi_nodes; ++i) {
ImportNode &n = nodesToParse[i];
/** Pass the unpacked node to the LUA call back **/
try {
luabind::call_function<int>(
scriptingEnvironment.getLuaStateForThreadID(omp_get_thread_num()),
"node_function",
boost::ref(n)
);
} catch (const luabind::error &er) {
lua_State* Ler=er.state();
report_errors(Ler, -1);
ERR(er.what());
}
// catch (...) {
// ERR("Unknown error occurred during PBF dense node parsing!");
// }
}
BOOST_FOREACH(ImportNode &n, nodesToParse) {
if(!externalMemory->nodeFunction(n))
std::cerr << "[PBFParser] dense node not parsed" << std::endl;
}
}
inline void parseNode(_ThreadData * ) {
ERR("Parsing of simple nodes not supported. PBF should use dense nodes");
}
inline void parseRelation(_ThreadData * threadData) {
//TODO: leave early, if relatio is not a restriction
//TODO: reuse rawRestriction container
const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID );
for(int i = 0; i < group.relations_size(); ++i ) {
const OSMPBF::Relation& inputRelation = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).relations(i);
bool isRestriction = false;
bool isOnlyRestriction = false;
for(int k = 0, endOfKeys = inputRelation.keys_size(); k < endOfKeys; ++k) {
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(inputRelation.keys(k));
const std::string & val = threadData->PBFprimitiveBlock.stringtable().s(inputRelation.vals(k));
if ("type" == key) {
if( "restriction" == val)
isRestriction = true;
else
break;
}
if ("restriction" == key) {
if(val.find("only_") == 0)
isOnlyRestriction = true;
}
}
if(isRestriction) {
long long lastRef = 0;
_RawRestrictionContainer currentRestrictionContainer(isOnlyRestriction);
for(int rolesIndex = 0; rolesIndex < inputRelation.roles_sid_size(); ++rolesIndex) {
std::string role(threadData->PBFprimitiveBlock.stringtable().s( inputRelation.roles_sid( rolesIndex ) ).data());
lastRef += inputRelation.memids(rolesIndex);
if(false == ("from" == role || "to" == role || "via" == role)) {
continue;
}
switch(inputRelation.types(rolesIndex)) {
case 0: //node
if("from" == role || "to" == role) //Only via should be a node
continue;
assert("via" == role);
if(UINT_MAX != currentRestrictionContainer.viaNode)
currentRestrictionContainer.viaNode = UINT_MAX;
assert(UINT_MAX == currentRestrictionContainer.viaNode);
currentRestrictionContainer.restriction.viaNode = lastRef;
break;
case 1: //way
assert("from" == role || "to" == role || "via" == role);
if("from" == role) {
currentRestrictionContainer.fromWay = lastRef;
}
if ("to" == role) {
currentRestrictionContainer.toWay = lastRef;
}
if ("via" == role) {
assert(currentRestrictionContainer.restriction.toNode == UINT_MAX);
currentRestrictionContainer.viaNode = lastRef;
}
break;
case 2: //relation, not used. relations relating to relations are evil.
continue;
assert(false);
break;
default: //should not happen
//cout << "unknown";
assert(false);
break;
}
}
// if(UINT_MAX != currentRestriction.viaNode) {
// cout << "restr from " << currentRestriction.from << " via ";
// cout << "node " << currentRestriction.viaNode;
// cout << " to " << currentRestriction.to << endl;
// }
if(!externalMemory->restrictionFunction(currentRestrictionContainer))
std::cerr << "[PBFParser] relation not parsed" << std::endl;
}
}
}
inline void parseWay(_ThreadData * threadData) {
_Way w;
std::vector<_Way> waysToParse(threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways_size());
for(int i = 0, ways_size = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways_size(); i < ways_size; ++i) {
w.Clear();
const OSMPBF::Way& inputWay = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways( i );
w.id = inputWay.id();
unsigned pathNode(0);
for(int i = 0; i < inputWay.refs_size(); ++i) {
pathNode += inputWay.refs(i);
w.path.push_back(pathNode);
}
assert(inputWay.keys_size() == inputWay.vals_size());
for(int i = 0; i < inputWay.keys_size(); ++i) {
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(inputWay.keys(i));
const std::string & val = threadData->PBFprimitiveBlock.stringtable().s(inputWay.vals(i));
w.keyVals.Add(key, val);
}
waysToParse.push_back(w);
}
unsigned endi_ways = waysToParse.size();
#pragma omp parallel for schedule ( guided )
for(unsigned i = 0; i < endi_ways; ++i) {
_Way & w = waysToParse[i];
/** Pass the unpacked way to the LUA call back **/
try {
luabind::call_function<int>(
scriptingEnvironment.getLuaStateForThreadID(omp_get_thread_num()),
"way_function",
boost::ref(w),
w.path.size()
);
} catch (const luabind::error &er) {
lua_State* Ler=er.state();
report_errors(Ler, -1);
ERR(er.what());
}
// catch (...) {
// ERR("Unknown error!");
// }
}
BOOST_FOREACH(_Way & w, waysToParse) {
if(!externalMemory->wayFunction(w)) {
std::cerr << "[PBFParser] way not parsed" << std::endl;
}
}
}
inline void loadGroup(_ThreadData * threadData) {
#ifndef NDEBUG
++groupCount;
#endif
const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID );
threadData->entityTypeIndicator = 0;
if ( group.nodes_size() != 0 ) {
threadData->entityTypeIndicator = TypeNode;
}
if ( group.ways_size() != 0 ) {
threadData->entityTypeIndicator = TypeWay;
}
if ( group.relations_size() != 0 ) {
threadData->entityTypeIndicator = TypeRelation;
}
if ( group.has_dense() ) {
threadData->entityTypeIndicator = TypeDenseNode;
assert( group.dense().id_size() != 0 );
}
assert( threadData->entityTypeIndicator != 0 );
}
inline void loadBlock(_ThreadData * threadData) {
#ifndef NDEBUG
++blockCount;
#endif
threadData->currentGroupID = 0;
threadData->currentEntityID = 0;
}
/* Reverses Network Byte Order into something usable, compiles down to a bswap-mov combination */
inline unsigned swapEndian(unsigned x) const {
if(getMachineEndianness() == LittleEndian)
return ( (x>>24) | ((x<<8) & 0x00FF0000) | ((x>>8) & 0x0000FF00) | (x<<24) );
return x;
}
inline bool readPBFBlobHeader(std::fstream& stream, _ThreadData * threadData) {
int size(0);
stream.read((char *)&size, sizeof(int));
size = swapEndian(size);
if(stream.eof()) {
return false;
}
if ( size > MAX_BLOB_HEADER_SIZE || size < 0 ) {
return false;
}
char *data = new char[size];
stream.read(data, size*sizeof(data[0]));
bool dataSuccessfullyParsed = (threadData->PBFBlobHeader).ParseFromArray( data, size);
delete[] data;
return dataSuccessfullyParsed;
}
inline bool unpackZLIB(std::fstream &, _ThreadData * threadData) {
unsigned rawSize = threadData->PBFBlob.raw_size();
char* unpackedDataArray = new char[rawSize];
z_stream compressedDataStream;
compressedDataStream.next_in = ( unsigned char* ) threadData->PBFBlob.zlib_data().data();
compressedDataStream.avail_in = threadData->PBFBlob.zlib_data().size();
compressedDataStream.next_out = ( unsigned char* ) unpackedDataArray;
compressedDataStream.avail_out = rawSize;
compressedDataStream.zalloc = Z_NULL;
compressedDataStream.zfree = Z_NULL;
compressedDataStream.opaque = Z_NULL;
int ret = inflateInit( &compressedDataStream );
if ( ret != Z_OK ) {
std::cerr << "[error] failed to init zlib stream" << std::endl;
delete[] unpackedDataArray;
return false;
}
ret = inflate( &compressedDataStream, Z_FINISH );
if ( ret != Z_STREAM_END ) {
std::cerr << "[error] failed to inflate zlib stream" << std::endl;
std::cerr << "[error] Error type: " << ret << std::endl;
delete[] unpackedDataArray;
return false;
}
ret = inflateEnd( &compressedDataStream );
if ( ret != Z_OK ) {
std::cerr << "[error] failed to deinit zlib stream" << std::endl;
delete[] unpackedDataArray;
return false;
}
threadData->charBuffer.clear(); threadData->charBuffer.resize(rawSize);
std::copy(unpackedDataArray, unpackedDataArray + rawSize, threadData->charBuffer.begin());
delete[] unpackedDataArray;
return true;
}
inline bool unpackLZMA(std::fstream &, _ThreadData * ) const {
return false;
}
inline bool readBlob(std::fstream& stream, _ThreadData * threadData) {
if(stream.eof())
return false;
const int size = threadData->PBFBlobHeader.datasize();
if ( size < 0 || size > MAX_BLOB_SIZE ) {
std::cerr << "[error] invalid Blob size:" << size << std::endl;
return false;
}
char* data = new char[size];
stream.read(data, sizeof(data[0])*size);
if ( !threadData->PBFBlob.ParseFromArray( data, size ) ) {
std::cerr << "[error] failed to parse blob" << std::endl;
delete[] data;
return false;
}
if ( threadData->PBFBlob.has_raw() ) {
const std::string& data = threadData->PBFBlob.raw();
threadData->charBuffer.clear();
threadData->charBuffer.resize( data.size() );
std::copy(data.begin(), data.end(), threadData->charBuffer.begin());
} else if ( threadData->PBFBlob.has_zlib_data() ) {
if ( !unpackZLIB(stream, threadData) ) {
std::cerr << "[error] zlib data encountered that could not be unpacked" << std::endl;
delete[] data;
return false;
}
} else if ( threadData->PBFBlob.has_lzma_data() ) {
if ( !unpackLZMA(stream, threadData) )
std::cerr << "[error] lzma data encountered that could not be unpacked" << std::endl;
delete[] data;
return false;
} else {
std::cerr << "[error] Blob contains no data" << std::endl;
delete[] data;
return false;
}
delete[] data;
return true;
}
inline bool readNextBlock(std::fstream& stream, _ThreadData * threadData) {
if(stream.eof()) {
return false;
}
if ( !readPBFBlobHeader(stream, threadData) ){
return false;
}
if ( threadData->PBFBlobHeader.type() != "OSMData" ) {
return false;
}
if ( !readBlob(stream, threadData) ) {
return false;
}
if ( !threadData->PBFprimitiveBlock.ParseFromArray( &(threadData->charBuffer[0]), threadData-> charBuffer.size() ) ) {
ERR("failed to parse PrimitiveBlock");
return false;
}
return true;
}
//Is optimized to a single 'mov eax,1' on GCC, clang and icc using -O3
inline Endianness getMachineEndianness() const {
int i(1);
char *p = (char *) &i;
if (1 == p[0])
return LittleEndian;
return BigEndian;
}
inline void loadGroup(ParserThreadData *thread_data);
inline void loadBlock(ParserThreadData *thread_data);
inline bool readPBFBlobHeader(std::fstream &stream, ParserThreadData *thread_data);
inline bool unpackZLIB(ParserThreadData *thread_data);
inline bool unpackLZMA(ParserThreadData *thread_data);
inline bool readBlob(std::fstream &stream, ParserThreadData *thread_data);
inline bool readNextBlock(std::fstream &stream, ParserThreadData *thread_data);
static const int NANO = 1000 * 1000 * 1000;
static const int MAX_BLOB_HEADER_SIZE = 64 * 1024;
static const int MAX_BLOB_SIZE = 32 * 1024 * 1024;
#ifndef NDEBUG
/* counting the number of read blocks and groups */
unsigned groupCount;
unsigned blockCount;
#endif
ExtractorCallbacks * externalMemory;
/* the input stream to parse */
std::fstream input;
unsigned group_count;
unsigned block_count;
/* ThreadData Queue */
boost::shared_ptr<ConcurrentQueue < _ThreadData* > > threadDataQueue;
ScriptingEnvironment scriptingEnvironment;
std::fstream input; // the input stream to parse
std::shared_ptr<ConcurrentQueue<ParserThreadData *>> thread_data_queue;
unsigned num_parser_threads;
};
#endif /* PBFPARSER_H_ */
+102 -103
View File
@@ -1,122 +1,121 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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.
extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
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 "ScriptingEnvironment.h"
#include "ExtractionHelperFunctions.h"
#include "ExtractionWay.h"
#include "../DataStructures/ImportNode.h"
#include "../Util/LuaUtil.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
#include "../Util/OpenMPWrapper.h"
ScriptingEnvironment::ScriptingEnvironment() {}
ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
INFO("Using script " << fileName);
ScriptingEnvironment::ScriptingEnvironment(const char *file_name)
: file_name(file_name)
{
SimpleLogger().Write() << "Using script " << file_name;
}
// Create a new lua state
for(int i = 0; i < omp_get_max_threads(); ++i)
luaStateVector.push_back(luaL_newstate());
void ScriptingEnvironment::initLuaState(lua_State* lua_state)
{
luabind::open(lua_state);
// open utility libraries string library;
luaL_openlibs(lua_state);
// Connect LuaBind to this lua state for all threads
#pragma omp parallel
luaAddScriptFolderToLoadPath(lua_state, file_name.c_str());
// Add our function to the state's global scope
luabind::module(lua_state)[
luabind::def("print", LUA_print<std::string>),
luabind::def("durationIsValid", durationIsValid),
luabind::def("parseDuration", parseDuration)
];
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()))
{
lua_State * myLuaState = getLuaStateForThreadID(omp_get_thread_num());
luabind::open(myLuaState);
//open utility libraries string library;
luaL_openlibs(myLuaState);
// Add our function to the state's global scope
luabind::module(myLuaState) [
luabind::def("print", LUA_print<std::string>),
luabind::def("parseMaxspeed", parseMaxspeed),
luabind::def("durationIsValid", durationIsValid),
luabind::def("parseDuration", parseDuration)
];
//#pragma omp critical
// {
// if(0 != luaL_dostring(
// myLuaState,
// "print('Initializing LUA engine')\n"
// )) {
// ERR(lua_tostring(myLuaState,-1)<< " occured in scripting block");
// }
// }
luabind::module(myLuaState) [
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(myLuaState) [
luabind::class_<ImportNode>("Node")
.def(luabind::constructor<>())
.def_readwrite("lat", &ImportNode::lat)
.def_readwrite("lon", &ImportNode::lon)
.def_readwrite("id", &ImportNode::id)
.def_readwrite("bollard", &ImportNode::bollard)
.def_readwrite("traffic_light", &ImportNode::trafficLight)
.def_readwrite("tags", &ImportNode::keyVals)
];
luabind::module(myLuaState) [
luabind::class_<_Way>("Way")
.def(luabind::constructor<>())
.def_readwrite("name", &_Way::name)
.def_readwrite("speed", &_Way::speed)
.def_readwrite("type", &_Way::type)
.def_readwrite("access", &_Way::access)
.def_readwrite("roundabout", &_Way::roundabout)
.def_readwrite("is_duration_set", &_Way::isDurationSet)
.def_readwrite("is_access_restricted", &_Way::isAccessRestricted)
.def_readwrite("ignore_in_grid", &_Way::ignoreInGrid)
.def_readwrite("tags", &_Way::keyVals)
.def_readwrite("direction", &_Way::direction)
.enum_("constants")
[
luabind::value("notSure", 0),
luabind::value("oneway", 1),
luabind::value("bidirectional", 2),
luabind::value("opposite", 3)
]
];
// Now call our function in a lua script
//#pragma omp critical
// {
// INFO("Parsing speedprofile from " << fileName );
// }
if(0 != luaL_dofile(myLuaState, fileName) ) {
ERR(lua_tostring(myLuaState,-1)<< " occured in scripting block");
}
throw OSRMException("ERROR occured in scripting block");
}
}
ScriptingEnvironment::~ScriptingEnvironment() {
for(unsigned i = 0; i < luaStateVector.size(); ++i) {
// luaStateVector[i];
lua_State *ScriptingEnvironment::getLuaState()
{
bool initialized = false;
auto& ref = script_contexts.local(initialized);
if (!initialized)
{
std::shared_ptr<lua_State> state(luaL_newstate(), lua_close);
ref = state;
initLuaState(ref.get());
}
return ref.get();
}
lua_State * ScriptingEnvironment::getLuaStateForThreadID(const int id) {
return luaStateVector[id];
}
+36 -32
View File
@@ -1,48 +1,52 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 SCRIPTINGENVIRONMENT_H_
#define SCRIPTINGENVIRONMENT_H_
extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
#include <luabind/luabind.hpp>
#include <string>
#include <memory>
#include <tbb/enumerable_thread_specific.h>
#include "ExtractionHelperFunctions.h"
#include "ExtractorStructs.h"
#include "LuaUtil.h"
struct lua_State;
#include "../DataStructures/ImportNode.h"
class ScriptingEnvironment {
public:
class ScriptingEnvironment
{
public:
ScriptingEnvironment();
ScriptingEnvironment(const char * fileName);
virtual ~ScriptingEnvironment();
explicit ScriptingEnvironment(const char *file_name);
lua_State * getLuaStateForThreadID(const int);
lua_State *getLuaState();
std::vector<lua_State *> luaStateVector;
private:
void initLuaState(lua_State* lua_state);
std::string file_name;
tbb::enumerable_thread_specific<std::shared_ptr<lua_State>> script_contexts;
};
#endif /* SCRIPTINGENVIRONMENT_H_ */
+353
View File
@@ -0,0 +1,353 @@
/*
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 "XMLParser.h"
#include "ExtractionWay.h"
#include "ExtractorCallbacks.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportNode.h"
#include "../DataStructures/InputReaderFactory.h"
#include "../DataStructures/Restriction.h"
#include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
XMLParser::XMLParser(const char *filename,
ExtractorCallbacks *extractor_callbacks,
ScriptingEnvironment &scripting_environment)
: BaseParser(extractor_callbacks, scripting_environment)
{
inputReader = inputReaderFactory(filename);
}
bool XMLParser::ReadHeader() { return xmlTextReaderRead(inputReader) == 1; }
bool XMLParser::Parse()
{
while (xmlTextReaderRead(inputReader) == 1)
{
const int type = xmlTextReaderNodeType(inputReader);
// 1 is Element
if (type != 1)
{
continue;
}
xmlChar *currentName = xmlTextReaderName(inputReader);
if (currentName == nullptr)
{
continue;
}
if (xmlStrEqual(currentName, (const xmlChar *)"node") == 1)
{
ImportNode current_node = ReadXMLNode();
ParseNodeInLua(current_node, lua_state);
extractor_callbacks->ProcessNode(current_node);
}
if (xmlStrEqual(currentName, (const xmlChar *)"way") == 1)
{
ExtractionWay way = ReadXMLWay();
ParseWayInLua(way, lua_state);
extractor_callbacks->ProcessWay(way);
}
if (use_turn_restrictions && xmlStrEqual(currentName, (const xmlChar *)"relation") == 1)
{
InputRestrictionContainer current_restriction = ReadXMLRestriction();
if ((UINT_MAX != current_restriction.fromWay) &&
!extractor_callbacks->ProcessRestriction(current_restriction))
{
std::cerr << "[XMLParser] restriction not parsed" << std::endl;
}
}
xmlFree(currentName);
}
return true;
}
InputRestrictionContainer XMLParser::ReadXMLRestriction()
{
InputRestrictionContainer restriction;
if (xmlTextReaderIsEmptyElement(inputReader) == 1)
{
return restriction;
}
std::string except_tag_string;
const int depth = xmlTextReaderDepth(inputReader);
while (xmlTextReaderRead(inputReader) == 1)
{
const int child_type = xmlTextReaderNodeType(inputReader);
if (child_type != 1 && child_type != 15)
{
continue;
}
const int child_depth = xmlTextReaderDepth(inputReader);
xmlChar *child_name = xmlTextReaderName(inputReader);
if (child_name == nullptr)
{
continue;
}
if (depth == child_depth && child_type == 15 &&
xmlStrEqual(child_name, (const xmlChar *)"relation") == 1)
{
xmlFree(child_name);
break;
}
if (child_type != 1)
{
xmlFree(child_name);
continue;
}
if (xmlStrEqual(child_name, (const xmlChar *)"tag") == 1)
{
xmlChar *key = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v");
if (key != nullptr && value != nullptr)
{
if (xmlStrEqual(key, (const xmlChar *)"restriction") &&
StringStartsWith((const char *)value, "only_"))
{
restriction.restriction.flags.isOnly = true;
}
if (xmlStrEqual(key, (const xmlChar *)"except"))
{
except_tag_string = (const char *)value;
}
}
if (key != nullptr)
{
xmlFree(key);
}
if (value != nullptr)
{
xmlFree(value);
}
}
else if (xmlStrEqual(child_name, (const xmlChar *)"member") == 1)
{
xmlChar *ref = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"ref");
if (ref != nullptr)
{
xmlChar *role = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"role");
xmlChar *type = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"type");
if (xmlStrEqual(role, (const xmlChar *)"to") &&
xmlStrEqual(type, (const xmlChar *)"way"))
{
restriction.toWay = StringToUint((const char *)ref);
}
if (xmlStrEqual(role, (const xmlChar *)"from") &&
xmlStrEqual(type, (const xmlChar *)"way"))
{
restriction.fromWay = StringToUint((const char *)ref);
}
if (xmlStrEqual(role, (const xmlChar *)"via") &&
xmlStrEqual(type, (const xmlChar *)"node"))
{
restriction.restriction.viaNode = StringToUint((const char *)ref);
}
if (nullptr != type)
{
xmlFree(type);
}
if (nullptr != role)
{
xmlFree(role);
}
if (nullptr != ref)
{
xmlFree(ref);
}
}
}
xmlFree(child_name);
}
if (ShouldIgnoreRestriction(except_tag_string))
{
restriction.fromWay = UINT_MAX; // workaround to ignore the restriction
}
return restriction;
}
ExtractionWay XMLParser::ReadXMLWay()
{
ExtractionWay way;
if (xmlTextReaderIsEmptyElement(inputReader) == 1)
{
return way;
}
const int depth = xmlTextReaderDepth(inputReader);
while (xmlTextReaderRead(inputReader) == 1)
{
const int child_type = xmlTextReaderNodeType(inputReader);
if (child_type != 1 && child_type != 15)
{
continue;
}
const int child_depth = xmlTextReaderDepth(inputReader);
xmlChar *child_name = xmlTextReaderName(inputReader);
if (child_name == nullptr)
{
continue;
}
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);
xmlFree(child_name);
break;
}
if (child_type != 1)
{
xmlFree(child_name);
continue;
}
if (xmlStrEqual(child_name, (const xmlChar *)"tag") == 1)
{
xmlChar *key = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v");
if (key != nullptr && value != nullptr)
{
way.keyVals.Add(std::string((char *)key), std::string((char *)value));
}
if (key != nullptr)
{
xmlFree(key);
}
if (value != nullptr)
{
xmlFree(value);
}
}
else if (xmlStrEqual(child_name, (const xmlChar *)"nd") == 1)
{
xmlChar *ref = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"ref");
if (ref != nullptr)
{
way.path.push_back(StringToUint((const char *)ref));
xmlFree(ref);
}
}
xmlFree(child_name);
}
return way;
}
ImportNode XMLParser::ReadXMLNode()
{
ImportNode node;
xmlChar *attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"lat");
if (attribute != nullptr)
{
node.lat = static_cast<int>(COORDINATE_PRECISION * StringToDouble((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));
xmlFree(attribute);
}
attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"id");
if (attribute != nullptr)
{
node.node_id = StringToUint((const char *)attribute);
xmlFree(attribute);
}
if (xmlTextReaderIsEmptyElement(inputReader) == 1)
{
return node;
}
const int depth = xmlTextReaderDepth(inputReader);
while (xmlTextReaderRead(inputReader) == 1)
{
const int child_type = xmlTextReaderNodeType(inputReader);
// 1 = Element, 15 = EndElement
if (child_type != 1 && child_type != 15)
{
continue;
}
const int child_depth = xmlTextReaderDepth(inputReader);
xmlChar *child_name = xmlTextReaderName(inputReader);
if (child_name == nullptr)
{
continue;
}
if (depth == child_depth && child_type == 15 &&
xmlStrEqual(child_name, (const xmlChar *)"node") == 1)
{
xmlFree(child_name);
break;
}
if (child_type != 1)
{
xmlFree(child_name);
continue;
}
if (xmlStrEqual(child_name, (const xmlChar *)"tag") == 1)
{
xmlChar *key = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v");
if (key != nullptr && value != nullptr)
{
node.keyVals.Add(std::string((char *)(key)), std::string((char *)(value)));
}
if (key != nullptr)
{
xmlFree(key);
}
if (value != nullptr)
{
xmlFree(value);
}
}
xmlFree(child_name);
}
return node;
}
+38 -292
View File
@@ -1,308 +1,54 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
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 XMLPARSER_H_
#define XMLPARSER_H_
#include <boost/ref.hpp>
#include "BaseParser.h"
#include "../DataStructures/Restriction.h"
#include <libxml/xmlreader.h>
#include "../typedefs.h"
#include "BaseParser.h"
#include "ExtractorStructs.h"
#include "ExtractorCallbacks.h"
#include "ScriptingEnvironment.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/InputReaderFactory.h"
class ExtractorCallbacks;
class XMLParser : public BaseParser<ExtractorCallbacks, _Node, _RawRestrictionContainer, _Way> {
public:
XMLParser(const char * filename) : externalMemory(NULL), myLuaState(NULL){
WARN("Parsing plain .osm/.osm.bz2 is deprecated. Switch to .pbf");
inputReader = inputReaderFactory(filename);
}
virtual ~XMLParser() {}
class XMLParser : public BaseParser
{
public:
XMLParser(const char *filename,
ExtractorCallbacks *extractor_callbacks,
ScriptingEnvironment &scripting_environment);
bool ReadHeader();
bool Parse();
void RegisterCallbacks(ExtractorCallbacks * em) {
externalMemory = em;
}
void RegisterScriptingEnvironment(ScriptingEnvironment & _se) {
myLuaState = _se.getLuaStateForThreadID(0);
}
bool Init() {
return (xmlTextReaderRead( inputReader ) == 1);
}
bool Parse() {
while ( xmlTextReaderRead( inputReader ) == 1 ) {
const int type = xmlTextReaderNodeType( inputReader );
//1 is Element
if ( type != 1 )
continue;
xmlChar* currentName = xmlTextReaderName( inputReader );
if ( currentName == NULL )
continue;
if ( xmlStrEqual( currentName, ( const xmlChar* ) "node" ) == 1 ) {
ImportNode n = _ReadXMLNode( );
/** Pass the unpacked node to the LUA call back **/
try {
luabind::call_function<int>(
myLuaState,
"node_function",
boost::ref(n)
);
if(!externalMemory->nodeFunction(n))
std::cerr << "[XMLParser] dense node not parsed" << std::endl;
} catch (const luabind::error &er) {
cerr << er.what() << endl;
lua_State* Ler=er.state();
report_errors(Ler, -1);
} catch (std::exception & e) {
ERR(e.what());
} catch (...) {
ERR("Unknown error occurred during XML node parsing!");
}
}
if ( xmlStrEqual( currentName, ( const xmlChar* ) "way" ) == 1 ) {
string name;
_Way way = _ReadXMLWay( );
/** Pass the unpacked way to the LUA call back **/
try {
luabind::call_function<int>(
myLuaState,
"way_function",
boost::ref(way),
way.path.size()
);
if(!externalMemory->wayFunction(way)) {
std::cerr << "[PBFParser] way not parsed" << std::endl;
}
} catch (const luabind::error &er) {
cerr << er.what() << endl;
lua_State* Ler=er.state();
report_errors(Ler, -1);
} catch (std::exception & e) {
ERR(e.what());
} catch (...) {
ERR("Unknown error occurred during XML way parsing!");
}
}
if ( xmlStrEqual( currentName, ( const xmlChar* ) "relation" ) == 1 ) {
_RawRestrictionContainer r = _ReadXMLRestriction();
if(r.fromWay != UINT_MAX) {
if(!externalMemory->restrictionFunction(r)) {
std::cerr << "[XMLParser] restriction not parsed" << std::endl;
}
}
}
xmlFree( currentName );
}
return true;
}
private:
_RawRestrictionContainer _ReadXMLRestriction ( ) {
_RawRestrictionContainer restriction;
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
const int depth = xmlTextReaderDepth( inputReader );while ( xmlTextReaderRead( inputReader ) == 1 ) {
const int childType = xmlTextReaderNodeType( inputReader );
if ( childType != 1 && childType != 15 )
continue;
const int childDepth = xmlTextReaderDepth( inputReader );
xmlChar* childName = xmlTextReaderName( inputReader );
if ( childName == NULL )
continue;
if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "relation" ) == 1 ) {
xmlFree( childName );
break;
}
if ( childType != 1 ) {
xmlFree( childName );
continue;
}
if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) {
xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" );
xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" );
if ( k != NULL && value != NULL ) {
if(xmlStrEqual(k, ( const xmlChar* ) "restriction" )){
if(0 == std::string((const char *) value).find("only_"))
restriction.restriction.flags.isOnly = true;
}
}
if ( k != NULL )
xmlFree( k );
if ( value != NULL )
xmlFree( value );
} else if ( xmlStrEqual( childName, ( const xmlChar* ) "member" ) == 1 ) {
xmlChar* ref = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "ref" );
if ( ref != NULL ) {
xmlChar * role = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "role" );
xmlChar * type = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "type" );
if(xmlStrEqual(role, (const xmlChar *) "to") && xmlStrEqual(type, (const xmlChar *) "way")) {
restriction.toWay = atoi((const char*) ref);
}
if(xmlStrEqual(role, (const xmlChar *) "from") && xmlStrEqual(type, (const xmlChar *) "way")) {
restriction.fromWay = atoi((const char*) ref);
}
if(xmlStrEqual(role, (const xmlChar *) "via") && xmlStrEqual(type, (const xmlChar *) "node")) {
restriction.restriction.viaNode = atoi((const char*) ref);
}
if(NULL != type)
xmlFree( type );
if(NULL != role)
xmlFree( role );
if(NULL != ref)
xmlFree( ref );
}
}
xmlFree( childName );
}
}
return restriction;
}
_Way _ReadXMLWay( ) {
_Way way;
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
const int depth = xmlTextReaderDepth( inputReader );
while ( xmlTextReaderRead( inputReader ) == 1 ) {
const int childType = xmlTextReaderNodeType( inputReader );
if ( childType != 1 && childType != 15 )
continue;
const int childDepth = xmlTextReaderDepth( inputReader );
xmlChar* childName = xmlTextReaderName( inputReader );
if ( childName == NULL )
continue;
if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "way" ) == 1 ) {
xmlChar* id = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" );
way.id = atoi((char*)id);
xmlFree(id);
xmlFree( childName );
break;
}
if ( childType != 1 ) {
xmlFree( childName );
continue;
}
if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) {
xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" );
xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" );
// cout << "->k=" << k << ", v=" << value << endl;
if ( k != NULL && value != NULL ) {
way.keyVals.Add(std::string( (char *) k ), std::string( (char *) value));
}
if ( k != NULL )
xmlFree( k );
if ( value != NULL )
xmlFree( value );
} else if ( xmlStrEqual( childName, ( const xmlChar* ) "nd" ) == 1 ) {
xmlChar* ref = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "ref" );
if ( ref != NULL ) {
way.path.push_back( atoi(( const char* ) ref ) );
xmlFree( ref );
}
}
xmlFree( childName );
}
}
return way;
}
ImportNode _ReadXMLNode( ) {
ImportNode node;
xmlChar* attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lat" );
if ( attribute != NULL ) {
node.lat = static_cast<NodeID>(100000.*atof(( const char* ) attribute ) );
xmlFree( attribute );
}
attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lon" );
if ( attribute != NULL ) {
node.lon = static_cast<NodeID>(100000.*atof(( const char* ) attribute ));
xmlFree( attribute );
}
attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" );
if ( attribute != NULL ) {
node.id = atoi(( const char* ) attribute );
xmlFree( attribute );
}
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
const int depth = xmlTextReaderDepth( inputReader );
while ( xmlTextReaderRead( inputReader ) == 1 ) {
const int childType = xmlTextReaderNodeType( inputReader );
// 1 = Element, 15 = EndElement
if ( childType != 1 && childType != 15 )
continue;
const int childDepth = xmlTextReaderDepth( inputReader );
xmlChar* childName = xmlTextReaderName( inputReader );
if ( childName == NULL )
continue;
if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "node" ) == 1 ) {
xmlFree( childName );
break;
}
if ( childType != 1 ) {
xmlFree( childName );
continue;
}
if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) {
xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" );
xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" );
if ( k != NULL && value != NULL ) {
node.keyVals.Add(std::string( reinterpret_cast<char*>(k) ), std::string( reinterpret_cast<char*>(value)));
}
if ( k != NULL )
xmlFree( k );
if ( value != NULL )
xmlFree( value );
}
xmlFree( childName );
}
}
return node;
}
/* Input Reader */
private:
InputRestrictionContainer ReadXMLRestriction();
ExtractionWay ReadXMLWay();
ImportNode ReadXMLNode();
xmlTextReaderPtr inputReader;
//holds the callback functions and storage for our temporary data
ExtractorCallbacks * externalMemory;
lua_State *myLuaState;
};
#endif /* XMLPARSER_H_ */
+15 -15
View File
@@ -1,23 +1,23 @@
GEM
remote: http://rubygems.org/
specs:
builder (3.0.0)
cucumber (1.1.4)
builder (3.2.2)
cucumber (1.3.8)
builder (>= 2.1.2)
diff-lcs (>= 1.1.2)
gherkin (~> 2.7.1)
json (>= 1.4.6)
term-ansicolor (>= 1.0.6)
diff-lcs (1.1.3)
gherkin (2.7.6)
json (>= 1.4.6)
json (1.6.5)
diff-lcs (>= 1.1.3)
gherkin (~> 2.12.1)
multi_json (>= 1.7.5, < 2.0)
multi_test (>= 0.0.2)
diff-lcs (1.2.4)
gherkin (2.12.1)
multi_json (~> 1.3)
multi_json (1.8.0)
multi_test (0.0.2)
osmlib-base (0.1.4)
rake (0.9.2.2)
rspec-expectations (2.11.3)
diff-lcs (~> 1.1.3)
sys-proctable (0.9.1)
term-ansicolor (1.0.7)
rake (10.1.0)
rspec-expectations (2.14.3)
diff-lcs (>= 1.1.3, < 2.0)
sys-proctable (0.9.3)
PLATFORMS
ruby
+105
View File
@@ -0,0 +1,105 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FIXED_POINT_COORDINATE_H_
#define FIXED_POINT_COORDINATE_H_
#include <functional>
#include <iosfwd> //for std::ostream
#include <string>
const float COORDINATE_PRECISION = 1000000.f;
struct FixedPointCoordinate
{
int lat;
int lon;
FixedPointCoordinate();
explicit FixedPointCoordinate(int lat, int lon);
void Reset();
bool isSet() const;
bool isValid() const;
bool operator==(const FixedPointCoordinate &other) const;
static double
ApproximateDistance(const int lat1, const int lon1, const int lat2, const int lon2);
static double ApproximateDistance(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate);
static float ApproximateEuclideanDistance(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate);
static float ApproximateEuclideanDistance(const int lat1,
const int lon1,
const int lat2,
const int lon2);
static float ApproximateSquaredEuclideanDistance(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate);
static void convertInternalLatLonToString(const int value, std::string &output);
static void convertInternalCoordinateToString(const FixedPointCoordinate &coordinate,
std::string &output);
static void convertInternalReversedCoordinateToString(const FixedPointCoordinate &coordinate,
std::string &output);
static float ComputePerpendicularDistance(const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location);
static float ComputePerpendicularDistance(const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location,
FixedPointCoordinate &nearest_location,
float &ratio);
static int OrderedPerpendicularDistanceApproximation(const FixedPointCoordinate& segment_source,
const FixedPointCoordinate& segment_target,
const FixedPointCoordinate& query_location);
static float GetBearing(const FixedPointCoordinate &A, const FixedPointCoordinate &B);
float GetBearing(const FixedPointCoordinate &other) const;
void Output(std::ostream &out) const;
static float DegreeToRadian(const float degree);
static float RadianToDegree(const float radian);
};
inline std::ostream &operator<<(std::ostream &out_stream, FixedPointCoordinate const &coordinate)
{
coordinate.Output(out_stream);
return out_stream;
}
#endif /* FIXED_POINT_COORDINATE_H_ */
+53
View File
@@ -0,0 +1,53 @@
/*
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 HTTP_HEADER_H
#define HTTP_HEADER_H
#include <string>
#include <algorithm>
namespace http
{
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)) {}
void Clear()
{
name.clear();
value.clear();
}
std::string name;
std::string value;
};
}
#endif // HTTP_HEADER_H

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