Compare commits

...

380 Commits

Author SHA1 Message Date
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
DennisOSRM dee7c339b3 Move edge-based node out ouf surrounding class 2013-10-11 16:14:59 +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 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 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 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
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 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
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
90 changed files with 5767 additions and 2974 deletions
+3
View File
@@ -72,7 +72,10 @@ stxxl.errlog
/win/bin/
/win/bin-debug/
/osrm-extract
/osrm-io-benchmark
/osrm-components
/osrm-routed
/osrm-datastore
/osrm-prepare
/osrm-cli
/nohup.out
+2 -3
View File
@@ -2,6 +2,7 @@ language: cpp
compiler:
- gcc
# - clang
# Make sure CMake is installed
install:
- sudo apt-get update >/dev/null
- sudo apt-get -q install libprotoc-dev libprotobuf7 protobuf-compiler libprotobuf-dev libosmpbf-dev libpng12-dev libbz2-dev libstxxl-dev libstxxl-doc libstxxl1 libxml2-dev libzip-dev libboost1.46-all-dev lua5.1 liblua5.1-0-dev libluabind-dev rubygems osmosis
@@ -12,9 +13,6 @@ before_script:
- cd build
- cmake .. $CMAKEOPTIONS
script: make
after_script:
- cd ..
- cucumber -p verify
branches:
only:
- master
@@ -30,6 +28,7 @@ notifications:
on_failure: always
use_notice: true
skip_join: false
recipients:
- dennis@mapbox.com
email:
-92
View File
@@ -1,92 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "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) {
SimpleLogger().Write() << "using hardware base sse computation";
return &CRC32::SSEBasedCRC32; //crc32 hardware accelarated;
} else {
SimpleLogger().Write() << "using software base sse computation";
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;
}
+7 -108
View File
@@ -29,6 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define DOUGLASPEUCKER_H_
#include "../DataStructures/Coordinate.h"
#include "../DataStructures/SegmentInformation.h"
#include <boost/assert.hpp>
@@ -45,11 +46,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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. };
template<class PointT>
class DouglasPeucker {
private:
typedef std::pair<std::size_t, std::size_t> PairOfPoints;
@@ -60,111 +56,14 @@ private:
* 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 = ( 0 == something ? 0 : ((point.lon - segA.lon) * p2x + (point.lat - segA.lat) * p2y) / something);
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;
}
int fastDistance(
const FixedPointCoordinate& point,
const FixedPointCoordinate& segA,
const FixedPointCoordinate& segB
) const;
public:
void Run(std::vector<PointT> & input_geometry, const unsigned zoom_level) {
{
BOOST_ASSERT_MSG(zoom_level < 19, "unsupported zoom level");
BOOST_ASSERT_MSG(1 < input_geometry.size(), "geometry invalid");
std::size_t left_border = 0;
std::size_t right_border = 1;
//Sweep linerarily over array and identify those ranges that need to be checked
do {
BOOST_ASSERT_MSG(
input_geometry[left_border].necessary,
"left border must be necessary"
);
BOOST_ASSERT_MSG(
input_geometry.back().necessary,
"right border must be necessary"
);
void Run(std::vector<SegmentInformation> & input_geometry, const unsigned zoom_level);
if(input_geometry[right_border].necessary) {
recursion_stack.push(std::make_pair(left_border, right_border));
left_border = right_border;
}
++right_border;
} while( right_border < input_geometry.size());
}
while(!recursion_stack.empty()) {
//pop next element
const PairOfPoints pair = recursion_stack.top();
recursion_stack.pop();
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_distance = INT_MIN;
std::size_t farthest_element_index = pair.second;
//find index idx of element with max_distance
for(std::size_t i = pair.first+1; i < pair.second; ++i){
const int temp_dist = fastDistance(
input_geometry[i].location,
input_geometry[pair.first].location,
input_geometry[pair.second].location
);
const double distance = std::fabs(temp_dist);
if(
distance > DouglasPeuckerThresholds[zoom_level] &&
distance > max_distance
) {
farthest_element_index = i;
max_distance = distance;
}
}
if (max_distance > DouglasPeuckerThresholds[zoom_level]) {
// mark idx as necessary
input_geometry[farthest_element_index].necessary = true;
if (1 < (farthest_element_index - pair.first) ) {
recursion_stack.push(
std::make_pair(pair.first, farthest_element_index)
);
}
if (1 < (pair.second - farthest_element_index) ) {
recursion_stack.push(
std::make_pair(farthest_element_index, pair.second)
);
}
}
}
}
};
#endif /* DOUGLASPEUCKER_H_ */
+166
View File
@@ -0,0 +1,166 @@
/*
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 "DouglasPeucker.h"
//These thresholds are more or less heuristically chosen.
static double DouglasPeuckerThresholds[19] = {
32000000., //z0
16240000., //z1
8240000., //z2
4240000., //z3
2000000., //z4
1000000., //z5
500000., //z6
240000., //z7
120000., //z8
60000., //z9
30000., //z10
19000., //z11
5000., //z12
2000., //z13
200., //z14
16., //z15
6., //z16
3., //z17
3. //z18
};
/**
* 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.
*/
int DouglasPeucker::fastDistance(
const FixedPointCoordinate& point,
const FixedPointCoordinate& segA,
const FixedPointCoordinate& segB
) const {
const int p2x = (segB.lon - segA.lon);
const int p2y = (segB.lat - segA.lat);
const int something = p2x*p2x + p2y*p2y;
double u = ( 0 == something ? 0 : ((point.lon - segA.lon) * p2x + (point.lat - segA.lat) * p2y) / something);
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;
}
void DouglasPeucker::Run(
std::vector<SegmentInformation> & input_geometry,
const unsigned zoom_level
) {
{
BOOST_ASSERT_MSG(zoom_level < 19, "unsupported zoom level");
BOOST_ASSERT_MSG(1 < input_geometry.size(), "geometry invalid");
std::size_t left_border = 0;
std::size_t right_border = 1;
//Sweep linerarily over array and identify those ranges that need to be checked
do {
BOOST_ASSERT_MSG(
input_geometry[left_border].necessary,
"left border must be necessary"
);
BOOST_ASSERT_MSG(
input_geometry.back().necessary,
"right border must be necessary"
);
if(input_geometry[right_border].necessary) {
recursion_stack.push(std::make_pair(left_border, right_border));
left_border = right_border;
}
++right_border;
} while( right_border < input_geometry.size());
}
while(!recursion_stack.empty()) {
//pop next element
const PairOfPoints pair = recursion_stack.top();
recursion_stack.pop();
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_distance = INT_MIN;
std::size_t farthest_element_index = pair.second;
//find index idx of element with max_distance
for(std::size_t i = pair.first+1; i < pair.second; ++i){
const int temp_dist = fastDistance(
input_geometry[i].location,
input_geometry[pair.first].location,
input_geometry[pair.second].location
);
const double distance = std::fabs(temp_dist);
if(
distance > DouglasPeuckerThresholds[zoom_level] &&
distance > max_distance
) {
farthest_element_index = i;
max_distance = distance;
}
}
if (max_distance > DouglasPeuckerThresholds[zoom_level]) {
// mark idx as necessary
input_geometry[farthest_element_index].necessary = true;
if (1 < (farthest_element_index - pair.first) ) {
recursion_stack.push(
std::make_pair(pair.first, farthest_element_index)
);
}
if (1 < (pair.second - farthest_element_index) ) {
recursion_stack.push(
std::make_pair(farthest_element_index, pair.second)
);
}
}
}
}
+147
View File
@@ -0,0 +1,147 @@
/*
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"
void PolylineCompressor::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 PolylineCompressor::encodeNumber(int number_to_encode, std::string & output) const {
while (number_to_encode >= 0x20) {
int nextValue = (0x20 | (number_to_encode & 0x1f)) + 63;
output += static_cast<char>(nextValue);
if(92 == nextValue) {
output += static_cast<char>(nextValue);
}
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);
}
}
void PolylineCompressor::printEncodedString(
const std::vector<SegmentInformation> & polyline,
std::string & output
) const {
std::vector<int> deltaNumbers;
output += "\"";
if(!polyline.empty()) {
FixedPointCoordinate 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 += "\"";
}
void PolylineCompressor::printEncodedString(
const std::vector<FixedPointCoordinate>& 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 += "\"";
}
void PolylineCompressor::printUnencodedString(
const std::vector<FixedPointCoordinate> & 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 += "]";
}
void PolylineCompressor::printUnencodedString(
const 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 += "]";
}
+20 -94
View File
@@ -32,112 +32,38 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../Util/StringUtil.h"
#include <string>
#include <vector>
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 encodeVectorSignedNumber(
std::vector<int> & numbers,
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;
}
numberToEncode += 63;
output += (static_cast<char> (numberToEncode));
if(92 == numberToEncode)
output += (static_cast<char> (numberToEncode));
}
void encodeNumber(int number_to_encode, std::string & output) const;
public:
inline void printEncodedString(
void printEncodedString(
const std::vector<SegmentInformation> & polyline,
std::string & output
) const {
std::vector<int> deltaNumbers;
output += "\"";
if(!polyline.empty()) {
FixedPointCoordinate 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 += "\"";
) const;
}
void printEncodedString(
const std::vector<FixedPointCoordinate>& polyline,
std::string &output
) const;
inline void printEncodedString(const std::vector<FixedPointCoordinate>& 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 += "\"";
}
void printUnencodedString(
const std::vector<FixedPointCoordinate> & polyline,
std::string & output
) const;
inline void printUnencodedString(std::vector<FixedPointCoordinate> & 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 += "]";
}
void printUnencodedString(
const std::vector<SegmentInformation> & polyline,
std::string & output
) const;
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 += "]";
}
};
#endif /* POLYLINECOMPRESSOR_H_ */
+75 -36
View File
@@ -1,8 +1,7 @@
cmake_minimum_required(VERSION 2.6)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
project(OSRM)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include(FindPackageHandleStandardArgs)
set(HUGO "${CMAKE_CURRENT_SOURCE_DIR}")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
include(GetGitRevisionDescription)
@@ -30,29 +29,34 @@ add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/Util/UUID.cpp UUID.cpp.alwaysbuild
add_custom_target(UUIDConfigure DEPENDS ${CMAKE_SOURCE_DIR}/Util/UUID.cpp )
set(BOOST_COMPONENTS filesystem program_options regex system thread)
set(BOOST_COMPONENTS filesystem iostreams program_options regex system thread)
configure_file(Util/GitDescription.cpp.in ${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp)
file(GLOB ExtractorGlob Extractor/*.cpp)
set(ExtractorSources extractor.cpp ${ExtractorGlob} Util/GitDescription.cpp)
set(ExtractorSources extractor.cpp ${ExtractorGlob})
add_executable(osrm-extract ${ExtractorSources} )
file(GLOB PrepareGlob Contractor/*.cpp)
set(PrepareSources createHierarchy.cpp ${PrepareGlob} Util/GitDescription.cpp)
add_executable(osrm-prepare ${PrepareSources} )
add_executable(osrm-routed routed.cpp Util/GitDescription.cpp)
set_target_properties(osrm-routed PROPERTIES COMPILE_FLAGS -DROUTED)
file( GLOB PrepareGlob Contractor/*.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/*.cpp)
file(GLOB AlgorithmGlob Algorithms/*.cpp)
file(GLOB HttpGlob Server/Http/*.cpp)
file(GLOB LibOSRMGlob Library/*.cpp)
file(GLOB SearchEngineSource DataStructures/SearchEngine*.cpp)
file(GLOB ServerStructureGlob Server/DataStructures/*.cpp)
set(OSRMSources ${LibOSRMGlob} ${DescriptorGlob} ${SearchEngineSource} ${ServerStructureGlob})
add_library(OSRM SHARED ${OSRMSources})
add_library(UUID STATIC Util/UUID.cpp)
set(OSRMSources ${LibOSRMGlob} ${DescriptorGlob} ${DatastructureGlob} ${AlgorithmGlob} ${HttpGlob})
add_library( OSRM SHARED ${OSRMSources} )
add_library( UUID STATIC Util/UUID.cpp )
add_library( GITDESCRIPTION STATIC Util/GitDescription.cpp )
add_dependencies( UUID UUIDConfigure )
add_dependencies( GITDESCRIPTION GIT_DESCRIPTION )
add_executable(osrm-routed routed.cpp ${ServerGlob})
set_target_properties(osrm-routed PROPERTIES COMPILE_FLAGS -DROUTED)
add_executable(osrm-datastore datastore.cpp)
# Check the release mode
if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
@@ -65,7 +69,14 @@ if(CMAKE_BUILD_TYPE MATCHES Release)
message(STATUS "Configuring OSRM in release mode")
endif(CMAKE_BUILD_TYPE MATCHES Release)
#Configuring compilers
# set compile switches
if (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# not using Visual Studio C++
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fPIC")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fPIC")
endif()
# Configuring compilers
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# using Clang
set(CMAKE_CXX_FLAGS "-Wall -Wno-unknown-pragmas -Wno-unneeded-internal-declaration")
@@ -80,11 +91,23 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# using Visual Studio C++
endif()
# Configuring other platform dependencies
if(APPLE)
SET(CMAKE_OSX_ARCHITECTURES "x86_64")
message("Set Architecture to x64 on OS X")
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 (DARWIN_VERSION GREATER 12)
MESSAGE(STATUS "Activating -std=c++11 flag for >= OS X 10.9")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++")
ENDIF (DARWIN_VERSION GREATER 12)
endif()
if(UNIX AND NOT APPLE)
target_link_libraries( osrm-datastore rt )
target_link_libraries( OSRM rt )
endif(UNIX AND NOT APPLE)
#Check Boost
set(BOOST_MIN_VERSION "1.44.0")
find_package( Boost ${BOOST_MIN_VERSION} COMPONENTS ${BOOST_COMPONENTS} REQUIRED )
@@ -98,9 +121,10 @@ IF( APPLE )
ELSE( APPLE )
target_link_libraries( OSRM ${Boost_LIBRARIES} )
ENDIF( APPLE )
target_link_libraries( osrm-extract ${Boost_LIBRARIES} UUID )
target_link_libraries( osrm-prepare ${Boost_LIBRARIES} UUID )
target_link_libraries( osrm-routed ${Boost_LIBRARIES} OSRM UUID )
target_link_libraries( osrm-extract ${Boost_LIBRARIES} UUID GITDESCRIPTION )
target_link_libraries( osrm-prepare ${Boost_LIBRARIES} UUID GITDESCRIPTION )
target_link_libraries( osrm-routed ${Boost_LIBRARIES} OSRM UUID GITDESCRIPTION )
target_link_libraries( osrm-datastore ${Boost_LIBRARIES} UUID GITDESCRIPTION )
find_package ( BZip2 REQUIRED )
include_directories(${BZIP_INCLUDE_DIRS})
@@ -114,17 +138,27 @@ target_link_libraries (osrm-routed ${ZLIB_LIBRARY})
find_package( Threads REQUIRED )
target_link_libraries (osrm-extract ${Threads_LIBRARY})
find_package( LuaJIT )
IF( NOT APPLE AND LUAJIT_INCLUDE_DIR AND LUAJIT_LIBRARIES)
include_directories(${LUAJIT_INCLUDE_DIR})
target_link_libraries( osrm-extract ${LUAJIT_LIBRARIES} )
target_link_libraries( osrm-prepare ${LUAJIT_LIBRARIES} )
ELSE( LUAJIT_INCLUDE_DIR )
find_package( Lua51 REQUIRED AND LUAJIT_LIBRARIES )
include_directories(${LUA_INCLUDE_DIR})
target_link_libraries( osrm-extract ${LUA_LIBRARY} )
target_link_libraries( osrm-prepare ${LUA_LIBRARY} )
ENDIF( NOT APPLE AND LUAJIT_INCLUDE_DIR AND LUAJIT_LIBRARIES )
find_package( Lua52 )
IF ( NOT LUA52_FOUND )
find_package( Lua51 REQUIRED )
IF (NOT APPLE)
find_package( LuaJIT 5.1 )
ENDIF ( NOT APPLE )
ELSE( NOT LUA52_FOUND )
IF(NOT APPLE)
find_package( LuaJIT 5.2 )
ENDIF(NOT APPLE)
ENDIF( NOT LUA52_FOUND )
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})
@@ -152,17 +186,22 @@ target_link_libraries (osrm-extract ${OSMPBF_LIBRARY})
target_link_libraries (osrm-prepare ${OSMPBF_LIBRARY})
if(WITH_TOOLS)
message("-- Activating OSRM internal tools")
message(STATUS "Activating OSRM internal tools")
find_package( GDAL )
if(GDAL_FOUND)
add_executable(osrm-components Tools/componentAnalysis.cpp)
include_directories(${GDAL_INCLUDE_DIR})
target_link_libraries(
osrm-components ${GDAL_LIBRARIES} ${Boost_LIBRARIES} UUID
osrm-components ${GDAL_LIBRARIES} ${Boost_LIBRARIES} UUID GITDESCRIPTION
)
endif(GDAL_FOUND)
add_executable ( osrm-cli Tools/simpleclient.cpp Util/GitDescription.cpp)
target_link_libraries( osrm-cli ${Boost_LIBRARIES} OSRM UUID )
add_executable ( osrm-cli Tools/simpleclient.cpp)
target_link_libraries( osrm-cli ${Boost_LIBRARIES} OSRM UUID GITDESCRIPTION )
add_executable ( osrm-io-benchmark Tools/io-benchmark.cpp )
target_link_libraries( osrm-io-benchmark ${Boost_LIBRARIES} )
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(UNIX AND NOT APPLE)
endif(WITH_TOOLS)
+1 -45
View File
@@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../typedefs.h"
#include "../DataStructures/DeallocatingVector.h"
#include "../DataStructures/DynamicGraph.h"
#include "../DataStructures/EdgeBasedNode.h"
#include "../Extractor/ExtractorStructs.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportEdge.h"
@@ -56,51 +57,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
class EdgeBasedGraphFactory : boost::noncopyable {
public:
struct EdgeBasedNode {
EdgeBasedNode() :
id(INT_MAX),
lat1(INT_MAX),
lat2(INT_MAX),
lon1(INT_MAX),
lon2(INT_MAX >> 1),
belongsToTinyComponent(false),
nameID(UINT_MAX),
weight(UINT_MAX >> 1),
ignoreInGrid(false)
{ }
bool operator<(const EdgeBasedNode & other) const {
return other.id < id;
}
bool operator==(const EdgeBasedNode & other) const {
return id == other.id;
}
inline FixedPointCoordinate Centroid() const {
FixedPointCoordinate centroid;
//The coordinates of the midpoint are given by:
//x = (x1 + x2) /2 and y = (y1 + y2) /2.
centroid.lon = (std::min(lon1, lon2) + std::max(lon1, lon2))/2;
centroid.lat = (std::min(lat1, lat2) + std::max(lat1, lat2))/2;
return centroid;
}
inline bool isIgnored() const {
return ignoreInGrid;
}
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),
+12 -8
View File
@@ -32,7 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/unordered_map.hpp>
#include <cassert>
#include <boost/assert.hpp>
#include <algorithm>
#include <limits>
@@ -132,6 +132,10 @@ public:
return static_cast<Key>( heap.size() - 1 );
}
bool Empty() const {
return 0 == Size();
}
void Insert( NodeID node, Weight weight, const Data &data ) {
HeapElement element;
element.index = static_cast<NodeID>(insertedNodes.size());
@@ -155,7 +159,7 @@ public:
}
bool WasRemoved( const NodeID node ) {
assert( WasInserted( node ) );
BOOST_ASSERT( WasInserted( node ) );
const Key index = nodeIndex[node];
return insertedNodes[index].key == 0;
}
@@ -168,12 +172,12 @@ public:
}
NodeID Min() const {
assert( heap.size() > 1 );
BOOST_ASSERT( heap.size() > 1 );
return insertedNodes[heap[1].index].node;
}
NodeID DeleteMin() {
assert( heap.size() > 1 );
BOOST_ASSERT( heap.size() > 1 );
const Key removedIndex = heap[1].index;
heap[1] = heap[heap.size()-1];
heap.pop_back();
@@ -192,10 +196,10 @@ public:
}
void DecreaseKey( NodeID node, Weight weight ) {
assert( UINT_MAX != node );
BOOST_ASSERT( UINT_MAX != node );
const Key & index = nodeIndex[node];
Key & key = insertedNodes[index].key;
assert ( key >= 0 );
BOOST_ASSERT ( key >= 0 );
insertedNodes[index].weight = weight;
heap[key].weight = weight;
@@ -253,7 +257,7 @@ private:
const Weight weight = heap[key].weight;
Key nextKey = key >> 1;
while ( heap[nextKey].weight > weight ) {
assert( nextKey != 0 );
BOOST_ASSERT( nextKey != 0 );
heap[key] = heap[nextKey];
insertedNodes[heap[key].index].key = key;
key = nextKey;
@@ -267,7 +271,7 @@ private:
void CheckHeap() {
#ifndef NDEBUG
for ( Key i = 2; i < (Key) heap.size(); ++i ) {
assert( heap[i].weight >= heap[i >> 1].weight );
BOOST_ASSERT( heap[i].weight >= heap[i >> 1].weight );
}
#endif
}
+9 -9
View File
@@ -31,7 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../DataStructures/MercatorUtil.h"
#include "../Util/StringUtil.h"
#include <cassert>
#include <boost/assert.hpp>
#include <cmath>
#include <climits>
@@ -74,10 +74,10 @@ inline std::ostream & operator<<(std::ostream & out, const FixedPointCoordinate
}
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);
BOOST_ASSERT(lat1 != INT_MIN);
BOOST_ASSERT(lon1 != INT_MIN);
BOOST_ASSERT(lat2 != INT_MIN);
BOOST_ASSERT(lon2 != INT_MIN);
double RAD = 0.017453292519943295769236907684886;
double lt1 = lat1/COORDINATE_PRECISION;
double ln1 = lon1/COORDINATE_PRECISION;
@@ -106,10 +106,10 @@ inline double ApproximateDistance(const FixedPointCoordinate &c1, const FixedPoi
}
inline double ApproximateEuclideanDistance(const FixedPointCoordinate &c1, const FixedPointCoordinate &c2) {
assert(c1.lat != INT_MIN);
assert(c1.lon != INT_MIN);
assert(c2.lat != INT_MIN);
assert(c2.lon != INT_MIN);
BOOST_ASSERT(c1.lat != INT_MIN);
BOOST_ASSERT(c1.lon != INT_MIN);
BOOST_ASSERT(c2.lat != INT_MIN);
BOOST_ASSERT(c2.lon != INT_MIN);
const double RAD = 0.017453292519943295769236907684886;
const double lat1 = (c1.lat/COORDINATE_PRECISION)*RAD;
const double lon1 = (c1.lon/COORDINATE_PRECISION)*RAD;
+50 -52
View File
@@ -28,7 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef DEALLOCATINGVECTOR_H_
#define DEALLOCATINGVECTOR_H_
#include <cassert>
#include <boost/assert.hpp>
#include <cstring>
#include <vector>
@@ -48,45 +48,32 @@ protected:
//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 std::size_t idx, const std::vector<ElementT *> & input_list) : mData(ptr), mIndex(idx), mBucketList(input_list) {}
explicit DeallocatingVectorIteratorState(const std::size_t idx, std::vector<ElementT *> & input_list) : mData(DEALLOCATION_VECTOR_NULL_PTR), mIndex(idx), mBucketList(input_list) {
setPointerForIndex();
explicit DeallocatingVectorIteratorState(const DeallocatingVectorIteratorState &r) : /*mData(r.mData),*/ mIndex(r.mIndex), mBucketList(r.mBucketList) {}
explicit DeallocatingVectorIteratorState(const std::size_t idx, std::vector<ElementT *> & input_list) : /*mData(DEALLOCATION_VECTOR_NULL_PTR),*/ mIndex(idx), mBucketList(input_list) {
}
ElementT * mData;
std::size_t mIndex;
std::vector<ElementT *> & mBucketList;
inline void setPointerForIndex() {
if(bucketSizeC*mBucketList.size() <= mIndex) {
mData = DEALLOCATION_VECTOR_NULL_PTR;
return;
}
std::size_t _bucket = mIndex/bucketSizeC;
std::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;
}
}
}
inline bool operator!=(const DeallocatingVectorIteratorState &other) {
return (mData != other.mData) || (mIndex != other.mIndex) || (mBucketList != other.mBucketList);
return mIndex != other.mIndex;
}
inline bool operator==(const DeallocatingVectorIteratorState &other) {
return (mData == other.mData) && (mIndex == other.mIndex) && (mBucketList == other.mBucketList);
return mIndex == other.mIndex;
}
inline bool operator<(const DeallocatingVectorIteratorState &other) {
bool operator<(const DeallocatingVectorIteratorState &other) const {
return mIndex < other.mIndex;
}
bool operator>(const DeallocatingVectorIteratorState &other) const {
return mIndex > other.mIndex;
}
bool operator>=(const DeallocatingVectorIteratorState &other) const {
return mIndex >= other.mIndex;
}
//This is a hack to make assignment operator possible with reference member
inline DeallocatingVectorIteratorState& operator= (const DeallocatingVectorIteratorState &a) {
if (this != &a) {
@@ -112,66 +99,69 @@ public:
DeallocatingVectorIterator(const DeallocatingVectorIterator<T2> & r) : mState(r.mState) {}
DeallocatingVectorIterator(std::size_t idx, std::vector<ElementT *> & input_list) : mState(idx, input_list) {}
//DeallocatingVectorIterator(std::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);
if(DeallocateC) BOOST_ASSERT(false);
mState = r.mState; return *this;
}
inline DeallocatingVectorIterator& operator++() { //prefix
// if(DeallocateC) assert(false);
++mState.mIndex; mState.setPointerForIndex(); return *this;
++mState.mIndex;
return *this;
}
inline DeallocatingVectorIterator& operator--() { //prefix
if(DeallocateC) assert(false);
--mState.mIndex; mState.setPointerForIndex(); return *this;
if(DeallocateC) BOOST_ASSERT(false);
--mState.mIndex;
return *this;
}
inline DeallocatingVectorIterator operator++(int) { //postfix
DeallocatingVectorIteratorState _myState(mState);
mState.mIndex++; mState.setPointerForIndex();
mState.mIndex++;
return DeallocatingVectorIterator(_myState);
}
inline DeallocatingVectorIterator operator --(int) { //postfix
if(DeallocateC) assert(false);
inline DeallocatingVectorIterator operator--(int) { //postfix
if(DeallocateC) BOOST_ASSERT(false);
DeallocatingVectorIteratorState _myState(mState);
mState.mIndex--; mState.setPointerForIndex();
mState.mIndex--;
return DeallocatingVectorIterator(_myState);
}
inline DeallocatingVectorIterator operator+(const difference_type& n) const {
DeallocatingVectorIteratorState _myState(mState);
_myState.mIndex+=n; _myState.setPointerForIndex();
_myState.mIndex+=n;
return DeallocatingVectorIterator(_myState);
}
inline DeallocatingVectorIterator& operator+=(const difference_type& n) const {
inline DeallocatingVectorIterator& operator+=(const difference_type& n) {
mState.mIndex+=n; return *this;
}
inline DeallocatingVectorIterator operator-(const difference_type& n) const {
if(DeallocateC) assert(false);
if(DeallocateC) BOOST_ASSERT(false);
DeallocatingVectorIteratorState _myState(mState);
_myState.mIndex-=n; _myState.setPointerForIndex();
_myState.mIndex-=n;
return DeallocatingVectorIterator(_myState);
}
inline DeallocatingVectorIterator& operator-=(const difference_type &n) const {
if(DeallocateC) assert(false);
if(DeallocateC) BOOST_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 reference operator*() const {
std::size_t _bucket = mState.mIndex/bucketSizeC;
std::size_t _index = mState.mIndex%bucketSizeC;
return (mState.mBucketList[_bucket][_index]);
}
inline pointer operator->() const {
std::size_t _bucket = mState.mIndex/bucketSizeC;
std::size_t _index = mState.mIndex%bucketSizeC;
return &(mState.mBucketList[_bucket][_index]);
}
inline bool operator!=(const DeallocatingVectorIterator & other) {
@@ -182,12 +172,20 @@ public:
return mState == other.mState;
}
bool operator<(const DeallocatingVectorIterator & other) {
inline bool operator<(const DeallocatingVectorIterator & other) const {
return mState < other.mState;
}
inline bool operator>(const DeallocatingVectorIterator & other) const {
return mState > other.mState;
}
inline bool operator>=(const DeallocatingVectorIterator & other) const {
return mState >= other.mState;
}
difference_type operator-(const DeallocatingVectorIterator & other) {
if(DeallocateC) assert(false);
if(DeallocateC) BOOST_ASSERT(false);
return mState.mIndex-other.mState.mIndex;
}
};
+51
View File
@@ -0,0 +1,51 @@
#ifndef EDGE_BASED_NODE_H
#define EDGE_BASED_NODE_H
#include "Coordinate.h"
struct EdgeBasedNode {
EdgeBasedNode() :
id(INT_MAX),
lat1(INT_MAX),
lat2(INT_MAX),
lon1(INT_MAX),
lon2(INT_MAX >> 1),
belongsToTinyComponent(false),
nameID(UINT_MAX),
weight(UINT_MAX >> 1),
ignoreInGrid(false)
{ }
bool operator<(const EdgeBasedNode & other) const {
return other.id < id;
}
bool operator==(const EdgeBasedNode & other) const {
return id == other.id;
}
inline FixedPointCoordinate Centroid() const {
FixedPointCoordinate centroid;
//The coordinates of the midpoint are given by:
//x = (x1 + x2) /2 and y = (y1 + y2) /2.
centroid.lon = (std::min(lon1, lon2) + std::max(lon1, lon2))/2;
centroid.lat = (std::min(lat1, lat2) + std::max(lat1, lat2))/2;
return centroid;
}
inline bool isIgnored() const {
return ignoreInGrid;
}
NodeID id;
int lat1;
int lat2;
int lon1;
int lon2:31;
bool belongsToTinyComponent:1;
NodeID nameID;
unsigned weight:31;
bool ignoreInGrid:1;
};
#endif //EDGE_BASED_NODE_H
+24 -8
View File
@@ -32,15 +32,31 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../DataStructures/HashTable.h"
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
) :
NodeInfo(lat, lon, id),
bollard(bollard),
trafficLight(traffic_light)
{ }
ExternalMemoryNode() : bollard(false), trafficLight(false) {}
static _Node min_value() {
return _Node(0,0,0, false, false);
static ExternalMemoryNode min_value() {
return ExternalMemoryNode(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);
static ExternalMemoryNode max_value() {
return ExternalMemoryNode(
std::numeric_limits<int>::max(),
std::numeric_limits<int>::max(),
std::numeric_limits<unsigned>::max(),
false,
false
);
}
NodeID key() const {
return id;
@@ -49,7 +65,7 @@ struct _Node : NodeInfo{
bool trafficLight;
};
struct ImportNode : public _Node {
struct ImportNode : public ExternalMemoryNode {
HashTable<std::string, std::string> keyVals;
inline void Clear() {
+2 -2
View File
@@ -35,11 +35,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
inline double y2lat(double a) {
return 180/M_PI * (2 * atan(exp(a*M_PI/180)) - M_PI/2);
return 180./M_PI * (2. * atan(exp(a*M_PI/180.)) - M_PI/2.);
}
inline double lat2y(double a) {
return 180/M_PI * log(tan(M_PI/4+a*(M_PI/180)/2));
return 180./M_PI * log(tan(M_PI/4.+a*(M_PI/180.)/2.));
}
#endif /* MERCATORUTIL_H_ */
-218
View File
@@ -1,218 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NODEINFORMATIONHELPDESK_H_
#define NODEINFORMATIONHELPDESK_H_
#include "QueryNode.h"
#include "PhantomNodes.h"
#include "StaticRTree.h"
#include "../Contractor/EdgeBasedGraphFactory.h"
#include "../Util/OSRMException.h"
#include "../typedefs.h"
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/noncopyable.hpp>
#include <iostream>
#include <string>
#include <vector>
typedef EdgeBasedGraphFactory::EdgeBasedNode RTreeLeaf;
class NodeInformationHelpDesk : boost::noncopyable {
public:
NodeInformationHelpDesk(
const std::string & ram_index_filename,
const std::string & mem_index_filename,
const std::string & nodes_filename,
const std::string & edges_filename,
const unsigned m_number_of_nodes,
const unsigned m_check_sum
) :
m_number_of_nodes(m_number_of_nodes),
m_check_sum(m_check_sum)
{
if ( ram_index_filename.empty() ) {
throw OSRMException("no ram index file name in server ini");
}
if ( mem_index_filename.empty() ) {
throw OSRMException("no mem index file name in server ini");
}
if ( nodes_filename.empty() ) {
throw OSRMException("no nodes file name in server ini");
}
if ( edges_filename.empty() ) {
throw OSRMException("no edges file name in server ini");
}
m_ro_rtree_ptr = new StaticRTree<RTreeLeaf>(
ram_index_filename,
mem_index_filename
);
BOOST_ASSERT_MSG(
0 == m_coordinate_list.size(),
"Coordinate vector not empty"
);
LoadNodesAndEdges(nodes_filename, edges_filename);
}
~NodeInformationHelpDesk() {
delete m_ro_rtree_ptr;
}
inline FixedPointCoordinate GetCoordinateOfNode(const unsigned id) const {
const NodeID node = m_via_node_list.at(id);
return m_coordinate_list.at(node);
}
inline unsigned GetNameIndexFromEdgeID(const unsigned id) const {
return m_name_ID_list.at(id);
}
inline TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const {
return m_turn_instruction_list.at(id);
}
inline NodeID GetNumberOfNodes() const {
return m_number_of_nodes;
}
inline bool LocateClosestEndPointForCoordinate(
const FixedPointCoordinate& input_coordinate,
FixedPointCoordinate& result,
const unsigned zoom_level = 18
) const {
bool found_node = m_ro_rtree_ptr->LocateClosestEndPointForCoordinate(
input_coordinate,
result, zoom_level
);
return found_node;
}
inline bool FindPhantomNodeForCoordinate(
const FixedPointCoordinate & input_coordinate,
PhantomNode & resulting_phantom_node,
const unsigned zoom_level
) const {
return m_ro_rtree_ptr->FindPhantomNodeForCoordinate(
input_coordinate,
resulting_phantom_node,
zoom_level
);
}
inline unsigned GetCheckSum() const {
return m_check_sum;
}
private:
void LoadNodesAndEdges(
const std::string & nodes_filename,
const std::string & edges_filename
) {
boost::filesystem::path nodes_file(nodes_filename);
if ( !boost::filesystem::exists( nodes_file ) ) {
throw OSRMException("nodes file does not exist");
}
if ( 0 == boost::filesystem::file_size( nodes_file ) ) {
throw OSRMException("nodes file is empty");
}
boost::filesystem::path edges_file(edges_filename);
if ( !boost::filesystem::exists( edges_file ) ) {
throw OSRMException("edges file does not exist");
}
if ( 0 == boost::filesystem::file_size( edges_file ) ) {
throw OSRMException("edges file is empty");
}
boost::filesystem::ifstream nodes_input_stream(
nodes_file,
std::ios::binary
);
boost::filesystem::ifstream edges_input_stream(
edges_file, std::ios::binary
);
SimpleLogger().Write(logDEBUG)
<< "Loading node data";
NodeInfo current_node;
while(!nodes_input_stream.eof()) {
nodes_input_stream.read((char *)&current_node, sizeof(NodeInfo));
m_coordinate_list.push_back(
FixedPointCoordinate(
current_node.lat,
current_node.lon
)
);
}
std::vector<FixedPointCoordinate>(m_coordinate_list).swap(m_coordinate_list);
nodes_input_stream.close();
SimpleLogger().Write(logDEBUG)
<< "Loading edge data";
unsigned number_of_edges = 0;
edges_input_stream.read((char*)&number_of_edges, sizeof(unsigned));
m_via_node_list.resize(number_of_edges);
m_name_ID_list.resize(number_of_edges);
m_turn_instruction_list.resize(number_of_edges);
OriginalEdgeData current_edge_data;
for(unsigned i = 0; i < number_of_edges; ++i) {
edges_input_stream.read(
(char*)&(current_edge_data),
sizeof(OriginalEdgeData)
);
m_via_node_list[i] = current_edge_data.viaNode;
m_name_ID_list[i] = current_edge_data.nameID;
m_turn_instruction_list[i] = current_edge_data.turnInstruction;
}
edges_input_stream.close();
SimpleLogger().Write(logDEBUG)
<< "Loaded " << number_of_edges << " orig edges";
SimpleLogger().Write(logDEBUG)
<< "Opening NN indices";
}
std::vector<FixedPointCoordinate> m_coordinate_list;
std::vector<NodeID> m_via_node_list;
std::vector<unsigned> m_name_ID_list;
std::vector<TurnInstruction> m_turn_instruction_list;
StaticRTree<EdgeBasedGraphFactory::EdgeBasedNode> * m_ro_rtree_ptr;
const unsigned m_number_of_nodes;
const unsigned m_check_sum;
};
#endif /*NODEINFORMATIONHELPDESK_H_*/
-6
View File
@@ -99,10 +99,4 @@ inline std::ostream& operator<<(std::ostream &out, const PhantomNode & pn){
return out;
}
struct NodesOfEdge {
NodeID edgeBasedNode;
double ratio;
FixedPointCoordinate projectedPoint;
};
#endif /* PHANTOMNODES_H_ */
+30 -22
View File
@@ -73,13 +73,13 @@ struct TurnRestriction {
}
};
struct _RawRestrictionContainer {
TurnRestriction restriction;
struct InputRestrictionContainer {
EdgeID fromWay;
EdgeID toWay;
unsigned viaNode;
TurnRestriction restriction;
_RawRestrictionContainer(
InputRestrictionContainer(
EdgeID fromWay,
EdgeID toWay,
NodeID vn,
@@ -91,7 +91,7 @@ struct _RawRestrictionContainer {
{
restriction.viaNode = vn;
}
_RawRestrictionContainer(
InputRestrictionContainer(
bool isOnly = false
) :
fromWay(UINT_MAX),
@@ -101,37 +101,45 @@ struct _RawRestrictionContainer {
restriction.flags.isOnly = isOnly;
}
static _RawRestrictionContainer min_value() {
return _RawRestrictionContainer(0, 0, 0, 0);
static InputRestrictionContainer min_value() {
return InputRestrictionContainer(0, 0, 0, 0);
}
static _RawRestrictionContainer max_value() {
return _RawRestrictionContainer(UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX);
static InputRestrictionContainer max_value() {
return InputRestrictionContainer(UINT_MAX, UINT_MAX, UINT_MAX, UINT_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 :
public std::binary_function<InputRestrictionContainer, InputRestrictionContainer, bool>
{
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();
inline value_type max_value() const {
return InputRestrictionContainer::max_value();
}
value_type min_value() {
return _RawRestrictionContainer::min_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: public std::binary_function<InputRestrictionContainer, InputRestrictionContainer, bool> {
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 max_value() const {
return InputRestrictionContainer::max_value();
}
value_type min_value() {
return _RawRestrictionContainer::min_value();
value_type min_value() const {
return InputRestrictionContainer::min_value();
}
};
-91
View File
@@ -1,91 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "SearchEngine.h"
SearchEngine::SearchEngine( QueryObjectsStorage * query_objects ) :
_queryData(query_objects),
shortestPath(_queryData),
alternativePaths(_queryData)
{}
SearchEngine::~SearchEngine() {}
void SearchEngine::GetCoordinatesForNodeID(
NodeID id,
FixedPointCoordinate& result
) const {
result = _queryData.nodeHelpDesk->GetCoordinateOfNode(id);
}
void SearchEngine::FindPhantomNodeForCoordinate(
const FixedPointCoordinate & location,
PhantomNode & result,
const unsigned zoomLevel
) const {
_queryData.nodeHelpDesk->FindPhantomNodeForCoordinate(
location,
result, zoomLevel
);
}
NodeID SearchEngine::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 QueryEdge::EdgeData ed = _queryData.graph->GetEdgeData(e);
return ed.id;
}
std::string SearchEngine::GetEscapedNameForNameID(const unsigned nameID) const {
std::string result;
_queryData.query_objects->GetName(nameID, result);
return HTMLEntitize(result);
}
SearchEngineHeapPtr SearchEngineData::forwardHeap;
SearchEngineHeapPtr SearchEngineData::backwardHeap;
SearchEngineHeapPtr SearchEngineData::forwardHeap2;
SearchEngineHeapPtr SearchEngineData::backwardHeap2;
SearchEngineHeapPtr SearchEngineData::forwardHeap3;
SearchEngineHeapPtr SearchEngineData::backwardHeap3;
+18 -23
View File
@@ -25,48 +25,43 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SEARCHENGINE_H_
#define SEARCHENGINE_H_
#ifndef SEARCHENGINE_H
#define SEARCHENGINE_H
#include "Coordinate.h"
#include "NodeInformationHelpDesk.h"
#include "SearchEngineData.h"
#include "PhantomNodes.h"
#include "QueryEdge.h"
#include "SearchEngineData.h"
#include "../RoutingAlgorithms/AlternativePathRouting.h"
#include "../RoutingAlgorithms/ShortestPathRouting.h"
#include "../Server/DataStructures/QueryObjectsStorage.h"
#include "../Util/StringUtil.h"
#include "../typedefs.h"
#include <boost/assert.hpp>
#include <climits>
#include <string>
#include <vector>
template<class DataFacadeT>
class SearchEngine {
private:
SearchEngineData _queryData;
DataFacadeT * facade;
SearchEngineData engine_working_data;
public:
ShortestPathRouting<SearchEngineData> shortestPath;
AlternativeRouting<SearchEngineData> alternativePaths;
ShortestPathRouting<DataFacadeT> shortest_path;
AlternativeRouting <DataFacadeT> alternative_path;
SearchEngine( QueryObjectsStorage * query_objects );
~SearchEngine();
SearchEngine( DataFacadeT * facade )
:
facade (facade),
shortest_path (facade, engine_working_data),
alternative_path (facade, engine_working_data)
{}
void GetCoordinatesForNodeID(NodeID id, FixedPointCoordinate& result) const;
~SearchEngine() {}
void FindPhantomNodeForCoordinate(
const FixedPointCoordinate & location,
PhantomNode & result,
unsigned zoomLevel
) const;
NodeID GetNameIDForOriginDestinationNodeID(
const NodeID s, const NodeID t) const;
std::string GetEscapedNameForNameID(const unsigned nameID) const;
};
#endif /* SEARCHENGINE_H_ */
#endif // SEARCHENGINE_H
+9 -9
View File
@@ -27,40 +27,40 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "SearchEngineData.h"
void SearchEngineData::InitializeOrClearFirstThreadLocalStorage() {
void SearchEngineData::InitializeOrClearFirstThreadLocalStorage(const unsigned number_of_nodes) {
if(!forwardHeap.get()) {
forwardHeap.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes()));
forwardHeap.reset(new QueryHeap(number_of_nodes));
} else {
forwardHeap->Clear();
}
if(!backwardHeap.get()) {
backwardHeap.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes()));
backwardHeap.reset(new QueryHeap(number_of_nodes));
} else {
backwardHeap->Clear();
}
}
void SearchEngineData::InitializeOrClearSecondThreadLocalStorage() {
void SearchEngineData::InitializeOrClearSecondThreadLocalStorage(const unsigned number_of_nodes) {
if(!forwardHeap2.get()) {
forwardHeap2.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes()));
forwardHeap2.reset(new QueryHeap(number_of_nodes));
} else {
forwardHeap2->Clear();
}
if(!backwardHeap2.get()) {
backwardHeap2.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes()));
backwardHeap2.reset(new QueryHeap(number_of_nodes));
} else {
backwardHeap2->Clear();
}
}
void SearchEngineData::InitializeOrClearThirdThreadLocalStorage() {
void SearchEngineData::InitializeOrClearThirdThreadLocalStorage(const unsigned number_of_nodes) {
if(!forwardHeap3.get()) {
forwardHeap3.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes()));
forwardHeap3.reset(new QueryHeap(number_of_nodes));
} else {
forwardHeap3->Clear();
}
if(!backwardHeap3.get()) {
backwardHeap3.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes()));
backwardHeap3.reset(new QueryHeap(number_of_nodes));
} else {
backwardHeap3->Clear();
}
+12 -19
View File
@@ -25,10 +25,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SEARCH_ENGINE_DATA_H
#define SEARCH_ENGINE_DATA_H
#include "BinaryHeap.h"
#include "QueryEdge.h"
#include "StaticGraph.h"
#include "../Server/DataStructures/QueryObjectsStorage.h"
#include "../typedefs.h"
@@ -41,23 +43,12 @@ struct _HeapData {
NodeID parent;
_HeapData( NodeID p ) : parent(p) { }
};
typedef StaticGraph<QueryEdge::EdgeData> QueryGraph;
typedef BinaryHeap< NodeID, NodeID, int, _HeapData, UnorderedMapStorage<NodeID, int> > QueryHeapType;
typedef boost::thread_specific_ptr<QueryHeapType> SearchEngineHeapPtr;
// typedef StaticGraph<QueryEdge::EdgeData> QueryGraph;
struct SearchEngineData {
typedef QueryGraph Graph;
typedef QueryHeapType QueryHeap;
SearchEngineData(QueryObjectsStorage * query_objects)
:
query_objects(query_objects),
graph(query_objects->graph),
nodeHelpDesk(query_objects->nodeHelpDesk)
{}
const QueryObjectsStorage * query_objects;
const QueryGraph * graph;
const NodeInformationHelpDesk * nodeHelpDesk;
typedef BinaryHeap< NodeID, NodeID, int, _HeapData, UnorderedMapStorage<NodeID, int> > QueryHeap;
typedef boost::thread_specific_ptr<QueryHeap> SearchEngineHeapPtr;
static SearchEngineHeapPtr forwardHeap;
static SearchEngineHeapPtr backwardHeap;
@@ -66,9 +57,11 @@ struct SearchEngineData {
static SearchEngineHeapPtr forwardHeap3;
static SearchEngineHeapPtr backwardHeap3;
void InitializeOrClearFirstThreadLocalStorage();
void InitializeOrClearFirstThreadLocalStorage(const unsigned number_of_nodes);
void InitializeOrClearSecondThreadLocalStorage();
void InitializeOrClearSecondThreadLocalStorage(const unsigned number_of_nodes);
void InitializeOrClearThirdThreadLocalStorage();
void InitializeOrClearThirdThreadLocalStorage(const unsigned number_of_nodes);
};
#endif // SEARCH_ENGINE_DATA_H
+250
View File
@@ -0,0 +1,250 @@
/*
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/noncopyable.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/integer.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/xsi_shared_memory.hpp>
#ifdef __linux__
#include <sys/ipc.h>
#include <sys/shm.h>
#endif
#include <cstring>
#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;
}
};
class SharedMemory : boost::noncopyable {
//Remove shared memory on destruction
class shm_remove : boost::noncopyable {
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(){
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();
}
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;
};
template<class LockFileT = OSRMLockFile>
class SharedMemoryFactory_tmpl : boost::noncopyable {
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());
}
}
private:
SharedMemoryFactory_tmpl() {}
};
typedef SharedMemoryFactory_tmpl<> SharedMemoryFactory;
#endif /* SHARED_MEMORY_POINTER_FACTORY_H */
+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.
*/
#ifndef SHARED_MEMORY_VECTOR_WRAPPER_H
#define SHARED_MEMORY_VECTOR_WRAPPER_H
#include "../Util/SimpleLogger.h"
#include <boost/assert.hpp>
#include <boost/type_traits.hpp>
#include <algorithm>
#include <iterator>
#include <vector>
template<typename DataT>
class ShMemIterator : public std::iterator<std::input_iterator_tag, DataT> {
DataT * p;
public:
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(NULL),
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 );
}
// void SetData(const DataT * ptr, const std::size_t size) {
// BOOST_ASSERT_MSG( 0 == m_size, "vector not empty");
// BOOST_ASSERT_MSG( 0 < size , "new vector empty");
// m_ptr.reset(ptr);
// m_size = size;
// }
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; }
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<typename DataT, bool UseSharedMemory>
struct ShM {
typedef typename boost::conditional<
UseSharedMemory,
SharedMemoryWrapper<DataT>,
std::vector<DataT>
>::type vector;
};
#endif //SHARED_MEMORY_VECTOR_WRAPPER_H
+22 -19
View File
@@ -29,13 +29,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define STATICGRAPH_H_INCLUDED
#include "../DataStructures/Percent.h"
#include "../DataStructures/SharedMemoryVectorWrapper.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
#include <algorithm>
#include <vector>
template< typename EdgeDataT>
template< typename EdgeDataT, bool UseSharedMemory = false>
class StaticGraph {
public:
typedef NodeID NodeIterator;
@@ -47,8 +48,9 @@ public:
NodeIterator source;
NodeIterator target;
bool operator<( const InputEdge& right ) const {
if ( source != right.source )
if ( source != right.source ) {
return source < right.source;
}
return target < right.target;
}
};
@@ -89,16 +91,16 @@ public:
}
}
StaticGraph( std::vector<_StrNode> & nodes, std::vector<_StrEdge> & edges) {
_numNodes = nodes.size();
StaticGraph(
typename ShM<_StrNode, UseSharedMemory>::vector & nodes,
typename ShM<_StrEdge, UseSharedMemory>::vector & edges
) {
_numNodes = nodes.size()-1;
_numEdges = edges.size();
_nodes.swap(nodes);
_edges.swap(edges);
//Add dummy node to end of _nodes array;
_nodes.push_back(_nodes.back());
#ifndef NDEBUG
Percent p(GetNumberOfNodes());
for(unsigned u = 0; u < GetNumberOfNodes(); ++u) {
@@ -136,32 +138,32 @@ public:
return _numEdges;
}
unsigned GetOutDegree( const NodeIterator &n ) const {
unsigned GetOutDegree( const NodeIterator n ) const {
return BeginEdges(n)-EndEdges(n) - 1;
}
inline NodeIterator GetTarget( const EdgeIterator &e ) const {
inline NodeIterator GetTarget( const EdgeIterator e ) const {
return NodeIterator( _edges[e].target );
}
inline EdgeDataT &GetEdgeData( const EdgeIterator &e ) {
inline EdgeDataT &GetEdgeData( const EdgeIterator e ) {
return _edges[e].data;
}
const EdgeDataT &GetEdgeData( const EdgeIterator &e ) const {
const EdgeDataT &GetEdgeData( const EdgeIterator e ) const {
return _edges[e].data;
}
EdgeIterator BeginEdges( const NodeIterator &n ) const {
EdgeIterator BeginEdges( const NodeIterator n ) const {
return EdgeIterator( _nodes[n].firstEdge );
}
EdgeIterator EndEdges( const NodeIterator &n ) const {
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 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++ ) {
@@ -174,17 +176,18 @@ public:
return smallestEdge;
}
EdgeIterator FindEdgeInEitherDirection( const NodeIterator &from, const NodeIterator &to ) const {
EdgeIterator FindEdgeInEitherDirection( const NodeIterator from, const NodeIterator to ) const {
EdgeIterator tmp = FindEdge( from, to );
return (UINT_MAX != tmp ? tmp : FindEdge( to, from ));
}
EdgeIterator FindEdgeIndicateIfReverse( const NodeIterator &from, const NodeIterator &to, bool & result ) const {
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)
if(UINT_MAX != tmp) {
result = true;
}
}
return tmp;
}
@@ -194,8 +197,8 @@ private:
NodeIterator _numNodes;
EdgeIterator _numEdges;
std::vector< _StrNode > _nodes;
std::vector< _StrEdge > _edges;
typename ShM< _StrNode, UseSharedMemory >::vector _nodes;
typename ShM< _StrEdge, UseSharedMemory >::vector _edges;
};
#endif // STATICGRAPH_H_INCLUDED
+5 -5
View File
@@ -30,7 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef STATICKDTREE_H_INCLUDED
#define STATICKDTREE_H_INCLUDED
#include <cassert>
#include <boost/assert.hpp>
#include <vector>
#include <algorithm>
#include <stack>
@@ -100,8 +100,8 @@ public:
};
StaticKDTree( std::vector< InputPoint > * points ){
assert( k > 0 );
assert ( points->size() > 0 );
BOOST_ASSERT( k > 0 );
BOOST_ASSERT ( points->size() > 0 );
size = points->size();
kdtree = new InputPoint[size];
for ( Iterator i = 0; i != size; ++i ) {
@@ -209,11 +209,11 @@ private:
public:
Less( unsigned d ) {
dimension = d;
assert( dimension < k );
BOOST_ASSERT( dimension < k );
}
bool operator() ( const InputPoint& left, const InputPoint& right ) {
assert( dimension < k );
BOOST_ASSERT( dimension < k );
return left.coordinates[dimension] < right.coordinates[dimension];
}
private:
+50 -19
View File
@@ -28,11 +28,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef STATICRTREE_H_
#define STATICRTREE_H_
#include "MercatorUtil.h"
#include "Coordinate.h"
#include "PhantomNodes.h"
#include "DeallocatingVector.h"
#include "HilbertValue.h"
#include "MercatorUtil.h"
#include "PhantomNodes.h"
#include "SharedMemoryFactory.h"
#include "SharedMemoryVectorWrapper.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../Util/TimingUtil.h"
@@ -48,6 +51,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/range/algorithm_ext/erase.hpp>
#include <boost/noncopyable.hpp>
#include <boost/thread.hpp>
#include <boost/type_traits.hpp>
#include <algorithm>
#include <limits>
@@ -63,9 +67,9 @@ const static uint32_t RTREE_LEAF_NODE_SIZE = 1170;
static boost::thread_specific_ptr<boost::filesystem::ifstream> thread_local_rtree_stream;
template<class DataT>
template<class DataT, bool UseSharedMemory = false>
class StaticRTree : boost::noncopyable {
private:
public:
struct RectangleInt2D {
RectangleInt2D() :
min_lon(INT_MAX),
@@ -237,6 +241,16 @@ private:
typedef RectangleInt2D RectangleT;
struct TreeNode {
TreeNode() : child_count(0), child_is_on_disk(false) {}
RectangleT minimum_bounding_rectangle;
uint32_t child_count:31;
bool child_is_on_disk:1;
uint32_t children[RTREE_BRANCHING_FACTOR];
};
private:
struct WrappedInputElement {
explicit WrappedInputElement(
const uint32_t _array_index,
@@ -259,14 +273,6 @@ private:
DataT objects[RTREE_LEAF_NODE_SIZE];
};
struct TreeNode {
TreeNode() : child_count(0), child_is_on_disk(false) {}
RectangleT minimum_bounding_rectangle;
uint32_t child_count:31;
bool child_is_on_disk:1;
uint32_t children[RTREE_BRANCHING_FACTOR];
};
struct QueryCandidate {
explicit QueryCandidate(
const uint32_t n_id,
@@ -280,7 +286,7 @@ private:
}
};
std::vector<TreeNode> m_search_tree;
typename ShM<TreeNode, UseSharedMemory>::vector m_search_tree;
uint64_t m_element_count;
const std::string m_leaf_node_filename;
@@ -414,11 +420,10 @@ public:
//Read-only operation for queries
explicit StaticRTree(
const std::string & node_filename,
const std::string & leaf_filename
) : m_leaf_node_filename(leaf_filename) {
const boost::filesystem::path & node_file,
const boost::filesystem::path & leaf_file
) : m_leaf_node_filename(leaf_file.string()) {
//open tree node file and load into RAM.
boost::filesystem::path node_file(node_filename);
if ( !boost::filesystem::exists( node_file ) ) {
throw OSRMException("ram index file does not exist");
@@ -434,9 +439,7 @@ public:
m_search_tree.resize(tree_size);
tree_node_file.read((char*)&m_search_tree[0], sizeof(TreeNode)*tree_size);
tree_node_file.close();
//open leaf node file and store thread specific pointer
boost::filesystem::path leaf_file(leaf_filename);
if ( !boost::filesystem::exists( leaf_file ) ) {
throw OSRMException("mem index file does not exist");
}
@@ -451,6 +454,34 @@ public:
//SimpleLogger().Write() << tree_size << " nodes in search tree";
//SimpleLogger().Write() << m_element_count << " elements in leafs";
}
explicit StaticRTree(
TreeNode * tree_node_ptr,
const uint32_t number_of_nodes,
const boost::filesystem::path & leaf_file
) : m_search_tree(tree_node_ptr, number_of_nodes),
m_leaf_node_filename(leaf_file.string())
{
//open leaf node file and store thread specific pointer
if ( !boost::filesystem::exists( leaf_file ) ) {
throw OSRMException("mem index file does not exist");
}
if ( 0 == boost::filesystem::file_size( leaf_file ) ) {
throw OSRMException("mem index file is empty");
}
boost::filesystem::ifstream leaf_node_file( leaf_file, std::ios::binary );
leaf_node_file.read((char*)&m_element_count, sizeof(uint64_t));
leaf_node_file.close();
if( thread_local_rtree_stream.get() ) {
thread_local_rtree_stream->close();
}
//SimpleLogger().Write() << tree_size << " nodes in search tree";
//SimpleLogger().Write() << m_element_count << " elements in leafs";
}
//Read-only operation for queries
/*
inline void FindKNearestPhantomNodesForCoordinate(
const FixedPointCoordinate & location,
+18 -9
View File
@@ -31,33 +31,42 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../DataStructures/HashTable.h"
#include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/RawRouteData.h"
#include "../DataStructures/SearchEngine.h"
#include "../Server/BasicDatastructures.h"
#include "../Server/Http/Reply.h"
#include "../Util/StringUtil.h"
#include "../typedefs.h"
#include <cassert>
#include <cmath>
#include <cstdio>
#include <string>
#include <vector>
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 DataFacadeT>
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, SearchEngine &sEngine) = 0;
virtual void SetConfig(const _DescriptorConfig & config) = 0;
virtual void Run(
http::Reply & reply,
const RawRouteData &rawRoute,
PhantomNodes &phantomNodes,
const DataFacadeT * facade
) = 0;
virtual void SetConfig(const DescriptorConfig & config) = 0;
};
#endif /* BASE_DESCRIPTOR_H_ */
+182 -149
View File
@@ -45,31 +45,47 @@ double DescriptionFactory::GetBearing(
) const {
double deltaLong = DegreeToRadian(B.lon/COORDINATE_PRECISION - A.lon/COORDINATE_PRECISION);
double lat1 = DegreeToRadian(A.lat/COORDINATE_PRECISION);
double lat2 = DegreeToRadian(B.lat/COORDINATE_PRECISION);
const double lat1 = DegreeToRadian(A.lat/COORDINATE_PRECISION);
const double lat2 = DegreeToRadian(B.lat/COORDINATE_PRECISION);
double y = sin(deltaLong) * cos(lat2);
double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(deltaLong);
const double y = sin(deltaLong) * cos(lat2);
const double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(deltaLong);
double result = RadianToDegree(atan2(y, x));
while(result <= 0.)
while(result < 0.) {
result += 360.;
while(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::SetStartSegment(const PhantomNode & sph) {
start_phantom = sph;
AppendSegment(
sph.location,
_PathData(0, sph.nodeBasedEdgeNameID, 10, sph.weight1)
);
}
void DescriptionFactory::SetEndSegment(const PhantomNode & _targetPhantom) {
targetPhantom = _targetPhantom;
pathDescription.push_back(SegmentInformation(_targetPhantom.location, _targetPhantom.nodeBasedEdgeNameID, 0, _targetPhantom.weight1, 0, true) );
void DescriptionFactory::SetEndSegment(const PhantomNode & tph) {
target_phantom = tph;
pathDescription.push_back(
SegmentInformation(
tph.location,
tph.nodeBasedEdgeNameID,
0,
tph.weight1,
0,
true
)
);
}
void DescriptionFactory::AppendSegment(const FixedPointCoordinate & coordinate, const _PathData & data ) {
void DescriptionFactory::AppendSegment(
const FixedPointCoordinate & coordinate,
const _PathData & data
) {
if(1 == pathDescription.size() && pathDescription.back().location == coordinate) {
pathDescription.back().nameID = data.nameID;
} else {
@@ -77,144 +93,161 @@ void DescriptionFactory::AppendSegment(const FixedPointCoordinate & coordinate,
}
}
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 SearchEngine &sEngine, const unsigned zoomLevel) {
if(0 == pathDescription.size())
return;
// unsigned entireLength = 0;
/** starts at index 1 */
pathDescription[0].length = 0;
for(unsigned i = 1; i < pathDescription.size(); ++i) {
pathDescription[i].length = ApproximateEuclideanDistance(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)
// ){
// SimpleLogger().Write() << "->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)
// ){
// SimpleLogger().Write() << "->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) {
//SimpleLogger().Write() << "Turn after " << lengthOfSegment << "m into way with name id " << segment.nameID;
assert(pathDescription[i].necessary);
lengthOfSegment = 0;
durationOfSegment = 0;
indexOfSegmentBegin = i;
}
}
// SimpleLogger().Write() << "#segs: " << pathDescription.size();
//Post-processing to remove empty or nearly empty path segments
if(std::numeric_limits<double>::epsilon() > pathDescription.back().length) {
// SimpleLogger().Write() << "#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;
// SimpleLogger().Write() << "Deleting last turn instruction";
}
void DescriptionFactory::AppendEncodedPolylineString(
const bool return_encoded,
std::vector<std::string> & output
) {
std::string temp;
if(return_encoded) {
polyline_compressor.printEncodedString(pathDescription, temp);
} else {
pathDescription[indexOfSegmentBegin].duration *= (1.-targetPhantom.ratio);
polyline_compressor.printUnencodedString(pathDescription, temp);
}
if(std::numeric_limits<double>::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;
// SimpleLogger().Write() << "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;
output.push_back(temp);
}
void DescriptionFactory::BuildRouteSummary(const double distance, const unsigned time) {
summary.startName = startPhantom.nodeBasedEdgeNameID;
summary.destName = targetPhantom.nodeBasedEdgeNameID;
void DescriptionFactory::AppendEncodedPolylineString(
std::vector<std::string> &output
) const {
std::string temp;
polyline_compressor.printEncodedString(pathDescription, temp);
output.push_back(temp);
}
void DescriptionFactory::AppendUnencodedPolylineString(
std::vector<std::string>& output
) const {
std::string temp;
polyline_compressor.printUnencodedString(pathDescription, temp);
output.push_back(temp);
}
// void DescriptionFactory::Run(const SearchEngine &sEngine, const unsigned zoomLevel) {
// if(0 == pathDescription.size())
// return;
// // unsigned entireLength = 0;
// /** starts at index 1 */
// pathDescription[0].length = 0;
// for(unsigned i = 1; i < pathDescription.size(); ++i) {
// pathDescription[i].length = ApproximateEuclideanDistance(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)
// // ){
// // SimpleLogger().Write() << "->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)
// // ){
// // SimpleLogger().Write() << "->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) {
// //SimpleLogger().Write() << "Turn after " << lengthOfSegment << "m into way with name id " << segment.nameID;
// assert(pathDescription[i].necessary);
// lengthOfSegment = 0;
// durationOfSegment = 0;
// indexOfSegmentBegin = i;
// }
// }
// // SimpleLogger().Write() << "#segs: " << pathDescription.size();
// //Post-processing to remove empty or nearly empty path segments
// if(FLT_EPSILON > pathDescription.back().length) {
// // SimpleLogger().Write() << "#segs: " << pathDescription.size() << ", last ratio: " << target_phantom.ratio << ", length: " << pathDescription.back().length;
// if(pathDescription.size() > 2){
// pathDescription.pop_back();
// pathDescription.back().necessary = true;
// pathDescription.back().turnInstruction = TurnInstructions.NoTurn;
// target_phantom.nodeBasedEdgeNameID = (pathDescription.end()-2)->nameID;
// // SimpleLogger().Write() << "Deleting last turn instruction";
// }
// } else {
// pathDescription[indexOfSegmentBegin].duration *= (1.-target_phantom.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;
// start_phantom.nodeBasedEdgeNameID = pathDescription[0].nameID;
// // SimpleLogger().Write() << "Deleting first turn instruction, ratio: " << start_phantom.ratio << ", length: " << pathDescription[0].length;
// }
// } else {
// pathDescription[0].duration *= start_phantom.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;
// }
void DescriptionFactory::BuildRouteSummary(
const double distance,
const unsigned time
) {
summary.startName = start_phantom.nodeBasedEdgeNameID;
summary.destName = target_phantom.nodeBasedEdgeNameID;
summary.BuildDurationAndLengthStrings(distance, time);
}
+148 -13
View File
@@ -31,7 +31,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../Algorithms/DouglasPeucker.h"
#include "../Algorithms/PolylineCompressor.h"
#include "../DataStructures/Coordinate.h"
#include "../DataStructures/SearchEngine.h"
#include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/RawRouteData.h"
#include "../DataStructures/SegmentInformation.h"
#include "../DataStructures/TurnInstructions.h"
#include "../Util/SimpleLogger.h"
@@ -44,20 +45,29 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* and produces the description plus the encoded polyline */
class DescriptionFactory {
DouglasPeucker<SegmentInformation> dp;
PolylineCompressor pc;
PhantomNode startPhantom, targetPhantom;
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 {
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) {
RouteSummary() :
lengthString("0"),
durationString("0"),
startName(0),
destName(0)
{}
void BuildDurationAndLengthStrings(
const double distance,
const unsigned time
) {
//compute distance/duration for route summary
intToString(round(distance), lengthString);
int travelTime = time/10 + 1;
@@ -72,14 +82,139 @@ public:
DescriptionFactory();
virtual ~DescriptionFactory();
double GetBearing(const FixedPointCoordinate& C, const FixedPointCoordinate& B) const;
void AppendEncodedPolylineString(std::string &output);
void AppendUnencodedPolylineString(std::string &output);
void AppendEncodedPolylineString(std::vector<std::string> &output) const;
void AppendUnencodedPolylineString(std::vector<std::string> &output) const;
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 SearchEngine &sEngine, const unsigned zoomLevel);
void SetStartSegment(const PhantomNode & start_phantom);
void SetEndSegment(const PhantomNode & start_phantom);
void AppendEncodedPolylineString(
const bool return_encoded,
std::vector<std::string> & output
);
template<class DataFacadeT>
void Run(const DataFacadeT * facade, const unsigned zoomLevel) {
if( pathDescription.empty() ) {
return;
}
// unsigned entireLength = 0;
/** starts at index 1 */
pathDescription[0].length = 0;
for(unsigned i = 1; i < pathDescription.size(); ++i) {
pathDescription[i].length = ApproximateEuclideanDistance(pathDescription[i-1].location, pathDescription[i].location);
}
double lengthOfSegment = 0;
unsigned durationOfSegment = 0;
unsigned indexOfSegmentBegin = 0;
// std::string string0 = facade->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)
// ){
// SimpleLogger().Write() << "->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)
// ){
// SimpleLogger().Write() << "->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) {
//SimpleLogger().Write() << "Turn after " << lengthOfSegment << "m into way with name id " << pathDescription[i].nameID;
assert(pathDescription[i].necessary);
lengthOfSegment = 0;
durationOfSegment = 0;
indexOfSegmentBegin = i;
}
}
// SimpleLogger().Write() << "#segs: " << pathDescription.size();
//Post-processing to remove empty or nearly empty path segments
if(std::numeric_limits<double>::epsilon() > pathDescription.back().length) {
// SimpleLogger().Write() << "#segs: " << pathDescription.size() << ", last ratio: " << target_phantom.ratio << ", length: " << pathDescription.back().length;
if(pathDescription.size() > 2){
pathDescription.pop_back();
pathDescription.back().necessary = true;
pathDescription.back().turnInstruction = TurnInstructions.NoTurn;
target_phantom.nodeBasedEdgeNameID = (pathDescription.end()-2)->nameID;
// SimpleLogger().Write() << "Deleting last turn instruction";
}
} else {
pathDescription[indexOfSegmentBegin].duration *= (1.-target_phantom.ratio);
}
if(std::numeric_limits<double>::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;
start_phantom.nodeBasedEdgeNameID = pathDescription[0].nameID;
// SimpleLogger().Write() << "Deleting first turn instruction, ratio: " << start_phantom.ratio << ", length: " << pathDescription[0].length;
}
} else {
pathDescription[0].duration *= start_phantom.ratio;
}
//Generalize poly line
polyline_generalizer.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;
}
};
#endif /* DESCRIPTIONFACTORY_H_ */
+54 -24
View File
@@ -32,42 +32,72 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/foreach.hpp>
class GPXDescriptor : public BaseDescriptor{
template<class DataFacadeT>
class GPXDescriptor : public BaseDescriptor<DataFacadeT> {
private:
_DescriptorConfig config;
DescriptorConfig config;
FixedPointCoordinate current;
std::string tmp;
public:
void SetConfig(const _DescriptorConfig& c) { config = c; }
void Run(http::Reply & reply, const RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngine &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\" "
void SetConfig(const DescriptorConfig & c) { config = c; }
//TODO: reorder parameters
void Run(
http::Reply & reply,
const RawRouteData &rawRoute,
PhantomNodes &phantomNodes,
const DataFacadeT * facade
) {
reply.content.push_back("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
reply.content.push_back(
"<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 += "<metadata><copyright author=\"Project OSRM\"><license>Data (c) OpenStreetMap contributors (ODbL)</license></copyright></metadata>";
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>";
"\">");
reply.content.push_back(
"<metadata><copyright author=\"Project OSRM\"><license>Data (c)"
" OpenStreetMap contributors (ODbL)</license></copyright>"
"</metadata>");
reply.content.push_back("<rte>");
bool found_route = (rawRoute.lengthOfShortestPath != INT_MAX) &&
(rawRoute.computedShortestPath.size() );
if( found_route ) {
convertInternalLatLonToString(
phantomNodes.startPhantom.location.lat,
tmp
);
reply.content.push_back("<rtept lat=\"" + tmp + "\" ");
convertInternalLatLonToString(
phantomNodes.startPhantom.location.lon,
tmp
);
reply.content.push_back("lon=\"" + tmp + "\"></rtept>");
BOOST_FOREACH(const _PathData & pathData, rawRoute.computedShortestPath) {
sEngine.GetCoordinatesForNodeID(pathData.node, current);
BOOST_FOREACH(
const _PathData & pathData,
rawRoute.computedShortestPath
) {
current = facade->GetCoordinateOfNode(pathData.node);
convertInternalLatLonToString(current.lat, tmp);
reply.content += "<rtept lat=\"" + tmp + "\" ";
reply.content.push_back("<rtept lat=\"" + tmp + "\" ");
convertInternalLatLonToString(current.lon, tmp);
reply.content += "lon=\"" + tmp + "\"></rtept>";
reply.content.push_back("lon=\"" + tmp + "\"></rtept>");
}
convertInternalLatLonToString(phantomNodes.targetPhantom.location.lat, tmp);
reply.content += "<rtept lat=\"" + tmp + "\" ";
convertInternalLatLonToString(phantomNodes.targetPhantom.location.lon, tmp);
reply.content += "lon=\"" + tmp + "\"></rtept>";
convertInternalLatLonToString(
phantomNodes.targetPhantom.location.lat,
tmp
);
reply.content.push_back("<rtept lat=\"" + tmp + "\" ");
convertInternalLatLonToString(
phantomNodes.targetPhantom.location.lon,
tmp
);
reply.content.push_back("lon=\"" + tmp + "\"></rtept>");
}
reply.content += "</rte></gpx>";
reply.content.push_back("</rte></gpx>");
}
};
#endif /* GPX_DESCRIPTOR_H_ */
#endif // GPX_DESCRIPTOR_H_
+279 -217
View File
@@ -41,32 +41,33 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <algorithm>
class JSONDescriptor : public BaseDescriptor{
template<class DataFacadeT>
class JSONDescriptor : public BaseDescriptor<DataFacadeT> {
private:
_DescriptorConfig config;
DescriptionFactory descriptionFactory;
DescriptorConfig config;
DescriptionFactory description_factory;
DescriptionFactory alternateDescriptionFactory;
FixedPointCoordinate current;
unsigned numberOfEnteredRestrictedAreas;
unsigned entered_restricted_area_count;
struct RoundAbout{
RoundAbout() :
startIndex(INT_MAX),
nameID(INT_MAX),
leaveAtExit(INT_MAX)
start_index(INT_MAX),
name_id(INT_MAX),
leave_at_exit(INT_MAX)
{}
int startIndex;
int nameID;
int leaveAtExit;
int start_index;
int name_id;
int leave_at_exit;
} 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;
Segment() : name_id(-1), length(-1), position(-1) {}
Segment(int n, int l, int p) : name_id(n), length(l), position(p) {}
int name_id;
int length;
int position;
};
std::vector<Segment> shortestSegments, alternativeSegments;
std::vector<Segment> shortest_path_segments, alternative_path_segments;
struct RouteNames {
std::string shortestPathName1;
@@ -76,207 +77,246 @@ private:
};
public:
JSONDescriptor() : numberOfEnteredRestrictedAreas(0) {}
void SetConfig(const _DescriptorConfig & c) { config = c; }
JSONDescriptor() : entered_restricted_area_count(0) {}
void SetConfig(const DescriptorConfig & c) { config = c; }
void Run(http::Reply & reply, const RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngine &sEngine) {
//TODO: reorder parameters
void Run(
http::Reply & reply,
const RawRouteData & raw_route_information,
PhantomNodes & phantom_nodes,
const DataFacadeT * facade
) {
WriteHeaderToOutput(reply.content);
if(rawRoute.lengthOfShortestPath != INT_MAX) {
descriptionFactory.SetStartSegment(phantomNodes.startPhantom);
reply.content += "0,"
"\"status_message\": \"Found route between points\",";
if(raw_route_information.lengthOfShortestPath != INT_MAX) {
description_factory.SetStartSegment(phantom_nodes.startPhantom);
reply.content.push_back("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 );
BOOST_FOREACH(const _PathData & path_data, raw_route_information.computedShortestPath) {
current = facade->GetCoordinateOfNode(path_data.node);
description_factory.AppendSegment(current, path_data );
}
descriptionFactory.SetEndSegment(phantomNodes.targetPhantom);
description_factory.SetEndSegment(phantom_nodes.targetPhantom);
} else {
//We do not need to do much, if there is no route ;-)
reply.content += "207,"
"\"status_message\": \"Cannot find route between points\",";
reply.content.push_back("207,"
"\"status_message\": \"Cannot find route between points\",");
}
descriptionFactory.Run(sEngine, config.z);
reply.content += "\"route_geometry\": ";
description_factory.Run(facade, config.zoom_level);
reply.content.push_back("\"route_geometry\": ");
if(config.geometry) {
descriptionFactory.AppendEncodedPolylineString(reply.content, config.encodeGeometry);
description_factory.AppendEncodedPolylineString(
config.encode_geometry,
reply.content
);
} else {
reply.content += "[]";
reply.content.push_back("[]");
}
reply.content += ","
"\"route_instructions\": [";
numberOfEnteredRestrictedAreas = 0;
reply.content.push_back(","
"\"route_instructions\": [");
entered_restricted_area_count = 0;
if(config.instructions) {
BuildTextualDescription(descriptionFactory, reply, rawRoute.lengthOfShortestPath, sEngine, shortestSegments);
BuildTextualDescription(
description_factory,
reply,
raw_route_information.lengthOfShortestPath,
facade,
shortest_path_segments
);
} else {
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) {
TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction);
BOOST_FOREACH(
const SegmentInformation & segment,
description_factory.pathDescription
) {
TurnInstruction current_instruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
entered_restricted_area_count += (current_instruction != segment.turnInstruction);
}
}
reply.content += "],";
descriptionFactory.BuildRouteSummary(descriptionFactory.entireLength, rawRoute.lengthOfShortestPath - ( numberOfEnteredRestrictedAreas*TurnInstructions.AccessRestrictionPenalty));
reply.content.push_back("],");
description_factory.BuildRouteSummary(
description_factory.entireLength,
raw_route_information.lengthOfShortestPath - ( entered_restricted_area_count*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 +=",";
reply.content.push_back("\"route_summary\":");
reply.content.push_back("{");
reply.content.push_back("\"total_distance\":");
reply.content.push_back(description_factory.summary.lengthString);
reply.content.push_back(","
"\"total_time\":");
reply.content.push_back(description_factory.summary.durationString);
reply.content.push_back(","
"\"start_point\":\"");
reply.content.push_back(
facade->GetEscapedNameForNameID(description_factory.summary.startName)
);
reply.content.push_back("\","
"\"end_point\":\"");
reply.content.push_back(
facade->GetEscapedNameForNameID(description_factory.summary.destName)
);
reply.content.push_back("\"");
reply.content.push_back("}");
reply.content.push_back(",");
//only one alternative route is computed at this time, so this is hardcoded
if(rawRoute.lengthOfAlternativePath != INT_MAX) {
alternateDescriptionFactory.SetStartSegment(phantomNodes.startPhantom);
if(raw_route_information.lengthOfAlternativePath != INT_MAX) {
alternateDescriptionFactory.SetStartSegment(phantom_nodes.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 );
BOOST_FOREACH(const _PathData & path_data, raw_route_information.computedAlternativePath) {
current = facade->GetCoordinateOfNode(path_data.node);
alternateDescriptionFactory.AppendSegment(current, path_data );
}
alternateDescriptionFactory.SetEndSegment(phantomNodes.targetPhantom);
alternateDescriptionFactory.SetEndSegment(phantom_nodes.targetPhantom);
}
alternateDescriptionFactory.Run(sEngine, config.z);
alternateDescriptionFactory.Run(facade, config.zoom_level);
//give an array of alternative routes
reply.content += "\"alternative_geometries\": [";
if(config.geometry && INT_MAX != rawRoute.lengthOfAlternativePath) {
reply.content.push_back("\"alternative_geometries\": [");
if(config.geometry && INT_MAX != raw_route_information.lengthOfAlternativePath) {
//Generate the linestrings for each alternative
alternateDescriptionFactory.AppendEncodedPolylineString(reply.content, config.encodeGeometry);
alternateDescriptionFactory.AppendEncodedPolylineString(
config.encode_geometry,
reply.content
);
}
reply.content += "],";
reply.content += "\"alternative_instructions\":[";
numberOfEnteredRestrictedAreas = 0;
if(INT_MAX != rawRoute.lengthOfAlternativePath) {
reply.content += "[";
reply.content.push_back("],");
reply.content.push_back("\"alternative_instructions\":[");
entered_restricted_area_count = 0;
if(INT_MAX != raw_route_information.lengthOfAlternativePath) {
reply.content.push_back("[");
//Generate instructions for each alternative
if(config.instructions) {
BuildTextualDescription(alternateDescriptionFactory, reply, rawRoute.lengthOfAlternativePath, sEngine, alternativeSegments);
BuildTextualDescription(
alternateDescriptionFactory,
reply,
raw_route_information.lengthOfAlternativePath,
facade,
alternative_path_segments
);
} else {
BOOST_FOREACH(const SegmentInformation & segment, alternateDescriptionFactory.pathDescription) {
TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction);
TurnInstruction current_instruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
entered_restricted_area_count += (current_instruction != segment.turnInstruction);
}
}
reply.content += "]";
reply.content.push_back("]");
}
reply.content += "],";
reply.content += "\"alternative_summaries\":[";
if(INT_MAX != rawRoute.lengthOfAlternativePath) {
reply.content.push_back("],");
reply.content.push_back("\"alternative_summaries\":[");
if(INT_MAX != raw_route_information.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 += "}";
alternateDescriptionFactory.BuildRouteSummary(alternateDescriptionFactory.entireLength, raw_route_information.lengthOfAlternativePath - ( entered_restricted_area_count*TurnInstructions.AccessRestrictionPenalty));
reply.content.push_back("{");
reply.content.push_back("\"total_distance\":");
reply.content.push_back(alternateDescriptionFactory.summary.lengthString);
reply.content.push_back(","
"\"total_time\":");
reply.content.push_back(alternateDescriptionFactory.summary.durationString);
reply.content.push_back(","
"\"start_point\":\"");
reply.content.push_back(facade->GetEscapedNameForNameID(description_factory.summary.startName));
reply.content.push_back("\","
"\"end_point\":\"");
reply.content.push_back(facade->GetEscapedNameForNameID(description_factory.summary.destName));
reply.content.push_back("\"");
reply.content.push_back("}");
}
reply.content += "],";
reply.content.push_back("],");
//Get Names for both routes
RouteNames routeNames;
GetRouteNames(shortestSegments, alternativeSegments, sEngine, routeNames);
GetRouteNames(shortest_path_segments, alternative_path_segments, facade, 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 += "],";
reply.content.push_back("\"route_name\":[\"");
reply.content.push_back(routeNames.shortestPathName1);
reply.content.push_back("\",\"");
reply.content.push_back(routeNames.shortestPathName2);
reply.content.push_back("\"],"
"\"alternative_names\":[");
reply.content.push_back("[\"");
reply.content.push_back(routeNames.alternativePathName1);
reply.content.push_back("\",\"");
reply.content.push_back(routeNames.alternativePathName2);
reply.content.push_back("\"]");
reply.content.push_back("],");
//list all viapoints so that the client may display it
reply.content += "\"via_points\":[";
reply.content.push_back("\"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);
if(config.geometry && INT_MAX != raw_route_information.lengthOfShortestPath) {
for(unsigned i = 0; i < raw_route_information.segmentEndCoordinates.size(); ++i) {
reply.content.push_back("[");
if(raw_route_information.segmentEndCoordinates[i].startPhantom.location.isSet())
convertInternalReversedCoordinateToString(raw_route_information.segmentEndCoordinates[i].startPhantom.location, tmp);
else
convertInternalReversedCoordinateToString(rawRoute.rawViaNodeCoordinates[i], tmp);
convertInternalReversedCoordinateToString(raw_route_information.rawViaNodeCoordinates[i], tmp);
reply.content += tmp;
reply.content += "],";
reply.content.push_back(tmp);
reply.content.push_back("],");
}
reply.content += "[";
if(rawRoute.segmentEndCoordinates.back().startPhantom.location.isSet())
convertInternalReversedCoordinateToString(rawRoute.segmentEndCoordinates.back().targetPhantom.location, tmp);
reply.content.push_back("[");
if(raw_route_information.segmentEndCoordinates.back().startPhantom.location.isSet())
convertInternalReversedCoordinateToString(raw_route_information.segmentEndCoordinates.back().targetPhantom.location, tmp);
else
convertInternalReversedCoordinateToString(rawRoute.rawViaNodeCoordinates.back(), tmp);
reply.content += tmp;
reply.content += "]";
convertInternalReversedCoordinateToString(raw_route_information.rawViaNodeCoordinates.back(), tmp);
reply.content.push_back(tmp);
reply.content.push_back("]");
}
reply.content += "],";
reply.content += "\"hint_data\": {";
reply.content += "\"checksum\":";
intToString(rawRoute.checkSum, tmp);
reply.content += tmp;
reply.content += ", \"locations\": [";
reply.content.push_back("],");
reply.content.push_back("\"hint_data\": {");
reply.content.push_back("\"checksum\":");
intToString(raw_route_information.checkSum, tmp);
reply.content.push_back(tmp);
reply.content.push_back(", \"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 += "\", ";
for(unsigned i = 0; i < raw_route_information.segmentEndCoordinates.size(); ++i) {
reply.content.push_back("\"");
EncodeObjectToBase64(raw_route_information.segmentEndCoordinates[i].startPhantom, hint);
reply.content.push_back(hint);
reply.content.push_back("\", ");
}
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 += "}";
EncodeObjectToBase64(raw_route_information.segmentEndCoordinates.back().targetPhantom, hint);
reply.content.push_back("\"");
reply.content.push_back(hint);
reply.content.push_back("\"]");
reply.content.push_back("},");
reply.content.push_back("\"transactionId\": \"OSRM Routing Engine JSON Descriptor (v0.3)\"");
reply.content.push_back("}");
}
void GetRouteNames(std::vector<Segment> & shortestSegments, std::vector<Segment> & alternativeSegments, const SearchEngine &sEngine, RouteNames & routeNames) {
/*** extract names for both alternatives ***/
// construct routes names
void GetRouteNames(
std::vector<Segment> & shortest_path_segments,
std::vector<Segment> & alternative_path_segments,
const DataFacadeT * facade,
RouteNames & routeNames
) {
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];
if(0 < shortest_path_segments.size()) {
sort(shortest_path_segments.begin(), shortest_path_segments.end(), boost::bind(&Segment::length, _1) > boost::bind(&Segment::length, _2) );
shortestSegment1 = shortest_path_segments[0];
if(0 < alternative_path_segments.size()) {
sort(alternative_path_segments.begin(), alternative_path_segments.end(), boost::bind(&Segment::length, _1) > boost::bind(&Segment::length, _2) );
alternativeSegment1 = alternative_path_segments[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) );
std::vector<Segment> shortestDifference(shortest_path_segments.size());
std::vector<Segment> alternativeDifference(alternative_path_segments.size());
std::set_difference(shortest_path_segments.begin(), shortest_path_segments.end(), alternative_path_segments.begin(), alternative_path_segments.end(), shortestDifference.begin(), boost::bind(&Segment::name_id, _1) < boost::bind(&Segment::name_id, _2) );
int size_of_difference = shortestDifference.size();
if(0 < size_of_difference ) {
int i = 0;
while( i < size_of_difference && shortestDifference[i].nameID == shortestSegments[0].nameID) {
while( i < size_of_difference && shortestDifference[i].name_id == shortest_path_segments[0].name_id) {
++i;
}
if(i < size_of_difference ) {
@@ -284,11 +324,11 @@ public:
}
}
std::set_difference(alternativeSegments.begin(), alternativeSegments.end(), shortestSegments.begin(), shortestSegments.end(), alternativeDifference.begin(), boost::bind(&Segment::nameID, _1) < boost::bind(&Segment::nameID, _2) );
std::set_difference(alternative_path_segments.begin(), alternative_path_segments.end(), shortest_path_segments.begin(), shortest_path_segments.end(), alternativeDifference.begin(), boost::bind(&Segment::name_id, _1) < boost::bind(&Segment::name_id, _2) );
size_of_difference = alternativeDifference.size();
if(0 < size_of_difference ) {
int i = 0;
while( i < size_of_difference && alternativeDifference[i].nameID == alternativeSegments[0].nameID) {
while( i < size_of_difference && alternativeDifference[i].name_id == alternative_path_segments[0].name_id) {
++i;
}
if(i < size_of_difference ) {
@@ -301,102 +341,124 @@ public:
if(alternativeSegment1.position > alternativeSegment2.position)
std::swap(alternativeSegment1, alternativeSegment2);
routeNames.shortestPathName1 = sEngine.GetEscapedNameForNameID(shortestSegment1.nameID);
routeNames.shortestPathName2 = sEngine.GetEscapedNameForNameID(shortestSegment2.nameID);
routeNames.shortestPathName1 = facade->GetEscapedNameForNameID(
shortestSegment1.name_id
);
routeNames.shortestPathName2 = facade->GetEscapedNameForNameID(
shortestSegment2.name_id
);
routeNames.alternativePathName1 = sEngine.GetEscapedNameForNameID(alternativeSegment1.nameID);
routeNames.alternativePathName2 = sEngine.GetEscapedNameForNameID(alternativeSegment2.nameID);
routeNames.alternativePathName1 = facade->GetEscapedNameForNameID(
alternativeSegment1.name_id
);
routeNames.alternativePathName2 = facade->GetEscapedNameForNameID(
alternativeSegment2.name_id
);
}
}
inline void WriteHeaderToOutput(std::string & output) {
output += "{"
"\"version\": 0.3,"
"\"status\":";
inline void WriteHeaderToOutput(std::vector<std::string> & output) {
output.push_back(
"{"
"\"version\": 0.3,"
"\"status\":"
);
}
inline void BuildTextualDescription(DescriptionFactory & descriptionFactory, http::Reply & reply, const int lengthOfRoute, const SearchEngine &sEngine, std::vector<Segment> & segmentVector) {
//TODO: reorder parameters
inline void BuildTextualDescription(
DescriptionFactory & description_factory,
http::Reply & reply,
const int route_length,
const DataFacadeT * facade,
std::vector<Segment> & route_segments_list
) {
//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;
roundAbout.leave_at_exit = 0;
roundAbout.name_id = 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;
BOOST_FOREACH(const SegmentInformation & segment, description_factory.pathDescription) {
TurnInstruction current_instruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
entered_restricted_area_count += (current_instruction != segment.turnInstruction);
if(TurnInstructions.TurnIsNecessary( current_instruction) ) {
if(TurnInstructions.EnterRoundAbout == current_instruction) {
roundAbout.name_id = segment.nameID;
roundAbout.start_index = prefixSumOfNecessarySegments;
} else {
if(0 != prefixSumOfNecessarySegments){
reply.content += ",";
reply.content.push_back(",");
}
reply.content += "[\"";
if(TurnInstructions.LeaveRoundAbout == currentInstruction) {
reply.content.push_back("[\"");
if(TurnInstructions.LeaveRoundAbout == current_instruction) {
intToString(TurnInstructions.EnterRoundAbout, tmpInstruction);
reply.content += tmpInstruction;
reply.content += "-";
intToString(roundAbout.leaveAtExit+1, tmpInstruction);
reply.content += tmpInstruction;
roundAbout.leaveAtExit = 0;
reply.content.push_back(tmpInstruction);
reply.content.push_back("-");
intToString(roundAbout.leave_at_exit+1, tmpInstruction);
reply.content.push_back(tmpInstruction);
roundAbout.leave_at_exit = 0;
} else {
intToString(currentInstruction, tmpInstruction);
reply.content += tmpInstruction;
intToString(current_instruction, tmpInstruction);
reply.content.push_back(tmpInstruction);
}
reply.content += "\",\"";
reply.content += sEngine.GetEscapedNameForNameID(segment.nameID);
reply.content += "\",";
reply.content.push_back("\",\"");
reply.content.push_back(facade->GetEscapedNameForNameID(segment.nameID));
reply.content.push_back("\",");
intToString(segment.length, tmpDist);
reply.content += tmpDist;
reply.content += ",";
reply.content.push_back(tmpDist);
reply.content.push_back(",");
intToString(prefixSumOfNecessarySegments, tmpLength);
reply.content += tmpLength;
reply.content += ",";
reply.content.push_back(tmpLength);
reply.content.push_back(",");
intToString(segment.duration/10, tmpDuration);
reply.content += tmpDuration;
reply.content += ",\"";
reply.content.push_back(tmpDuration);
reply.content.push_back(",\"");
intToString(segment.length, tmpLength);
reply.content += tmpLength;
reply.content += "m\",\"";
reply.content += Azimuth::Get(segment.bearing);
reply.content += "\",";
reply.content.push_back(tmpLength);
reply.content.push_back("m\",\"");
reply.content.push_back(Azimuth::Get(segment.bearing));
reply.content.push_back("\",");
intToString(round(segment.bearing), tmpBearing);
reply.content += tmpBearing;
reply.content += "]";
reply.content.push_back(tmpBearing);
reply.content.push_back("]");
segmentVector.push_back( Segment(segment.nameID, segment.length, segmentVector.size() ));
route_segments_list.push_back(
Segment(
segment.nameID,
segment.length,
route_segments_list.size()
)
);
}
} else if(TurnInstructions.StayOnRoundAbout == currentInstruction) {
++roundAbout.leaveAtExit;
} else if(TurnInstructions.StayOnRoundAbout == current_instruction) {
++roundAbout.leave_at_exit;
}
if(segment.necessary)
++prefixSumOfNecessarySegments;
}
if(INT_MAX != lengthOfRoute) {
reply.content += ",[\"";
if(INT_MAX != route_length) {
reply.content.push_back(",[\"");
intToString(TurnInstructions.ReachedYourDestination, tmpInstruction);
reply.content += tmpInstruction;
reply.content += "\",\"";
reply.content += "\",";
reply.content += "0";
reply.content += ",";
reply.content.push_back(tmpInstruction);
reply.content.push_back("\",\"");
reply.content.push_back("\",");
reply.content.push_back("0");
reply.content.push_back(",");
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 += "]";
reply.content.push_back(tmpLength);
reply.content.push_back(",");
reply.content.push_back("0");
reply.content.push_back(",\"");
reply.content.push_back("\",\"");
reply.content.push_back(Azimuth::Get(0.0));
reply.content.push_back("\",");
reply.content.push_back("0.0");
reply.content.push_back("]");
}
}
+263 -159
View File
@@ -27,266 +27,356 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ExtractionContainers.h"
void ExtractionContainers::PrepareData(const std::string & output_file_name, const std::string restrictionsFileName, const unsigned amountOfRAM) {
void ExtractionContainers::PrepareData(
const std::string & output_file_name,
const std::string & restrictions_file_name
) {
try {
unsigned usedNodeCounter = 0;
unsigned usedEdgeCounter = 0;
unsigned number_of_used_nodes = 0;
unsigned number_of_used_edges = 0;
double time = get_timestamp();
boost::uint64_t memory_to_use = static_cast<boost::uint64_t>(amountOfRAM) * 1024 * 1024 * 1024;
std::cout << "[extractor] Sorting used nodes ... " << std::flush;
stxxl::sort(usedNodeIDs.begin(), usedNodeIDs.end(), Cmp(), memory_to_use);
stxxl::sort(
used_node_id_list.begin(),
used_node_id_list.end(),
Cmp(),
4294967296
);
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp();
std::cout << "[extractor] Erasing duplicate nodes ... " << std::flush;
stxxl::vector<NodeID>::iterator NewEnd = std::unique ( usedNodeIDs.begin(),usedNodeIDs.end() ) ;
usedNodeIDs.resize ( NewEnd - usedNodeIDs.begin() );
stxxl::vector<NodeID>::iterator NewEnd = std::unique ( used_node_id_list.begin(),used_node_id_list.end() ) ;
used_node_id_list.resize ( NewEnd - used_node_id_list.begin() );
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp();
std::cout << "[extractor] Sorting all nodes ... " << std::flush;
stxxl::sort(allNodes.begin(), allNodes.end(), CmpNodeByID(), memory_to_use);
stxxl::sort(
all_nodes_list.begin(),
all_nodes_list.end(),
CmpNodeByID(),
4294967296
);
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp();
std::cout << "[extractor] Sorting used ways ... " << std::flush;
stxxl::sort(wayStartEndVector.begin(), wayStartEndVector.end(), CmpWayByID(), memory_to_use);
stxxl::sort(
way_start_end_id_list.begin(),
way_start_end_id_list.end(),
CmpWayByID(),
4294967296
);
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
std::cout << "[extractor] Sorting restrctns. by from... " << std::flush;
stxxl::sort(restrictionsVector.begin(), restrictionsVector.end(), CmpRestrictionContainerByFrom(), memory_to_use);
stxxl::sort(
restrictions_list.begin(),
restrictions_list.end(),
CmpRestrictionContainerByFrom(),
4294967296
);
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
std::cout << "[extractor] Fixing restriction starts ... " << std::flush;
STXXLRestrictionsVector::iterator restrictionsIT = restrictionsVector.begin();
STXXLWayIDStartEndVector::iterator wayStartAndEndEdgeIT = wayStartEndVector.begin();
STXXLRestrictionsVector::iterator restrictions_iterator = restrictions_list.begin();
STXXLWayIDStartEndVector::iterator way_start_and_end_iterator = way_start_end_id_list.begin();
while(wayStartAndEndEdgeIT != wayStartEndVector.end() && restrictionsIT != restrictionsVector.end()) {
if(wayStartAndEndEdgeIT->wayID < restrictionsIT->fromWay){
++wayStartAndEndEdgeIT;
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(wayStartAndEndEdgeIT->wayID > restrictionsIT->fromWay) {
++restrictionsIT;
if(way_start_and_end_iterator->wayID > restrictions_iterator->fromWay) {
++restrictions_iterator;
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;
BOOST_ASSERT(way_start_and_end_iterator->wayID == restrictions_iterator->fromWay);
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;
}
++restrictionsIT;
++restrictions_iterator;
}
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp();
std::cout << "[extractor] Sorting restrctns. by to ... " << std::flush;
stxxl::sort(restrictionsVector.begin(), restrictionsVector.end(), CmpRestrictionContainerByTo(), memory_to_use);
stxxl::sort(
restrictions_list.begin(),
restrictions_list.end(),
CmpRestrictionContainerByTo(),
4294967296
);
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp();
unsigned usableRestrictionsCounter(0);
std::cout << "[extractor] Fixing restriction ends ... " << std::flush;
restrictionsIT = restrictionsVector.begin();
wayStartAndEndEdgeIT = wayStartEndVector.begin();
while(wayStartAndEndEdgeIT != wayStartEndVector.end() && restrictionsIT != restrictionsVector.end()) {
if(wayStartAndEndEdgeIT->wayID < restrictionsIT->toWay){
++wayStartAndEndEdgeIT;
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(wayStartAndEndEdgeIT->wayID > restrictionsIT->toWay) {
++restrictionsIT;
if(way_start_and_end_iterator->wayID > restrictions_iterator->toWay) {
++restrictions_iterator;
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;
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(
UINT_MAX != restrictionsIT->restriction.fromNode &&
UINT_MAX != restrictionsIT->restriction.toNode
UINT_MAX != restrictions_iterator->restriction.fromNode &&
UINT_MAX != restrictions_iterator->restriction.toNode
) {
++usableRestrictionsCounter;
}
++restrictionsIT;
++restrictions_iterator;
}
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
SimpleLogger().Write() << "usable restrictions: " << usableRestrictionsCounter;
//serialize restrictions
std::ofstream restrictionsOutstream;
restrictionsOutstream.open(restrictionsFileName.c_str(), std::ios::binary);
restrictionsOutstream.write((char*)&uuid, sizeof(UUID));
restrictionsOutstream.write((char*)&usableRestrictionsCounter, sizeof(unsigned));
std::ofstream restrictions_out_stream;
restrictions_out_stream.open(restrictions_file_name.c_str(), std::ios::binary);
restrictions_out_stream.write((char*)&uuid, sizeof(UUID));
restrictions_out_stream.write(
(char*)&usableRestrictionsCounter,
sizeof(unsigned)
);
for(
restrictionsIT = restrictionsVector.begin();
restrictionsIT != restrictionsVector.end();
++restrictionsIT
restrictions_iterator = restrictions_list.begin();
restrictions_iterator != restrictions_list.end();
++restrictions_iterator
) {
if(
UINT_MAX != restrictionsIT->restriction.fromNode &&
UINT_MAX != restrictionsIT->restriction.toNode
UINT_MAX != restrictions_iterator->restriction.fromNode &&
UINT_MAX != restrictions_iterator->restriction.toNode
) {
restrictionsOutstream.write((char *)&(restrictionsIT->restriction), sizeof(TurnRestriction));
restrictions_out_stream.write(
(char *)&(restrictions_iterator->restriction),
sizeof(TurnRestriction)
);
}
}
restrictionsOutstream.close();
restrictions_out_stream.close();
std::ofstream fout;
fout.open(output_file_name.c_str(), std::ios::binary);
fout.write((char*)&uuid, sizeof(UUID));
fout.write((char*)&usedNodeCounter, sizeof(unsigned));
std::ofstream file_out_stream;
file_out_stream.open(output_file_name.c_str(), std::ios::binary);
file_out_stream.write((char*)&uuid, sizeof(UUID));
file_out_stream.write((char*)&number_of_used_nodes, sizeof(unsigned));
time = get_timestamp();
std::cout << "[extractor] Confirming/Writing used nodes ... " << std::flush;
STXXLNodeVector::iterator nodesIT = allNodes.begin();
STXXLNodeIDVector::iterator usedNodeIDsIT = usedNodeIDs.begin();
while(usedNodeIDsIT != usedNodeIDs.end() && nodesIT != allNodes.end()) {
if(*usedNodeIDsIT < nodesIT->id){
++usedNodeIDsIT;
//identify all used nodes by a merging step of two sorted lists
STXXLNodeVector::iterator node_iterator = all_nodes_list.begin();
STXXLNodeIDVector::iterator 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->id){
++node_id_iterator;
continue;
}
if(*usedNodeIDsIT > nodesIT->id) {
++nodesIT;
if(*node_id_iterator > node_iterator->id) {
++node_iterator;
continue;
}
if(*usedNodeIDsIT == nodesIT->id) {
fout.write((char*)&(*nodesIT), sizeof(_Node));
++usedNodeCounter;
++usedNodeIDsIT;
++nodesIT;
}
BOOST_ASSERT( *node_id_iterator == node_iterator->id);
file_out_stream.write(
(char*)&(*node_iterator),
sizeof(ExternalMemoryNode)
);
++number_of_used_nodes;
++node_id_iterator;
++node_iterator;
}
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
std::cout << "[extractor] setting number of nodes ... " << std::flush;
std::ios::pos_type positionInFile = fout.tellp();
fout.seekp(std::ios::beg+sizeof(UUID));
fout.write((char*)&usedNodeCounter, sizeof(unsigned));
fout.seekp(positionInFile);
std::ios::pos_type previous_file_position = file_out_stream.tellp();
file_out_stream.seekp(std::ios::beg+sizeof(UUID));
file_out_stream.write((char*)&number_of_used_nodes, sizeof(unsigned));
file_out_stream.seekp(previous_file_position);
std::cout << "ok" << std::endl;
time = get_timestamp();
// Sort edges by start.
std::cout << "[extractor] Sorting edges by start ... " << std::flush;
stxxl::sort(allEdges.begin(), allEdges.end(), CmpEdgeByStartID(), memory_to_use);
stxxl::sort(
all_edges_list.begin(),
all_edges_list.end(),
CmpEdgeByStartID(),
4294967296
);
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp();
std::cout << "[extractor] Setting start coords ... " << std::flush;
fout.write((char*)&usedEdgeCounter, sizeof(unsigned));
file_out_stream.write((char*)&number_of_used_edges, 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;
node_iterator = all_nodes_list.begin();
STXXLEdgeVector::iterator 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->id){
++edge_iterator;
continue;
}
if(edgeIT->start > nodesIT->id) {
nodesIT++;
if(edge_iterator->start > node_iterator->id) {
node_iterator++;
continue;
}
if(edgeIT->start == nodesIT->id) {
edgeIT->startCoord.lat = nodesIT->lat;
edgeIT->startCoord.lon = nodesIT->lon;
++edgeIT;
}
BOOST_ASSERT(edge_iterator->start == node_iterator->id);
edge_iterator->startCoord.lat = node_iterator->lat;
edge_iterator->startCoord.lon = node_iterator->lon;
++edge_iterator;
}
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp();
// Sort Edges by target
std::cout << "[extractor] Sorting edges by target ... " << std::flush;
stxxl::sort(allEdges.begin(), allEdges.end(), CmpEdgeByTargetID(), memory_to_use);
stxxl::sort(
all_edges_list.begin(),
all_edges_list.end(),
CmpEdgeByTargetID(),
4294967296
);
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp();
std::cout << "[extractor] Setting target coords ... " << std::flush;
// Traverse list of edges and nodes in parallel and set target coord
nodesIT = allNodes.begin();
edgeIT = allEdges.begin();
node_iterator = all_nodes_list.begin();
edge_iterator = all_edges_list.begin();
while(edgeIT != allEdges.end() && nodesIT != allNodes.end()) {
if(edgeIT->target < nodesIT->id){
++edgeIT;
while(
edge_iterator != all_edges_list.end() &&
node_iterator != all_nodes_list.end()
) {
if(edge_iterator->target < node_iterator->id){
++edge_iterator;
continue;
}
if(edgeIT->target > nodesIT->id) {
++nodesIT;
if(edge_iterator->target > node_iterator->id) {
++node_iterator;
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;
BOOST_ASSERT(edge_iterator->target == node_iterator->id);
if(edge_iterator->startCoord.lat != INT_MIN && edge_iterator->startCoord.lon != INT_MIN) {
edge_iterator->targetCoord.lat = node_iterator->lat;
edge_iterator->targetCoord.lon = node_iterator->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;
const double distance = ApproximateDistance(
edge_iterator->startCoord.lat,
edge_iterator->startCoord.lon,
node_iterator->lat,
node_iterator->lon
);
fout.write((char*)&edgeIT->start, sizeof(unsigned));
fout.write((char*)&edgeIT->target, sizeof(unsigned));
fout.write((char*)&intDist, sizeof(int));
switch(edgeIT->direction) {
case ExtractionWay::notSure:
fout.write((char*)&zero, sizeof(short));
break;
case ExtractionWay::oneway:
fout.write((char*)&one, sizeof(short));
break;
case ExtractionWay::bidirectional:
fout.write((char*)&zero, sizeof(short));
BOOST_ASSERT(edge_iterator->speed != -1);
const double weight = ( distance * 10. ) / (edge_iterator->speed / 3.6);
int integer_weight = std::max( 1, (int)std::floor((edge_iterator->isDurationSet ? edge_iterator->speed : weight)+.5) );
int integer_distance = std::max( 1, (int)distance );
short zero = 0;
short one = 1;
break;
case ExtractionWay::opposite:
fout.write((char*)&one, sizeof(short));
break;
default:
std::cerr << "[error] edge with no direction: " << edgeIT->direction << std::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));
fout.write((char*)&edgeIT->isContraFlow, sizeof(bool));
++usedEdgeCounter;
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");
break;
}
++edgeIT;
file_out_stream.write(
(char*)&integer_weight, sizeof(int)
);
BOOST_ASSERT(edge_iterator->type >= 0);
file_out_stream.write(
(char*)&edge_iterator->type,
sizeof(short)
);
file_out_stream.write(
(char*)&edge_iterator->nameID,
sizeof(unsigned)
);
file_out_stream.write(
(char*)&edge_iterator->isRoundabout,
sizeof(bool)
);
file_out_stream.write(
(char*)&edge_iterator->ignoreInGrid,
sizeof(bool)
);
file_out_stream.write(
(char*)&edge_iterator->isAccessRestricted,
sizeof(bool)
);
file_out_stream.write(
(char*)&edge_iterator->isContraFlow,
sizeof(bool)
);
++number_of_used_edges;
}
++edge_iterator;
}
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
std::cout << "[extractor] setting number of edges ... " << std::flush;
fout.seekp(positionInFile);
fout.write((char*)&usedEdgeCounter, sizeof(unsigned));
fout.close();
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;
time = get_timestamp();
@@ -297,32 +387,46 @@ void ExtractionContainers::PrepareData(const std::string & output_file_name, con
std::ios::binary
);
const unsigned number_of_ways = name_list.size()+1;
name_file_stream.write((char *)&(number_of_ways), sizeof(unsigned));
//write number of names
const unsigned number_of_names = name_list.size()+1;
name_file_stream.write((char *)&(number_of_names), sizeof(unsigned));
//compute total number of chars
unsigned total_number_of_chars = 0;
BOOST_FOREACH(const std::string & temp_string, name_list) {
total_number_of_chars += temp_string.length();
}
//write total number of chars
name_file_stream.write(
(char *)&(total_number_of_chars),
sizeof(unsigned)
);
//write prefixe sums
unsigned name_lengths_prefix_sum = 0;
BOOST_FOREACH(const std::string & str, name_list) {
BOOST_FOREACH(const std::string & temp_string, name_list) {
name_file_stream.write(
(char *)&(name_lengths_prefix_sum),
sizeof(unsigned)
);
name_lengths_prefix_sum += strlen(str.c_str());
name_lengths_prefix_sum += temp_string.length();
}
//duplicate on purpose!
name_file_stream.write(
(char *)&(name_lengths_prefix_sum),
sizeof(unsigned)
);
//duplicate on purpose!
name_file_stream.write((char *)&(name_lengths_prefix_sum), sizeof(unsigned));
BOOST_FOREACH(const std::string & str, name_list) {
const unsigned lengthOfRawString = strlen(str.c_str());
name_file_stream.write(str.c_str(), lengthOfRawString);
//write all chars consecutively
BOOST_FOREACH(const std::string & temp_string, name_list) {
const unsigned string_length = temp_string.length();
name_file_stream.write(temp_string.c_str(), string_length);
}
name_file_stream.close();
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
SimpleLogger().Write() <<
"Processed " << usedNodeCounter << " nodes and " << usedEdgeCounter << " edges";
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;
+23 -22
View File
@@ -33,48 +33,49 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../Util/TimingUtil.h"
#include "../Util/UUID.h"
#include <boost/assert.hpp>
#include <boost/foreach.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <stxxl.h>
#include <stxxl/sort>
#include <stxxl/vector>
class ExtractionContainers {
public:
typedef stxxl::vector<NodeID> STXXLNodeIDVector;
typedef stxxl::vector<_Node> 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<NodeID> STXXLNodeIDVector;
typedef stxxl::vector<ExternalMemoryNode> STXXLNodeVector;
typedef stxxl::vector<InternalExtractorEdge> STXXLEdgeVector;
typedef stxxl::vector<std::string> STXXLStringVector;
typedef stxxl::vector<InputRestrictionContainer> STXXLRestrictionsVector;
typedef stxxl::vector<_WayIDStartAndEndEdge> STXXLWayIDStartEndVector;
STXXLNodeIDVector usedNodeIDs;
STXXLNodeVector allNodes;
STXXLEdgeVector allEdges;
STXXLNodeIDVector used_node_id_list;
STXXLNodeVector all_nodes_list;
STXXLEdgeVector all_edges_list;
STXXLStringVector name_list;
STXXLRestrictionsVector restrictionsVector;
STXXLWayIDStartEndVector wayStartEndVector;
STXXLRestrictionsVector restrictions_list;
STXXLWayIDStartEndVector way_start_end_id_list;
const UUID uuid;
ExtractionContainers() {
//Check if another instance of stxxl is already running or if there is a general problem
stxxl::vector<unsigned> testForRunningInstance;
//Check if stxxl can be instantiated
stxxl::vector<unsigned> dummy_vector;
name_list.push_back("");
}
virtual ~ExtractionContainers() {
usedNodeIDs.clear();
allNodes.clear();
allEdges.clear();
used_node_id_list.clear();
all_nodes_list.clear();
all_edges_list.clear();
name_list.clear();
restrictionsVector.clear();
wayStartEndVector.clear();
restrictions_list.clear();
way_start_end_id_list.clear();
}
void PrepareData(
const std::string & output_file_name,
const std::string restrictionsFileName,
const unsigned amountOfRAM
const std::string & restrictions_file_name
);
};
+10 -10
View File
@@ -36,14 +36,14 @@ ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers * ext, StringMap * s
ExtractorCallbacks::~ExtractorCallbacks() { }
/** warning: caller needs to take care of synchronization! */
void ExtractorCallbacks::nodeFunction(const _Node &n) {
void ExtractorCallbacks::nodeFunction(const ExternalMemoryNode &n) {
if(n.lat <= 85*COORDINATE_PRECISION && n.lat >= -85*COORDINATE_PRECISION) {
externalMemory->allNodes.push_back(n);
externalMemory->all_nodes_list.push_back(n);
}
}
bool ExtractorCallbacks::restrictionFunction(const _RawRestrictionContainer &r) {
externalMemory->restrictionsVector.push_back(r);
bool ExtractorCallbacks::restrictionFunction(const InputRestrictionContainer &r) {
externalMemory->restrictions_list.push_back(r);
return true;
}
@@ -86,7 +86,7 @@ void ExtractorCallbacks::wayFunction(ExtractionWay &parsed_way) {
const bool split_bidirectional_edge = (parsed_way.backward_speed > 0) && (parsed_way.speed != parsed_way.backward_speed);
for(std::vector< NodeID >::size_type n = 0; n < parsed_way.path.size()-1; ++n) {
externalMemory->allEdges.push_back(
externalMemory->all_edges_list.push_back(
InternalExtractorEdge(parsed_way.path[n],
parsed_way.path[n+1],
parsed_way.type,
@@ -99,17 +99,17 @@ void ExtractorCallbacks::wayFunction(ExtractionWay &parsed_way) {
parsed_way.isAccessRestricted
)
);
externalMemory->usedNodeIDs.push_back(parsed_way.path[n]);
externalMemory->used_node_id_list.push_back(parsed_way.path[n]);
}
externalMemory->usedNodeIDs.push_back(parsed_way.path.back());
externalMemory->used_node_id_list.push_back(parsed_way.path.back());
//The following information is needed to identify start and end segments of restrictions
externalMemory->wayStartEndVector.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()));
externalMemory->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_bidirectional_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) {
externalMemory->allEdges.push_back(
externalMemory->all_edges_list.push_back(
InternalExtractorEdge(parsed_way.path[n],
parsed_way.path[n+1],
parsed_way.type,
@@ -124,7 +124,7 @@ void ExtractorCallbacks::wayFunction(ExtractionWay &parsed_way) {
)
);
}
externalMemory->wayStartEndVector.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()));
externalMemory->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()));
}
}
}
+2 -2
View File
@@ -55,9 +55,9 @@ public:
~ExtractorCallbacks();
/** warning: caller needs to take care of synchronization! */
void nodeFunction(const _Node &n);
void nodeFunction(const ExternalMemoryNode &n);
bool restrictionFunction(const _RawRestrictionContainer &r);
bool restrictionFunction(const InputRestrictionContainer &r);
/** warning: caller needs to take care of synchronization! */
void wayFunction(ExtractionWay &w);
+8 -5
View File
@@ -172,16 +172,19 @@ struct Cmp : public std::binary_function<NodeID, NodeID, bool> {
}
};
struct CmpNodeByID : public std::binary_function<_Node, _Node, bool> {
typedef _Node value_type;
bool operator () (const _Node & a, const _Node & b) const {
struct CmpNodeByID : public std::binary_function<ExternalMemoryNode, ExternalMemoryNode, bool> {
typedef ExternalMemoryNode value_type;
bool operator () (
const ExternalMemoryNode & a,
const ExternalMemoryNode & b
) const {
return a.id < b.id;
}
value_type max_value() {
return _Node::max_value();
return ExternalMemoryNode::max_value();
}
value_type min_value() {
return _Node::min_value();
return ExternalMemoryNode::min_value();
}
};
+1 -1
View File
@@ -248,7 +248,7 @@ inline void PBFParser::parseRelation(_ThreadData * threadData) {
if(isRestriction) {
int64_t lastRef = 0;
_RawRestrictionContainer currentRestrictionContainer(isOnlyRestriction);
InputRestrictionContainer currentRestrictionContainer(isOnlyRestriction);
for(
int rolesIndex = 0, last_role = inputRelation.roles_sid_size();
rolesIndex < last_role;
+6 -3
View File
@@ -66,7 +66,7 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
.def(luabind::constructor<>())
.def_readwrite("lat", &ImportNode::lat)
.def_readwrite("lon", &ImportNode::lon)
.def_readwrite("id", &ImportNode::id)
.def_readonly("id", &ImportNode::id)
.def_readwrite("bollard", &ImportNode::bollard)
.def_readwrite("traffic_light", &ImportNode::trafficLight)
.def_readwrite("tags", &ImportNode::keyVals)
@@ -75,6 +75,7 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
luabind::module(myLuaState) [
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)
@@ -94,9 +95,11 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
]
];
// fails on c++11/OS X 10.9
luabind::module(myLuaState) [
luabind::class_<std::vector<std::string> >("vector")
.def("Add", &std::vector<std::string>::push_back)
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(myLuaState, fileName) ) {
+3 -3
View File
@@ -74,7 +74,7 @@ bool XMLParser::Parse() {
}
if( use_turn_restrictions ) {
if ( xmlStrEqual( currentName, ( const xmlChar* ) "relation" ) == 1 ) {
_RawRestrictionContainer r = _ReadXMLRestriction();
InputRestrictionContainer r = _ReadXMLRestriction();
if(r.fromWay != UINT_MAX) {
if(!extractor_callbacks->restrictionFunction(r)) {
std::cerr << "[XMLParser] restriction not parsed" << std::endl;
@@ -87,8 +87,8 @@ bool XMLParser::Parse() {
return true;
}
_RawRestrictionContainer XMLParser::_ReadXMLRestriction() {
_RawRestrictionContainer restriction;
InputRestrictionContainer XMLParser::_ReadXMLRestriction() {
InputRestrictionContainer restriction;
std::string except_tag_string;
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
+1 -1
View File
@@ -44,7 +44,7 @@ public:
bool Parse();
private:
_RawRestrictionContainer _ReadXMLRestriction();
InputRestrictionContainer _ReadXMLRestriction();
ExtractionWay _ReadXMLWay();
ImportNode _ReadXMLNode();
xmlTextReaderPtr inputReader;
+83 -16
View File
@@ -26,39 +26,106 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "OSRM.h"
#include <boost/foreach.hpp>
OSRM::OSRM( const ServerPaths & server_paths, const bool use_shared_memory )
:
use_shared_memory(use_shared_memory)
{
if( !use_shared_memory ) {
query_data_facade = new InternalDataFacade<QueryEdge::EdgeData>(
server_paths
);
} else {
query_data_facade = new SharedDataFacade<QueryEdge::EdgeData>( );
}
OSRM::OSRM(boost::unordered_map<const std::string,boost::filesystem::path>& paths) {
objects = new QueryObjectsStorage( paths );
RegisterPlugin(new HelloWorldPlugin());
RegisterPlugin(new LocatePlugin(objects));
RegisterPlugin(new NearestPlugin(objects));
RegisterPlugin(new TimestampPlugin(objects));
RegisterPlugin(new ViaRoutePlugin(objects));
//The following plugins handle all requests.
RegisterPlugin(
new HelloWorldPlugin()
);
RegisterPlugin(
new LocatePlugin<BaseDataFacade<QueryEdge::EdgeData> >(
query_data_facade
)
);
RegisterPlugin(
new NearestPlugin<BaseDataFacade<QueryEdge::EdgeData> >(
query_data_facade
)
);
RegisterPlugin(
new TimestampPlugin<BaseDataFacade<QueryEdge::EdgeData> >(
query_data_facade
)
);
RegisterPlugin(
new ViaRoutePlugin<BaseDataFacade<QueryEdge::EdgeData> >(
query_data_facade
)
);
}
OSRM::~OSRM() {
BOOST_FOREACH(PluginMap::value_type & plugin_pointer, pluginMap) {
BOOST_FOREACH(PluginMap::value_type & plugin_pointer, plugin_map) {
delete plugin_pointer.second;
}
delete objects;
}
void OSRM::RegisterPlugin(BasePlugin * plugin) {
SimpleLogger().Write() << "loaded plugin: " << plugin->GetDescriptor();
if( pluginMap.find(plugin->GetDescriptor()) != pluginMap.end() ) {
delete pluginMap.find(plugin->GetDescriptor())->second;
if( plugin_map.find(plugin->GetDescriptor()) != plugin_map.end() ) {
delete plugin_map.find(plugin->GetDescriptor())->second;
}
pluginMap.emplace(plugin->GetDescriptor(), plugin);
plugin_map.emplace(plugin->GetDescriptor(), plugin);
}
void OSRM::RunQuery(RouteParameters & route_parameters, http::Reply & reply) {
const PluginMap::const_iterator & iter = pluginMap.find(route_parameters.service);
if(pluginMap.end() != iter) {
const PluginMap::const_iterator & iter = plugin_map.find(
route_parameters.service
);
if(plugin_map.end() != iter) {
reply.status = http::Reply::ok;
if( use_shared_memory ) {
// lock update pending
boost::interprocess::scoped_lock<
boost::interprocess::named_mutex
> pending_lock(barrier.pending_update_mutex);
// lock query
boost::interprocess::scoped_lock<
boost::interprocess::named_mutex
> query_lock(barrier.query_mutex);
// unlock update pending
pending_lock.unlock();
// increment query count
++(barrier.number_of_queries);
(static_cast<SharedDataFacade<QueryEdge::EdgeData>* >(query_data_facade))->CheckAndReloadFacade();
}
iter->second->HandleRequest(route_parameters, reply );
if( use_shared_memory ) {
// lock query
boost::interprocess::scoped_lock<
boost::interprocess::named_mutex
> query_lock(barrier.query_mutex);
// decrement query count
--(barrier.number_of_queries);
BOOST_ASSERT_MSG(
0 <= barrier.number_of_queries,
"invalid number of queries"
);
// notify all processes that were waiting for this condition
if (0 == barrier.number_of_queries) {
barrier.no_running_queries_condition.notify_all();
}
}
} else {
reply = http::Reply::stockReply(http::Reply::badRequest);
reply = http::Reply::StockReply(http::Reply::badRequest);
}
}
+20 -5
View File
@@ -36,30 +36,45 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../Plugins/NearestPlugin.h"
#include "../Plugins/TimestampPlugin.h"
#include "../Plugins/ViaRoutePlugin.h"
#include "../Server/DataStructures/BaseDataFacade.h"
#include "../Server/DataStructures/InternalDataFacade.h"
#include "../Server/DataStructures/SharedBarriers.h"
#include "../Server/DataStructures/SharedDataFacade.h"
#include "../Server/DataStructures/RouteParameters.h"
#include "../Util/InputFileUtil.h"
#include "../Util/OSRMException.h"
#include "../Util/ProgramOptions.h"
#include "../Util/SimpleLogger.h"
#include "../Server/BasicDatastructures.h"
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <vector>
class OSRM : boost::noncopyable {
private:
typedef boost::unordered_map<std::string, BasePlugin *> PluginMap;
QueryObjectsStorage * objects;
public:
OSRM(boost::unordered_map<const std::string,boost::filesystem::path>& paths);
OSRM(
const ServerPaths & paths,
const bool use_shared_memory = false
);
~OSRM();
void RunQuery(RouteParameters & route_parameters, http::Reply & reply);
private:
void RegisterPlugin(BasePlugin * plugin);
PluginMap pluginMap;
PluginMap plugin_map;
bool use_shared_memory;
SharedBarriers barrier;
//base class pointer to the objects
BaseDataFacade<QueryEdge::EdgeData> * query_data_facade;
};
#endif //OSRM_H
+1 -1
View File
@@ -29,8 +29,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define BASEPLUGIN_H_
#include "../DataStructures/Coordinate.h"
#include "../Server/BasicDatastructures.h"
#include "../Server/DataStructures/RouteParameters.h"
#include "../Server/Http/Reply.h"
#include <string>
#include <vector>
+50 -19
View File
@@ -29,10 +29,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define HELLOWORLDPLUGIN_H_
#include "BasePlugin.h"
#include "../Util/StringUtil.h"
#include <sstream>
#include <string>
class HelloWorldPlugin : public BasePlugin {
private:
std::string temp_string;
public:
HelloWorldPlugin() : descriptor_string("hello"){}
virtual ~HelloWorldPlugin() { }
@@ -40,28 +43,56 @@ public:
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
reply.status = http::Reply::ok;
reply.content.append("<html><head><title>Hello World Demonstration Document</title></head><body><h1>Hello, World!</h1>");
std::stringstream content;
content << "<pre>";
content << "zoom level: " << routeParameters.zoomLevel << "\n";
content << "checksum: " << routeParameters.checkSum << "\n";
content << "instructions: " << (routeParameters.printInstructions ? "yes" : "no") << "\n";
content << "geometry: " << (routeParameters.geometry ? "yes" : "no") << "\n";
content << "compression: " << (routeParameters.compression ? "yes" : "no") << "\n";
content << "output format: " << routeParameters.outputFormat << "\n";
content << "json parameter: " << routeParameters.jsonpParameter << "\n";
content << "language: " << routeParameters.language << "<br>";
content << "Number of locations: " << routeParameters.coordinates.size() << "\n";
reply.content.push_back("<html><head><title>Hello World Demonstration Document</title></head><body><h1>Hello, World!</h1>");
reply.content.push_back("<pre>");
reply.content.push_back("zoom level: ");
intToString(routeParameters.zoomLevel, temp_string);
reply.content.push_back(temp_string);
reply.content.push_back("\nchecksum: ");
intToString(routeParameters.checkSum, temp_string);
reply.content.push_back(temp_string);
reply.content.push_back("\ninstructions: ");
reply.content.push_back((routeParameters.printInstructions ? "yes" : "no"));
reply.content.push_back(temp_string);
reply.content.push_back("\ngeometry: ");
reply.content.push_back((routeParameters.geometry ? "yes" : "no"));
reply.content.push_back("\ncompression: ");
reply.content.push_back((routeParameters.compression ? "yes" : "no"));
reply.content.push_back("\noutput format: ");
reply.content.push_back(routeParameters.outputFormat);
reply.content.push_back("\njson parameter: ");
reply.content.push_back(routeParameters.jsonpParameter);
reply.content.push_back("\nlanguage: ");
reply.content.push_back(routeParameters.language);
reply.content.push_back("\nNumber of locations: ");
intToString(routeParameters.coordinates.size(), temp_string);
reply.content.push_back(temp_string);
reply.content.push_back("\n");
for(unsigned i = 0; i < routeParameters.coordinates.size(); ++i) {
content << " [" << i << "] " << routeParameters.coordinates[i].lat/COORDINATE_PRECISION << "," << routeParameters.coordinates[i].lon/COORDINATE_PRECISION << "\n";
reply.content.push_back( " [");
intToString(i, temp_string);
reply.content.push_back(temp_string);
reply.content.push_back("] ");
doubleToString(routeParameters.coordinates[i].lat/COORDINATE_PRECISION, temp_string);
reply.content.push_back(temp_string);
reply.content.push_back(",");
doubleToString(routeParameters.coordinates[i].lon/COORDINATE_PRECISION, temp_string);
reply.content.push_back(temp_string);
reply.content.push_back("\n");
}
content << "Number of hints: " << routeParameters.hints.size() << "\n";
reply.content.push_back( "Number of hints: ");
intToString(routeParameters.hints.size(), temp_string);
reply.content.push_back(temp_string);
reply.content.push_back("\n");
for(unsigned i = 0; i < routeParameters.hints.size(); ++i) {
content << " [" << i << "] " << routeParameters.hints[i] << "\n";
reply.content.push_back( " [");
intToString(i, temp_string);
reply.content.push_back(temp_string);
reply.content.push_back("] ");
reply.content.push_back(routeParameters.hints[i]);
reply.content.push_back("\n");
}
content << "</pre>";
reply.content.append(content.str());
reply.content.append("</body></html>");
reply.content.push_back( "</pre></body></html>");
}
private:
std::string descriptor_string;
+45 -33
View File
@@ -29,27 +29,31 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define LOCATEPLUGIN_H_
#include "BasePlugin.h"
#include "../DataStructures/NodeInformationHelpDesk.h"
#include "../Server/DataStructures/QueryObjectsStorage.h"
#include "../Util/StringUtil.h"
/*
* This Plugin locates the nearest node in the road network for a given coordinate.
*/
//locates the nearest node in the road network for a given coordinate.
template<class DataFacadeT>
class LocatePlugin : public BasePlugin {
public:
LocatePlugin(QueryObjectsStorage * objects) : descriptor_string("locate") {
nodeHelpDesk = objects->nodeHelpDesk;
}
LocatePlugin(DataFacadeT * facade)
:
descriptor_string("locate"),
facade(facade)
{ }
const std::string & GetDescriptor() const { return descriptor_string; }
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
void HandleRequest(
const RouteParameters & routeParameters,
http::Reply& reply
) {
//check number of parameters
if(!routeParameters.coordinates.size()) {
reply = http::Reply::stockReply(http::Reply::badRequest);
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
}
if(false == checkCoord(routeParameters.coordinates[0])) {
reply = http::Reply::stockReply(http::Reply::badRequest);
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
}
@@ -58,35 +62,39 @@ public:
std::string tmp;
//json
// JSONParameter = routeParameters.options.Find("jsonp");
if("" != routeParameters.jsonpParameter) {
reply.content += routeParameters.jsonpParameter;
reply.content += "(";
if(!routeParameters.jsonpParameter.empty()) {
reply.content.push_back(routeParameters.jsonpParameter);
reply.content.push_back("(");
}
reply.status = http::Reply::ok;
reply.content += ("{");
reply.content += ("\"version\":0.3,");
if(!nodeHelpDesk->LocateClosestEndPointForCoordinate(routeParameters.coordinates[0], result)) {
reply.content += ("\"status\":207,");
reply.content += ("\"mapped_coordinate\":[]");
reply.content.push_back ("{");
reply.content.push_back ("\"version\":0.3,");
if(
!facade->LocateClosestEndPointForCoordinate(
routeParameters.coordinates[0],
result
)
) {
reply.content.push_back ("\"status\":207,");
reply.content.push_back ("\"mapped_coordinate\":[]");
} else {
//Write coordinate to stream
reply.status = http::Reply::ok;
reply.content += ("\"status\":0,");
reply.content += ("\"mapped_coordinate\":");
reply.content.push_back ("\"status\":0,");
reply.content.push_back ("\"mapped_coordinate\":");
convertInternalLatLonToString(result.lat, tmp);
reply.content += "[";
reply.content += tmp;
reply.content.push_back("[");
reply.content.push_back(tmp);
convertInternalLatLonToString(result.lon, tmp);
reply.content += ",";
reply.content += tmp;
reply.content += "]";
reply.content.push_back(",");
reply.content.push_back(tmp);
reply.content.push_back("]");
}
reply.content += ",\"transactionId\": \"OSRM Routing Engine JSON Locate (v0.3)\"";
reply.content += ("}");
reply.content.push_back(",\"transactionId\": \"OSRM Routing Engine JSON Locate (v0.3)\"");
reply.content.push_back("}");
reply.headers.resize(3);
if("" != routeParameters.jsonpParameter) {
reply.content += ")";
if(!routeParameters.jsonpParameter.empty()) {
reply.content.push_back( ")");
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "text/javascript";
reply.headers[2].name = "Content-Disposition";
@@ -98,14 +106,18 @@ public:
reply.headers[2].value = "attachment; filename=\"location.json\"";
}
reply.headers[0].name = "Content-Length";
intToString(reply.content.size(), tmp);
unsigned content_length = 0;
BOOST_FOREACH(const std::string & snippet, reply.content) {
content_length += snippet.length();
}
intToString(content_length, tmp);
reply.headers[0].value = tmp;
return;
}
private:
NodeInformationHelpDesk * nodeHelpDesk;
std::string descriptor_string;
DataFacadeT * facade;
};
#endif /* LOCATEPLUGIN_H_ */
+37 -34
View File
@@ -29,19 +29,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define NearestPlugin_H_
#include "BasePlugin.h"
#include "../DataStructures/NodeInformationHelpDesk.h"
#include "../Server/DataStructures/QueryObjectsStorage.h"
#include "../DataStructures/PhantomNodes.h"
#include "../Util/StringUtil.h"
/*
* This Plugin locates the nearest point on a street in the road network for a given coordinate.
*/
template<class DataFacadeT>
class NearestPlugin : public BasePlugin {
public:
NearestPlugin(QueryObjectsStorage * objects )
NearestPlugin(DataFacadeT * facade )
:
m_query_objects(objects),
facade(facade),
descriptor_string("nearest")
{
descriptorTable.insert(std::make_pair("" , 0)); //default descriptor
@@ -51,17 +51,16 @@ public:
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
//check number of parameters
if(!routeParameters.coordinates.size()) {
reply = http::Reply::stockReply(http::Reply::badRequest);
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
}
if(false == checkCoord(routeParameters.coordinates[0])) {
reply = http::Reply::stockReply(http::Reply::badRequest);
if( !checkCoord(routeParameters.coordinates[0]) ) {
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
}
NodeInformationHelpDesk * nodeHelpDesk = m_query_objects->nodeHelpDesk;
//query to helpdesk
PhantomNode result;
nodeHelpDesk->FindPhantomNodeForCoordinate(
facade->FindPhantomNodeForCoordinate(
routeParameters.coordinates[0],
result,
routeParameters.zoomLevel
@@ -71,40 +70,40 @@ public:
//json
if("" != routeParameters.jsonpParameter) {
reply.content += routeParameters.jsonpParameter;
reply.content += "(";
reply.content.push_back(routeParameters.jsonpParameter);
reply.content.push_back("(");
}
reply.status = http::Reply::ok;
reply.content += ("{");
reply.content += ("\"version\":0.3,");
reply.content += ("\"status\":");
reply.content.push_back("{");
reply.content.push_back("\"version\":0.3,");
reply.content.push_back("\"status\":");
if(UINT_MAX != result.edgeBasedNode) {
reply.content += "0,";
reply.content.push_back("0,");
} else {
reply.content += "207,";
reply.content.push_back("207,");
}
reply.content += ("\"mapped_coordinate\":");
reply.content += "[";
reply.content.push_back("\"mapped_coordinate\":");
reply.content.push_back("[");
if(UINT_MAX != result.edgeBasedNode) {
convertInternalLatLonToString(result.location.lat, temp_string);
reply.content += temp_string;
reply.content.push_back(temp_string);
convertInternalLatLonToString(result.location.lon, temp_string);
reply.content += ",";
reply.content += temp_string;
reply.content.push_back(",");
reply.content.push_back(temp_string);
}
reply.content += "],";
reply.content += "\"name\":\"";
reply.content.push_back("],");
reply.content.push_back("\"name\":\"");
if(UINT_MAX != result.edgeBasedNode) {
m_query_objects->GetName(result.nodeBasedEdgeNameID, temp_string);
reply.content += temp_string;
facade->GetName(result.nodeBasedEdgeNameID, temp_string);
reply.content.push_back(temp_string);
}
reply.content += "\"";
reply.content += ",\"transactionId\":\"OSRM Routing Engine JSON Nearest (v0.3)\"";
reply.content += ("}");
reply.content.push_back("\"");
reply.content.push_back(",\"transactionId\":\"OSRM Routing Engine JSON Nearest (v0.3)\"");
reply.content.push_back("}");
reply.headers.resize(3);
if("" != routeParameters.jsonpParameter) {
reply.content += ")";
if( !routeParameters.jsonpParameter.empty() ) {
reply.content.push_back(")");
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "text/javascript";
reply.headers[2].name = "Content-Disposition";
@@ -116,12 +115,16 @@ public:
reply.headers[2].value = "attachment; filename=\"location.json\"";
}
reply.headers[0].name = "Content-Length";
intToString(reply.content.size(), temp_string);
unsigned content_length = 0;
BOOST_FOREACH(const std::string & snippet, reply.content) {
content_length += snippet.length();
}
intToString(content_length, temp_string);
reply.headers[0].value = temp_string;
}
private:
QueryObjectsStorage * m_query_objects;
DataFacadeT * facade;
HashTable<std::string, unsigned> descriptorTable;
std::string descriptor_string;
};
+21 -17
View File
@@ -30,10 +30,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "BasePlugin.h"
template<class DataFacadeT>
class TimestampPlugin : public BasePlugin {
public:
TimestampPlugin(QueryObjectsStorage * o)
: objects(o), descriptor_string("timestamp")
TimestampPlugin(const DataFacadeT * facade)
: facade(facade), descriptor_string("timestamp")
{ }
const std::string & GetDescriptor() const { return descriptor_string; }
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
@@ -41,23 +42,23 @@ public:
//json
if("" != routeParameters.jsonpParameter) {
reply.content += routeParameters.jsonpParameter;
reply.content += "(";
reply.content.push_back(routeParameters.jsonpParameter);
reply.content.push_back("(");
}
reply.status = http::Reply::ok;
reply.content += ("{");
reply.content += ("\"version\":0.3,");
reply.content += ("\"status\":");
reply.content += "0,";
reply.content += ("\"timestamp\":\"");
reply.content += objects->timestamp;
reply.content += "\"";
reply.content += ",\"transactionId\":\"OSRM Routing Engine JSON timestamp (v0.3)\"";
reply.content += ("}");
reply.content.push_back("{");
reply.content.push_back("\"version\":0.3,");
reply.content.push_back("\"status\":");
reply.content.push_back("0,");
reply.content.push_back("\"timestamp\":\"");
reply.content.push_back(facade->GetTimestamp());
reply.content.push_back("\"");
reply.content.push_back(",\"transactionId\":\"OSRM Routing Engine JSON timestamp (v0.3)\"");
reply.content.push_back("}");
reply.headers.resize(3);
if("" != routeParameters.jsonpParameter) {
reply.content += ")";
reply.content.push_back(")");
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "text/javascript";
reply.headers[2].name = "Content-Disposition";
@@ -68,12 +69,15 @@ public:
reply.headers[2].name = "Content-Disposition";
reply.headers[2].value = "attachment; filename=\"timestamp.json\"";
}
reply.headers[0].name = "Content-Length";
intToString(reply.content.size(), tmp);
unsigned content_length = 0;
BOOST_FOREACH(const std::string & snippet, reply.content) {
content_length += snippet.length();
}
intToString(content_length, tmp);
reply.headers[0].value = tmp;
}
private:
QueryObjectsStorage * objects;
const DataFacadeT * facade;
std::string descriptor_string;
};
+56 -46
View File
@@ -32,12 +32,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../Algorithms/ObjectToBase64.h"
#include "../DataStructures/QueryEdge.h"
#include "../DataStructures/StaticGraph.h"
#include "../DataStructures/SearchEngine.h"
#include "../Descriptors/BaseDescriptor.h"
#include "../Descriptors/GPXDescriptor.h"
#include "../Descriptors/JSONDescriptor.h"
#include "../Server/DataStructures/QueryObjectsStorage.h"
#include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h"
@@ -48,49 +46,48 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include <vector>
template<class DataFacadeT>
class ViaRoutePlugin : public BasePlugin {
private:
NodeInformationHelpDesk * nodeHelpDesk;
StaticGraph<QueryEdge::EdgeData> * graph;
HashTable<std::string, unsigned> descriptorTable;
SearchEngine * searchEnginePtr;
boost::unordered_map<std::string, unsigned> descriptorTable;
SearchEngine<DataFacadeT> * search_engine_ptr;
public:
ViaRoutePlugin(QueryObjectsStorage * objects)
ViaRoutePlugin(DataFacadeT * facade)
:
// objects(objects),
descriptor_string("viaroute")
descriptor_string("viaroute"),
facade(facade)
{
nodeHelpDesk = objects->nodeHelpDesk;
graph = objects->graph;
//TODO: set up an engine for each thread!!
search_engine_ptr = new SearchEngine<DataFacadeT>(facade);
searchEnginePtr = new SearchEngine(objects);
// descriptorTable.emplace("" , 0);
descriptorTable.emplace("json", 0);
descriptorTable.emplace("gpx" , 1);
}
virtual ~ViaRoutePlugin() {
delete searchEnginePtr;
delete search_engine_ptr;
}
const std::string & GetDescriptor() const { return descriptor_string; }
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
void HandleRequest(
const RouteParameters & routeParameters,
http::Reply& reply
) {
//check number of parameters
if( 2 > routeParameters.coordinates.size() ) {
reply = http::Reply::stockReply(http::Reply::badRequest);
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
}
RawRouteData rawRoute;
rawRoute.checkSum = nodeHelpDesk->GetCheckSum();
rawRoute.checkSum = facade->GetCheckSum();
bool checksumOK = (routeParameters.checkSum == rawRoute.checkSum);
std::vector<std::string> textCoord;
for(unsigned i = 0; i < routeParameters.coordinates.size(); ++i) {
if(false == checkCoord(routeParameters.coordinates[i])) {
reply = http::Reply::stockReply(http::Reply::badRequest);
if( !checkCoord(routeParameters.coordinates[i]) ) {
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
}
rawRoute.rawViaNodeCoordinates.push_back(routeParameters.coordinates[i]);
@@ -100,13 +97,17 @@ public:
if(checksumOK && i < routeParameters.hints.size() && "" != routeParameters.hints[i]) {
// SimpleLogger().Write() <<"Decoding hint: " << routeParameters.hints[i] << " for location index " << i;
DecodeObjectFromBase64(routeParameters.hints[i], phantomNodeVector[i]);
if(phantomNodeVector[i].isValid(nodeHelpDesk->GetNumberOfNodes())) {
if(phantomNodeVector[i].isValid(facade->GetNumberOfNodes())) {
// SimpleLogger().Write() << "Decoded hint " << i << " successfully";
continue;
}
}
// SimpleLogger().Write() << "Brute force lookup of coordinate " << i;
searchEnginePtr->FindPhantomNodeForCoordinate( rawRoute.rawViaNodeCoordinates[i], phantomNodeVector[i], routeParameters.zoomLevel);
facade->FindPhantomNodeForCoordinate(
rawRoute.rawViaNodeCoordinates[i],
phantomNodeVector[i],
routeParameters.zoomLevel
);
}
for(unsigned i = 0; i < phantomNodeVector.size()-1; ++i) {
@@ -115,73 +116,81 @@ public:
segmentPhantomNodes.targetPhantom = phantomNodeVector[i+1];
rawRoute.segmentEndCoordinates.push_back(segmentPhantomNodes);
}
if( ( routeParameters.alternateRoute ) && (1 == rawRoute.segmentEndCoordinates.size()) ) {
// SimpleLogger().Write() << "Checking for alternative paths";
searchEnginePtr->alternativePaths(rawRoute.segmentEndCoordinates[0], rawRoute);
if(
( routeParameters.alternateRoute ) &&
(1 == rawRoute.segmentEndCoordinates.size())
) {
search_engine_ptr->alternative_path(
rawRoute.segmentEndCoordinates[0],
rawRoute
);
} else {
searchEnginePtr->shortestPath(rawRoute.segmentEndCoordinates, rawRoute);
search_engine_ptr->shortest_path(
rawRoute.segmentEndCoordinates,
rawRoute
);
}
if(INT_MAX == rawRoute.lengthOfShortestPath ) {
SimpleLogger().Write(logDEBUG) << "Error occurred, single path not found";
SimpleLogger().Write(logDEBUG) <<
"Error occurred, single path not found";
}
reply.status = http::Reply::ok;
//TODO: Move to member as smart pointer
BaseDescriptor * desc;
BaseDescriptor<DataFacadeT> * desc;
if("" != routeParameters.jsonpParameter) {
reply.content += routeParameters.jsonpParameter;
reply.content += "(";
reply.content.push_back(routeParameters.jsonpParameter);
reply.content.push_back("(");
}
_DescriptorConfig descriptorConfig;
DescriptorConfig descriptorConfig;
unsigned descriptorType = 0;
if(descriptorTable.find(routeParameters.outputFormat) != descriptorTable.end() ) {
descriptorType = descriptorTable.find(routeParameters.outputFormat)->second;
}
descriptorConfig.z = routeParameters.zoomLevel;
descriptorConfig.zoom_level = routeParameters.zoomLevel;
descriptorConfig.instructions = routeParameters.printInstructions;
descriptorConfig.geometry = routeParameters.geometry;
descriptorConfig.encodeGeometry = routeParameters.compression;
descriptorConfig.encode_geometry = routeParameters.compression;
switch(descriptorType){
case 0:
desc = new JSONDescriptor();
desc = new JSONDescriptor<DataFacadeT>();
break;
case 1:
desc = new GPXDescriptor();
desc = new GPXDescriptor<DataFacadeT>();
break;
default:
desc = new JSONDescriptor();
desc = new JSONDescriptor<DataFacadeT>();
break;
}
PhantomNodes phantomNodes;
phantomNodes.startPhantom = rawRoute.segmentEndCoordinates[0].startPhantom;
// SimpleLogger().Write() << "Start location: " << phantomNodes.startPhantom.location;
phantomNodes.targetPhantom = rawRoute.segmentEndCoordinates[rawRoute.segmentEndCoordinates.size()-1].targetPhantom;
// SimpleLogger().Write() << "TargetLocation: " << phantomNodes.targetPhantom.location;
// SimpleLogger().Write() << "Number of segments: " << rawRoute.segmentEndCoordinates.size();
desc->SetConfig(descriptorConfig);
desc->Run(reply, rawRoute, phantomNodes, *searchEnginePtr);
desc->Run(reply, rawRoute, phantomNodes, facade);
if("" != routeParameters.jsonpParameter) {
reply.content += ")\n";
reply.content.push_back(")\n");
}
reply.headers.resize(3);
reply.headers[0].name = "Content-Length";
std::string tmp;
intToString(reply.content.size(), tmp);
unsigned content_length = 0;
BOOST_FOREACH(const std::string & snippet, reply.content) {
content_length += snippet.length();
}
intToString(content_length, tmp);
reply.headers[0].value = tmp;
switch(descriptorType){
case 0:
if("" != routeParameters.jsonpParameter){
if( !routeParameters.jsonpParameter.empty() ){
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "text/javascript";
reply.headers[2].name = "Content-Disposition";
@@ -202,7 +211,7 @@ public:
break;
default:
if("" != routeParameters.jsonpParameter){
if( !routeParameters.jsonpParameter.empty() ){
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "text/javascript";
reply.headers[2].name = "Content-Disposition";
@@ -221,6 +230,7 @@ public:
}
private:
std::string descriptor_string;
DataFacadeT * facade;
};
+1 -1
View File
@@ -6,7 +6,7 @@ require 'sys/proctable'
BUILD_FOLDER = 'build'
DATA_FOLDER = 'sandbox'
PROFILE = 'bicycle'
PROFILE = 'examples/postgis'
OSRM_PORT = 5000
PROFILES_FOLDER = '../profiles'
+154 -80
View File
@@ -29,6 +29,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define ALTERNATIVEROUTES_H_
#include "BasicRoutingInterface.h"
#include "../DataStructures/SearchEngineData.h"
#include <boost/unordered_map.hpp>
#include <cmath>
#include <vector>
@@ -37,15 +39,20 @@ const double VIAPATH_ALPHA = 0.15;
const double VIAPATH_EPSILON = 0.10; //alternative at most 15% longer
const double VIAPATH_GAMMA = 0.75; //alternative shares at most 75% with the shortest.
template<class QueryDataT>
class AlternativeRouting : private BasicRoutingInterface<QueryDataT> {
typedef BasicRoutingInterface<QueryDataT> super;
typedef typename QueryDataT::Graph SearchGraph;
typedef typename QueryDataT::QueryHeap QueryHeap;
template<class DataFacadeT>
class AlternativeRouting : private BasicRoutingInterface<DataFacadeT> {
typedef BasicRoutingInterface<DataFacadeT> super;
typedef typename DataFacadeT::EdgeData EdgeData;
typedef SearchEngineData::QueryHeap QueryHeap;
typedef std::pair<NodeID, NodeID> SearchSpaceEdge;
struct RankedCandidateNode {
RankedCandidateNode(const NodeID n, const int l, const int s) : node(n), length(l), sharing(s) {}
RankedCandidateNode(const NodeID n, const int l, const int s) :
node(n),
length(l),
sharing(s)
{ }
NodeID node;
int length;
int sharing;
@@ -53,66 +60,129 @@ class AlternativeRouting : private BasicRoutingInterface<QueryDataT> {
return (2*length + sharing) < (2*other.length + other.sharing);
}
};
const SearchGraph * search_graph;
DataFacadeT * facade;
SearchEngineData & engine_working_data;
public:
AlternativeRouting(QueryDataT & qd) : super(qd), search_graph(qd.graph) { }
AlternativeRouting(
DataFacadeT * facade,
SearchEngineData & engine_working_data
) :
super(facade),
facade(facade),
engine_working_data(engine_working_data)
{ }
~AlternativeRouting() {}
void operator()(const PhantomNodes & phantomNodePair, RawRouteData & rawRouteData) {
if(!phantomNodePair.AtLeastOnePhantomNodeIsUINTMAX() || phantomNodePair.PhantomNodesHaveEqualLocation()) {
rawRouteData.lengthOfShortestPath = rawRouteData.lengthOfAlternativePath = INT_MAX;
void operator()(
const PhantomNodes & phantom_node_pair,
RawRouteData & raw_route_data) {
if( (!phantom_node_pair.AtLeastOnePhantomNodeIsUINTMAX()) ||
phantom_node_pair.PhantomNodesHaveEqualLocation()
) {
raw_route_data.lengthOfShortestPath = INT_MAX;
raw_route_data.lengthOfAlternativePath = INT_MAX;
return;
}
std::vector<NodeID> alternativePath;
std::vector<NodeID> viaNodeCandidates;
std::vector<NodeID> alternative_path;
std::vector<NodeID> via_node_candidate_list;
std::vector<SearchSpaceEdge> forward_search_space;
std::vector<SearchSpaceEdge> reverse_search_space;
//Initialize Queues, semi-expensive because access to TSS invokes a system call
super::_queryData.InitializeOrClearFirstThreadLocalStorage();
super::_queryData.InitializeOrClearSecondThreadLocalStorage();
super::_queryData.InitializeOrClearThirdThreadLocalStorage();
//Init queues, semi-expensive because access to TSS invokes a sys-call
engine_working_data.InitializeOrClearFirstThreadLocalStorage(
super::facade->GetNumberOfNodes()
);
engine_working_data.InitializeOrClearSecondThreadLocalStorage(
super::facade->GetNumberOfNodes()
);
engine_working_data.InitializeOrClearThirdThreadLocalStorage(
super::facade->GetNumberOfNodes()
);
QueryHeap & forward_heap1 = *(super::_queryData.forwardHeap);
QueryHeap & reverse_heap1 = *(super::_queryData.backwardHeap);
QueryHeap & forward_heap2 = *(super::_queryData.forwardHeap2);
QueryHeap & reverse_heap2 = *(super::_queryData.backwardHeap2);
QueryHeap & forward_heap1 = *(engine_working_data.forwardHeap);
QueryHeap & reverse_heap1 = *(engine_working_data.backwardHeap);
QueryHeap & forward_heap2 = *(engine_working_data.forwardHeap2);
QueryHeap & reverse_heap2 = *(engine_working_data.backwardHeap2);
int upper_bound_to_shortest_path_distance = INT_MAX;
NodeID middle_node = UINT_MAX;
forward_heap1.Insert(phantomNodePair.startPhantom.edgeBasedNode, -phantomNodePair.startPhantom.weight1, phantomNodePair.startPhantom.edgeBasedNode);
if(phantomNodePair.startPhantom.isBidirected() ) {
forward_heap1.Insert(phantomNodePair.startPhantom.edgeBasedNode+1, -phantomNodePair.startPhantom.weight2, phantomNodePair.startPhantom.edgeBasedNode+1);
}
reverse_heap1.Insert(phantomNodePair.targetPhantom.edgeBasedNode, phantomNodePair.targetPhantom.weight1, phantomNodePair.targetPhantom.edgeBasedNode);
if(phantomNodePair.targetPhantom.isBidirected() ) {
reverse_heap1.Insert(phantomNodePair.targetPhantom.edgeBasedNode+1, phantomNodePair.targetPhantom.weight2, phantomNodePair.targetPhantom.edgeBasedNode+1);
forward_heap1.Insert(
phantom_node_pair.startPhantom.edgeBasedNode,
-phantom_node_pair.startPhantom.weight1,
phantom_node_pair.startPhantom.edgeBasedNode
);
if(phantom_node_pair.startPhantom.isBidirected() ) {
forward_heap1.Insert(
phantom_node_pair.startPhantom.edgeBasedNode+1,
-phantom_node_pair.startPhantom.weight2,
phantom_node_pair.startPhantom.edgeBasedNode+1
);
}
const int forward_offset = phantomNodePair.startPhantom.weight1 + (phantomNodePair.startPhantom.isBidirected() ? phantomNodePair.startPhantom.weight2 : 0);
const int reverse_offset = phantomNodePair.targetPhantom.weight1 + (phantomNodePair.targetPhantom.isBidirected() ? phantomNodePair.targetPhantom.weight2 : 0);
reverse_heap1.Insert(
phantom_node_pair.targetPhantom.edgeBasedNode,
phantom_node_pair.targetPhantom.weight1,
phantom_node_pair.targetPhantom.edgeBasedNode
);
if(phantom_node_pair.targetPhantom.isBidirected() ) {
reverse_heap1.Insert(
phantom_node_pair.targetPhantom.edgeBasedNode+1,
phantom_node_pair.targetPhantom.weight2,
phantom_node_pair.targetPhantom.edgeBasedNode+1
);
}
//exploration dijkstra from nodes s and t until deletemin/(1+epsilon) > _lengthOfShortestPath
const int forward_offset = super::ComputeEdgeOffset(
phantom_node_pair.startPhantom
);
const int reverse_offset = super::ComputeEdgeOffset(
phantom_node_pair.targetPhantom
);
//search from s and t till new_min/(1+epsilon) > length_of_shortest_path
while(0 < (forward_heap1.Size() + reverse_heap1.Size())){
if(0 < forward_heap1.Size()){
AlternativeRoutingStep<true >(forward_heap1, reverse_heap1, &middle_node, &upper_bound_to_shortest_path_distance, viaNodeCandidates, forward_search_space, forward_offset);
AlternativeRoutingStep<true>(
forward_heap1,
reverse_heap1,
&middle_node,
&upper_bound_to_shortest_path_distance,
via_node_candidate_list,
forward_search_space,
forward_offset
);
}
if(0 < reverse_heap1.Size()){
AlternativeRoutingStep<false>(reverse_heap1, forward_heap1, &middle_node, &upper_bound_to_shortest_path_distance, viaNodeCandidates, reverse_search_space, reverse_offset);
AlternativeRoutingStep<false>(
reverse_heap1,
forward_heap1,
&middle_node,
&upper_bound_to_shortest_path_distance,
via_node_candidate_list,
reverse_search_space,
reverse_offset
);
}
}
sort_unique_resize(viaNodeCandidates);
sort_unique_resize(via_node_candidate_list);
std::vector<NodeID> packed_forward_path;
std::vector<NodeID> packed_reverse_path;
super::RetrievePackedPathFromSingleHeap(forward_heap1, middle_node, packed_forward_path);
super::RetrievePackedPathFromSingleHeap(reverse_heap1, middle_node, packed_reverse_path);
super::RetrievePackedPathFromSingleHeap(
forward_heap1,
middle_node,
packed_forward_path
);
super::RetrievePackedPathFromSingleHeap(
reverse_heap1,
middle_node,
packed_reverse_path
);
boost::unordered_map<NodeID, int> approximated_forward_sharing;
boost::unordered_map<NodeID, int> approximated_reverse_sharing;
@@ -146,7 +216,7 @@ public:
}
}
std::vector<NodeID> nodes_that_passed_preselection;
BOOST_FOREACH(const NodeID node, viaNodeCandidates) {
BOOST_FOREACH(const NodeID node, via_node_candidate_list) {
int approximated_sharing = approximated_forward_sharing[node] + approximated_reverse_sharing[node];
int approximated_length = forward_heap1.GetKey(node)+reverse_heap1.GetKey(node);
bool lengthPassed = (approximated_length < upper_bound_to_shortest_path_distance*(1+VIAPATH_EPSILON));
@@ -187,17 +257,17 @@ public:
//Unpack shortest path and alternative, if they exist
if(INT_MAX != upper_bound_to_shortest_path_distance) {
super::UnpackPath(packedShortestPath, rawRouteData.computedShortestPath);
rawRouteData.lengthOfShortestPath = upper_bound_to_shortest_path_distance;
super::UnpackPath(packedShortestPath, raw_route_data.computedShortestPath);
raw_route_data.lengthOfShortestPath = upper_bound_to_shortest_path_distance;
} else {
rawRouteData.lengthOfShortestPath = INT_MAX;
raw_route_data.lengthOfShortestPath = INT_MAX;
}
if(selectedViaNode != UINT_MAX) {
retrievePackedViaPath(forward_heap1, reverse_heap1, forward_heap2, reverse_heap2, s_v_middle, v_t_middle, rawRouteData.computedAlternativePath);
rawRouteData.lengthOfAlternativePath = lengthOfViaPath;
retrievePackedViaPath(forward_heap1, reverse_heap1, forward_heap2, reverse_heap2, s_v_middle, v_t_middle, raw_route_data.computedAlternativePath);
raw_route_data.lengthOfAlternativePath = lengthOfViaPath;
} else {
rawRouteData.lengthOfAlternativePath = INT_MAX;
raw_route_data.lengthOfAlternativePath = INT_MAX;
}
}
@@ -219,12 +289,14 @@ private:
const int offset, const std::vector<NodeID> & packed_shortest_path) {
//compute and unpack <s,..,v> and <v,..,t> by exploring search spaces from v and intersecting against queues
//only half-searches have to be done at this stage
super::_queryData.InitializeOrClearSecondThreadLocalStorage();
engine_working_data.InitializeOrClearSecondThreadLocalStorage(
super::facade->GetNumberOfNodes()
);
QueryHeap & existingForwardHeap = *super::_queryData.forwardHeap;
QueryHeap & existingBackwardHeap = *super::_queryData.backwardHeap;
QueryHeap & newForwardHeap = *super::_queryData.forwardHeap2;
QueryHeap & newBackwardHeap = *super::_queryData.backwardHeap2;
QueryHeap & existingForwardHeap = *engine_working_data.forwardHeap;
QueryHeap & existingBackwardHeap = *engine_working_data.backwardHeap;
QueryHeap & newForwardHeap = *engine_working_data.forwardHeap2;
QueryHeap & newBackwardHeap = *engine_working_data.backwardHeap2;
std::vector < NodeID > packed_s_v_path;
std::vector < NodeID > packed_v_t_path;
@@ -258,8 +330,8 @@ private:
//First partially unpack s-->v until paths deviate, note length of common path.
for (unsigned i = 0, lengthOfPackedPath = std::min( packed_s_v_path.size(), packed_shortest_path.size()) - 1; (i < lengthOfPackedPath); ++i) {
if (packed_s_v_path[i] == packed_shortest_path[i] && packed_s_v_path[i + 1] == packed_shortest_path[i + 1]) {
typename SearchGraph::EdgeIterator edgeID = search_graph->FindEdgeInEitherDirection(packed_s_v_path[i], packed_s_v_path[i + 1]);
*sharing_of_via_path += search_graph->GetEdgeData(edgeID).distance;
EdgeID edgeID = facade->FindEdgeInEitherDirection(packed_s_v_path[i], packed_s_v_path[i + 1]);
*sharing_of_via_path += facade->GetEdgeData(edgeID).distance;
} else {
if (packed_s_v_path[i] == packed_shortest_path[i]) {
super::UnpackEdge(packed_s_v_path[i], packed_s_v_path[i+1], partiallyUnpackedViaPath);
@@ -270,8 +342,8 @@ private:
}
//traverse partially unpacked edge and note common prefix
for (int i = 0, lengthOfPackedPath = std::min( partiallyUnpackedViaPath.size(), partiallyUnpackedShortestPath.size()) - 1; (i < lengthOfPackedPath) && (partiallyUnpackedViaPath[i] == partiallyUnpackedShortestPath[i] && partiallyUnpackedViaPath[i+1] == partiallyUnpackedShortestPath[i+1]); ++i) {
typename SearchGraph::EdgeIterator edgeID = search_graph->FindEdgeInEitherDirection(partiallyUnpackedViaPath[i], partiallyUnpackedViaPath[i+1]);
*sharing_of_via_path += search_graph->GetEdgeData(edgeID).distance;
EdgeID edgeID = facade->FindEdgeInEitherDirection(partiallyUnpackedViaPath[i], partiallyUnpackedViaPath[i+1]);
*sharing_of_via_path += facade->GetEdgeData(edgeID).distance;
}
//Second, partially unpack v-->t in reverse order until paths deviate and note lengths
@@ -279,8 +351,8 @@ private:
int shortestPathIndex = packed_shortest_path.size() - 1;
for (; viaPathIndex > 0 && shortestPathIndex > 0; --viaPathIndex,--shortestPathIndex ) {
if (packed_v_t_path[viaPathIndex - 1] == packed_shortest_path[shortestPathIndex - 1] && packed_v_t_path[viaPathIndex] == packed_shortest_path[shortestPathIndex]) {
typename SearchGraph::EdgeIterator edgeID = search_graph->FindEdgeInEitherDirection( packed_v_t_path[viaPathIndex - 1], packed_v_t_path[viaPathIndex]);
*sharing_of_via_path += search_graph->GetEdgeData(edgeID).distance;
EdgeID edgeID = facade->FindEdgeInEitherDirection( packed_v_t_path[viaPathIndex - 1], packed_v_t_path[viaPathIndex]);
*sharing_of_via_path += facade->GetEdgeData(edgeID).distance;
} else {
if (packed_v_t_path[viaPathIndex] == packed_shortest_path[shortestPathIndex]) {
super::UnpackEdge(packed_v_t_path[viaPathIndex-1], packed_v_t_path[viaPathIndex], partiallyUnpackedViaPath);
@@ -294,8 +366,8 @@ private:
shortestPathIndex = partiallyUnpackedShortestPath.size() - 1;
for (; viaPathIndex > 0 && shortestPathIndex > 0; --viaPathIndex,--shortestPathIndex) {
if (partiallyUnpackedViaPath[viaPathIndex - 1] == partiallyUnpackedShortestPath[shortestPathIndex - 1] && partiallyUnpackedViaPath[viaPathIndex] == partiallyUnpackedShortestPath[shortestPathIndex]) {
typename SearchGraph::EdgeIterator edgeID = search_graph->FindEdgeInEitherDirection( partiallyUnpackedViaPath[viaPathIndex - 1], partiallyUnpackedViaPath[viaPathIndex]);
*sharing_of_via_path += search_graph->GetEdgeData(edgeID).distance;
EdgeID edgeID = facade->FindEdgeInEitherDirection( partiallyUnpackedViaPath[viaPathIndex - 1], partiallyUnpackedViaPath[viaPathIndex]);
*sharing_of_via_path += facade->GetEdgeData(edgeID).distance;
} else {
break;
}
@@ -315,8 +387,8 @@ private:
//compute forward sharing
while( (packedAlternativePath[aindex] == packedShortestPath[aindex]) && (packedAlternativePath[aindex+1] == packedShortestPath[aindex+1]) ) {
// SimpleLogger().Write() << "retrieving edge (" << packedAlternativePath[aindex] << "," << packedAlternativePath[aindex+1] << ")";
typename SearchGraph::EdgeIterator edgeID = search_graph->FindEdgeInEitherDirection(packedAlternativePath[aindex], packedAlternativePath[aindex+1]);
sharing += search_graph->GetEdgeData(edgeID).distance;
EdgeID edgeID = facade->FindEdgeInEitherDirection(packedAlternativePath[aindex], packedAlternativePath[aindex+1]);
sharing += facade->GetEdgeData(edgeID).distance;
++aindex;
}
@@ -324,8 +396,8 @@ private:
int bindex = packedShortestPath.size()-1;
//compute backward sharing
while( aindex > 0 && bindex > 0 && (packedAlternativePath[aindex] == packedShortestPath[bindex]) && (packedAlternativePath[aindex-1] == packedShortestPath[bindex-1]) ) {
typename SearchGraph::EdgeIterator edgeID = search_graph->FindEdgeInEitherDirection(packedAlternativePath[aindex], packedAlternativePath[aindex-1]);
sharing += search_graph->GetEdgeData(edgeID).distance;
EdgeID edgeID = facade->FindEdgeInEitherDirection(packedAlternativePath[aindex], packedAlternativePath[aindex-1]);
sharing += facade->GetEdgeData(edgeID).distance;
--aindex; --bindex;
}
return sharing;
@@ -363,12 +435,12 @@ private:
}
}
for ( typename SearchGraph::EdgeIterator edge = search_graph->BeginEdges( node ); edge < search_graph->EndEdges(node); edge++ ) {
const typename SearchGraph::EdgeData & data = search_graph->GetEdgeData(edge);
for ( EdgeID edge = facade->BeginEdges( node ); edge < facade->EndEdges(node); edge++ ) {
const EdgeData & data = facade->GetEdgeData(edge);
bool forwardDirectionFlag = (forwardDirection ? data.forward : data.backward );
if(forwardDirectionFlag) {
const NodeID to = search_graph->GetTarget(edge);
const NodeID to = facade->GetTarget(edge);
const int edgeWeight = data.distance;
assert( edgeWeight > 0 );
@@ -438,8 +510,8 @@ private:
std::stack<SearchSpaceEdge> unpackStack;
//Traverse path s-->v
for (unsigned i = packed_s_v_path.size() - 1; (i > 0) && unpackStack.empty(); --i) {
typename SearchGraph::EdgeIterator edgeID = search_graph->FindEdgeInEitherDirection( packed_s_v_path[i - 1], packed_s_v_path[i]);
int lengthOfCurrentEdge = search_graph->GetEdgeData(edgeID).distance;
EdgeID edgeID = facade->FindEdgeInEitherDirection( packed_s_v_path[i - 1], packed_s_v_path[i]);
int lengthOfCurrentEdge = facade->GetEdgeData(edgeID).distance;
if (lengthOfCurrentEdge + unpackedUntilDistance >= T_threshold) {
unpackStack.push(std::make_pair(packed_s_v_path[i - 1], packed_s_v_path[i]));
} else {
@@ -451,15 +523,15 @@ private:
while (!unpackStack.empty()) {
const SearchSpaceEdge viaPathEdge = unpackStack.top();
unpackStack.pop();
typename SearchGraph::EdgeIterator edgeIDInViaPath = search_graph->FindEdgeInEitherDirection(viaPathEdge.first, viaPathEdge.second);
EdgeID edgeIDInViaPath = facade->FindEdgeInEitherDirection(viaPathEdge.first, viaPathEdge.second);
if(UINT_MAX == edgeIDInViaPath)
return false;
typename SearchGraph::EdgeData currentEdgeData = search_graph->GetEdgeData(edgeIDInViaPath);
EdgeData currentEdgeData = facade->GetEdgeData(edgeIDInViaPath);
bool IsViaEdgeShortCut = currentEdgeData.shortcut;
if (IsViaEdgeShortCut) {
const NodeID middleOfViaPath = currentEdgeData.id;
typename SearchGraph::EdgeIterator edgeIDOfSecondSegment = search_graph->FindEdgeInEitherDirection(middleOfViaPath, viaPathEdge.second);
int lengthOfSecondSegment = search_graph->GetEdgeData(edgeIDOfSecondSegment).distance;
EdgeID edgeIDOfSecondSegment = facade->FindEdgeInEitherDirection(middleOfViaPath, viaPathEdge.second);
int lengthOfSecondSegment = facade->GetEdgeData(edgeIDOfSecondSegment).distance;
//attention: !unpacking in reverse!
//Check if second segment is the one to go over treshold? if yes add second segment to stack, else push first segment to stack and add distance of second one.
if (unpackedUntilDistance + lengthOfSecondSegment >= T_threshold) {
@@ -479,8 +551,8 @@ private:
unpackedUntilDistance = 0;
//Traverse path s-->v
for (unsigned i = 0, lengthOfPackedPath = packed_v_t_path.size() - 1; (i < lengthOfPackedPath) && unpackStack.empty(); ++i) {
typename SearchGraph::EdgeIterator edgeID = search_graph->FindEdgeInEitherDirection( packed_v_t_path[i], packed_v_t_path[i + 1]);
int lengthOfCurrentEdge = search_graph->GetEdgeData(edgeID).distance;
EdgeID edgeID = facade->FindEdgeInEitherDirection( packed_v_t_path[i], packed_v_t_path[i + 1]);
int lengthOfCurrentEdge = facade->GetEdgeData(edgeID).distance;
if (lengthOfCurrentEdge + unpackedUntilDistance >= T_threshold) {
unpackStack.push( std::make_pair(packed_v_t_path[i], packed_v_t_path[i + 1]));
} else {
@@ -492,15 +564,15 @@ private:
while (!unpackStack.empty()) {
const SearchSpaceEdge viaPathEdge = unpackStack.top();
unpackStack.pop();
typename SearchGraph::EdgeIterator edgeIDInViaPath = search_graph->FindEdgeInEitherDirection(viaPathEdge.first, viaPathEdge.second);
EdgeID edgeIDInViaPath = facade->FindEdgeInEitherDirection(viaPathEdge.first, viaPathEdge.second);
if(UINT_MAX == edgeIDInViaPath)
return false;
typename SearchGraph::EdgeData currentEdgeData = search_graph->GetEdgeData(edgeIDInViaPath);
EdgeData currentEdgeData = facade->GetEdgeData(edgeIDInViaPath);
const bool IsViaEdgeShortCut = currentEdgeData.shortcut;
if (IsViaEdgeShortCut) {
const NodeID middleOfViaPath = currentEdgeData.id;
typename SearchGraph::EdgeIterator edgeIDOfFirstSegment = search_graph->FindEdgeInEitherDirection(viaPathEdge.first, middleOfViaPath);
int lengthOfFirstSegment = search_graph->GetEdgeData( edgeIDOfFirstSegment).distance;
EdgeID edgeIDOfFirstSegment = facade->FindEdgeInEitherDirection(viaPathEdge.first, middleOfViaPath);
int lengthOfFirstSegment = facade->GetEdgeData( edgeIDOfFirstSegment).distance;
//Check if first segment is the one to go over treshold? if yes first segment to stack, else push second segment to stack and add distance of first one.
if (unpackedUntilDistance + lengthOfFirstSegment >= T_threshold) {
unpackStack.push( std::make_pair(viaPathEdge.first, middleOfViaPath));
@@ -517,10 +589,12 @@ private:
lengthOfPathT_Test_Path += unpackedUntilDistance;
//Run actual T-Test query and compare if distances equal.
super::_queryData.InitializeOrClearThirdThreadLocalStorage();
engine_working_data.InitializeOrClearThirdThreadLocalStorage(
super::facade->GetNumberOfNodes()
);
QueryHeap& forward_heap3 = *super::_queryData.forwardHeap3;
QueryHeap& backward_heap3 = *super::_queryData.backwardHeap3;
QueryHeap& forward_heap3 = *engine_working_data.forwardHeap3;
QueryHeap& backward_heap3 = *engine_working_data.backwardHeap3;
int _upperBound = INT_MAX;
NodeID middle = UINT_MAX;
forward_heap3.Insert(s_P, 0, s_P);
+198 -115
View File
@@ -29,135 +29,180 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define BASICROUTINGINTERFACE_H_
#include "../DataStructures/RawRouteData.h"
#include "../DataStructures/SearchEngineData.h"
#include "../Util/ContainerUtils.h"
#include "../Util/SimpleLogger.h"
#include <boost/assert.hpp>
#include <boost/noncopyable.hpp>
#include <cassert>
#include <climits>
#include <stack>
template<class QueryDataT>
class BasicRoutingInterface : boost::noncopyable{
SearchEngineData::SearchEngineHeapPtr SearchEngineData::forwardHeap;
SearchEngineData::SearchEngineHeapPtr SearchEngineData::backwardHeap;
SearchEngineData::SearchEngineHeapPtr SearchEngineData::forwardHeap2;
SearchEngineData::SearchEngineHeapPtr SearchEngineData::backwardHeap2;
SearchEngineData::SearchEngineHeapPtr SearchEngineData::forwardHeap3;
SearchEngineData::SearchEngineHeapPtr SearchEngineData::backwardHeap3;
template<class DataFacadeT>
class BasicRoutingInterface : boost::noncopyable {
private:
typedef typename DataFacadeT::EdgeData EdgeData;
protected:
QueryDataT & _queryData;
DataFacadeT * facade;
public:
BasicRoutingInterface(QueryDataT & qd) : _queryData(qd) { }
BasicRoutingInterface( DataFacadeT * facade ) : facade(facade) { }
virtual ~BasicRoutingInterface(){ };
inline void RoutingStep(typename QueryDataT::QueryHeap & _forwardHeap, typename QueryDataT::QueryHeap & _backwardHeap, NodeID *middle, int *_upperbound, const int edgeBasedOffset, const bool forwardDirection) const {
const NodeID node = _forwardHeap.DeleteMin();
const int distance = _forwardHeap.GetKey(node);
//SimpleLogger().Write() << "Settled (" << _forwardHeap.GetData( node ).parent << "," << node << ")=" << distance;
if(_backwardHeap.WasInserted(node) ){
const int newDistance = _backwardHeap.GetKey(node) + distance;
if(newDistance < *_upperbound ){
if(newDistance>=0 ) {
*middle = node;
*_upperbound = newDistance;
} else {
inline void RoutingStep(
SearchEngineData::QueryHeap & forward_heap,
SearchEngineData::QueryHeap & reverse_heap,
NodeID * middle_node_id,
int * upper_bound,
const int edge_expansion_offset,
const bool forward_direction
) const {
const NodeID node = forward_heap.DeleteMin();
const int distance = forward_heap.GetKey(node);
//SimpleLogger().Write() << "Settled (" << forward_heap.GetData( node ).parent << "," << node << ")=" << distance;
if(reverse_heap.WasInserted(node) ){
const int new_distance = reverse_heap.GetKey(node) + distance;
if(new_distance < *upper_bound ){
if( new_distance >= 0 ) {
*middle_node_id = node;
*upper_bound = new_distance;
}
}
}
if(distance-edgeBasedOffset > *_upperbound){
_forwardHeap.DeleteAll();
if( (distance-edge_expansion_offset) > *upper_bound ){
forward_heap.DeleteAll();
return;
}
//Stalling
for ( typename QueryDataT::Graph::EdgeIterator edge = _queryData.graph->BeginEdges( node ); edge < _queryData.graph->EndEdges(node); ++edge ) {
const typename QueryDataT::Graph::EdgeData & data = _queryData.graph->GetEdgeData(edge);
bool backwardDirectionFlag = (!forwardDirection) ? data.forward : data.backward;
if(backwardDirectionFlag) {
const NodeID to = _queryData.graph->GetTarget(edge);
const int edgeWeight = data.distance;
for(
EdgeID edge = facade->BeginEdges( node );
edge < facade->EndEdges(node);
++edge
) {
const EdgeData & data = facade->GetEdgeData(edge);
const bool reverse_flag = (!forward_direction) ? data.forward : data.backward;
if( reverse_flag ) {
const NodeID to = facade->GetTarget(edge);
const int edge_weight = data.distance;
assert( edgeWeight > 0 );
BOOST_ASSERT_MSG( edge_weight > 0, "edge_weight invalid" );
if(_forwardHeap.WasInserted( to )) {
if(_forwardHeap.GetKey( to ) + edgeWeight < distance) {
if(forward_heap.WasInserted( to )) {
if(forward_heap.GetKey( to ) + edge_weight < distance) {
return;
}
}
}
}
for ( typename QueryDataT::Graph::EdgeIterator edge = _queryData.graph->BeginEdges( node ); edge < _queryData.graph->EndEdges(node); ++edge ) {
const typename QueryDataT::Graph::EdgeData & data = _queryData.graph->GetEdgeData(edge);
bool forwardDirectionFlag = (forwardDirection ? data.forward : data.backward );
if(forwardDirectionFlag) {
for(
EdgeID edge = facade->BeginEdges(node), end_edge = facade->EndEdges(node);
edge < end_edge;
++edge
) {
const EdgeData & data = facade->GetEdgeData(edge);
bool forward_directionFlag = (forward_direction ? data.forward : data.backward );
if( forward_directionFlag ) {
const NodeID to = _queryData.graph->GetTarget(edge);
const int edgeWeight = data.distance;
const NodeID to = facade->GetTarget(edge);
const int edge_weight = data.distance;
assert( edgeWeight > 0 );
const int toDistance = distance + edgeWeight;
BOOST_ASSERT_MSG( edge_weight > 0, "edge_weight invalid" );
const int to_distance = distance + edge_weight;
//New Node discovered -> Add to Heap + Node Info Storage
if ( !_forwardHeap.WasInserted( to ) ) {
_forwardHeap.Insert( to, toDistance, node );
if ( !forward_heap.WasInserted( to ) ) {
forward_heap.Insert( to, to_distance, node );
}
//Found a shorter Path -> Update distance
else if ( toDistance < _forwardHeap.GetKey( to ) ) {
_forwardHeap.GetData( to ).parent = node;
_forwardHeap.DecreaseKey( to, toDistance );
else if ( to_distance < forward_heap.GetKey( to ) ) {
forward_heap.GetData( to ).parent = node;
forward_heap.DecreaseKey( to, to_distance );
//new parent
}
}
}
}
inline void UnpackPath(const std::vector<NodeID> & packedPath, std::vector<_PathData> & unpackedPath) const {
const unsigned sizeOfPackedPath = packedPath.size();
std::stack<std::pair<NodeID, NodeID> > recursionStack;
inline void UnpackPath(
const std::vector<NodeID> & packed_path,
std::vector<_PathData> & unpacked_path
) const {
const unsigned packed_path_size = packed_path.size();
std::stack<std::pair<NodeID, NodeID> > recursion_stack;
//We have to push the path in reverse order onto the stack because it's LIFO.
for(unsigned i = sizeOfPackedPath-1; i > 0; --i){
recursionStack.push(std::make_pair(packedPath[i-1], packedPath[i]));
for(unsigned i = packed_path_size-1; i > 0; --i){
recursion_stack.push(
std::make_pair(packed_path[i-1], packed_path[i])
);
}
std::pair<NodeID, NodeID> edge;
while(!recursionStack.empty()) {
edge = recursionStack.top();
recursionStack.pop();
while(!recursion_stack.empty()) {
edge = recursion_stack.top();
recursion_stack.pop();
typename QueryDataT::Graph::EdgeIterator smallestEdge = SPECIAL_EDGEID;
int smallestWeight = INT_MAX;
for(typename QueryDataT::Graph::EdgeIterator eit = _queryData.graph->BeginEdges(edge.first);eit < _queryData.graph->EndEdges(edge.first);++eit){
const int weight = _queryData.graph->GetEdgeData(eit).distance;
if(_queryData.graph->GetTarget(eit) == edge.second && weight < smallestWeight && _queryData.graph->GetEdgeData(eit).forward){
smallestEdge = eit;
smallestWeight = weight;
EdgeID smaller_edge_id = SPECIAL_EDGEID;
int edge_weight = INT_MAX;
for(
EdgeID edge_id = facade->BeginEdges(edge.first);
edge_id < facade->EndEdges(edge.first);
++edge_id
){
const int weight = facade->GetEdgeData(edge_id).distance;
if(
(facade->GetTarget(edge_id) == edge.second) &&
(weight < edge_weight) &&
facade->GetEdgeData(edge_id).forward
){
smaller_edge_id = edge_id;
edge_weight = weight;
}
}
if(smallestEdge == SPECIAL_EDGEID){
for(typename QueryDataT::Graph::EdgeIterator eit = _queryData.graph->BeginEdges(edge.second);eit < _queryData.graph->EndEdges(edge.second);++eit){
const int weight = _queryData.graph->GetEdgeData(eit).distance;
if(_queryData.graph->GetTarget(eit) == edge.first && weight < smallestWeight && _queryData.graph->GetEdgeData(eit).backward){
smallestEdge = eit;
smallestWeight = weight;
if( SPECIAL_EDGEID == smaller_edge_id ){
for(
EdgeID edge_id = facade->BeginEdges(edge.second);
edge_id < facade->EndEdges(edge.second);
++edge_id
){
const int weight = facade->GetEdgeData(edge_id).distance;
if(
(facade->GetTarget(edge_id) == edge.first) &&
(weight < edge_weight) &&
facade->GetEdgeData(edge_id).backward
){
smaller_edge_id = edge_id;
edge_weight = weight;
}
}
}
assert(smallestWeight != INT_MAX);
BOOST_ASSERT_MSG(edge_weight != INT_MAX, "edge id invalid");
const typename QueryDataT::Graph::EdgeData& ed = _queryData.graph->GetEdgeData(smallestEdge);
if(ed.shortcut) {//unpack
const NodeID middle = ed.id;
const EdgeData& ed = facade->GetEdgeData(smaller_edge_id);
if( ed.shortcut ) {//unpack
const NodeID middle_node_id = ed.id;
//again, we need to this in reversed order
recursionStack.push(std::make_pair(middle, edge.second));
recursionStack.push(std::make_pair(edge.first, middle));
recursion_stack.push(std::make_pair(middle_node_id, edge.second));
recursion_stack.push(std::make_pair(edge.first, middle_node_id));
} else {
assert(!ed.shortcut);
unpackedPath.push_back(
BOOST_ASSERT_MSG(!ed.shortcut, "edge must be a shortcut");
unpacked_path.push_back(
_PathData(
ed.id,
_queryData.nodeHelpDesk->GetNameIndexFromEdgeID(ed.id),
_queryData.nodeHelpDesk->GetTurnInstructionForEdgeID(ed.id),
facade->GetNameIndexFromEdgeID(ed.id),
facade->GetTurnInstructionForEdgeID(ed.id),
ed.distance
)
);
@@ -165,74 +210,112 @@ public:
}
}
inline void UnpackEdge(const NodeID s, const NodeID t, std::vector<NodeID> & unpackedPath) const {
std::stack<std::pair<NodeID, NodeID> > recursionStack;
recursionStack.push(std::make_pair(s,t));
inline void UnpackEdge(
const NodeID s,
const NodeID t,
std::vector<NodeID> & unpacked_path
) const {
std::stack<std::pair<NodeID, NodeID> > recursion_stack;
recursion_stack.push(std::make_pair(s,t));
std::pair<NodeID, NodeID> edge;
while(!recursionStack.empty()) {
edge = recursionStack.top();
recursionStack.pop();
while(!recursion_stack.empty()) {
edge = recursion_stack.top();
recursion_stack.pop();
typename QueryDataT::Graph::EdgeIterator smallestEdge = SPECIAL_EDGEID;
int smallestWeight = INT_MAX;
for(typename QueryDataT::Graph::EdgeIterator eit = _queryData.graph->BeginEdges(edge.first);eit < _queryData.graph->EndEdges(edge.first);++eit){
const int weight = _queryData.graph->GetEdgeData(eit).distance;
if(_queryData.graph->GetTarget(eit) == edge.second && weight < smallestWeight && _queryData.graph->GetEdgeData(eit).forward){
smallestEdge = eit;
smallestWeight = weight;
EdgeID smaller_edge_id = SPECIAL_EDGEID;
int edge_weight = INT_MAX;
for(
EdgeID edge_id = facade->BeginEdges(edge.first);
edge_id < facade->EndEdges(edge.first);
++edge_id
){
const int weight = facade->GetEdgeData(edge_id).distance;
if(
(facade->GetTarget(edge_id) == edge.second) &&
(weight < edge_weight) &&
facade->GetEdgeData(edge_id).forward
){
smaller_edge_id = edge_id;
edge_weight = weight;
}
}
if(smallestEdge == SPECIAL_EDGEID){
for(typename QueryDataT::Graph::EdgeIterator eit = _queryData.graph->BeginEdges(edge.second);eit < _queryData.graph->EndEdges(edge.second);++eit){
const int weight = _queryData.graph->GetEdgeData(eit).distance;
if(_queryData.graph->GetTarget(eit) == edge.first && weight < smallestWeight && _queryData.graph->GetEdgeData(eit).backward){
smallestEdge = eit;
smallestWeight = weight;
if( SPECIAL_EDGEID == smaller_edge_id ){
for(
EdgeID edge_id = facade->BeginEdges(edge.second);
edge_id < facade->EndEdges(edge.second);
++edge_id
){
const int weight = facade->GetEdgeData(edge_id).distance;
if(
(facade->GetTarget(edge_id) == edge.first) &&
(weight < edge_weight) &&
facade->GetEdgeData(edge_id).backward
){
smaller_edge_id = edge_id;
edge_weight = weight;
}
}
}
assert(smallestWeight != INT_MAX);
BOOST_ASSERT_MSG(edge_weight != INT_MAX, "edge weight invalid");
const typename QueryDataT::Graph::EdgeData& ed = _queryData.graph->GetEdgeData(smallestEdge);
const EdgeData& ed = facade->GetEdgeData(smaller_edge_id);
if(ed.shortcut) {//unpack
const NodeID middle = ed.id;
const NodeID middle_node_id = ed.id;
//again, we need to this in reversed order
recursionStack.push(std::make_pair(middle, edge.second));
recursionStack.push(std::make_pair(edge.first, middle));
recursion_stack.push(
std::make_pair(middle_node_id, edge.second)
);
recursion_stack.push(
std::make_pair(edge.first, middle_node_id)
);
} else {
assert(!ed.shortcut);
unpackedPath.push_back(edge.first );
BOOST_ASSERT_MSG(!ed.shortcut, "edge must be shortcut");
unpacked_path.push_back(edge.first );
}
}
unpackedPath.push_back(t);
unpacked_path.push_back(t);
}
inline void RetrievePackedPathFromHeap(typename QueryDataT::QueryHeap & _fHeap, typename QueryDataT::QueryHeap & _bHeap, const NodeID middle, std::vector<NodeID>& packedPath) const {
NodeID pathNode = middle;
while(pathNode != _fHeap.GetData(pathNode).parent) {
pathNode = _fHeap.GetData(pathNode).parent;
packedPath.push_back(pathNode);
inline void RetrievePackedPathFromHeap(
SearchEngineData::QueryHeap & forward_heap,
SearchEngineData::QueryHeap & reverse_heap,
const NodeID middle_node_id,
std::vector<NodeID> & packed_path
) const {
NodeID current_node_id = middle_node_id;
while(current_node_id != forward_heap.GetData(current_node_id).parent) {
current_node_id = forward_heap.GetData(current_node_id).parent;
packed_path.push_back(current_node_id);
}
std::reverse(packedPath.begin(), packedPath.end());
packedPath.push_back(middle);
pathNode = middle;
while (pathNode != _bHeap.GetData(pathNode).parent){
pathNode = _bHeap.GetData(pathNode).parent;
packedPath.push_back(pathNode);
std::reverse(packed_path.begin(), packed_path.end());
packed_path.push_back(middle_node_id);
current_node_id = middle_node_id;
while (current_node_id != reverse_heap.GetData(current_node_id).parent){
current_node_id = reverse_heap.GetData(current_node_id).parent;
packed_path.push_back(current_node_id);
}
}
inline void RetrievePackedPathFromSingleHeap(typename QueryDataT::QueryHeap & search_heap, const NodeID middle, std::vector<NodeID>& packed_path) const {
NodeID pathNode = middle;
while(pathNode != search_heap.GetData(pathNode).parent) {
pathNode = search_heap.GetData(pathNode).parent;
packed_path.push_back(pathNode);
//TODO: reorder parameters
inline void RetrievePackedPathFromSingleHeap(
SearchEngineData::QueryHeap & search_heap,
const NodeID middle_node_id,
std::vector<NodeID>& packed_path
) const {
NodeID current_node_id = middle_node_id;
while(current_node_id != search_heap.GetData(current_node_id).parent) {
current_node_id = search_heap.GetData(current_node_id).parent;
packed_path.push_back(current_node_id);
}
}
int ComputeEdgeOffset(const PhantomNode & phantom) const {
return phantom.weight1 + (phantom.isBidirected() ? phantom.weight2 : 0);
}
};
#endif /* BASICROUTINGINTERFACE_H_ */
+232 -94
View File
@@ -28,176 +28,314 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef SHORTESTPATHROUTING_H_
#define SHORTESTPATHROUTING_H_
#include "BasicRoutingInterface.h"
#include <boost/assert.hpp>
#include "BasicRoutingInterface.h"
#include "../DataStructures/SearchEngineData.h"
template<class DataFacadeT>
class ShortestPathRouting : public BasicRoutingInterface<DataFacadeT>{
typedef BasicRoutingInterface<DataFacadeT> super;
typedef SearchEngineData::QueryHeap QueryHeap;
SearchEngineData & engine_working_data;
template<class QueryDataT>
class ShortestPathRouting : public BasicRoutingInterface<QueryDataT>{
typedef BasicRoutingInterface<QueryDataT> super;
typedef typename QueryDataT::QueryHeap QueryHeap;
public:
ShortestPathRouting( QueryDataT & qd) : super(qd) {}
ShortestPathRouting(
DataFacadeT * facade,
SearchEngineData & engine_working_data
) :
super(facade),
engine_working_data(engine_working_data)
{}
~ShortestPathRouting() {}
void operator()(std::vector<PhantomNodes> & phantomNodesVector, RawRouteData & rawRouteData) const {
BOOST_FOREACH(const PhantomNodes & phantomNodePair, phantomNodesVector) {
if(!phantomNodePair.AtLeastOnePhantomNodeIsUINTMAX()) {
rawRouteData.lengthOfShortestPath = rawRouteData.lengthOfAlternativePath = INT_MAX;
void operator()(
std::vector<PhantomNodes> & phantom_nodes_vector,
RawRouteData & raw_route_data
) const {
BOOST_FOREACH(
const PhantomNodes & phantom_node_pair,
phantom_nodes_vector
){
if(!phantom_node_pair.AtLeastOnePhantomNodeIsUINTMAX()) {
raw_route_data.lengthOfShortestPath = INT_MAX;
raw_route_data.lengthOfAlternativePath = INT_MAX;
return;
}
}
int distance1 = 0;
int distance2 = 0;
bool searchFrom1stStartNode = true;
bool searchFrom2ndStartNode = true;
bool search_from_1st_node = true;
bool search_from_2nd_node = true;
NodeID middle1 = UINT_MAX;
NodeID middle2 = UINT_MAX;
std::vector<NodeID> packedPath1;
std::vector<NodeID> packedPath2;
std::vector<NodeID> packed_path1;
std::vector<NodeID> packed_path2;
super::_queryData.InitializeOrClearFirstThreadLocalStorage();
super::_queryData.InitializeOrClearSecondThreadLocalStorage();
super::_queryData.InitializeOrClearThirdThreadLocalStorage();
engine_working_data.InitializeOrClearFirstThreadLocalStorage(
super::facade->GetNumberOfNodes()
);
engine_working_data.InitializeOrClearSecondThreadLocalStorage(
super::facade->GetNumberOfNodes()
);
engine_working_data.InitializeOrClearThirdThreadLocalStorage(
super::facade->GetNumberOfNodes()
);
QueryHeap & forward_heap1 = *(super::_queryData.forwardHeap);
QueryHeap & reverse_heap1 = *(super::_queryData.backwardHeap);
QueryHeap & forward_heap2 = *(super::_queryData.forwardHeap2);
QueryHeap & reverse_heap2 = *(super::_queryData.backwardHeap2);
QueryHeap & forward_heap1 = *(engine_working_data.forwardHeap);
QueryHeap & reverse_heap1 = *(engine_working_data.backwardHeap);
QueryHeap & forward_heap2 = *(engine_working_data.forwardHeap2);
QueryHeap & reverse_heap2 = *(engine_working_data.backwardHeap2);
//Get distance to next pair of target nodes.
BOOST_FOREACH(const PhantomNodes & phantomNodePair, phantomNodesVector) {
BOOST_FOREACH(
const PhantomNodes & phantom_node_pair,
phantom_nodes_vector
){
forward_heap1.Clear(); forward_heap2.Clear();
reverse_heap1.Clear(); reverse_heap2.Clear();
int _localUpperbound1 = INT_MAX;
int _localUpperbound2 = INT_MAX;
int local_upper_bound1 = INT_MAX;
int local_upper_bound2 = INT_MAX;
middle1 = UINT_MAX;
middle2 = UINT_MAX;
//insert new starting nodes into forward heap, adjusted by previous distances.
if(searchFrom1stStartNode) {
forward_heap1.Insert(phantomNodePair.startPhantom.edgeBasedNode, distance1-phantomNodePair.startPhantom.weight1, phantomNodePair.startPhantom.edgeBasedNode);
// INFO("fw1: " << phantomNodePair.startPhantom.edgeBasedNode << "´, w: " << -phantomNodePair.startPhantom.weight1);
forward_heap2.Insert(phantomNodePair.startPhantom.edgeBasedNode, distance1-phantomNodePair.startPhantom.weight1, phantomNodePair.startPhantom.edgeBasedNode);
// INFO("fw2: " << phantomNodePair.startPhantom.edgeBasedNode << "´, w: " << -phantomNodePair.startPhantom.weight1);
if(search_from_1st_node) {
forward_heap1.Insert(
phantom_node_pair.startPhantom.edgeBasedNode,
distance1-phantom_node_pair.startPhantom.weight1,
phantom_node_pair.startPhantom.edgeBasedNode
);
// INFO("fw1: " << phantom_node_pair.startPhantom.edgeBasedNode << "´, w: " << -phantomNodePair.startPhantom.weight1);
forward_heap2.Insert(
phantom_node_pair.startPhantom.edgeBasedNode,
distance1-phantom_node_pair.startPhantom.weight1,
phantom_node_pair.startPhantom.edgeBasedNode
);
// INFO("fw2: " << phantom_node_pair.startPhantom.edgeBasedNode << "´, w: " << -phantomNodePair.startPhantom.weight1);
}
if(phantomNodePair.startPhantom.isBidirected() && searchFrom2ndStartNode) {
forward_heap1.Insert(phantomNodePair.startPhantom.edgeBasedNode+1, distance2-phantomNodePair.startPhantom.weight2, phantomNodePair.startPhantom.edgeBasedNode+1);
// INFO("fw1: " << phantomNodePair.startPhantom.edgeBasedNode+1 << "´, w: " << -phantomNodePair.startPhantom.weight2);
forward_heap2.Insert(phantomNodePair.startPhantom.edgeBasedNode+1, distance2-phantomNodePair.startPhantom.weight2, phantomNodePair.startPhantom.edgeBasedNode+1);
// INFO("fw2: " << phantomNodePair.startPhantom.edgeBasedNode+1 << "´, w: " << -phantomNodePair.startPhantom.weight2);
if(phantom_node_pair.startPhantom.isBidirected() && search_from_2nd_node) {
forward_heap1.Insert(
phantom_node_pair.startPhantom.edgeBasedNode+1,
distance2-phantom_node_pair.startPhantom.weight2,
phantom_node_pair.startPhantom.edgeBasedNode+1
);
// INFO("fw1: " << phantom_node_pair.startPhantom.edgeBasedNode+1 << "´, w: " << -phantomNodePair.startPhantom.weight2);
forward_heap2.Insert(
phantom_node_pair.startPhantom.edgeBasedNode+1,
distance2-phantom_node_pair.startPhantom.weight2,
phantom_node_pair.startPhantom.edgeBasedNode+1
);
// INFO("fw2: " << phantom_node_pair.startPhantom.edgeBasedNode+1 << "´, w: " << -phantomNodePair.startPhantom.weight2);
}
//insert new backward nodes into backward heap, unadjusted.
reverse_heap1.Insert(phantomNodePair.targetPhantom.edgeBasedNode, phantomNodePair.targetPhantom.weight1, phantomNodePair.targetPhantom.edgeBasedNode);
// INFO("rv1: " << phantomNodePair.targetPhantom.edgeBasedNode << ", w;" << phantomNodePair.targetPhantom.weight1 );
if(phantomNodePair.targetPhantom.isBidirected() ) {
reverse_heap2.Insert(phantomNodePair.targetPhantom.edgeBasedNode+1, phantomNodePair.targetPhantom.weight2, phantomNodePair.targetPhantom.edgeBasedNode+1);
// INFO("rv2: " << phantomNodePair.targetPhantom.edgeBasedNode+1 << ", w;" << phantomNodePair.targetPhantom.weight2 );
reverse_heap1.Insert(
phantom_node_pair.targetPhantom.edgeBasedNode,
phantom_node_pair.targetPhantom.weight1,
phantom_node_pair.targetPhantom.edgeBasedNode
);
// INFO("rv1: " << phantom_node_pair.targetPhantom.edgeBasedNode << ", w;" << phantom_node_pair.targetPhantom.weight1 );
if(phantom_node_pair.targetPhantom.isBidirected() ) {
reverse_heap2.Insert(
phantom_node_pair.targetPhantom.edgeBasedNode+1,
phantom_node_pair.targetPhantom.weight2,
phantom_node_pair.targetPhantom.edgeBasedNode+1
);
// INFO("rv2: " << phantom_node_pair.targetPhantom.edgeBasedNode+1 << ", w;" << phantom_node_pair.targetPhantom.weight2 );
}
const int forward_offset = phantomNodePair.startPhantom.weight1 + (phantomNodePair.startPhantom.isBidirected() ? phantomNodePair.startPhantom.weight2 : 0);
const int reverse_offset = phantomNodePair.targetPhantom.weight1 + (phantomNodePair.targetPhantom.isBidirected() ? phantomNodePair.targetPhantom.weight2 : 0);
const int forward_offset = super::ComputeEdgeOffset(
phantom_node_pair.startPhantom
);
const int reverse_offset = super::ComputeEdgeOffset(
phantom_node_pair.targetPhantom
);
//run two-Target Dijkstra routing step.
while(0 < (forward_heap1.Size() + reverse_heap1.Size() )){
if(0 < forward_heap1.Size()){
super::RoutingStep(forward_heap1, reverse_heap1, &middle1, &_localUpperbound1, forward_offset, true);
if( !forward_heap1.Empty()){
super::RoutingStep(
forward_heap1,
reverse_heap1,
&middle1,
&local_upper_bound1,
forward_offset,
true
);
}
if(0 < reverse_heap1.Size() ){
super::RoutingStep(reverse_heap1, forward_heap1, &middle1, &_localUpperbound1, reverse_offset, false);
if( !reverse_heap1.Empty() ){
super::RoutingStep(
reverse_heap1,
forward_heap1,
&middle1,
&local_upper_bound1,
reverse_offset,
false
);
}
}
if(0 < reverse_heap2.Size()) {
if( !reverse_heap2.Empty() ) {
while(0 < (forward_heap2.Size() + reverse_heap2.Size() )){
if(0 < forward_heap2.Size()){
super::RoutingStep(forward_heap2, reverse_heap2, &middle2, &_localUpperbound2, forward_offset, true);
if( !forward_heap2.Empty() ){
super::RoutingStep(
forward_heap2,
reverse_heap2,
&middle2,
&local_upper_bound2,
forward_offset,
true
);
}
if(0 < reverse_heap2.Size()){
super::RoutingStep(reverse_heap2, forward_heap2, &middle2, &_localUpperbound2, reverse_offset, false);
if( !reverse_heap2.Empty() ){
super::RoutingStep(
reverse_heap2,
forward_heap2,
&middle2,
&local_upper_bound2,
reverse_offset,
false
);
}
}
}
//No path found for both target nodes?
if((INT_MAX == _localUpperbound1) && (INT_MAX == _localUpperbound2)) {
rawRouteData.lengthOfShortestPath = rawRouteData.lengthOfAlternativePath = INT_MAX;
if(
(INT_MAX == local_upper_bound1) &&
(INT_MAX == local_upper_bound2)
) {
raw_route_data.lengthOfShortestPath = INT_MAX;
raw_route_data.lengthOfAlternativePath = INT_MAX;
return;
}
if(UINT_MAX == middle1) {
searchFrom1stStartNode = false;
search_from_1st_node = false;
}
if(UINT_MAX == middle2) {
searchFrom2ndStartNode = false;
search_from_2nd_node = false;
}
//Was at most one of the two paths not found?
assert(!(INT_MAX == distance1 && INT_MAX == distance2));
BOOST_ASSERT_MSG(
(INT_MAX != distance1 || INT_MAX != distance2),
"no path found"
);
//Unpack paths if they exist
std::vector<NodeID> temporaryPackedPath1;
std::vector<NodeID> temporaryPackedPath2;
if(INT_MAX != _localUpperbound1) {
super::RetrievePackedPathFromHeap(forward_heap1, reverse_heap1, middle1, temporaryPackedPath1);
std::vector<NodeID> temporary_packed_path1;
std::vector<NodeID> temporary_packed_path2;
if(INT_MAX != local_upper_bound1) {
super::RetrievePackedPathFromHeap(
forward_heap1,
reverse_heap1,
middle1,
temporary_packed_path1
);
}
if(INT_MAX != _localUpperbound2) {
super::RetrievePackedPathFromHeap(forward_heap2, reverse_heap2, middle2, temporaryPackedPath2);
if(INT_MAX != local_upper_bound2) {
super::RetrievePackedPathFromHeap(
forward_heap2,
reverse_heap2,
middle2,
temporary_packed_path2
);
}
//if one of the paths was not found, replace it with the other one.
if(0 == temporaryPackedPath1.size()) {
temporaryPackedPath1.insert(temporaryPackedPath1.end(), temporaryPackedPath2.begin(), temporaryPackedPath2.end());
_localUpperbound1 = _localUpperbound2;
if( temporary_packed_path1.empty() ) {
temporary_packed_path1.insert(
temporary_packed_path1.end(),
temporary_packed_path2.begin(),
temporary_packed_path2.end()
);
local_upper_bound1 = local_upper_bound2;
}
if(0 == temporaryPackedPath2.size()) {
temporaryPackedPath2.insert(temporaryPackedPath2.end(), temporaryPackedPath1.begin(), temporaryPackedPath1.end());
_localUpperbound2 = _localUpperbound1;
if( temporary_packed_path2.empty() ) {
temporary_packed_path2.insert(
temporary_packed_path2.end(),
temporary_packed_path1.begin(),
temporary_packed_path1.end()
);
local_upper_bound2 = local_upper_bound1;
}
assert(0 < temporaryPackedPath1.size() && 0 < temporaryPackedPath2.size());
BOOST_ASSERT_MSG(
!temporary_packed_path1.empty() ||
!temporary_packed_path2.empty(),
"tempory packed paths empty"
);
//Plug paths together, s.t. end of packed path is begin of temporary packed path
if(0 < packedPath1.size() && 0 < packedPath2.size() ) {
if( *(temporaryPackedPath1.begin()) == *(temporaryPackedPath2.begin())) {
//both new route segments start with the same node, thus one of the packedPath must go.
assert( (packedPath1.size() == packedPath2.size() ) || (*(packedPath1.end()-1) != *(packedPath2.end()-1)) );
if( *(packedPath1.end()-1) == *(temporaryPackedPath1.begin())) {
packedPath2.clear();
packedPath2.insert(packedPath2.end(), packedPath1.begin(), packedPath1.end());
if( !packed_path1.empty() && !packed_path2.empty() ) {
if(
temporary_packed_path1.front() ==
temporary_packed_path2.front()
) {
//both new route segments start with the same node
//thus, one of the packedPath must go.
BOOST_ASSERT_MSG(
(packed_path1.size() == packed_path2.size() ) ||
(packed_path1.back() != packed_path2.back() ),
"packed paths must be different"
);
if( packed_path1.back() == temporary_packed_path1.front()) {
packed_path2.clear();
packed_path2.insert(
packed_path2.end(),
packed_path1.begin(),
packed_path1.end()
);
} else {
packedPath1.clear();
packedPath1.insert(packedPath1.end(), packedPath2.begin(), packedPath2.end());
packed_path1.clear();
packed_path1.insert(
packed_path1.end(),
packed_path2.begin(),
packed_path2.end()
);
}
} else {
//packed paths 1 and 2 may need to switch.
if(*(packedPath1.end()-1) != *(temporaryPackedPath1.begin())) {
packedPath1.swap(packedPath2);
if( packed_path1.back() != temporary_packed_path1.front()) {
packed_path1.swap(packed_path2);
std::swap(distance1, distance2);
}
}
}
packedPath1.insert(packedPath1.end(), temporaryPackedPath1.begin(), temporaryPackedPath1.end());
packedPath2.insert(packedPath2.end(), temporaryPackedPath2.begin(), temporaryPackedPath2.end());
packed_path1.insert(
packed_path1.end(),
temporary_packed_path1.begin(),
temporary_packed_path1.end()
);
packed_path2.insert(
packed_path2.end(),
temporary_packed_path2.begin(),
temporary_packed_path2.end()
);
if( (packedPath1.back() == packedPath2.back()) && phantomNodePair.targetPhantom.isBidirected() ) {
NodeID lastNodeID = packedPath2.back();
searchFrom1stStartNode &= !(lastNodeID == phantomNodePair.targetPhantom.edgeBasedNode+1);
searchFrom2ndStartNode &= !(lastNodeID == phantomNodePair.targetPhantom.edgeBasedNode);
if(
(packed_path1.back() == packed_path2.back()) &&
phantom_node_pair.targetPhantom.isBidirected()
) {
const NodeID last_node_id = packed_path2.back();
search_from_1st_node &= !(last_node_id == phantom_node_pair.targetPhantom.edgeBasedNode+1);
search_from_2nd_node &= !(last_node_id == phantom_node_pair.targetPhantom.edgeBasedNode);
}
distance1 = _localUpperbound1;
distance2 = _localUpperbound2;
distance1 = local_upper_bound1;
distance2 = local_upper_bound2;
}
if(distance1 > distance2){
std::swap(packedPath1, packedPath2);
if( distance1 > distance2 ) {
std::swap( packed_path1, packed_path2 );
}
remove_consecutive_duplicates_from_vector(packedPath1);
super::UnpackPath(packedPath1, rawRouteData.computedShortestPath);
rawRouteData.lengthOfShortestPath = std::min(distance1, distance2);
return;
remove_consecutive_duplicates_from_vector(packed_path1);
super::UnpackPath(packed_path1, raw_route_data.computedShortestPath);
raw_route_data.lengthOfShortestPath = std::min(distance1, distance2);
}
};
-167
View File
@@ -1,167 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BASIC_DATASTRUCTURES_H
#define BASIC_DATASTRUCTURES_H
#include "../Util/StringUtil.h"
#include <boost/asio.hpp>
#include <boost/foreach.hpp>
#include <string>
#include <sstream>
#include <vector>
namespace http {
const std::string okString = "HTTP/1.0 200 OK\r\n";
const std::string badRequestString = "HTTP/1.0 400 Bad Request\r\n";
const std::string internalServerErrorString = "HTTP/1.0 500 Internal Server Error\r\n";
const char okHTML[] = "";
const char badRequestHTML[] = "<html><head><title>Bad Request</title></head><body><h1>400 Bad Request</h1></body></html>";
const char internalServerErrorHTML[] = "<html><head><title>Internal Server Error</title></head><body><h1>500 Internal Server Error</h1></body></html>";
const char seperators[] = { ':', ' ' };
const char crlf[] = { '\r', '\n' };
struct Header {
std::string name;
std::string value;
void Clear() {
name.clear();
value.clear();
}
};
enum CompressionType {
noCompression,
gzipRFC1952,
deflateRFC1951
} Compression;
struct Request {
std::string uri;
std::string referrer;
std::string agent;
boost::asio::ip::address endpoint;
};
struct Reply {
Reply() : status(ok) { content.reserve(2 << 20); }
enum status_type {
ok = 200,
badRequest = 400,
internalServerError = 500
} status;
std::vector<Header> headers;
std::vector<boost::asio::const_buffer> toBuffers();
std::vector<boost::asio::const_buffer> HeaderstoBuffers();
std::string content;
static Reply stockReply(status_type status);
void setSize(const unsigned size) {
BOOST_FOREACH ( Header& h, headers) {
if("Content-Length" == h.name) {
std::string sizeString;
intToString(size,h.value);
}
}
}
};
boost::asio::const_buffer ToBuffer(Reply::status_type status) {
switch (status) {
case Reply::ok:
return boost::asio::buffer(okString);
case Reply::internalServerError:
return boost::asio::buffer(internalServerErrorString);
default:
return boost::asio::buffer(badRequestString);
}
}
std::string ToString(Reply::status_type status) {
switch (status) {
case Reply::ok:
return okHTML;
case Reply::badRequest:
return badRequestHTML;
default:
return internalServerErrorHTML;
}
}
std::vector<boost::asio::const_buffer> Reply::toBuffers(){
std::vector<boost::asio::const_buffer> buffers;
buffers.push_back(ToBuffer(status));
for (std::size_t i = 0; i < headers.size(); ++i) {
Header& h = headers[i];
buffers.push_back(boost::asio::buffer(h.name));
buffers.push_back(boost::asio::buffer(seperators));
buffers.push_back(boost::asio::buffer(h.value));
buffers.push_back(boost::asio::buffer(crlf));
}
buffers.push_back(boost::asio::buffer(crlf));
buffers.push_back(boost::asio::buffer(content));
return buffers;
}
std::vector<boost::asio::const_buffer> Reply::HeaderstoBuffers(){
std::vector<boost::asio::const_buffer> buffers;
buffers.push_back(ToBuffer(status));
for (std::size_t i = 0; i < headers.size(); ++i) {
Header& h = headers[i];
buffers.push_back(boost::asio::buffer(h.name));
buffers.push_back(boost::asio::buffer(seperators));
buffers.push_back(boost::asio::buffer(h.value));
buffers.push_back(boost::asio::buffer(crlf));
}
buffers.push_back(boost::asio::buffer(crlf));
return buffers;
}
Reply Reply::stockReply(Reply::status_type status) {
Reply rep;
rep.status = status;
rep.content = ToString(status);
rep.headers.resize(3);
rep.headers[0].name = "Access-Control-Allow-Origin";
rep.headers[0].value = "*";
rep.headers[1].name = "Content-Length";
std::string s;
intToString(rep.content.size(), s);
rep.headers[1].value = s;
rep.headers[2].name = "Content-Type";
rep.headers[2].value = "text/html";
return rep;
}
} // namespace http
#endif //BASIC_DATASTRUCTURES_H
+101 -70
View File
@@ -28,7 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef CONNECTION_H
#define CONNECTION_H
#include "BasicDatastructures.h"
#include "Http/CompressionType.h"
#include "RequestHandler.h"
#include "RequestParser.h"
@@ -37,11 +37,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/assert.hpp>
#include <boost/bind.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <zlib.h>
// #include <zlib.h>
#include <string>
#include <vector>
namespace http {
@@ -92,7 +96,7 @@ private:
request_handler.handle_request(request, reply);
Header compression_header;
std::vector<unsigned char> compressed_output;
std::vector<char> compressed_output;
std::vector<boost::asio::const_buffer> output_buffer;
switch(compression_type) {
case deflateRFC1951:
@@ -102,11 +106,10 @@ private:
reply.headers.begin(),
compression_header
);
compressCharArray(
reply.content.c_str(),
reply.content.length(),
compressed_output,
compression_type
compressBufferCollection(
reply.content,
compression_type,
compressed_output
);
reply.setSize(compressed_output.size());
output_buffer = reply.HeaderstoBuffers();
@@ -132,11 +135,10 @@ private:
reply.headers.begin(),
compression_header
);
compressCharArray(
reply.content.c_str(),
reply.content.length(),
compressed_output,
compression_type
compressBufferCollection(
reply.content,
compression_type,
compressed_output
);
reply.setSize(compressed_output.size());
output_buffer = reply.HeaderstoBuffers();
@@ -170,7 +172,7 @@ private:
break;
}
} else if (!result) {
reply = Reply::stockReply(Reply::badRequest);
reply = Reply::StockReply(Reply::badRequest);
boost::asio::async_write(
TCP_socket,
reply.toBuffers(),
@@ -210,71 +212,100 @@ private:
}
}
void compressBufferCollection(
std::vector<std::string> uncompressed_data,
CompressionType compression_type,
std::vector<char> & compressed_data
) {
boost::iostreams::gzip_params compression_parameters;
compression_parameters.level = boost::iostreams::zlib::best_speed;
if ( deflateRFC1951 == compression_type ) {
compression_parameters.noheader = true;
}
BOOST_ASSERT( compressed_data.empty() );
boost::iostreams::filtering_ostream compressing_stream;
compressing_stream.push(
boost::iostreams::gzip_compressor(compression_parameters)
);
compressing_stream.push(
boost::iostreams::back_inserter(compressed_data)
);
BOOST_FOREACH( const std::string & line, uncompressed_data) {
compressing_stream << line;
}
compressing_stream.reset();
}
// Big thanks to deusty who explains how to use gzip compression by
// the right call to deflateInit2():
// http://deusty.blogspot.com/2007/07/gzip-compressiondecompression.html
void compressCharArray(
const char * in_data,
size_t in_data_size,
std::vector<unsigned char> & buffer,
CompressionType type
) {
const size_t BUFSIZE = 128 * 1024;
unsigned char temp_buffer[BUFSIZE];
// void compressCharArray(
// const char * in_data,
// size_t in_data_size,
// std::vector<unsigned char> & buffer,
// CompressionType type
// ) {
// const size_t BUFSIZE = 128 * 1024;
// unsigned char temp_buffer[BUFSIZE];
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.total_out = 0;
strm.next_in = (unsigned char *)(in_data);
strm.avail_in = in_data_size;
strm.next_out = temp_buffer;
strm.avail_out = BUFSIZE;
strm.data_type = Z_ASCII;
// z_stream strm;
// strm.zalloc = Z_NULL;
// strm.zfree = Z_NULL;
// strm.opaque = Z_NULL;
// strm.total_out = 0;
// strm.next_in = (unsigned char *)(in_data);
// strm.avail_in = in_data_size;
// strm.next_out = temp_buffer;
// strm.avail_out = BUFSIZE;
// strm.data_type = Z_ASCII;
switch(type){
case deflateRFC1951:
deflateInit(&strm, Z_BEST_SPEED);
break;
case gzipRFC1952:
deflateInit2(
&strm,
Z_DEFAULT_COMPRESSION,
Z_DEFLATED,
(15+16),
9,
Z_DEFAULT_STRATEGY
);
break;
default:
BOOST_ASSERT_MSG(false, "should not happen");
break;
}
// switch(type){
// case deflateRFC1951:
// deflateInit(&strm, Z_BEST_SPEED);
// break;
// case gzipRFC1952:
// deflateInit2(
// &strm,
// Z_DEFAULT_COMPRESSION,
// Z_DEFLATED,
// (15+16),
// 9,
// Z_DEFAULT_STRATEGY
// );
// break;
// default:
// BOOST_ASSERT_MSG(false, "should not happen");
// break;
// }
int deflate_res = Z_OK;
do {
if ( 0 == strm.avail_out ) {
buffer.insert(buffer.end(), temp_buffer, temp_buffer + BUFSIZE);
strm.next_out = temp_buffer;
strm.avail_out = BUFSIZE;
}
deflate_res = deflate(&strm, Z_FINISH);
// int deflate_res = Z_OK;
// do {
// if ( 0 == strm.avail_out ) {
// buffer.insert(buffer.end(), temp_buffer, temp_buffer + BUFSIZE);
// strm.next_out = temp_buffer;
// strm.avail_out = BUFSIZE;
// }
// deflate_res = deflate(&strm, Z_FINISH);
} while (deflate_res == Z_OK);
// } while (deflate_res == Z_OK);
BOOST_ASSERT_MSG(
deflate_res == Z_STREAM_END,
"compression not properly finished"
);
// BOOST_ASSERT_MSG(
// deflate_res == Z_STREAM_END,
// "compression not properly finished"
// );
buffer.insert(
buffer.end(),
temp_buffer,
temp_buffer + BUFSIZE - strm.avail_out
);
deflateEnd(&strm);
}
// buffer.insert(
// buffer.end(),
// temp_buffer,
// temp_buffer + BUFSIZE - strm.avail_out
// );
// deflateEnd(&strm);
// }
boost::asio::io_service::strand strand;
boost::asio::ip::tcp::socket TCP_socket;
+122
View File
@@ -0,0 +1,122 @@
/*
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_DATA_FACADE_H
#define QUERY_DATA_FACADE_H
//Exposes all data access interfaces to the algorithms via base class ptr
#include "../../DataStructures/Coordinate.h"
#include "../../DataStructures/EdgeBasedNode.h"
#include "../../DataStructures/ImportNode.h"
#include "../../DataStructures/PhantomNodes.h"
#include "../../DataStructures/TurnInstructions.h"
#include "../../Util/OSRMException.h"
#include "../../Util/StringUtil.h"
#include "../../typedefs.h"
#include <string>
template<class EdgeDataT>
class BaseDataFacade {
public:
typedef EdgeBasedNode RTreeLeaf;
typedef EdgeDataT EdgeData;
BaseDataFacade( ) { }
virtual ~BaseDataFacade() { }
//search graph access
virtual unsigned GetNumberOfNodes() const = 0;
virtual unsigned GetNumberOfEdges() const = 0;
virtual unsigned GetOutDegree( const NodeID n ) const = 0;
virtual NodeID GetTarget( const EdgeID e ) const = 0;
virtual EdgeDataT &GetEdgeData( const EdgeID e ) = 0;
// virtual const EdgeDataT &GetEdgeData( const EdgeID e ) const = 0;
virtual EdgeID BeginEdges( const NodeID n ) const = 0;
virtual EdgeID EndEdges( const NodeID n ) const = 0;
//searches for a specific edge
virtual EdgeID FindEdge( const NodeID from, const NodeID to ) const = 0;
virtual EdgeID FindEdgeInEitherDirection(
const NodeID from,
const NodeID to
) const = 0;
virtual EdgeID FindEdgeIndicateIfReverse(
const NodeID from,
const NodeID to,
bool & result
) const = 0;
//node and edge information access
virtual FixedPointCoordinate GetCoordinateOfNode(
const unsigned id
) const = 0;
virtual TurnInstruction GetTurnInstructionForEdgeID(
const unsigned id
) const = 0;
virtual bool LocateClosestEndPointForCoordinate(
const FixedPointCoordinate& input_coordinate,
FixedPointCoordinate& result,
const unsigned zoom_level = 18
) const = 0;
virtual bool FindPhantomNodeForCoordinate(
const FixedPointCoordinate & input_coordinate,
PhantomNode & resulting_phantom_node,
const unsigned zoom_level
) const = 0;
virtual unsigned GetCheckSum() const = 0;
virtual unsigned GetNameIndexFromEdgeID(const unsigned id) const = 0;
virtual void GetName(
const unsigned name_id,
std::string & result
) const = 0;
std::string GetEscapedNameForNameID(const unsigned name_id) const {
std::string temporary_string;
GetName(name_id, temporary_string);
return HTMLEntitize(temporary_string);
}
virtual std::string GetTimestamp() const = 0;
};
#endif // QUERY_DATA_FACADE_H
+396
View File
@@ -0,0 +1,396 @@
/*
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_DATA_FACADE
#define INTERNAL_DATA_FACADE
//implements all data storage when shared memory is _NOT_ used
#include "BaseDataFacade.h"
#include "../../DataStructures/Coordinate.h"
#include "../../DataStructures/QueryNode.h"
#include "../../DataStructures/QueryEdge.h"
#include "../../DataStructures/SharedMemoryVectorWrapper.h"
#include "../../DataStructures/StaticGraph.h"
#include "../../DataStructures/StaticRTree.h"
#include "../../Util/BoostFileSystemFix.h"
#include "../../Util/GraphLoader.h"
#include "../../Util/IniFile.h"
#include "../../Util/ProgramOptions.h"
#include "../../Util/SimpleLogger.h"
template<class EdgeDataT>
class InternalDataFacade : public BaseDataFacade<EdgeDataT> {
private:
typedef BaseDataFacade<EdgeDataT> super;
typedef StaticGraph<typename super::EdgeData> QueryGraph;
typedef typename QueryGraph::InputEdge InputEdge;
typedef typename super::RTreeLeaf RTreeLeaf;
InternalDataFacade() { }
unsigned m_check_sum;
unsigned m_number_of_nodes;
QueryGraph * m_query_graph;
std::string m_timestamp;
ShM<FixedPointCoordinate, false>::vector m_coordinate_list;
ShM<NodeID, false>::vector m_via_node_list;
ShM<unsigned, false>::vector m_name_ID_list;
ShM<TurnInstruction, false>::vector m_turn_instruction_list;
ShM<char, false>::vector m_names_char_list;
ShM<unsigned, false>::vector m_name_begin_indices;
StaticRTree<RTreeLeaf, false> * m_static_rtree;
void LoadTimestamp(const boost::filesystem::path & timestamp_path) {
if( boost::filesystem::exists(timestamp_path) ) {
SimpleLogger().Write() << "Loading Timestamp";
boost::filesystem::ifstream timestampInStream( timestamp_path );
if(!timestampInStream) {
SimpleLogger().Write(logWARNING) << timestamp_path << " not found";
}
getline(timestampInStream, m_timestamp);
timestampInStream.close();
}
if(m_timestamp.empty()) {
m_timestamp = "n/a";
}
if(25 < m_timestamp.length()) {
m_timestamp.resize(25);
}
}
void LoadGraph(const boost::filesystem::path & hsgr_path) {
typename ShM<typename QueryGraph::_StrNode, false>::vector node_list;
typename ShM<typename QueryGraph::_StrEdge, false>::vector edge_list;
SimpleLogger().Write() << "loading graph from " << hsgr_path.string();
m_number_of_nodes = readHSGRFromStream(
hsgr_path,
node_list,
edge_list,
&m_check_sum
);
BOOST_ASSERT_MSG(0 != node_list.size(), "node list empty");
BOOST_ASSERT_MSG(0 != edge_list.size(), "edge list empty");
SimpleLogger().Write() << "loaded " << node_list.size() << " nodes and " << edge_list.size() << " edges";
m_query_graph = new QueryGraph(node_list, edge_list);
BOOST_ASSERT_MSG(0 == node_list.size(), "node list not flushed");
BOOST_ASSERT_MSG(0 == edge_list.size(), "edge list not flushed");
SimpleLogger().Write() << "Data checksum is " << m_check_sum;
}
void LoadNodeAndEdgeInformation(
const boost::filesystem::path nodes_file,
const boost::filesystem::path edges_file
) {
boost::filesystem::ifstream nodes_input_stream(
nodes_file,
std::ios::binary
);
SimpleLogger().Write(logDEBUG) << "Loading node data";
NodeInfo current_node;
unsigned number_of_coordinates = 0;
nodes_input_stream.read(
(char *)&number_of_coordinates,
sizeof(unsigned)
);
m_coordinate_list.resize(number_of_coordinates);
for(unsigned i = 0; i < number_of_coordinates; ++i) {
nodes_input_stream.read((char *)&current_node, sizeof(NodeInfo));
m_coordinate_list[i] = FixedPointCoordinate(
current_node.lat,
current_node.lon
);
}
std::vector<FixedPointCoordinate>(m_coordinate_list).swap(m_coordinate_list);
nodes_input_stream.close();
SimpleLogger().Write(logDEBUG) << "Loading edge data";
boost::filesystem::ifstream edges_input_stream(
edges_file,
std::ios::binary
);
unsigned number_of_edges = 0;
edges_input_stream.read((char*)&number_of_edges, sizeof(unsigned));
m_via_node_list.resize(number_of_edges);
m_name_ID_list.resize(number_of_edges);
m_turn_instruction_list.resize(number_of_edges);
OriginalEdgeData current_edge_data;
for(unsigned i = 0; i < number_of_edges; ++i) {
edges_input_stream.read(
(char*)&(current_edge_data),
sizeof(OriginalEdgeData)
);
m_via_node_list[i] = current_edge_data.viaNode;
m_name_ID_list[i] = current_edge_data.nameID;
m_turn_instruction_list[i] = current_edge_data.turnInstruction;
}
edges_input_stream.close();
}
void LoadRTree(
const boost::filesystem::path & ram_index_path,
const boost::filesystem::path & file_index_path
) {
m_static_rtree = new StaticRTree<RTreeLeaf>(
ram_index_path,
file_index_path
);
}
void LoadStreetNames(
const boost::filesystem::path & names_file
) {
boost::filesystem::ifstream name_stream(names_file, std::ios::binary);
unsigned number_of_names = 0;
unsigned number_of_chars = 0;
name_stream.read((char *)&number_of_names, sizeof(unsigned));
name_stream.read((char *)&number_of_chars, sizeof(unsigned));
BOOST_ASSERT_MSG(0 != number_of_names, "name file broken");
BOOST_ASSERT_MSG(0 != number_of_chars, "name file broken");
m_name_begin_indices.resize(number_of_names);
name_stream.read(
(char*)&m_name_begin_indices[0],
number_of_names*sizeof(unsigned)
);
m_names_char_list.resize(number_of_chars+1); //+1 gives sentinel element
name_stream.read(
(char *)&m_names_char_list[0],
number_of_chars*sizeof(char)
);
BOOST_ASSERT_MSG(
0 != m_names_char_list.size(),
"could not load any names"
);
name_stream.close();
}
public:
~InternalDataFacade() {
delete m_query_graph;
delete m_static_rtree;
}
InternalDataFacade( const ServerPaths & server_paths ) {
//generate paths of data files
if( server_paths.find("hsgrdata") == server_paths.end() ) {
throw OSRMException("no hsgr file given in ini file");
}
if( server_paths.find("ramindex") == server_paths.end() ) {
throw OSRMException("no ram index file given in ini file");
}
if( server_paths.find("fileindex") == server_paths.end() ) {
throw OSRMException("no leaf index file given in ini file");
}
if( server_paths.find("nodesdata") == server_paths.end() ) {
throw OSRMException("no nodes file given in ini file");
}
if( server_paths.find("edgesdata") == server_paths.end() ) {
throw OSRMException("no edges file given in ini file");
}
if( server_paths.find("namesdata") == server_paths.end() ) {
throw OSRMException("no names file given in ini file");
}
ServerPaths::const_iterator paths_iterator = server_paths.find("hsgrdata");
BOOST_ASSERT(server_paths.end() != paths_iterator);
const boost::filesystem::path & hsgr_path = paths_iterator->second;
paths_iterator = server_paths.find("timestamp");
BOOST_ASSERT(server_paths.end() != paths_iterator);
const boost::filesystem::path & timestamp_path = paths_iterator->second;
paths_iterator = server_paths.find("ramindex");
BOOST_ASSERT(server_paths.end() != paths_iterator);
const boost::filesystem::path & ram_index_path = paths_iterator->second;
paths_iterator = server_paths.find("fileindex");
BOOST_ASSERT(server_paths.end() != paths_iterator);
const boost::filesystem::path & file_index_path = paths_iterator->second;
paths_iterator = server_paths.find("nodesdata");
BOOST_ASSERT(server_paths.end() != paths_iterator);
const boost::filesystem::path & nodes_data_path = paths_iterator->second;
paths_iterator = server_paths.find("edgesdata");
BOOST_ASSERT(server_paths.end() != paths_iterator);
const boost::filesystem::path & edges_data_path = paths_iterator->second;
paths_iterator = server_paths.find("namesdata");
BOOST_ASSERT(server_paths.end() != paths_iterator);
const boost::filesystem::path & names_data_path = paths_iterator->second;
//load data
SimpleLogger().Write() << "loading graph data";
LoadGraph(hsgr_path);
SimpleLogger().Write() << "loading egde information";
LoadNodeAndEdgeInformation(nodes_data_path, edges_data_path);
SimpleLogger().Write() << "loading r-tree";
LoadRTree(ram_index_path, file_index_path);
SimpleLogger().Write() << "loading timestamp";
LoadTimestamp(timestamp_path);
SimpleLogger().Write() << "loading street names";
LoadStreetNames(names_data_path);
}
//search graph access
unsigned GetNumberOfNodes() const {
return m_query_graph->GetNumberOfNodes();
}
unsigned GetNumberOfEdges() const {
return m_query_graph->GetNumberOfEdges();
}
unsigned GetOutDegree( const NodeID n ) const {
return m_query_graph->GetOutDegree(n);
}
NodeID GetTarget( const EdgeID e ) const {
return m_query_graph->GetTarget(e); }
EdgeDataT &GetEdgeData( const EdgeID e ) {
return m_query_graph->GetEdgeData(e);
}
const EdgeDataT &GetEdgeData( const EdgeID e ) const {
return m_query_graph->GetEdgeData(e);
}
EdgeID BeginEdges( const NodeID n ) const {
return m_query_graph->BeginEdges(n);
}
EdgeID EndEdges( const NodeID n ) const {
return m_query_graph->EndEdges(n);
}
//searches for a specific edge
EdgeID FindEdge( const NodeID from, const NodeID to ) const {
return m_query_graph->FindEdge(from, to);
}
EdgeID FindEdgeInEitherDirection(
const NodeID from,
const NodeID to
) const {
return m_query_graph->FindEdgeInEitherDirection(from, to);
}
EdgeID FindEdgeIndicateIfReverse(
const NodeID from,
const NodeID to,
bool & result
) const {
return m_query_graph->FindEdgeIndicateIfReverse(from, to, result);
}
//node and edge information access
FixedPointCoordinate GetCoordinateOfNode(
const unsigned id
) const {
const NodeID node = m_via_node_list.at(id);
return m_coordinate_list.at(node);
};
TurnInstruction GetTurnInstructionForEdgeID(
const unsigned id
) const {
return m_turn_instruction_list.at(id);
}
bool LocateClosestEndPointForCoordinate(
const FixedPointCoordinate& input_coordinate,
FixedPointCoordinate& result,
const unsigned zoom_level = 18
) const {
return m_static_rtree->LocateClosestEndPointForCoordinate(
input_coordinate,
result,
zoom_level
);
}
bool FindPhantomNodeForCoordinate(
const FixedPointCoordinate & input_coordinate,
PhantomNode & resulting_phantom_node,
const unsigned zoom_level
) const {
return m_static_rtree->FindPhantomNodeForCoordinate(
input_coordinate,
resulting_phantom_node,
zoom_level
);
}
unsigned GetCheckSum() const { return m_check_sum; }
unsigned GetNameIndexFromEdgeID(const unsigned id) const {
return m_name_ID_list.at(id);
};
void GetName( const unsigned name_id, std::string & result ) const {
if(UINT_MAX == name_id) {
result = "";
return;
}
BOOST_ASSERT_MSG(
name_id < m_name_begin_indices.size(),
"name id too high"
);
unsigned begin_index = m_name_begin_indices[name_id];
unsigned end_index = m_name_begin_indices[name_id+1];
BOOST_ASSERT_MSG(
begin_index < m_names_char_list.size(),
"begin index of name too high"
);
BOOST_ASSERT_MSG(
end_index < m_names_char_list.size(),
"end index of name too high"
);
BOOST_ASSERT_MSG(begin_index <= end_index, "string ends before begin");
result.clear();
result.resize(end_index - begin_index);
std::copy(
m_names_char_list.begin() + begin_index,
m_names_char_list.begin() + end_index,
result.begin()
);
}
std::string GetTimestamp() const {
return m_timestamp;
}
};
#endif // INTERNAL_DATA_FACADE
@@ -1,183 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "QueryObjectsStorage.h"
QueryObjectsStorage::QueryObjectsStorage( const ServerPaths & paths ) {
if( paths.find("hsgrdata") == paths.end() ) {
throw OSRMException("no hsgr file given in ini file");
}
if( paths.find("ramindex") == paths.end() ) {
throw OSRMException("no ram index file given in ini file");
}
if( paths.find("fileindex") == paths.end() ) {
throw OSRMException("no mem index file given in ini file");
}
if( paths.find("nodesdata") == paths.end() ) {
throw OSRMException("no nodes file given in ini file");
}
if( paths.find("edgesdata") == paths.end() ) {
throw OSRMException("no edges file given in ini file");
}
if( paths.find("namesdata") == paths.end() ) {
throw OSRMException("no names file given in ini file");
}
SimpleLogger().Write() << "loading graph data";
//Deserialize road network graph
ServerPaths::const_iterator paths_iterator = paths.find("hsgrdata");
BOOST_ASSERT(paths.end() != paths_iterator);
const std::string & hsgr_data_string = paths_iterator->second.string();
std::vector< QueryGraph::_StrNode> node_list;
std::vector< QueryGraph::_StrEdge> edge_list;
const int number_of_nodes = readHSGRFromStream(
hsgr_data_string,
node_list,
edge_list,
&check_sum
);
SimpleLogger().Write() << "Data checksum is " << check_sum;
graph = new QueryGraph(node_list, edge_list);
BOOST_ASSERT(0 == node_list.size());
BOOST_ASSERT(0 == edge_list.size());
paths_iterator = paths.find("timestamp");
if(paths.end() != paths_iterator) {
SimpleLogger().Write() << "Loading Timestamp";
const std::string & timestamp_string = paths_iterator->second.string();
boost::filesystem::ifstream time_stamp_instream(timestamp_string);
if( !time_stamp_instream.good() ) {
SimpleLogger().Write(logWARNING) << timestamp_string << " not found";
}
getline(time_stamp_instream, timestamp);
time_stamp_instream.close();
}
if(!timestamp.length()) {
timestamp = "n/a";
}
if(25 < timestamp.length()) {
timestamp.resize(25);
}
SimpleLogger().Write() << "Loading auxiliary information";
paths_iterator = paths.find("ramindex");
BOOST_ASSERT(paths.end() != paths_iterator);
const std::string & ram_index_string = paths_iterator->second.string();
paths_iterator = paths.find("fileindex");
BOOST_ASSERT(paths.end() != paths_iterator);
const std::string & file_index_string = paths_iterator->second.string();
paths_iterator = paths.find("nodesdata");
BOOST_ASSERT(paths.end() != paths_iterator);
const std::string & nodes_data_string = paths_iterator->second.string();
paths_iterator = paths.find("edgesdata");
BOOST_ASSERT(paths.end() != paths_iterator);
const std::string & edges_data_string = paths_iterator->second.string();
//Init nearest neighbor data structure
nodeHelpDesk = new NodeInformationHelpDesk(
ram_index_string,
file_index_string,
nodes_data_string,
edges_data_string,
number_of_nodes,
check_sum
);
//deserialize street name list
SimpleLogger().Write() << "Loading names index";
paths_iterator = paths.find("namesdata");
BOOST_ASSERT(paths.end() != paths_iterator);
const std::string & names_data_string = paths_iterator->second.string();
if ( !boost::filesystem::exists( paths_iterator->second ) ) {
throw OSRMException("names file does not exist");
}
if ( 0 == boost::filesystem::file_size( paths_iterator->second ) ) {
throw OSRMException("names file is empty");
}
boost::filesystem::ifstream name_stream(names_data_string, std::ios::binary);
unsigned size = 0;
name_stream.read((char *)&size, sizeof(unsigned));
BOOST_ASSERT_MSG(0 != size, "name file broken");
m_name_begin_indices.resize(size);
name_stream.read((char*)&m_name_begin_indices[0], size*sizeof(unsigned));
name_stream.read((char *)&size, sizeof(unsigned));
BOOST_ASSERT_MSG(0 != size, "name file broken");
m_names_char_list.resize(size+1); //+1 is sentinel/dummy element
name_stream.read((char *)&m_names_char_list[0], size*sizeof(char));
BOOST_ASSERT_MSG(0 != m_names_char_list.size(), "could not load any names");
name_stream.close();
SimpleLogger().Write() << "All query data structures loaded";
}
void QueryObjectsStorage::GetName(
const unsigned name_id,
std::string & result
) const {
if(UINT_MAX == name_id) {
result = "";
return;
}
BOOST_ASSERT_MSG(
name_id < m_name_begin_indices.size(),
"name id too high"
);
unsigned begin_index = m_name_begin_indices[name_id];
unsigned end_index = m_name_begin_indices[name_id+1];
BOOST_ASSERT_MSG(
begin_index < m_names_char_list.size(),
"begin index of name too high"
);
BOOST_ASSERT_MSG(
end_index < m_names_char_list.size(),
"end index of name too high"
);
BOOST_ASSERT_MSG(begin_index <= end_index, "string ends before begin");
result.clear();
result.resize(end_index - begin_index);
std::copy(
m_names_char_list.begin() + begin_index,
m_names_char_list.begin() + end_index,
result.begin()
);
}
QueryObjectsStorage::~QueryObjectsStorage() {
delete graph;
delete nodeHelpDesk;
}
+40
View File
@@ -0,0 +1,40 @@
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/interprocess/sync/named_condition.hpp>
struct SharedBarriers {
SharedBarriers ()
:
pending_update_mutex(
boost::interprocess::open_or_create,
"pending_update"
),
update_mutex(
boost::interprocess::open_or_create,
"update"
),
query_mutex(
boost::interprocess::open_or_create,
"query"
),
no_running_queries_condition(
boost::interprocess::open_or_create,
"no_running_queries"
),
update_ongoing(false),
number_of_queries(0)
{ }
// Mutex to protect access to the boolean variable
boost::interprocess::named_mutex pending_update_mutex;
boost::interprocess::named_mutex update_mutex;
boost::interprocess::named_mutex query_mutex;
// Condition that no update is running
boost::interprocess::named_condition no_running_queries_condition;
// Is there an ongoing update?
bool update_ongoing;
// Is there any query?
int number_of_queries;
};
+385
View File
@@ -0,0 +1,385 @@
/*
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_DATA_FACADE_H
#define SHARED_DATA_FACADE_H
//implements all data storage when shared memory is _NOT_ used
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include "BaseDataFacade.h"
#include "SharedDataType.h"
#include "../../DataStructures/StaticGraph.h"
#include "../../DataStructures/StaticRTree.h"
#include "../../Util/BoostFileSystemFix.h"
#include "../../Util/ProgramOptions.h"
#include "../../Util/SimpleLogger.h"
#include <algorithm>
template<class EdgeDataT>
class SharedDataFacade : public BaseDataFacade<EdgeDataT> {
private:
typedef EdgeDataT EdgeData;
typedef BaseDataFacade<EdgeData> super;
typedef StaticGraph<EdgeData, true> QueryGraph;
typedef typename StaticGraph<EdgeData, true>::_StrNode GraphNode;
typedef typename StaticGraph<EdgeData, true>::_StrEdge GraphEdge;
typedef typename QueryGraph::InputEdge InputEdge;
typedef typename super::RTreeLeaf RTreeLeaf;
typedef typename StaticRTree<RTreeLeaf, true>::TreeNode RTreeNode;
SharedDataLayout * data_layout;
char * shared_memory;
SharedDataTimestamp * data_timestamp_ptr;
SharedDataType CURRENT_LAYOUT;
SharedDataType CURRENT_DATA;
unsigned CURRENT_TIMESTAMP;
unsigned m_check_sum;
unsigned m_number_of_nodes;
boost::shared_ptr<QueryGraph> m_query_graph;
boost::shared_ptr<SharedMemory> m_layout_memory;
boost::shared_ptr<SharedMemory> m_large_memory;
std::string m_timestamp;
ShM<FixedPointCoordinate, true>::vector m_coordinate_list;
ShM<NodeID, true>::vector m_via_node_list;
ShM<unsigned, true>::vector m_name_ID_list;
ShM<TurnInstruction, true>::vector m_turn_instruction_list;
ShM<char, true>::vector m_names_char_list;
ShM<unsigned, true>::vector m_name_begin_indices;
boost::shared_ptr<StaticRTree<RTreeLeaf, true> > m_static_rtree;
// SharedDataFacade() { }
void LoadTimestamp() {
char * timestamp_ptr = shared_memory + data_layout->GetTimeStampOffset();
m_timestamp.resize(data_layout->timestamp_length);
std::copy(
timestamp_ptr,
timestamp_ptr+data_layout->timestamp_length,
m_timestamp.begin()
);
}
void LoadRTree(
const boost::filesystem::path & file_index_path
) {
RTreeNode * tree_ptr = (RTreeNode *)(
shared_memory + data_layout->GetRSearchTreeOffset()
);
m_static_rtree = boost::make_shared<StaticRTree<RTreeLeaf, true> >(
tree_ptr,
data_layout->r_search_tree_size,
file_index_path
);
}
void LoadGraph() {
m_number_of_nodes = data_layout->graph_node_list_size;
GraphNode * graph_nodes_ptr = (GraphNode *)(
shared_memory + data_layout->GetGraphNodeListOffset()
);
GraphEdge * graph_edges_ptr = (GraphEdge *)(
shared_memory + data_layout->GetGraphEdgeListOffsett()
);
typename ShM<GraphNode, true>::vector node_list(
graph_nodes_ptr,
data_layout->graph_node_list_size
);
typename ShM<GraphEdge, true>::vector edge_list(
graph_edges_ptr,
data_layout->graph_edge_list_size
);
m_query_graph.reset(
new QueryGraph(node_list, edge_list)
);
}
void LoadNodeAndEdgeInformation() {
FixedPointCoordinate * coordinate_list_ptr = (FixedPointCoordinate *)(
shared_memory + data_layout->GetCoordinateListOffset()
);
typename ShM<FixedPointCoordinate, true>::vector coordinate_list(
coordinate_list_ptr,
data_layout->coordinate_list_size
);
m_coordinate_list.swap( coordinate_list );
TurnInstruction * turn_instruction_list_ptr = (TurnInstruction *)(
shared_memory + data_layout->GetTurnInstructionListOffset()
);
typename ShM<TurnInstruction, true>::vector turn_instruction_list(
turn_instruction_list_ptr,
data_layout->turn_instruction_list_size
);
m_turn_instruction_list.swap(turn_instruction_list);
unsigned * name_id_list_ptr = (unsigned *)(
shared_memory + data_layout->GetNameIDListOffset()
);
typename ShM<unsigned, true>::vector name_id_list(
name_id_list_ptr,
data_layout->name_id_list_size
);
m_name_ID_list.swap(name_id_list);
}
void LoadViaNodeList() {
NodeID * via_node_list_ptr = (NodeID *)(
shared_memory + data_layout->GetViaNodeListOffset()
);
typename ShM<NodeID, true>::vector via_node_list(
via_node_list_ptr,
data_layout->via_node_list_size
);
m_via_node_list.swap(via_node_list);
}
void LoadNames() {
unsigned * street_names_index_ptr = (unsigned *)(
shared_memory + data_layout->GetNameIndexOffset()
);
typename ShM<unsigned, true>::vector name_begin_indices(
street_names_index_ptr,
data_layout->name_index_list_size
);
m_name_begin_indices.swap(name_begin_indices);
char * names_list_ptr = (char *)(
shared_memory + data_layout->GetNameListOffset()
);
typename ShM<char, true>::vector names_char_list(
names_list_ptr,
data_layout->name_char_list_size
);
m_names_char_list.swap(names_char_list);
}
public:
SharedDataFacade( ) {
data_timestamp_ptr = (SharedDataTimestamp *)SharedMemoryFactory::Get(
CURRENT_REGIONS,
sizeof(SharedDataTimestamp),
false,
false
)->Ptr();
CURRENT_LAYOUT = LAYOUT_NONE;
CURRENT_DATA = DATA_NONE;
CURRENT_TIMESTAMP = 0;
//load data
CheckAndReloadFacade();
}
void CheckAndReloadFacade() {
if(
CURRENT_LAYOUT != data_timestamp_ptr->layout ||
CURRENT_DATA != data_timestamp_ptr->data ||
CURRENT_TIMESTAMP != data_timestamp_ptr->timestamp
) {
// release the previous shared memory segments
SharedMemory::Remove(CURRENT_LAYOUT);
SharedMemory::Remove(CURRENT_DATA);
CURRENT_LAYOUT = data_timestamp_ptr->layout;
CURRENT_DATA = data_timestamp_ptr->data;
CURRENT_TIMESTAMP = data_timestamp_ptr->timestamp;
m_layout_memory.reset( SharedMemoryFactory::Get(CURRENT_LAYOUT) );
data_layout = (SharedDataLayout *)(
m_layout_memory->Ptr()
);
boost::filesystem::path ram_index_path(data_layout->ram_index_file_name);
if( !boost::filesystem::exists(ram_index_path) ) {
throw OSRMException(
"no leaf index file given. "
"Is any data loaded into shared memory?"
);
}
m_large_memory.reset( SharedMemoryFactory::Get(CURRENT_DATA) );
shared_memory = (char *)(
m_large_memory->Ptr()
);
LoadGraph();
LoadNodeAndEdgeInformation();
LoadRTree(ram_index_path);
LoadTimestamp();
LoadViaNodeList();
LoadNames();
data_layout->PrintInformation();
}
}
//search graph access
unsigned GetNumberOfNodes() const {
return m_query_graph->GetNumberOfNodes();
}
unsigned GetNumberOfEdges() const {
return m_query_graph->GetNumberOfEdges();
}
unsigned GetOutDegree( const NodeID n ) const {
return m_query_graph->GetOutDegree(n);
}
NodeID GetTarget( const EdgeID e ) const {
return m_query_graph->GetTarget(e); }
EdgeDataT &GetEdgeData( const EdgeID e ) {
return m_query_graph->GetEdgeData(e);
}
// const EdgeDataT &GetEdgeData( const EdgeID e ) const {
// return m_query_graph->GetEdgeData(e);
// }
EdgeID BeginEdges( const NodeID n ) const {
return m_query_graph->BeginEdges(n);
}
EdgeID EndEdges( const NodeID n ) const {
return m_query_graph->EndEdges(n);
}
//searches for a specific edge
EdgeID FindEdge( const NodeID from, const NodeID to ) const {
return m_query_graph->FindEdge(from, to);
}
EdgeID FindEdgeInEitherDirection(
const NodeID from,
const NodeID to
) const {
return m_query_graph->FindEdgeInEitherDirection(from, to);
}
EdgeID FindEdgeIndicateIfReverse(
const NodeID from,
const NodeID to,
bool & result
) const {
return m_query_graph->FindEdgeIndicateIfReverse(from, to, result);
}
//node and edge information access
FixedPointCoordinate GetCoordinateOfNode(
const unsigned id
) const {
const NodeID node = m_via_node_list.at(id);
return m_coordinate_list.at(node);
};
TurnInstruction GetTurnInstructionForEdgeID(
const unsigned id
) const {
return m_turn_instruction_list.at(id);
}
bool LocateClosestEndPointForCoordinate(
const FixedPointCoordinate& input_coordinate,
FixedPointCoordinate& result,
const unsigned zoom_level = 18
) const {
return m_static_rtree->LocateClosestEndPointForCoordinate(
input_coordinate,
result,
zoom_level
);
}
bool FindPhantomNodeForCoordinate(
const FixedPointCoordinate & input_coordinate,
PhantomNode & resulting_phantom_node,
const unsigned zoom_level
) const {
return m_static_rtree->FindPhantomNodeForCoordinate(
input_coordinate,
resulting_phantom_node,
zoom_level
);
}
unsigned GetCheckSum() const { return m_check_sum; }
unsigned GetNameIndexFromEdgeID(const unsigned id) const {
return m_name_ID_list.at(id);
};
void GetName( const unsigned name_id, std::string & result ) const {
if(UINT_MAX == name_id) {
result = "";
return;
}
BOOST_ASSERT_MSG(
name_id < m_name_begin_indices.size(),
"name id too high"
);
unsigned begin_index = m_name_begin_indices[name_id];
unsigned end_index = m_name_begin_indices[name_id+1];
BOOST_ASSERT_MSG(
begin_index < m_names_char_list.size(),
"begin index of name too high"
);
BOOST_ASSERT_MSG(
end_index < m_names_char_list.size(),
"end index of name too high"
);
BOOST_ASSERT_MSG(begin_index <= end_index, "string ends before begin");
result.clear();
result.resize(end_index - begin_index);
std::copy(
m_names_char_list.begin() + begin_index,
m_names_char_list.begin() + end_index,
result.begin()
);
}
std::string GetTimestamp() const {
return m_timestamp;
}
};
#endif // SHARED_DATA_FACADE_H
+229
View File
@@ -0,0 +1,229 @@
/*
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_DATA_TYPE_H_
#define SHARED_DATA_TYPE_H_
#include "BaseDataFacade.h"
#include "../../DataStructures/Coordinate.h"
#include "../../DataStructures/QueryEdge.h"
#include "../../DataStructures/StaticGraph.h"
#include "../../DataStructures/StaticRTree.h"
#include "../../DataStructures/TurnInstructions.h"
#include "../../typedefs.h"
#include <boost/integer.hpp>
typedef BaseDataFacade<QueryEdge::EdgeData>::RTreeLeaf RTreeLeaf;
typedef StaticRTree<RTreeLeaf, true>::TreeNode RTreeNode;
typedef StaticGraph<QueryEdge::EdgeData> QueryGraph;
struct SharedDataLayout {
uint64_t name_index_list_size;
uint64_t name_char_list_size;
uint64_t name_id_list_size;
uint64_t via_node_list_size;
uint64_t graph_node_list_size;
uint64_t graph_edge_list_size;
uint64_t coordinate_list_size;
uint64_t turn_instruction_list_size;
uint64_t r_search_tree_size;
unsigned checksum;
unsigned timestamp_length;
char ram_index_file_name[1024];
SharedDataLayout() :
name_index_list_size(0),
name_char_list_size(0),
name_id_list_size(0),
via_node_list_size(0),
graph_node_list_size(0),
graph_edge_list_size(0),
coordinate_list_size(0),
turn_instruction_list_size(0),
r_search_tree_size(0),
checksum(0),
timestamp_length(0)
{
ram_index_file_name[0] = '\0';
}
void PrintInformation() const {
SimpleLogger().Write(logDEBUG) << "-";
SimpleLogger().Write(logDEBUG) << "name_index_list_size: " << name_index_list_size;
SimpleLogger().Write(logDEBUG) << "name_char_list_size: " << name_char_list_size;
SimpleLogger().Write(logDEBUG) << "name_id_list_size: " << name_id_list_size;
SimpleLogger().Write(logDEBUG) << "via_node_list_size: " << via_node_list_size;
SimpleLogger().Write(logDEBUG) << "graph_node_list_size: " << graph_node_list_size;
SimpleLogger().Write(logDEBUG) << "graph_edge_list_size: " << graph_edge_list_size;
SimpleLogger().Write(logDEBUG) << "timestamp_length: " << timestamp_length;
SimpleLogger().Write(logDEBUG) << "coordinate_list_size: " << coordinate_list_size;
SimpleLogger().Write(logDEBUG) << "turn_instruction_list_size: " << turn_instruction_list_size;
SimpleLogger().Write(logDEBUG) << "r_search_tree_size: " << r_search_tree_size;
SimpleLogger().Write(logDEBUG) << "sizeof(checksum): " << sizeof(checksum);
SimpleLogger().Write(logDEBUG) << "ram index file name: " << ram_index_file_name;
}
uint64_t GetSizeOfLayout() const {
uint64_t result =
(name_index_list_size * sizeof(unsigned) ) +
(name_char_list_size * sizeof(char) ) +
(name_id_list_size * sizeof(unsigned) ) +
(via_node_list_size * sizeof(NodeID) ) +
(graph_node_list_size * sizeof(QueryGraph::_StrNode)) +
(graph_edge_list_size * sizeof(QueryGraph::_StrEdge)) +
(timestamp_length * sizeof(char) ) +
(coordinate_list_size * sizeof(FixedPointCoordinate)) +
(turn_instruction_list_size * sizeof(TurnInstructions) ) +
(r_search_tree_size * sizeof(RTreeNode) ) +
sizeof(checksum) +
1024*sizeof(char);
return result;
}
uint64_t GetNameIndexOffset() const {
return 0;
}
uint64_t GetNameListOffset() const {
uint64_t result =
(name_index_list_size * sizeof(unsigned) );
return result;
}
uint64_t GetNameIDListOffset() const {
uint64_t result =
(name_index_list_size * sizeof(unsigned) ) +
(name_char_list_size * sizeof(char) );
return result;
}
uint64_t GetViaNodeListOffset() const {
uint64_t result =
(name_index_list_size * sizeof(unsigned) ) +
(name_char_list_size * sizeof(char) ) +
(name_id_list_size * sizeof(unsigned) );
return result;
}
uint64_t GetGraphNodeListOffset() const {
uint64_t result =
(name_index_list_size * sizeof(unsigned) ) +
(name_char_list_size * sizeof(char) ) +
(name_id_list_size * sizeof(unsigned) ) +
(via_node_list_size * sizeof(NodeID) );
return result;
}
uint64_t GetGraphEdgeListOffsett() const {
uint64_t result =
(name_index_list_size * sizeof(unsigned) ) +
(name_char_list_size * sizeof(char) ) +
(name_id_list_size * sizeof(unsigned) ) +
(via_node_list_size * sizeof(NodeID) ) +
(graph_node_list_size * sizeof(QueryGraph::_StrNode)) ;
return result;
}
uint64_t GetTimeStampOffset() const {
uint64_t result =
(name_index_list_size * sizeof(unsigned) ) +
(name_char_list_size * sizeof(char) ) +
(name_id_list_size * sizeof(unsigned) ) +
(via_node_list_size * sizeof(NodeID) ) +
(graph_node_list_size * sizeof(QueryGraph::_StrNode)) +
(graph_edge_list_size * sizeof(QueryGraph::_StrEdge));
return result;
}
uint64_t GetCoordinateListOffset() const {
uint64_t result =
(name_index_list_size * sizeof(unsigned) ) +
(name_char_list_size * sizeof(char) ) +
(name_id_list_size * sizeof(unsigned) ) +
(via_node_list_size * sizeof(NodeID) ) +
(graph_node_list_size * sizeof(QueryGraph::_StrNode)) +
(graph_edge_list_size * sizeof(QueryGraph::_StrEdge)) +
(timestamp_length * sizeof(char) );
return result;
}
uint64_t GetTurnInstructionListOffset() const {
uint64_t result =
(name_index_list_size * sizeof(unsigned) ) +
(name_char_list_size * sizeof(char) ) +
(name_id_list_size * sizeof(unsigned) ) +
(via_node_list_size * sizeof(NodeID) ) +
(graph_node_list_size * sizeof(QueryGraph::_StrNode)) +
(graph_edge_list_size * sizeof(QueryGraph::_StrEdge)) +
(timestamp_length * sizeof(char) ) +
(coordinate_list_size * sizeof(FixedPointCoordinate));
return result;
}
uint64_t GetRSearchTreeOffset() const {
uint64_t result =
(name_index_list_size * sizeof(unsigned) ) +
(name_char_list_size * sizeof(char) ) +
(name_id_list_size * sizeof(unsigned) ) +
(via_node_list_size * sizeof(NodeID) ) +
(graph_node_list_size * sizeof(QueryGraph::_StrNode)) +
(graph_edge_list_size * sizeof(QueryGraph::_StrEdge)) +
(timestamp_length * sizeof(char) ) +
(coordinate_list_size * sizeof(FixedPointCoordinate)) +
(turn_instruction_list_size * sizeof(TurnInstructions) );
return result;
}
uint64_t GetChecksumOffset() const {
uint64_t result =
(name_index_list_size * sizeof(unsigned) ) +
(name_char_list_size * sizeof(char) ) +
(name_id_list_size * sizeof(unsigned) ) +
(via_node_list_size * sizeof(NodeID) ) +
(graph_node_list_size * sizeof(QueryGraph::_StrNode)) +
(graph_edge_list_size * sizeof(QueryGraph::_StrEdge)) +
(timestamp_length * sizeof(char) ) +
(coordinate_list_size * sizeof(FixedPointCoordinate)) +
(turn_instruction_list_size * sizeof(TurnInstructions) ) +
(r_search_tree_size * sizeof(RTreeNode) );
return result;
}
};
enum SharedDataType {
CURRENT_REGIONS,
LAYOUT_1,
DATA_1,
LAYOUT_2,
DATA_2,
LAYOUT_NONE,
DATA_NONE
};
struct SharedDataTimestamp {
SharedDataType layout;
SharedDataType data;
unsigned timestamp;
};
#endif /* SHARED_DATA_TYPE_H_ */
+41
View File
@@ -0,0 +1,41 @@
/*
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 BASIC_DATASTRUCTURES_H
#define BASIC_DATASTRUCTURES_H
namespace http {
enum CompressionType {
noCompression,
gzipRFC1952,
deflateRFC1951
};
} // namespace http
#endif //BASIC_DATASTRUCTURES_H
+13 -24
View File
@@ -25,33 +25,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BRESENHAM_H_
#define BRESENHAM_H_
#ifndef HTTP_HEADER_H
#define HTTP_HEADER_H
#include <cmath>
#include <vector>
#include <string>
typedef std::pair<unsigned, unsigned> BresenhamPixel;
namespace http {
inline void Bresenham (int x0, int y0, const int x1, int const 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;
struct Header {
std::string name;
std::string value;
void Clear() {
name.clear();
value.clear();
}
if(e2 < dx) {
err+= dx;
y0 += sy;
}
}
};
}
#endif /* BRESENHAM_H_ */
#endif //HTTP_HEADER_H
+117
View File
@@ -0,0 +1,117 @@
/*
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 "Reply.h"
namespace http {
void Reply::setSize(const unsigned size) {
BOOST_FOREACH ( Header& h, headers) {
if("Content-Length" == h.name) {
std::string sizeString;
intToString(size,h.value);
}
}
}
std::vector<boost::asio::const_buffer> Reply::toBuffers(){
std::vector<boost::asio::const_buffer> buffers;
buffers.push_back(ToBuffer(status));
BOOST_FOREACH(const Header & h, headers) {
buffers.push_back(boost::asio::buffer(h.name));
buffers.push_back(boost::asio::buffer(seperators));
buffers.push_back(boost::asio::buffer(h.value));
buffers.push_back(boost::asio::buffer(crlf));
}
buffers.push_back(boost::asio::buffer(crlf));
BOOST_FOREACH(const std::string & line, content) {
buffers.push_back(boost::asio::buffer(line));
}
return buffers;
}
std::vector<boost::asio::const_buffer> Reply::HeaderstoBuffers(){
std::vector<boost::asio::const_buffer> buffers;
buffers.push_back(ToBuffer(status));
for (std::size_t i = 0; i < headers.size(); ++i) {
Header& h = headers[i];
buffers.push_back(boost::asio::buffer(h.name));
buffers.push_back(boost::asio::buffer(seperators));
buffers.push_back(boost::asio::buffer(h.value));
buffers.push_back(boost::asio::buffer(crlf));
}
buffers.push_back(boost::asio::buffer(crlf));
return buffers;
}
Reply Reply::StockReply(Reply::status_type status) {
Reply rep;
rep.status = status;
rep.content.clear();
rep.content.push_back( ToString(status) );
rep.headers.resize(3);
rep.headers[0].name = "Access-Control-Allow-Origin";
rep.headers[0].value = "*";
rep.headers[1].name = "Content-Length";
std::string s;
intToString(rep.content.size(), s);
rep.headers[1].value = s;
rep.headers[2].name = "Content-Type";
rep.headers[2].value = "text/html";
return rep;
}
std::string Reply::ToString(Reply::status_type status) {
switch (status) {
case Reply::ok:
return okHTML;
case Reply::badRequest:
return badRequestHTML;
default:
return internalServerErrorHTML;
}
}
boost::asio::const_buffer Reply::ToBuffer(Reply::status_type status) {
switch (status) {
case Reply::ok:
return boost::asio::buffer(okString);
case Reply::internalServerError:
return boost::asio::buffer(internalServerErrorString);
default:
return boost::asio::buffer(badRequestString);
}
}
Reply::Reply() : status(ok) {
}
}
+73
View File
@@ -0,0 +1,73 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef REPLY_H
#define REPLY_H
#include "Header.h"
#include "../../Util/StringUtil.h"
#include <boost/asio.hpp>
#include <boost/foreach.hpp>
#include <vector>
namespace http {
const char okHTML[] = "";
const char badRequestHTML[] = "<html><head><title>Bad Request</title></head><body><h1>400 Bad Request</h1></body></html>";
const char internalServerErrorHTML[] = "<html><head><title>Internal Server Error</title></head><body><h1>500 Internal Server Error</h1></body></html>";
const char seperators[] = { ':', ' ' };
const char crlf[] = { '\r', '\n' };
const std::string okString = "HTTP/1.0 200 OK\r\n";
const std::string badRequestString = "HTTP/1.0 400 Bad Request\r\n";
const std::string internalServerErrorString = "HTTP/1.0 500 Internal Server Error\r\n";
class Reply {
public:
enum status_type {
ok = 200,
badRequest = 400,
internalServerError = 500
} status;
std::vector<Header> headers;
std::vector<boost::asio::const_buffer> toBuffers();
std::vector<boost::asio::const_buffer> HeaderstoBuffers();
std::vector<std::string> content;
static Reply StockReply(status_type status);
void setSize(const unsigned size);
Reply();
private:
static std::string ToString(Reply::status_type status);
boost::asio::const_buffer ToBuffer(Reply::status_type status);
};
}
#endif //REPLY_H
@@ -25,54 +25,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SIMPLESTACK_H_
#define SIMPLESTACK_H_
#ifndef REQUEST_H
#define REQUEST_H
#include <cassert>
#include <vector>
#include "../../Util/StringUtil.h"
template<typename StackItemT, class ContainerT = std::vector<StackItemT> >
class SimpleStack {
#include <boost/asio.hpp>
private:
int last;
ContainerT arr;
#include <string>
public:
SimpleStack() : last(-1) {
}
namespace http {
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);
}
struct Request {
std::string uri;
std::string referrer;
std::string agent;
boost::asio::ip::address endpoint;
};
} // namespace http
#endif /* SIMPLESTACK_H_ */
#endif //REQUEST_H
+12 -10
View File
@@ -29,8 +29,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define REQUEST_HANDLER_H
#include "APIGrammar.h"
#include "BasicDatastructures.h"
#include "DataStructures/RouteParameters.h"
#include "Http/Request.h"
#include "../Library/OSRM.h"
#include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h"
@@ -81,20 +81,22 @@ public:
);
if ( !result || (it != request.end()) ) {
rep = http::Reply::stockReply(http::Reply::badRequest);
rep = http::Reply::StockReply(http::Reply::badRequest);
const int position = std::distance(request.begin(), it);
std::string tmp_position_string;
intToString(position, tmp_position_string);
rep.content += "Input seems to be malformed close to position ";
rep.content += "<br><pre>";
rep.content += request;
rep.content += tmp_position_string;
rep.content += "<br>";
rep.content.push_back(
"Input seems to be malformed close to position "
"<br><pre>"
);
rep.content.push_back( request );
rep.content.push_back(tmp_position_string);
rep.content.push_back("<br>");
const unsigned end = std::distance(request.begin(), it);
for(unsigned i = 0; i < end; ++i) {
rep.content += "&nbsp;";
rep.content.push_back("&nbsp;");
}
rep.content += "^<br></pre>";
rep.content.push_back("^<br></pre>");
} else {
//parsing done, lets call the right plugin to handle the request
BOOST_ASSERT_MSG(
@@ -105,7 +107,7 @@ public:
return;
}
} catch(std::exception& e) {
rep = http::Reply::stockReply(http::Reply::internalServerError);
rep = http::Reply::StockReply(http::Reply::internalServerError);
SimpleLogger().Write(logWARNING) <<
"[server error] code: " << e.what() << ", uri: " << req.uri;
return;
+270
View File
@@ -0,0 +1,270 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "RequestParser.h"
namespace http {
RequestParser::RequestParser() : state_(method_start) { }
void RequestParser::Reset() { state_ = method_start; }
boost::tuple<boost::tribool, char*> RequestParser::Parse(
Request& req,
char* begin,
char* end,
http::CompressionType * compressionType
) {
while (begin != end) {
boost::tribool result = consume(req, *begin++, compressionType);
if (result || !result){
return boost::make_tuple(result, begin);
}
}
boost::tribool result = boost::indeterminate;
return boost::make_tuple(result, begin);
}
boost::tribool RequestParser::consume(
Request& req, char input,
http::CompressionType * compressionType
) {
switch (state_) {
case method_start:
if (!isChar(input) || isCTL(input) || isTSpecial(input)) {
return false;
} else {
state_ = method;
return boost::indeterminate;
}
case method:
if (input == ' ') {
state_ = uri;
return boost::indeterminate;
} else if (!isChar(input) || isCTL(input) || isTSpecial(input)) {
return false;
} else {
return boost::indeterminate;
}
case uri_start:
if (isCTL(input)) {
return false;
} else {
state_ = uri;
req.uri.push_back(input);
return boost::indeterminate;
}
case uri:
if (input == ' ') {
state_ = http_version_h;
return boost::indeterminate;
} else if (isCTL(input)) {
return false;
} else {
req.uri.push_back(input);
return boost::indeterminate;
}
case http_version_h:
if (input == 'H') {
state_ = http_version_t_1;
return boost::indeterminate;
} else {
return false;
}
case http_version_t_1:
if (input == 'T') {
state_ = http_version_t_2;
return boost::indeterminate;
} else {
return false;
}
case http_version_t_2:
if (input == 'T') {
state_ = http_version_p;
return boost::indeterminate;
} else {
return false;
}
case http_version_p:
if (input == 'P') {
state_ = http_version_slash;
return boost::indeterminate;
} else {
return false;
}
case http_version_slash:
if (input == '/') {
state_ = http_version_major_start;
return boost::indeterminate;
} else {
return false;
}
case http_version_major_start:
if (isDigit(input)) {
state_ = http_version_major;
return boost::indeterminate;
} else {
return false;
}
case http_version_major:
if (input == '.') {
state_ = http_version_minor_start;
return boost::indeterminate;
} else if (isDigit(input)) {
return boost::indeterminate;
} else {
return false;
}
case http_version_minor_start:
if (isDigit(input)) {
state_ = http_version_minor;
return boost::indeterminate;
} else {
return false;
}
case http_version_minor:
if (input == '\r') {
state_ = expecting_newline_1;
return boost::indeterminate;
} else if (isDigit(input)) {
return boost::indeterminate;
}
else {
return false;
}
case expecting_newline_1:
if (input == '\n') {
state_ = header_line_start;
return boost::indeterminate;
} else {
return false;
}
case header_line_start:
if(header.name == "Accept-Encoding") {
/* giving gzip precedence over deflate */
if(header.value.find("deflate") != std::string::npos)
*compressionType = deflateRFC1951;
if(header.value.find("gzip") != std::string::npos)
*compressionType = gzipRFC1952;
}
if("Referer" == header.name)
req.referrer = header.value;
if("User-Agent" == header.name)
req.agent = header.value;
if (input == '\r') {
state_ = expecting_newline_3;
return boost::indeterminate;
} else if (!isChar(input) || isCTL(input) || isTSpecial(input)) {
return false;
} else {
state_ = header_name;
header.Clear();
header.name.push_back(input);
return boost::indeterminate;
}
case header_lws:
if (input == '\r') {
state_ = expecting_newline_2;
return boost::indeterminate;
} else if (input == ' ' || input == '\t') {
return boost::indeterminate;
}
else if (isCTL(input)) {
return false;
} else {
state_ = header_value;
return boost::indeterminate;
}
case header_name:
if (input == ':') {
state_ = space_before_header_value;
return boost::indeterminate;
} else if (!isChar(input) || isCTL(input) || isTSpecial(input)) {
return false;
} else {
header.name.push_back(input);
return boost::indeterminate;
}
case space_before_header_value:
if (input == ' ') {
state_ = header_value;
return boost::indeterminate;
} else {
return false;
}
case header_value:
if (input == '\r') {
state_ = expecting_newline_2;
return boost::indeterminate;
} else if (isCTL(input)) {
return false;
} else {
header.value.push_back(input);
return boost::indeterminate;
}
case expecting_newline_2:
if (input == '\n') {
state_ = header_line_start;
return boost::indeterminate;
} else {
return false;
}
case expecting_newline_3:
return (input == '\n');
default:
return false;
}
}
inline bool RequestParser::isChar(int c) {
return c >= 0 && c <= 127;
}
inline bool RequestParser::isCTL(int c) {
return (c >= 0 && c <= 31) || (c == 127);
}
inline bool RequestParser::isTSpecial(int c) {
switch (c) {
case '(': case ')': case '<': case '>': case '@':
case ',': case ';': case ':': case '\\': case '"':
case '/': case '[': case ']': case '?': case '=':
case '{': case '}': case ' ': case '\t':
return true;
default:
return false;
}
}
inline bool RequestParser::isDigit(int c) {
return c >= '0' && c <= '9';
}
}
+20 -223
View File
@@ -28,7 +28,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef REQUEST_PARSER_H
#define REQUEST_PARSER_H
#include "BasicDatastructures.h"
#include "Http/CompressionType.h"
#include "Http/Header.h"
#include "Http/Request.h"
#include <boost/logic/tribool.hpp>
#include <boost/tuple/tuple.hpp>
@@ -37,235 +39,30 @@ namespace http {
class RequestParser {
public:
RequestParser() : state_(method_start) { }
void Reset() { state_ = method_start; }
RequestParser();
void Reset();
boost::tuple<boost::tribool, char*> Parse(Request& req, char* begin, char* end, CompressionType * compressionType) {
while (begin != end) {
boost::tribool result = consume(req, *begin++, compressionType);
if (result || !result){
return boost::make_tuple(result, begin);
}
}
boost::tribool result = boost::indeterminate;
return boost::make_tuple(result, begin);
}
boost::tuple<boost::tribool, char*> Parse(
Request& req,
char* begin,
char* end,
CompressionType * compressionType
);
private:
boost::tribool consume(Request& req, char input, CompressionType * compressionType) {
switch (state_) {
case method_start:
if (!isChar(input) || isCTL(input) || isTSpecial(input)) {
return false;
} else {
state_ = method;
return boost::indeterminate;
}
case method:
if (input == ' ') {
state_ = uri;
return boost::indeterminate;
} else if (!isChar(input) || isCTL(input) || isTSpecial(input)) {
return false;
} else {
return boost::indeterminate;
}
case uri_start:
if (isCTL(input)) {
return false;
} else {
state_ = uri;
req.uri.push_back(input);
return boost::indeterminate;
}
case uri:
if (input == ' ') {
state_ = http_version_h;
return boost::indeterminate;
} else if (isCTL(input)) {
return false;
} else {
req.uri.push_back(input);
return boost::indeterminate;
}
case http_version_h:
if (input == 'H') {
state_ = http_version_t_1;
return boost::indeterminate;
} else {
return false;
}
case http_version_t_1:
if (input == 'T') {
state_ = http_version_t_2;
return boost::indeterminate;
} else {
return false;
}
case http_version_t_2:
if (input == 'T') {
state_ = http_version_p;
return boost::indeterminate;
} else {
return false;
}
case http_version_p:
if (input == 'P') {
state_ = http_version_slash;
return boost::indeterminate;
} else {
return false;
}
case http_version_slash:
if (input == '/') {
state_ = http_version_major_start;
return boost::indeterminate;
} else {
return false;
}
case http_version_major_start:
if (isDigit(input)) {
state_ = http_version_major;
return boost::indeterminate;
} else {
return false;
}
case http_version_major:
if (input == '.') {
state_ = http_version_minor_start;
return boost::indeterminate;
} else if (isDigit(input)) {
return boost::indeterminate;
} else {
return false;
}
case http_version_minor_start:
if (isDigit(input)) {
state_ = http_version_minor;
return boost::indeterminate;
} else {
return false;
}
case http_version_minor:
if (input == '\r') {
state_ = expecting_newline_1;
return boost::indeterminate;
} else if (isDigit(input)) {
return boost::indeterminate;
}
else {
return false;
}
case expecting_newline_1:
if (input == '\n') {
state_ = header_line_start;
return boost::indeterminate;
} else {
return false;
}
case header_line_start:
if(header.name == "Accept-Encoding") {
/* giving gzip precedence over deflate */
if(header.value.find("deflate") != std::string::npos)
*compressionType = deflateRFC1951;
if(header.value.find("gzip") != std::string::npos)
*compressionType = gzipRFC1952;
}
boost::tribool consume(
Request& req,
char input,
CompressionType * compressionType
);
if("Referer" == header.name)
req.referrer = header.value;
inline bool isChar(int c);
if("User-Agent" == header.name)
req.agent = header.value;
inline bool isCTL(int c);
if (input == '\r') {
state_ = expecting_newline_3;
return boost::indeterminate;
} else if (!isChar(input) || isCTL(input) || isTSpecial(input)) {
return false;
} else {
state_ = header_name;
header.Clear();
header.name.push_back(input);
return boost::indeterminate;
}
case header_lws:
if (input == '\r') {
state_ = expecting_newline_2;
return boost::indeterminate;
} else if (input == ' ' || input == '\t') {
return boost::indeterminate;
}
else if (isCTL(input)) {
return false;
} else {
state_ = header_value;
return boost::indeterminate;
}
case header_name:
if (input == ':') {
state_ = space_before_header_value;
return boost::indeterminate;
} else if (!isChar(input) || isCTL(input) || isTSpecial(input)) {
return false;
} else {
header.name.push_back(input);
return boost::indeterminate;
}
case space_before_header_value:
if (input == ' ') {
state_ = header_value;
return boost::indeterminate;
} else {
return false;
}
case header_value:
if (input == '\r') {
state_ = expecting_newline_2;
return boost::indeterminate;
} else if (isCTL(input)) {
return false;
} else {
header.value.push_back(input);
return boost::indeterminate;
}
case expecting_newline_2:
if (input == '\n') {
state_ = header_line_start;
return boost::indeterminate;
} else {
return false;
}
case expecting_newline_3:
return (input == '\n');
default:
return false;
}
}
inline bool isTSpecial(int c);
inline bool isChar(int c) {
return c >= 0 && c <= 127;
}
inline bool isCTL(int c) {
return (c >= 0 && c <= 31) || (c == 127);
}
inline bool isTSpecial(int c) {
switch (c) {
case '(': case ')': case '<': case '>': case '@':
case ',': case ';': case ':': case '\\': case '"':
case '/': case '[': case ']': case '?': case '=':
case '{': case '}': case ' ': case '\t':
return true;
default:
return false;
}
}
inline bool isDigit(int c) {
return c >= '0' && c <= '9';
}
inline bool isDigit(int c);
enum state {
method_start,
+4 -2
View File
@@ -25,6 +25,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "../Util/GitDescription.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../Util/TimingUtil.h"
@@ -74,8 +75,9 @@ void RunStatistics(std::vector<double> & timings_vector, Statistics & stats) {
int main (int argc, char * argv[]) {
LogPolicy::GetInstance().Unmute();
SimpleLogger().Write(logDEBUG) << "starting up engines, compiled at " <<
__DATE__ << ", " __TIME__;
SimpleLogger().Write() <<
"starting up engines, " << g_GIT_DESCRIPTION << ", " <<
"compiled at " << __DATE__ << ", " __TIME__;
if( 1 == argc ) {
SimpleLogger().Write(logWARNING) <<
+9 -6
View File
@@ -55,7 +55,7 @@ int main (int argc, const char * argv[]) {
try {
std::string ip_address;
int ip_port, requested_num_threads;
bool use_shared_memory = false;
ServerPaths server_paths;
if( !GenerateServerProgramOptions(
argc,
@@ -63,7 +63,8 @@ int main (int argc, const char * argv[]) {
server_paths,
ip_address,
ip_port,
requested_num_threads
requested_num_threads,
use_shared_memory
)
) {
return 0;
@@ -73,7 +74,7 @@ int main (int argc, const char * argv[]) {
"starting up engines, " << g_GIT_DESCRIPTION << ", " <<
"compiled at " << __DATE__ << ", " __TIME__;
OSRM routing_machine(server_paths);
OSRM routing_machine( server_paths, use_shared_memory );
RouteParameters route_parameters;
route_parameters.zoomLevel = 18; //no generalization
@@ -97,12 +98,14 @@ int main (int argc, const char * argv[]) {
routing_machine.RunQuery(route_parameters, osrm_reply);
std::cout << osrm_reply.content << std::endl;
//attention: super-inefficient hack below:
std::stringstream ss;
ss << osrm_reply.content;
BOOST_FOREACH(const std::string & line, osrm_reply.content) {
std::cout << line;
ss << line;
}
std::cout << std::endl;
boost::property_tree::ptree pt;
boost::property_tree::read_json(ss, pt);
@@ -25,30 +25,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CRC32_H_
#define CRC32_H_
#include "../Util/GitDescription.h"
#include "../Util/SimpleLogger.h"
#include "../Server/DataStructures/SharedBarriers.h"
#include <boost/crc.hpp> // for boost::crc_32_type
#include <iostream>
class CRC32 {
private:
unsigned crc;
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_ */
int main() {
LogPolicy::GetInstance().Unmute();
SimpleLogger().Write() <<
"starting up engines, " << g_GIT_DESCRIPTION << ", " <<
"compiled at " << __DATE__ << ", " __TIME__;
SimpleLogger().Write() << "Releasing all locks";
SharedBarriers barrier;
barrier.pending_update_mutex.unlock();
barrier.query_mutex.unlock();
barrier.update_mutex.unlock();
return 0;
}
@@ -25,40 +25,36 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef QUERYOBJECTSSTORAGE_H_
#define QUERYOBJECTSSTORAGE_H_
#ifndef BOOST_FILE_SYSTEM_FIX_H
#define BOOST_FILE_SYSTEM_FIX_H
#include "../../Util/GraphLoader.h"
#include "../../Util/OSRMException.h"
#include "../../Util/ProgramOptions.h"
#include "../../Util/SimpleLogger.h"
#include "../../DataStructures/NodeInformationHelpDesk.h"
#include "../../DataStructures/QueryEdge.h"
#include "../../DataStructures/StaticGraph.h"
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <vector>
#include <string>
//This is one big workaround for latest boost renaming woes.
#if BOOST_FILESYSTEM_VERSION < 3
#warning Boost Installation with Filesystem3 missing, activating workaround
#include <cstdio>
namespace boost {
namespace filesystem {
inline path temp_directory_path() {
char * buffer;
buffer = tmpnam (NULL);
struct QueryObjectsStorage {
typedef StaticGraph<QueryEdge::EdgeData> QueryGraph;
typedef QueryGraph::InputEdge InputEdge;
return path(buffer);
}
NodeInformationHelpDesk * nodeHelpDesk;
std::vector<char> m_names_char_list;
std::vector<unsigned> m_name_begin_indices;
QueryGraph * graph;
std::string timestamp;
unsigned check_sum;
inline path unique_path(const path&) {
return temp_directory_path();
}
void GetName( const unsigned name_id, std::string & result ) const;
}
}
QueryObjectsStorage( const ServerPaths & paths );
~QueryObjectsStorage();
};
#endif
#endif /* QUERYOBJECTSSTORAGE_H_ */
#ifndef BOOST_FILESYSTEM_VERSION
#define BOOST_FILESYSTEM_VERSION 3
#endif
#endif /* BOOST_FILE_SYSTEM_FIX_H */
+82 -80
View File
@@ -42,7 +42,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/filesystem/fstream.hpp>
#include <boost/unordered_map.hpp>
#include <cassert>
#include <cmath>
#include <algorithm>
@@ -54,7 +53,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
typedef boost::unordered_map<NodeID, NodeID> ExternalNodeMap;
template<class EdgeT>
struct _ExcessRemover {
struct NodesWithoutSourceRemover {
inline bool operator()( const EdgeT & edge ) const {
return edge.source() == UINT_MAX;
}
@@ -62,16 +61,16 @@ struct _ExcessRemover {
template<typename EdgeT>
NodeID readBinaryOSRMGraphFromStream(
std::istream &in,
std::vector<EdgeT>& edgeList,
std::vector<NodeID> &bollardNodes,
std::vector<NodeID> &trafficLightNodes,
std::vector<NodeInfo> * int2ExtNodeMap,
std::vector<TurnRestriction> & inputRestrictions
std::istream & input_stream,
std::vector<EdgeT> & edge_list,
std::vector<NodeID> & barrier_node_list,
std::vector<NodeID> & traffic_light_node_list,
std::vector<NodeInfo> * int_to_ext_node_id_map,
std::vector<TurnRestriction> & restriction_list
) {
const UUID uuid_orig;
UUID uuid_loaded;
in.read((char *) &uuid_loaded, sizeof(UUID));
input_stream.read((char *) &uuid_loaded, sizeof(UUID));
if( !uuid_loaded.TestGraphUtil(uuid_orig) ) {
SimpleLogger().Write(logWARNING) <<
@@ -83,29 +82,31 @@ NodeID readBinaryOSRMGraphFromStream(
EdgeID m;
short dir;// direction (0 = open, 1 = forward, 2+ = open)
ExternalNodeMap ext_to_int_id_map;
in.read((char*)&n, sizeof(NodeID));
input_stream.read((char*)&n, sizeof(NodeID));
SimpleLogger().Write() << "Importing n = " << n << " nodes ";
_Node node;
for (NodeID i=0; i<n; ++i) {
in.read((char*)&node, sizeof(_Node));
int2ExtNodeMap->push_back(NodeInfo(node.lat, node.lon, node.id));
ExternalMemoryNode node;
for( NodeID i=0; i<n; ++i ) {
input_stream.read((char*)&node, sizeof(ExternalMemoryNode));
int_to_ext_node_id_map->push_back(
NodeInfo(node.lat, node.lon, node.id)
);
ext_to_int_id_map.emplace(node.id, i);
if(node.bollard) {
bollardNodes.push_back(i);
barrier_node_list.push_back(i);
}
if(node.trafficLight) {
trafficLightNodes.push_back(i);
traffic_light_node_list.push_back(i);
}
}
//tighten vector sizes
std::vector<NodeID>(bollardNodes).swap(bollardNodes);
std::vector<NodeID>(trafficLightNodes).swap(trafficLightNodes);
std::vector<NodeID>(barrier_node_list).swap(barrier_node_list);
std::vector<NodeID>(traffic_light_node_list).swap(traffic_light_node_list);
in.read((char*)&m, sizeof(unsigned));
input_stream.read((char*)&m, sizeof(unsigned));
SimpleLogger().Write() << " and " << m << " edges ";
// for(unsigned i = 0; i < inputRestrictions.size(); ++i) {
BOOST_FOREACH(TurnRestriction & current_restriction, inputRestrictions) {
// for(unsigned i = 0; i < restriction_list.size(); ++i) {
BOOST_FOREACH(TurnRestriction & current_restriction, restriction_list) {
ExternalNodeMap::iterator intNodeID = ext_to_int_id_map.find(current_restriction.fromNode);
if( intNodeID == ext_to_int_id_map.end()) {
SimpleLogger().Write(logDEBUG) << "Unmapped from Node of restriction";
@@ -129,7 +130,7 @@ NodeID readBinaryOSRMGraphFromStream(
current_restriction.toNode = intNodeID->second;
}
edgeList.reserve(m);
edge_list.reserve(m);
EdgeWeight weight;
short type;
NodeID nameID;
@@ -137,17 +138,17 @@ NodeID readBinaryOSRMGraphFromStream(
bool isRoundabout, ignoreInGrid, isAccessRestricted, isContraFlow;
for (EdgeID i=0; i<m; ++i) {
in.read((char*)&source, sizeof(unsigned));
in.read((char*)&target, sizeof(unsigned));
in.read((char*)&length, sizeof(int));
in.read((char*)&dir, sizeof(short));
in.read((char*)&weight, sizeof(int));
in.read((char*)&type, sizeof(short));
in.read((char*)&nameID, sizeof(unsigned));
in.read((char*)&isRoundabout, sizeof(bool));
in.read((char*)&ignoreInGrid, sizeof(bool));
in.read((char*)&isAccessRestricted, sizeof(bool));
in.read((char*)&isContraFlow, sizeof(bool));
input_stream.read((char*)&source, sizeof(unsigned));
input_stream.read((char*)&target, sizeof(unsigned));
input_stream.read((char*)&length, sizeof(int));
input_stream.read((char*)&dir, sizeof(short));
input_stream.read((char*)&weight, sizeof(int));
input_stream.read((char*)&type, sizeof(short));
input_stream.read((char*)&nameID, sizeof(unsigned));
input_stream.read((char*)&isRoundabout, sizeof(bool));
input_stream.read((char*)&ignoreInGrid, sizeof(bool));
input_stream.read((char*)&isAccessRestricted, sizeof(bool));
input_stream.read((char*)&isContraFlow, sizeof(bool));
BOOST_ASSERT_MSG(length > 0, "loaded null length edge" );
BOOST_ASSERT_MSG(weight > 0, "loaded null weight");
@@ -158,7 +159,7 @@ NodeID readBinaryOSRMGraphFromStream(
if (1 == dir) { backward = false; }
if (2 == dir) { forward = false; }
assert(type >= 0);
BOOST_ASSERT(type >= 0);
// translate the external NodeIDs to internal IDs
ExternalNodeMap::iterator intNodeID = ext_to_int_id_map.find(source);
@@ -189,47 +190,52 @@ NodeID readBinaryOSRMGraphFromStream(
}
EdgeT inputEdge(source, target, nameID, weight, forward, backward, type, isRoundabout, ignoreInGrid, isAccessRestricted, isContraFlow );
edgeList.push_back(inputEdge);
edge_list.push_back(inputEdge);
}
std::sort(edgeList.begin(), edgeList.end());
for(unsigned i = 1; i < edgeList.size(); ++i) {
if( (edgeList[i-1].target() == edgeList[i].target()) && (edgeList[i-1].source() == edgeList[i].source()) ) {
bool edgeFlagsAreEquivalent = (edgeList[i-1].isForward() == edgeList[i].isForward()) && (edgeList[i-1].isBackward() == edgeList[i].isBackward());
bool edgeFlagsAreSuperSet1 = (edgeList[i-1].isForward() && edgeList[i-1].isBackward()) && (edgeList[i].isBackward() != edgeList[i].isBackward() );
bool edgeFlagsAreSuperSet2 = (edgeList[i].isForward() && edgeList[i].isBackward()) && (edgeList[i-1].isBackward() != edgeList[i-1].isBackward() );
std::sort(edge_list.begin(), edge_list.end());
for(unsigned i = 1; i < edge_list.size(); ++i) {
if( (edge_list[i-1].target() == edge_list[i].target()) && (edge_list[i-1].source() == edge_list[i].source()) ) {
bool edgeFlagsAreEquivalent = (edge_list[i-1].isForward() == edge_list[i].isForward()) && (edge_list[i-1].isBackward() == edge_list[i].isBackward());
bool edgeFlagsAreSuperSet1 = (edge_list[i-1].isForward() && edge_list[i-1].isBackward()) && (edge_list[i].isBackward() != edge_list[i].isBackward() );
bool edgeFlagsAreSuperSet2 = (edge_list[i].isForward() && edge_list[i].isBackward()) && (edge_list[i-1].isBackward() != edge_list[i-1].isBackward() );
if( edgeFlagsAreEquivalent ) {
edgeList[i]._weight = std::min(edgeList[i-1].weight(), edgeList[i].weight());
edgeList[i-1]._source = UINT_MAX;
edge_list[i]._weight = std::min(edge_list[i-1].weight(), edge_list[i].weight());
edge_list[i-1]._source = UINT_MAX;
} else if (edgeFlagsAreSuperSet1) {
if(edgeList[i-1].weight() <= edgeList[i].weight()) {
if(edge_list[i-1].weight() <= edge_list[i].weight()) {
//edge i-1 is smaller and goes in both directions. Throw away the other edge
edgeList[i]._source = UINT_MAX;
edge_list[i]._source = UINT_MAX;
} else {
//edge i-1 is open in both directions, but edge i is smaller in one direction. Close edge i-1 in this direction
edgeList[i-1].forward = !edgeList[i].isForward();
edgeList[i-1].backward = !edgeList[i].isBackward();
edge_list[i-1].forward = !edge_list[i].isForward();
edge_list[i-1].backward = !edge_list[i].isBackward();
}
} else if (edgeFlagsAreSuperSet2) {
if(edgeList[i-1].weight() <= edgeList[i].weight()) {
if(edge_list[i-1].weight() <= edge_list[i].weight()) {
//edge i-1 is smaller for one direction. edge i is open in both. close edge i in the other direction
edgeList[i].forward = !edgeList[i-1].isForward();
edgeList[i].backward = !edgeList[i-1].isBackward();
edge_list[i].forward = !edge_list[i-1].isForward();
edge_list[i].backward = !edge_list[i-1].isBackward();
} else {
//edge i is smaller and goes in both direction. Throw away edge i-1
edgeList[i-1]._source = UINT_MAX;
edge_list[i-1]._source = UINT_MAX;
}
}
}
}
typename std::vector<EdgeT>::iterator newEnd = std::remove_if(edgeList.begin(), edgeList.end(), _ExcessRemover<EdgeT>());
typename std::vector<EdgeT>::iterator newEnd = std::remove_if(edge_list.begin(), edge_list.end(), NodesWithoutSourceRemover<EdgeT>());
ext_to_int_id_map.clear();
std::vector<EdgeT>(edgeList.begin(), newEnd).swap(edgeList); //remove excess candidates.
SimpleLogger().Write() << "Graph loaded ok and has " << edgeList.size() << " edges";
std::vector<EdgeT>(edge_list.begin(), newEnd).swap(edge_list); //remove excess candidates.
SimpleLogger().Write() << "Graph loaded ok and has " << edge_list.size() << " edges";
return n;
}
template<typename EdgeT>
NodeID readDTMPGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, std::vector<NodeInfo> * int2ExtNodeMap) {
NodeID readDTMPGraphFromStream(
std::istream &in,
std::vector<EdgeT>& edge_list,
std::vector<NodeInfo> * int_to_ext_node_id_map
) {
NodeID n, source, target, id;
EdgeID m;
int dir, xcoord, ycoord;// direction (0 = open, 1 = forward, 2+ = open)
@@ -238,13 +244,13 @@ NodeID readDTMPGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
SimpleLogger().Write(logDEBUG) << "Importing n = " << n << " nodes ";
for (NodeID i=0; i<n; ++i) {
in >> id >> ycoord >> xcoord;
int2ExtNodeMap->push_back(NodeInfo(xcoord, ycoord, id));
int_to_ext_node_id_map->push_back(NodeInfo(xcoord, ycoord, id));
ext_to_int_id_map.insert(std::make_pair(id, i));
}
in >> m;
SimpleLogger().Write(logDEBUG) << " and " << m << " edges";
edgeList.reserve(m);
edge_list.reserve(m);
for (EdgeID i=0; i<m; ++i) {
EdgeWeight weight;
unsigned speedType(0);
@@ -308,12 +314,12 @@ NodeID readDTMPGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
if(speedType == 13) {
weight = length;
}
assert(length > 0);
assert(weight > 0);
BOOST_ASSERT(length > 0);
BOOST_ASSERT(weight > 0);
if(dir <0 || dir > 2) {
SimpleLogger().Write(logWARNING) << "direction bogus: " << dir;
}
assert(0<=dir && dir<=2);
BOOST_ASSERT(0<=dir && dir<=2);
bool forward = true;
bool backward = true;
@@ -345,16 +351,16 @@ NodeID readDTMPGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
}
EdgeT inputEdge(source, target, 0, weight, forward, backward, type );
edgeList.push_back(inputEdge);
edge_list.push_back(inputEdge);
}
ext_to_int_id_map.clear();
std::vector<EdgeT>(edgeList.begin(), edgeList.end()).swap(edgeList); //remove excess candidates.
std::vector<EdgeT>(edge_list.begin(), edge_list.end()).swap(edge_list); //remove excess candidates.
std::cout << "ok" << std::endl;
return n;
}
template<typename EdgeT>
NodeID readDDSGGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, std::vector<NodeID> & int2ExtNodeMap) {
NodeID readDDSGGraphFromStream(std::istream &in, std::vector<EdgeT>& edge_list, std::vector<NodeID> & int_to_ext_node_id_map) {
ExternalNodeMap nodeMap;
NodeID n, source, target;
unsigned numberOfNodes = 0;
@@ -368,16 +374,16 @@ NodeID readDDSGGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
SimpleLogger().Write(logDEBUG) <<
"expecting " << n << " nodes and " << m << " edges ...";
edgeList.reserve(m);
edge_list.reserve(m);
for (EdgeID i=0; i<m; i++) {
EdgeWeight weight;
in >> source >> target >> weight >> dir;
assert(weight > 0);
BOOST_ASSERT(weight > 0);
if(dir <0 || dir > 3) {
throw OSRMException( "[error] direction bogus");
}
assert(0<=dir && dir<=3);
BOOST_ASSERT(0<=dir && dir<=3);
bool forward = true;
bool backward = true;
@@ -391,18 +397,18 @@ NodeID readDDSGGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
if( nodeMap.find(source) == nodeMap.end()) {
nodeMap.insert(std::make_pair(source, numberOfNodes ));
int2ExtNodeMap.push_back(source);
int_to_ext_node_id_map.push_back(source);
numberOfNodes++;
}
if( nodeMap.find(target) == nodeMap.end()) {
nodeMap.insert(std::make_pair(target, numberOfNodes));
int2ExtNodeMap.push_back(target);
int_to_ext_node_id_map.push_back(target);
numberOfNodes++;
}
EdgeT inputEdge(source, target, 0, weight, forward, backward, 1 );
edgeList.push_back(inputEdge);
edge_list.push_back(inputEdge);
}
std::vector<EdgeT>(edgeList.begin(), edgeList.end()).swap(edgeList); //remove excess candidates.
std::vector<EdgeT>(edge_list.begin(), edge_list.end()).swap(edge_list); //remove excess candidates.
nodeMap.clear();
return numberOfNodes;
@@ -410,12 +416,11 @@ NodeID readDDSGGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
template<typename NodeT, typename EdgeT>
unsigned readHSGRFromStream(
const std::string & hsgr_filename,
const boost::filesystem::path & hsgr_file,
std::vector<NodeT> & node_list,
std::vector<EdgeT> & edge_list,
unsigned * check_sum
) {
boost::filesystem::path hsgr_file(hsgr_filename);
if ( !boost::filesystem::exists( hsgr_file ) ) {
throw OSRMException("hsgr file does not exist");
}
@@ -434,20 +439,17 @@ unsigned readHSGRFromStream(
}
unsigned number_of_nodes = 0;
hsgr_input_stream.read((char*) check_sum, sizeof(unsigned));
hsgr_input_stream.read((char*) & number_of_nodes, sizeof(unsigned));
unsigned number_of_edges = 0;
hsgr_input_stream.read( (char*) check_sum, sizeof(unsigned) );
hsgr_input_stream.read( (char*) &number_of_nodes, sizeof(unsigned) );
BOOST_ASSERT_MSG( 0 != number_of_nodes, "number of nodes is zero");
hsgr_input_stream.read( (char*) &number_of_edges, sizeof(unsigned) );
BOOST_ASSERT_MSG( 0 != number_of_edges, "number of edges is zero");
node_list.resize(number_of_nodes + 1);
hsgr_input_stream.read(
(char*) &(node_list[0]),
number_of_nodes*sizeof(NodeT)
);
unsigned number_of_edges = 0;
hsgr_input_stream.read(
(char*) &number_of_edges,
sizeof(unsigned)
);
BOOST_ASSERT_MSG( 0 != number_of_edges, "number of edges is zero");
edge_list.resize(number_of_edges);
hsgr_input_stream.read(
+4
View File
@@ -71,6 +71,10 @@ public:
return parameters.Find(key);
}
std::string GetParameter(const std::string & key) const {
return parameters.Find(key);
}
bool Holds(const std::string & key) const {
return parameters.Holds(key);
}
+74 -57
View File
@@ -52,7 +52,7 @@ namespace boost {
// Validator for boost::filesystem::path, that verifies that the file
// exists. The validate() function must be defined in the same namespace
// as the target type, (boost::filesystem::path in this case), otherwise
// it is not be called
// it is not called
inline void validate(
boost::any & v,
const std::vector<std::string> & values,
@@ -65,20 +65,18 @@ namespace boost {
if(boost::filesystem::is_regular_file(input_string)) {
v = boost::any(boost::filesystem::path(input_string));
} else {
throw OSRMException(input_string);
throw OSRMException(input_string + " not found");
}
}
}
}
// support old capitalized option names by downcasing them with a regex replace
// read from file and store in a stringstream that can be passed to
// boost::program_options
// support old capitalized option names by down-casing them with a regex replace
inline void PrepareConfigFile(
const boost::filesystem::path& path,
std::string& output
) {
std::ifstream config_stream(path.string().c_str());
std::ifstream config_stream( path.string().c_str() );
std::string input_str(
(std::istreambuf_iterator<char>(config_stream)),
std::istreambuf_iterator<char>()
@@ -96,7 +94,8 @@ inline bool GenerateServerProgramOptions(
ServerPaths & paths,
std::string & ip_address,
int & ip_port,
int & requested_num_threads
int & requested_num_threads,
bool & use_shared_memory
) {
// declare a group of options that will be allowed only on command line
@@ -160,6 +159,11 @@ inline bool GenerateServerProgramOptions(
"threads,t",
boost::program_options::value<int>(&requested_num_threads)->default_value(8),
"Number of threads to use"
)
(
"sharedmemory,s",
boost::program_options::value<bool>(&use_shared_memory)->default_value(false),
"Load data from shared memory"
);
// hidden options, will be allowed both on command line and in config
@@ -208,9 +212,12 @@ inline bool GenerateServerProgramOptions(
boost::program_options::notify(option_variables);
// parse config file
ServerPaths::const_iterator path_iterator = paths.find("config");
if( path_iterator != paths.end() &&
boost::filesystem::is_regular_file(path_iterator->second)) {
ServerPaths::iterator path_iterator = paths.find("config");
if(
path_iterator != paths.end() &&
boost::filesystem::is_regular_file(path_iterator->second) &&
!option_variables.count("base")
) {
SimpleLogger().Write() <<
"Reading options from: " << path_iterator->second.string();
std::string config_str;
@@ -223,56 +230,66 @@ inline bool GenerateServerProgramOptions(
boost::program_options::notify(option_variables);
}
if(!option_variables.count("hsgrdata")) {
if(!option_variables.count("base")) {
throw OSRMException("hsgrdata (or base) must be specified");
if( !use_shared_memory && option_variables.count("base") ) {
std::string base_string = paths["base"].string();
path_iterator = paths.find("hsgrdata");
if(
path_iterator != paths.end() &&
!boost::filesystem::is_regular_file(path_iterator->second)
) {
path_iterator->second = base_string + ".hsgr";
}
path_iterator = paths.find("nodesdata");
if(
path_iterator != paths.end() &&
!boost::filesystem::is_regular_file(path_iterator->second)
) {
path_iterator->second = base_string + ".nodes";
}
path_iterator = paths.find("edgesdata");
if(
path_iterator != paths.end() &&
!boost::filesystem::is_regular_file(path_iterator->second)
) {
path_iterator->second = base_string + ".edges";
}
path_iterator = paths.find("ramindex");
if(
path_iterator != paths.end() &&
!boost::filesystem::is_regular_file(path_iterator->second)
) {
path_iterator->second = base_string + ".ramIndex";
}
path_iterator = paths.find("fileindex");
if(
path_iterator != paths.end() &&
!boost::filesystem::is_regular_file(path_iterator->second)
) {
path_iterator->second = base_string + ".fileIndex";
}
path_iterator = paths.find("namesdata");
if(
path_iterator != paths.end() &&
!boost::filesystem::is_regular_file(path_iterator->second)
) {
path_iterator->second = base_string + ".names";
}
path_iterator = paths.find("timestamp");
if(
path_iterator != paths.end() &&
!boost::filesystem::is_regular_file(path_iterator->second)
) {
path_iterator->second = base_string + ".timestamp";
}
paths["hsgrdata"] = std::string( paths["base"].string()) + ".hsgr";
}
if(!option_variables.count("nodesdata")) {
if(!option_variables.count("base")) {
throw OSRMException("nodesdata (or base) must be specified");
}
paths["nodesdata"] = std::string( paths["base"].c_str()) + ".nodes";
}
if(!option_variables.count("edgesdata")) {
if(!option_variables.count("base")) {
throw OSRMException("edgesdata (or base) must be specified");
}
paths["edgesdata"] = std::string( paths["base"].c_str()) + ".edges";
}
if(!option_variables.count("ramindex")) {
if(!option_variables.count("base")) {
throw OSRMException("ramindex (or base) must be specified");
}
paths["ramindex"] = std::string( paths["base"].c_str()) + ".ramIndex";
}
if(!option_variables.count("fileindex")) {
if(!option_variables.count("base")) {
throw OSRMException("fileindex (or base) must be specified");
}
paths["fileindex"] = std::string( paths["base"].c_str()) + ".fileIndex";
}
if(!option_variables.count("namesdata")) {
if(!option_variables.count("base")) {
throw OSRMException("namesdata (or base) must be specified");
}
paths["namesdata"] = std::string( paths["base"].c_str()) + ".names";
}
if(!option_variables.count("timestamp")) {
if(!option_variables.count("base")) {
throw OSRMException("timestamp (or base) must be specified");
}
paths["timestamp"] = std::string( paths["base"].c_str()) + ".timestamp";
}
if(1 > requested_num_threads) {
if( 1 > requested_num_threads ) {
throw OSRMException("Number of threads must be a positive number");
}
return true;
+10 -3
View File
@@ -37,6 +37,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
enum LogLevel { logINFO, logWARNING, logDEBUG };
static boost::mutex logger_mutex;
const char COL_RESET[] = "\x1b[0m";
const char RED[] = "\x1b[31m";
const char GREEN[] = "\x1b[32m";
const char YELLOW[] = "\x1b[33m";
const char BLUE[] = "\x1b[34m";
const char MAGENTA[] = "\x1b[35m";
const char CYAN[] = "\x1b[36m";
class LogPolicy : boost::noncopyable {
public:
@@ -97,14 +104,14 @@ public:
if(!LogPolicy::GetInstance().IsMute()) {
switch(level) {
case logINFO:
std::cout << os.str() << std::endl;
std::cout << os.str() << COL_RESET << std::endl;
break;
case logWARNING:
std::cerr << os.str() << std::endl;
std::cerr << RED << os.str() << COL_RESET << std::endl;
break;
case logDEBUG:
#ifndef NDEBUG
std::cout << os.str() << std::endl;
std::cout << YELLOW << os.str() << COL_RESET << std::endl;
#endif
break;
default:
+18 -4
View File
@@ -132,7 +132,10 @@ static inline void doubleToString(const double value, std::string & output){
boost::spirit::karma::generate(sink, boost::spirit::karma::double_, value);
}
static inline void doubleToStringWithTwoDigitsBehindComma(const double value, std::string & output){
static inline void doubleToStringWithTwoDigitsBehindComma(
const double value,
std::string & output
){
// The largest 32-bit integer is 4294967295, that is 10 chars
// On the safe side, add 1 for sign, and 1 for trailing zero
char buffer[12] ;
@@ -140,11 +143,19 @@ static inline void doubleToStringWithTwoDigitsBehindComma(const double value, st
output = buffer ;
}
inline void replaceAll(std::string &s, const std::string &sub, const std::string &other) {
inline void replaceAll(
std::string & s,
const std::string & sub,
const std::string & other
) {
boost::replace_all(s, sub, other);
}
inline void stringSplit(const std::string &s, const char delim, std::vector<std::string>& result) {
inline void stringSplit(
const std::string &s,
const char delim,
std::vector<std::string>& result
) {
boost::split(result, s, boost::is_any_of(std::string(&delim)));
}
@@ -166,7 +177,10 @@ inline std::string HTMLDeEntitize( std::string & result) {
return result;
}
inline bool StringStartsWith(const std::string & input, const std::string & prefix) {
inline bool StringStartsWith(
const std::string & input,
const std::string & prefix
) {
return boost::starts_with(input, prefix);
}
+4 -12
View File
@@ -30,13 +30,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#cmakedefine01 HAS64BITS
#cmakedefine MD5PREPARE "${MD5PREPARE}"
#cmakedefine MD5RTREE "${MD5RTREE}"
#cmakedefine MD5NODEINFO "${MD5NODEINFO}"
#cmakedefine MD5GRAPH "${MD5GRAPH}"
#cmakedefine MD5OBJECTS "${MD5OBJECTS}"
UUID::UUID() : magic_number(1297240911) {
md5_prepare[32] = md5_tree[32] = md5_nodeinfo[32] = md5_graph[32] =
md5_objects[32] = '\0';
md5_prepare[32] =
md5_tree[32] =
md5_graph[32] =
md5_objects[32] = '\0';
boost::uuids::name_generator gen(named_uuid);
std::string temp_string(__DATE__);
@@ -46,8 +47,6 @@ UUID::UUID() : magic_number(1297240911) {
temp_string += md5_prepare;
std::copy(MD5RTREE, MD5RTREE+32, md5_tree);
temp_string += md5_tree;
std::copy(MD5NODEINFO, MD5NODEINFO+32, md5_nodeinfo);
temp_string += md5_nodeinfo;
std::copy(MD5GRAPH, MD5GRAPH+32, md5_graph);
temp_string += md5_graph;
std::copy(MD5OBJECTS, MD5OBJECTS+32, md5_objects);
@@ -90,13 +89,6 @@ bool UUID::TestRTree(const UUID & other) const {
return std::equal(md5_tree, md5_tree+32, other.md5_tree);
}
bool UUID::TestNodeInfo(const UUID & other) const {
if(!other.IsMagicNumberOK()) {
throw OSRMException("nodes file misses magic number. Check or reprocess the file");
}
return std::equal(md5_nodeinfo, md5_nodeinfo+32, other.md5_nodeinfo);
}
bool UUID::TestQueryObjects(const UUID & other) const {
if(!other.IsMagicNumberOK()) {
throw OSRMException("missing magic number. Check or reprocess the file");
-1
View File
@@ -58,7 +58,6 @@ private:
const unsigned magic_number;
char md5_prepare[33];
char md5_tree[33];
char md5_nodeinfo[33];
char md5_graph[33];
char md5_objects[33];
+82
View File
@@ -0,0 +1,82 @@
# Locate Lua library
# This module defines
# LUA52_FOUND, if false, do not try to link to Lua
# LUA_LIBRARIES
# LUA_INCLUDE_DIR, where to find lua.h
# LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8)
#
# Note that the expected include convention is
# #include "lua.h"
# and not
# #include <lua/lua.h>
# This is because, the lua location is not standardized and may exist
# in locations other than lua/
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
# Copyright 2013 for Project-OSRM, Lua5.1 => Lua5.2
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
find_path(LUA_INCLUDE_DIR lua.h
HINTS
ENV LUA_DIR
PATH_SUFFIXES include/lua52 include/lua5.2 include/lua-5.2 include/lua include
PATHS
~/Library/Frameworks
/Library/Frameworks
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
)
find_library(LUA_LIBRARY
NAMES lua52 lua5.2 lua-5.2 lua
HINTS
ENV LUA_DIR
PATH_SUFFIXES lib
PATHS
~/Library/Frameworks
/Library/Frameworks
/sw
/opt/local
/opt/csw
/opt
)
if(LUA_LIBRARY)
# include the math library for Unix
if(UNIX AND NOT APPLE AND NOT BEOS)
find_library(LUA_MATH_LIBRARY m)
set( LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries")
# For Windows and Mac, don't need to explicitly include the math library
else()
set( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries")
endif()
endif()
if(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"")
string(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}")
unset(lua_version_str)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LUA_FOUND to TRUE if
# all listed variables are TRUE
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua52
REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
VERSION_VAR LUA_VERSION_STRING)
mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY)
+19 -12
View File
@@ -1,8 +1,8 @@
# Locate Lua library
# This module defines
# LUAJIT_FOUND, if false, do not try to link to Lua
# LUAJIT_FOUND, if false, do not try to link to Lua
# LUAJIT_LIBRARIES
# LUAJIT_INCLUDE_DIR, where to find lua.h
# LUAJIT_INCLUDE_DIR, where to find lua.h
#
# Note that the expected include convention is
# #include "lua.h"
@@ -28,8 +28,12 @@
# 2010 - modified for cronkite to find luajit instead of lua, as it was before.
#
if ( NOT LuaJIT_FIND_VERSION )
MESSAGE(FATAL_ERROR "You need to specify a version of libluajit to use")
ENDIF()
IF( NOT LUAJIT_FIND_QUIETLY )
MESSAGE(STATUS "Looking for LuaJIT...")
MESSAGE(STATUS "Looking for LuaJIT ${LuaJIT_FIND_VERSION}")
ENDIF()
FIND_PATH(LUAJIT_INCLUDE_DIR lua.h
@@ -47,8 +51,8 @@ FIND_PATH(LUAJIT_INCLUDE_DIR lua.h
/opt
)
FIND_LIBRARY(LUAJIT_LIBRARY
NAMES luajit-51 luajit-5.1 luajit
FIND_LIBRARY(LUAJIT_LIBRARY
NAMES luajit-${LuaJIT_FIND_VERSION_MAJOR}${LuaJIT_FIND_VERSION_MINOR} luajit-${LuaJIT_FIND_VERSION}
HINTS
$ENV{LUAJIT_DIR}
PATH_SUFFIXES lib64 lib
@@ -63,6 +67,7 @@ FIND_LIBRARY(LUAJIT_LIBRARY
/opt
)
IF(LUAJIT_LIBRARY)
# include the math library for Unix
IF(UNIX AND NOT APPLE)
FIND_LIBRARY(LUAJIT_MATH_LIBRARY m)
@@ -71,16 +76,18 @@ FIND_LIBRARY(LUAJIT_LIBRARY
ELSE(UNIX AND NOT APPLE)
SET( LUAJIT_LIBRARIES "${LUAJIT_LIBRARY}" CACHE STRING "Lua Libraries")
ENDIF(UNIX AND NOT APPLE)
#ENDIF(LUAJIT_LIBRARY)
ENDIF(LUAJIT_LIBRARY)
INCLUDE(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LUAJIT_FOUND to TRUE if
# handle the QUIETLY and REQUIRED arguments and set LUAJIT_FOUND to TRUE if
# all listed variables are TRUE
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LuaJIT DEFAULT_MSG LUAJIT_LIBRARIES LUAJIT_INCLUDE_DIR)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LUAJIT DEFAULT_MSG LUAJIT_LIBRARIES LUAJIT_INCLUDE_DIR)
IF( NOT LUAJIT_FIND_QUIETLY )
IF( LUAJIT_FOUND )
MESSAGE(STATUS "Found LuaJIT: ${LUAJIT_LIBRARY}" )
ENDIF()
IF( LUAJIT_FOUND AND LUAJIT_LIBRARIES)
MESSAGE(STATUS "Found LuaJIT: ${LUAJIT_LIBRARY}" )
MARK_AS_ADVANCED(LUAJIT_INCLUDE_DIR LUAJIT_LIBRARIES LUAJIT_LIBRARY LUAJIT_MATH_LIBRARY)
ELSE()
SET ( LUAJIT_FOUND FALSE )
ENDIF()
ENDIF()
MARK_AS_ADVANCED(LUAJIT_INCLUDE_DIR LUAJIT_LIBRARIES LUAJIT_LIBRARY LUAJIT_MATH_LIBRARY)
+1 -1
View File
@@ -48,4 +48,4 @@ IF( NOT STXXL_FIND_QUIETLY )
ENDIF()
ENDIF()
MARK_AS_ADVANCED(STXXL_INCLUDE_DIR STXXL_LIBRARY)
MARK_AS_ADVANCED(STXXL_INCLUDE_DIR STXXL_LIBRARY)
+2 -3
View File
@@ -2,10 +2,9 @@ set(OLDFILE ${SOURCE_DIR}/Util/UUID.cpp)
if (EXISTS ${OLDFILE})
file(REMOVE_RECURSE ${OLDFILE})
endif()
file(MD5 ${SOURCE_DIR}/createHierarchy.cpp MD5PREPARE)
file(MD5 ${SOURCE_DIR}/prepare.cpp MD5PREPARE)
file(MD5 ${SOURCE_DIR}/DataStructures/StaticRTree.h MD5RTREE)
file(MD5 ${SOURCE_DIR}/DataStructures/NodeInformationHelpDesk.h MD5NODEINFO)
file(MD5 ${SOURCE_DIR}/Util/GraphLoader.h MD5GRAPH)
file(MD5 ${SOURCE_DIR}/Server/DataStructures/QueryObjectsStorage.cpp MD5OBJECTS)
file(MD5 ${SOURCE_DIR}/Server/DataStructures/InternalDataFacade.h MD5OBJECTS)
CONFIGURE_FILE( ${SOURCE_DIR}/Util/UUID.cpp.in ${SOURCE_DIR}/Util/UUID.cpp )
+430
View File
@@ -0,0 +1,430 @@
/*
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 "DataStructures/QueryEdge.h"
#include "DataStructures/SharedMemoryFactory.h"
#include "DataStructures/SharedMemoryVectorWrapper.h"
#include "DataStructures/StaticGraph.h"
#include "DataStructures/StaticRTree.h"
#include "Server/DataStructures/BaseDataFacade.h"
#include "Server/DataStructures/SharedDataType.h"
#include "Server/DataStructures/SharedBarriers.h"
#include "Util/BoostFileSystemFix.h"
#include "Util/ProgramOptions.h"
#include "Util/SimpleLogger.h"
#include "Util/UUID.h"
#include "typedefs.h"
#ifdef __linux__
#include <sys/mman.h>
#endif
#include <boost/integer.hpp>
#include <boost/filesystem/fstream.hpp>
#include <string>
#include <vector>
int main( const int argc, const char * argv[] ) {
SharedBarriers barrier;
#ifdef __linux__
if( -1 == mlockall(MCL_CURRENT | MCL_FUTURE) ) {
SimpleLogger().Write(logWARNING) <<
"Process " << argv[0] << " could not request RAM lock";
}
#endif
try {
boost::interprocess::scoped_lock<
boost::interprocess::named_mutex
> pending_lock(barrier.pending_update_mutex);
} catch(...) {
// hard unlock in case of any exception.
barrier.pending_update_mutex.unlock();
}
try {
LogPolicy::GetInstance().Unmute();
SimpleLogger().Write(logDEBUG) << "Checking input parameters";
bool use_shared_memory = false;
std::string ip_address;
int ip_port, requested_num_threads;
ServerPaths server_paths;
if(
!GenerateServerProgramOptions(
argc,
argv,
server_paths,
ip_address,
ip_port,
requested_num_threads,
use_shared_memory
)
) {
return 0;
}
if( server_paths.find("hsgrdata") == server_paths.end() ) {
throw OSRMException("no hsgr file given in ini file");
}
if( server_paths.find("ramindex") == server_paths.end() ) {
throw OSRMException("no ram index file given in ini file");
}
if( server_paths.find("fileindex") == server_paths.end() ) {
throw OSRMException("no leaf index file given in ini file");
}
if( server_paths.find("nodesdata") == server_paths.end() ) {
throw OSRMException("no nodes file given in ini file");
}
if( server_paths.find("edgesdata") == server_paths.end() ) {
throw OSRMException("no edges file given in ini file");
}
if( server_paths.find("namesdata") == server_paths.end() ) {
throw OSRMException("no names file given in ini file");
}
ServerPaths::const_iterator paths_iterator = server_paths.find("hsgrdata");
BOOST_ASSERT(server_paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path & hsgr_path = paths_iterator->second;
paths_iterator = server_paths.find("timestamp");
BOOST_ASSERT(server_paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path & timestamp_path = paths_iterator->second;
paths_iterator = server_paths.find("ramindex");
BOOST_ASSERT(server_paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path & ram_index_path = paths_iterator->second;
paths_iterator = server_paths.find("fileindex");
BOOST_ASSERT(server_paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const std::string & file_index_file_name = paths_iterator->second.string();
paths_iterator = server_paths.find("nodesdata");
BOOST_ASSERT(server_paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path & nodes_data_path = paths_iterator->second;
paths_iterator = server_paths.find("edgesdata");
BOOST_ASSERT(server_paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path & edges_data_path = paths_iterator->second;
paths_iterator = server_paths.find("namesdata");
BOOST_ASSERT(server_paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path & names_data_path = paths_iterator->second;
// get the shared memory segment to use
bool use_first_segment = SharedMemory::RegionExists( LAYOUT_2 );
SharedDataType LAYOUT = ( use_first_segment ? LAYOUT_1 : LAYOUT_2 );
SharedDataType DATA = ( use_first_segment ? DATA_1 : DATA_2 );
// Allocate a memory layout in shared memory, deallocate previous
SharedMemory * layout_memory = SharedMemoryFactory::Get(
LAYOUT,
sizeof(SharedDataLayout)
);
SharedDataLayout * shared_layout_ptr = static_cast<SharedDataLayout *>(
layout_memory->Ptr()
);
shared_layout_ptr = new(layout_memory->Ptr()) SharedDataLayout();
std::copy(
file_index_file_name.begin(),
(file_index_file_name.length() <= 1024 ? file_index_file_name.end() : file_index_file_name.begin()+1023),
shared_layout_ptr->ram_index_file_name
);
// add zero termination
unsigned end_of_string_index = std::min(1023ul, file_index_file_name.length());
shared_layout_ptr->ram_index_file_name[end_of_string_index] = '\0';
// collect number of elements to store in shared memory object
SimpleLogger().Write(logDEBUG) << "Collecting files sizes";
SimpleLogger().Write() << "load names from: " << names_data_path;
// number of entries in name index
boost::filesystem::ifstream name_stream(
names_data_path, std::ios::binary
);
unsigned name_index_size = 0;
name_stream.read((char *)&name_index_size, sizeof(unsigned));
shared_layout_ptr->name_index_list_size = name_index_size;
SimpleLogger().Write() << "size: " << name_index_size;
// SimpleLogger().Write() << "name index size: " << shared_layout_ptr->name_index_list_size;
BOOST_ASSERT_MSG(0 != shared_layout_ptr->name_index_list_size, "name file broken");
unsigned number_of_chars = 0;
name_stream.read((char *)&number_of_chars, sizeof(unsigned));
shared_layout_ptr->name_char_list_size = number_of_chars;
// SimpleLogger().Write() << "name char size: " << shared_layout_ptr->name_char_list_size;
//Loading information for original edges
boost::filesystem::ifstream edges_input_stream(
edges_data_path,
std::ios::binary
);
unsigned number_of_original_edges = 0;
edges_input_stream.read((char*)&number_of_original_edges, sizeof(unsigned));
shared_layout_ptr->via_node_list_size = number_of_original_edges;
shared_layout_ptr->name_id_list_size = number_of_original_edges;
shared_layout_ptr->turn_instruction_list_size = number_of_original_edges;
boost::filesystem::ifstream hsgr_input_stream(
hsgr_path,
std::ios::binary
);
UUID uuid_loaded, uuid_orig;
hsgr_input_stream.read((char *)&uuid_loaded, sizeof(UUID));
if( !uuid_loaded.TestGraphUtil(uuid_orig) ) {
SimpleLogger().Write(logWARNING) <<
".hsgr was prepared with different build. "
"Reprocess to get rid of this warning.";
} else {
SimpleLogger().Write(logDEBUG) << "UUID checked out ok";
}
// load checksum
unsigned checksum = 0;
hsgr_input_stream.read((char*)&checksum, sizeof(unsigned) );
shared_layout_ptr->checksum = checksum;
// load graph node size
unsigned number_of_graph_nodes = 0;
hsgr_input_stream.read(
(char*) &number_of_graph_nodes,
sizeof(unsigned)
);
BOOST_ASSERT_MSG(
(0 != number_of_graph_nodes),
"number of nodes is zero"
);
shared_layout_ptr->graph_node_list_size = number_of_graph_nodes;
// load graph edge size
unsigned number_of_graph_edges = 0;
hsgr_input_stream.read( (char*) &number_of_graph_edges, sizeof(unsigned) );
BOOST_ASSERT_MSG(
0 != number_of_graph_edges,
"number of graph edges is zero"
);
shared_layout_ptr->graph_edge_list_size = number_of_graph_edges;
// load rsearch tree size
boost::filesystem::ifstream tree_node_file(
ram_index_path,
std::ios::binary
);
uint32_t tree_size = 0;
tree_node_file.read((char*)&tree_size, sizeof(uint32_t));
shared_layout_ptr->r_search_tree_size = tree_size;
//load timestamp size
std::string m_timestamp;
if( boost::filesystem::exists(timestamp_path) ) {
boost::filesystem::ifstream timestampInStream( timestamp_path );
if(!timestampInStream) {
SimpleLogger().Write(logWARNING) <<
timestamp_path << " not found. setting to default";
} else {
getline(timestampInStream, m_timestamp);
timestampInStream.close();
}
}
if(m_timestamp.empty()) {
m_timestamp = "n/a";
}
if(25 < m_timestamp.length()) {
m_timestamp.resize(25);
}
shared_layout_ptr->timestamp_length = m_timestamp.length();
//load coordinate size
boost::filesystem::ifstream nodes_input_stream(
nodes_data_path,
std::ios::binary
);
unsigned coordinate_list_size = 0;
nodes_input_stream.read((char *)&coordinate_list_size, sizeof(unsigned));
shared_layout_ptr->coordinate_list_size = coordinate_list_size;
// allocate shared memory block
SimpleLogger().Write() << "allocating shared memory of " << shared_layout_ptr->GetSizeOfLayout() << " bytes";
SharedMemory * shared_memory = SharedMemoryFactory::Get(
DATA,
shared_layout_ptr->GetSizeOfLayout()
);
char * shared_memory_ptr = static_cast<char *>(shared_memory->Ptr());
// read actual data into shared memory object //
// Loading street names
// SimpleLogger().Write() << "Loading names index and chars from: " << names_data_path.string();
unsigned * name_index_ptr = (unsigned*)(
shared_memory_ptr + shared_layout_ptr->GetNameIndexOffset()
);
// SimpleLogger().Write(logDEBUG) << "Bytes: " << shared_layout_ptr->name_index_list_size*sizeof(unsigned);
name_stream.read(
(char*)name_index_ptr,
shared_layout_ptr->name_index_list_size*sizeof(unsigned)
);
char * name_char_ptr = shared_memory_ptr + shared_layout_ptr->GetNameListOffset();
name_stream.read(
name_char_ptr,
shared_layout_ptr->name_char_list_size*sizeof(char)
);
name_stream.close();
//load original edge information
NodeID * via_node_ptr = (NodeID *)(
shared_memory_ptr + shared_layout_ptr->GetViaNodeListOffset()
);
unsigned * name_id_ptr = (unsigned *)(
shared_memory_ptr + shared_layout_ptr->GetNameIDListOffset()
);
TurnInstruction * turn_instructions_ptr = (TurnInstruction *)(
shared_memory_ptr + shared_layout_ptr->GetTurnInstructionListOffset()
);
OriginalEdgeData current_edge_data;
for(unsigned i = 0; i < number_of_original_edges; ++i) {
// SimpleLogger().Write() << i << "/" << number_of_edges;
edges_input_stream.read(
(char*)&(current_edge_data),
sizeof(OriginalEdgeData)
);
via_node_ptr[i] = current_edge_data.viaNode;
name_id_ptr[i] = current_edge_data.nameID;
turn_instructions_ptr[i] = current_edge_data.turnInstruction;
}
edges_input_stream.close();
// Loading list of coordinates
FixedPointCoordinate * coordinates_ptr = (FixedPointCoordinate *)(
shared_memory_ptr + shared_layout_ptr->GetCoordinateListOffset()
);
NodeInfo current_node;
for(unsigned i = 0; i < coordinate_list_size; ++i) {
nodes_input_stream.read((char *)&current_node, sizeof(NodeInfo));
coordinates_ptr[i] = FixedPointCoordinate(current_node.lat, current_node.lon);
}
nodes_input_stream.close();
//store timestamp
char * timestamp_ptr = static_cast<char *>(
shared_memory_ptr + shared_layout_ptr->GetTimeStampOffset()
);
std::copy(
m_timestamp.c_str(),
m_timestamp.c_str()+m_timestamp.length(),
timestamp_ptr
);
// store search tree portion of rtree
char * rtree_ptr = static_cast<char *>(
shared_memory_ptr + shared_layout_ptr->GetRSearchTreeOffset()
);
tree_node_file.read(rtree_ptr, sizeof(RTreeNode)*tree_size);
tree_node_file.close();
// load the nodes of the search graph
QueryGraph::_StrNode * graph_node_list_ptr = (QueryGraph::_StrNode*)(
shared_memory_ptr + shared_layout_ptr->GetGraphNodeListOffset()
);
hsgr_input_stream.read(
(char*) graph_node_list_ptr,
shared_layout_ptr->graph_node_list_size*sizeof(QueryGraph::_StrNode)
);
// load the edges of the search graph
QueryGraph::_StrEdge * graph_edge_list_ptr = (QueryGraph::_StrEdge *)(
shared_memory_ptr + shared_layout_ptr->GetGraphEdgeListOffsett()
);
hsgr_input_stream.read(
(char*) graph_edge_list_ptr,
shared_layout_ptr->graph_edge_list_size*sizeof(QueryGraph::_StrEdge)
);
hsgr_input_stream.close();
//TODO acquire lock
SharedMemory * data_type_memory = SharedMemoryFactory::Get(
CURRENT_REGIONS,
sizeof(SharedDataTimestamp),
true,
false
);
SharedDataTimestamp * data_timestamp_ptr = static_cast<SharedDataTimestamp*>(
data_type_memory->Ptr()
);
boost::interprocess::scoped_lock<
boost::interprocess::named_mutex
> query_lock(barrier.query_mutex);
// notify all processes that were waiting for this condition
if (0 < barrier.number_of_queries) {
barrier.no_running_queries_condition.wait(query_lock);
}
data_timestamp_ptr->layout = LAYOUT;
data_timestamp_ptr->data = DATA;
data_timestamp_ptr->timestamp +=1;
if(use_first_segment) {
BOOST_ASSERT( DATA == DATA_1 );
BOOST_ASSERT( LAYOUT == LAYOUT_1 );
if( !SharedMemory::Remove(DATA_2) ) {
SimpleLogger().Write(logWARNING) << "could not delete DATA_2";
}
if( !SharedMemory::Remove(LAYOUT_2) ) {
SimpleLogger().Write(logWARNING) << "could not delete LAYOUT_2";
}
} else {
BOOST_ASSERT( DATA == DATA_2 );
BOOST_ASSERT( LAYOUT == LAYOUT_2 );
if( !SharedMemory::Remove(DATA_1) ) {
SimpleLogger().Write(logWARNING) << "could not delete DATA_1";
}
if( !SharedMemory::Remove(LAYOUT_1) ) {
SimpleLogger().Write(logWARNING) << "could not delete LAYOUT_1";
}
}
SimpleLogger().Write() << "all data loaded";
} catch(const std::exception & e) {
SimpleLogger().Write(logWARNING) << "caught exception: " << e.what();
}
return 0;
}
+1 -7
View File
@@ -169,12 +169,6 @@ int main (int argc, char *argv[]) {
}
}
unsigned amountOfRAM = 1;
unsigned installedRAM = GetPhysicalmemory();
if(installedRAM < 2048264) {
SimpleLogger().Write(logWARNING) << "Machine has less than 2GB RAM.";
}
StringMap stringMap;
ExtractionContainers externalMemory;
@@ -197,7 +191,7 @@ int main (int argc, char *argv[]) {
(get_timestamp() - parsing_start_time) <<
" seconds";
externalMemory.PrepareData(output_file_name, restrictionsFileName, amountOfRAM);
externalMemory.PrepareData(output_file_name, restrictionsFileName);
delete parser;
delete extractCallBacks;
+31 -20
View File
@@ -236,18 +236,13 @@ int main (int argc, char *argv[]) {
NodeID nodeBasedNodeNumber = readBinaryOSRMGraphFromStream(in, edgeList, bollardNodes, trafficLightNodes, &internalToExternalNodeMapping, inputRestrictions);
in.close();
SimpleLogger().Write() <<
inputRestrictions.size() <<
" restrictions, " <<
bollardNodes.size() <<
" bollard nodes, " <<
trafficLightNodes.size() <<
" traffic lights";
inputRestrictions.size() << " restrictions, " <<
bollardNodes.size() << " bollard nodes, " <<
trafficLightNodes.size() << " traffic lights";
if(0 == edgeList.size()) {
std::cerr <<
"The input data is broken. "
"It is impossible to do any turns in this graph" <<
std::endl;
if( edgeList.empty() ) {
SimpleLogger().Write(logWARNING) << "The input data is broken. "
"It is impossible to do any turns in this graph";
return -1;
}
@@ -265,7 +260,7 @@ int main (int argc, char *argv[]) {
NodeID edgeBasedNodeNumber = edgeBasedGraphFactory->GetNumberOfNodes();
DeallocatingVector<EdgeBasedEdge> edgeBasedEdgeList;
edgeBasedGraphFactory->GetEdgeBasedEdges(edgeBasedEdgeList);
std::vector<EdgeBasedGraphFactory::EdgeBasedNode> nodeBasedEdgeList;
std::vector<EdgeBasedNode> nodeBasedEdgeList;
edgeBasedGraphFactory->GetEdgeBasedNodes(nodeBasedEdgeList);
delete edgeBasedGraphFactory;
@@ -275,7 +270,12 @@ int main (int argc, char *argv[]) {
SimpleLogger().Write() << "writing node map ...";
std::ofstream mapOutFile(nodeOut.c_str(), std::ios::binary);
mapOutFile.write((char *)&(internalToExternalNodeMapping[0]), internalToExternalNodeMapping.size()*sizeof(NodeInfo));
const unsigned size_of_mapping = internalToExternalNodeMapping.size();
mapOutFile.write((char *)&size_of_mapping, sizeof(unsigned));
mapOutFile.write(
(char *)&(internalToExternalNodeMapping[0]),
size_of_mapping*sizeof(NodeInfo)
);
mapOutFile.close();
std::vector<NodeInfo>().swap(internalToExternalNodeMapping);
@@ -286,14 +286,14 @@ int main (int argc, char *argv[]) {
*/
SimpleLogger().Write() << "building r-tree ...";
StaticRTree<EdgeBasedGraphFactory::EdgeBasedNode> * rtree =
new StaticRTree<EdgeBasedGraphFactory::EdgeBasedNode>(
StaticRTree<EdgeBasedNode> * rtree =
new StaticRTree<EdgeBasedNode>(
nodeBasedEdgeList,
rtree_nodes_path.c_str(),
rtree_leafs_path.c_str()
);
delete rtree;
IteratorbasedCRC32<std::vector<EdgeBasedGraphFactory::EdgeBasedNode> > crc32;
IteratorbasedCRC32<std::vector<EdgeBasedNode> > crc32;
unsigned crc32OfNodeBasedEdgeList = crc32(nodeBasedEdgeList.begin(), nodeBasedEdgeList.end() );
nodeBasedEdgeList.clear();
SimpleLogger().Write() << "CRC32: " << crc32OfNodeBasedEdgeList;
@@ -346,20 +346,31 @@ int main (int argc, char *argv[]) {
StaticGraph<EdgeData>::EdgeIterator edge = 0;
StaticGraph<EdgeData>::EdgeIterator position = 0;
for ( StaticGraph<EdgeData>::NodeIterator node = 0; node <= numberOfNodes; ++node ) {
for ( StaticGraph<EdgeData>::NodeIterator node = 0; node < numberOfNodes; ++node ) {
StaticGraph<EdgeData>::EdgeIterator lastEdge = edge;
while ( edge < numberOfEdges && contractedEdgeList[edge].source == node )
++edge;
_nodes[node].firstEdge = position; //=edge
position += edge - lastEdge; //remove
}
_nodes.back().firstEdge = numberOfEdges; //sentinel element
++numberOfNodes;
//Serialize numberOfNodes, nodes
BOOST_ASSERT_MSG(
_nodes.size() == numberOfNodes,
"no. of nodes dont match"
);
//serialize crc32, aka checksum
hsgr_output_stream.write((char*) &crc32OfNodeBasedEdgeList, sizeof(unsigned));
//serialize number f nodes
hsgr_output_stream.write((char*) &numberOfNodes, sizeof(unsigned));
hsgr_output_stream.write((char*) &_nodes[0], sizeof(StaticGraph<EdgeData>::_StrNode)*(numberOfNodes));
//Serialize number of Edges
//serialize number of edges
hsgr_output_stream.write((char*) &position, sizeof(unsigned));
//serialize all nodes
hsgr_output_stream.write((char*) &_nodes[0], sizeof(StaticGraph<EdgeData>::_StrNode)*(numberOfNodes));
//serialize all edges
--numberOfNodes;
edge = 0;
int usedEdgeCounter = 0;
+11 -2
View File
@@ -3,7 +3,7 @@ require("lib/access")
barrier_whitelist = { ["cattle_grid"] = true, ["border_control"] = true, ["toll_booth"] = true, ["sally_port"] = true, ["gate"] = true, ["no"] = true, ["entrance"] = true}
access_tag_whitelist = { ["yes"] = true, ["motorcar"] = true, ["motor_vehicle"] = true, ["vehicle"] = true, ["permissive"] = true, ["designated"] = true }
access_tag_blacklist = { ["no"] = true, ["private"] = true, ["agricultural"] = true, ["forestry"] = true }
access_tag_blacklist = { ["no"] = true, ["private"] = true, ["agricultural"] = true, ["forestry"] = true, ["emergency"] = true }
access_tag_restricted = { ["destination"] = true, ["delivery"] = true }
access_tags = { "motorcar", "motor_vehicle", "vehicle" }
access_tags_hierachy = { "motorcar", "motor_vehicle", "vehicle", "access" }
@@ -101,6 +101,16 @@ function way_function (way)
return
end
local impassable = way.tags:Find("impassable")
if "yes" == impassable then
return
end
local status = way.tags:Find("status")
if "impassable" == status then
return
end
-- Check if we are allowed to access the way
local access = Access.find_access_tag(way, access_tags_hierachy)
if access_tag_blacklist[access] then
@@ -121,7 +131,6 @@ function way_function (way)
local duration = way.tags:Find("duration")
local service = way.tags:Find("service")
-- Set the name that will be used for instructions
if "" ~= ref then
way.name = ref
+82
View File
@@ -0,0 +1,82 @@
-- This example shows how to query external data stored in PostGIS when processing ways.
-- This profile assumes that OSM data has been imported to PostGIS using imposm to a db
-- with the name 'imposm', the default user and no password. It assumes areas with
-- landusage=* was imported to the table osm_landusages, containting the columns type and area.
-- Seee http://imposm.org/ for more info on imposm.
-- Other tools for importing OSM data to PostGIS include osm2pgsql and osmosis.
-- It uses the PostGIS function ST_DWithin() to find areas tagged with landuse=industrial
-- that are within 100 meters of the way.
-- It then slows down the routing depending on the number and size of the industrial area.
-- The end result is that routes will tend to avoid industrial area. Passing through
-- industrial areas is still possible, it's just slower, and thus avoided if a reasonable
-- alternative is found.
-- We use the osm id as the key when querying PostGIS. Be sure to add an index to the colunn
-- containing the osm id (osm_id in this case), otherwise you will suffer form very
-- bad performance. You should also have spatial indexes on the relevant gemoetry columns.
-- More info about using SQL form LUA can be found at http://www.keplerproject.org/luasql/
-- Happy routing!
-- Open PostGIS connection
lua_sql = require "luasql.postgres" -- we will connect to a postgresql database
sql_env = assert( lua_sql.postgres() )
sql_con = assert( sql_env:connect("imposm") ) -- you can add db user/password here if needed
print("PostGIS connection opened")
-- these settings are read directly by osrm
take_minimum_of_speeds = true
obey_oneway = true
obey_bollards = true
use_restrictions = true
ignore_areas = true -- future feature
traffic_signal_penalty = 7 -- seconds
u_turn_penalty = 20
-- nodes processing, called from OSRM
function node_function(node)
return 1
end
-- ways processing, called from OSRM
function way_function (way)
-- only route on ways with highway=*
local highway = way.tags:Find("highway")
if (not highway or highway=='') then
return 0
end
-- Query PostGIS for industrial areas close to the way, then group by way and sum the areas.
-- We take the square root of the area to get a estimate of the length of the side of the area,
-- and thus a rough guess of how far we might be travelling along the area.
local sql_query = " " ..
"SELECT SUM(SQRT(area.area)) AS val " ..
"FROM osm_ways way " ..
"LEFT JOIN osm_landusages area ON ST_DWithin(way.geometry, area.geometry, 100) " ..
"WHERE area.type IN ('industrial') AND way.osm_id=" .. way.id .. " " ..
"GROUP BY way.id"
local cursor = assert( sql_con:execute(sql_query) ) -- execute querty
local row = cursor:fetch( {}, "a" ) -- fetch first (and only) row
way.speed = 20.0 -- default speed
if row then
local val = tonumber(row.val) -- read 'val' from row
if val > 10 then
way.speed = way.speed / math.log10( val ) -- reduce speed by amount of industry close by
end
end
cursor:close() -- done with this query
-- set other required info for this way
way.name = way.tags:Find("name")
way.direction = Way.bidirectional
way.type = 1
return 1
end
+33 -26
View File
@@ -72,12 +72,13 @@ int main (int argc, const char * argv[]) {
try {
LogPolicy::GetInstance().Unmute();
#ifdef __linux__
if(!mlockall(MCL_CURRENT | MCL_FUTURE)) {
if( -1 == mlockall(MCL_CURRENT | MCL_FUTURE) ) {
SimpleLogger().Write(logWARNING) <<
"Process " << argv[0] << "could not be locked to RAM";
"Process " << argv[0] << " could not be locked to RAM";
}
installCrashHandler(argv[0]);
#endif
bool use_shared_memory = false;
std::string ip_address;
int ip_port, requested_num_threads;
@@ -88,7 +89,8 @@ int main (int argc, const char * argv[]) {
server_paths,
ip_address,
ip_port,
requested_num_threads
requested_num_threads,
use_shared_memory
)
) {
return 0;
@@ -98,27 +100,30 @@ int main (int argc, const char * argv[]) {
"starting up engines, " << g_GIT_DESCRIPTION << ", " <<
"compiled at " << __DATE__ << ", " __TIME__;
SimpleLogger().Write() <<
"HSGR file:\t" << server_paths["hsgrdata"];
SimpleLogger().Write() <<
"Nodes file:\t" << server_paths["nodesdata"];
SimpleLogger().Write() <<
"Edges file:\t" << server_paths["edgesdata"];
SimpleLogger().Write() <<
"RAM file:\t" << server_paths["ramindex"];
SimpleLogger().Write() <<
"Index file:\t" << server_paths["fileindex"];
SimpleLogger().Write() <<
"Names file:\t" << server_paths["namesdata"];
SimpleLogger().Write() <<
"Timestamp file:\t" << server_paths["timestamp"];
SimpleLogger().Write() <<
"Threads:\t" << requested_num_threads;
SimpleLogger().Write() <<
"IP address:\t" << ip_address;
SimpleLogger().Write() <<
"IP port:\t" << ip_port;
if( use_shared_memory ) {
SimpleLogger().Write(logDEBUG) << "Loading from shared memory";
} else {
SimpleLogger().Write() <<
"HSGR file:\t" << server_paths["hsgrdata"];
SimpleLogger().Write(logDEBUG) <<
"Nodes file:\t" << server_paths["nodesdata"];
SimpleLogger().Write(logDEBUG) <<
"Edges file:\t" << server_paths["edgesdata"];
SimpleLogger().Write(logDEBUG) <<
"RAM file:\t" << server_paths["ramindex"];
SimpleLogger().Write(logDEBUG) <<
"Index file:\t" << server_paths["fileindex"];
SimpleLogger().Write(logDEBUG) <<
"Names file:\t" << server_paths["namesdata"];
SimpleLogger().Write(logDEBUG) <<
"Timestamp file:\t" << server_paths["timestamp"];
SimpleLogger().Write(logDEBUG) <<
"Threads:\t" << requested_num_threads;
SimpleLogger().Write(logDEBUG) <<
"IP address:\t" << ip_address;
SimpleLogger().Write(logDEBUG) <<
"IP port:\t" << ip_port;
}
#ifndef _WIN32
int sig = 0;
sigset_t new_mask;
@@ -127,12 +132,13 @@ int main (int argc, const char * argv[]) {
pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask);
#endif
OSRM routing_machine(server_paths);
OSRM routing_machine(server_paths, use_shared_memory);
Server * s = ServerFactory::CreateServer(
ip_address,
ip_port,
requested_num_threads
);
s->GetRequestHandlerPtr().RegisterRoutingMachine(&routing_machine);
boost::thread t(boost::bind(&Server::Run, s));
@@ -159,7 +165,8 @@ int main (int argc, const char * argv[]) {
std::cout << "[server] stopping threads" << std::endl;
if(!t.timed_join(boost::posix_time::seconds(2))) {
SimpleLogger().Write(logDEBUG) << "Threads did not finish within 2 seconds. Hard abort!";
SimpleLogger().Write(logDEBUG) <<
"Threads did not finish within 2 seconds. Hard abort!";
}
std::cout << "[server] freeing objects" << std::endl;